From 833f7b6324908c83dcf458aae3c6d9c3abcd9be0 Mon Sep 17 00:00:00 2001 From: msanft Date: Mon, 8 Dec 2025 15:18:38 +0000 Subject: [PATCH] =?UTF-8?q?Remove=20preview=20for=20PR=204027=20?= =?UTF-8?q?=F0=9F=9B=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2.22/architecture/attestation/index.html | 229 ---- .../architecture/encrypted-storage/index.html | 58 - .../2.22/architecture/images/index.html | 38 - .../pr-4027/2.22/architecture/keys/index.html | 114 -- .../architecture/microservices/index.html | 47 - .../2.22/architecture/networking/index.html | 33 - .../architecture/observability/index.html | 59 -- .../architecture/orchestration/index.html | 80 -- .../2.22/architecture/overview/index.html | 34 - .../2.22/architecture/versions/index.html | 30 - .../2.22/category/architecture/index.html | 16 - .../pr-4027/2.22/category/basics/index.html | 16 - .../2.22/category/getting-started/index.html | 16 - .../2.22/category/reference/index.html | 16 - .../2.22/category/workflows/index.html | 16 - .../examples/emojivoto/index.html | 30 - .../examples/filestash-s3proxy/index.html | 58 - .../examples/horizontal-scaling/index.html | 60 -- .../2.22/getting-started/examples/index.html | 22 - .../examples/online-boutique/index.html | 33 - .../first-steps-local/index.html | 97 -- .../getting-started/first-steps/index.html | 90 -- .../2.22/getting-started/install/index.html | 234 ----- .../getting-started/marketplaces/index.html | 21 - pr-preview/pr-4027/2.22/index.html | 33 - .../pr-4027/2.22/overview/clouds/index.html | 57 - .../confidential-kubernetes/index.html | 40 - .../pr-4027/2.22/overview/license/index.html | 32 - .../performance/application/index.html | 55 - .../overview/performance/compute/index.html | 21 - .../2.22/overview/performance/index.html | 25 - .../2.22/overview/performance/io/index.html | 153 --- .../pr-4027/2.22/overview/product/index.html | 25 - .../overview/security-benefits/index.html | 27 - .../pr-4027/2.22/reference/cli/index.html | 331 ------ .../2.22/reference/migration/index.html | 91 -- .../pr-4027/2.22/reference/slsa/index.html | 51 - .../2.22/reference/terraform/index.html | 42 - .../2.22/workflows/cert-manager/index.html | 24 - .../pr-4027/2.22/workflows/config/index.html | 162 --- .../pr-4027/2.22/workflows/create/index.html | 42 - .../pr-4027/2.22/workflows/lb/index.html | 29 - .../2.22/workflows/recovery/index.html | 53 - .../workflows/reproducible-builds/index.html | 61 -- .../pr-4027/2.22/workflows/s3proxy/index.html | 59 -- .../pr-4027/2.22/workflows/sbom/index.html | 42 - .../pr-4027/2.22/workflows/scale/index.html | 71 -- .../pr-4027/2.22/workflows/storage/index.html | 161 --- .../2.22/workflows/terminate/index.html | 24 - .../workflows/terraform-provider/index.html | 62 -- .../2.22/workflows/troubleshooting/index.html | 115 -- .../2.22/workflows/trusted-launch/index.html | 35 - .../pr-4027/2.22/workflows/upgrade/index.html | 73 -- .../2.22/workflows/verify-cli/index.html | 47 - .../2.22/workflows/verify-cluster/index.html | 54 - .../2.23/architecture/attestation/index.html | 229 ---- .../architecture/encrypted-storage/index.html | 58 - .../2.23/architecture/images/index.html | 38 - .../pr-4027/2.23/architecture/keys/index.html | 114 -- .../architecture/microservices/index.html | 47 - .../2.23/architecture/networking/index.html | 33 - .../architecture/observability/index.html | 59 -- .../architecture/orchestration/index.html | 80 -- .../2.23/architecture/overview/index.html | 34 - .../2.23/architecture/versions/index.html | 30 - .../2.23/category/architecture/index.html | 16 - .../pr-4027/2.23/category/basics/index.html | 16 - .../2.23/category/getting-started/index.html | 16 - .../2.23/category/reference/index.html | 16 - .../2.23/category/workflows/index.html | 16 - .../examples/emojivoto/index.html | 30 - .../examples/filestash-s3proxy/index.html | 58 - .../examples/horizontal-scaling/index.html | 60 -- .../2.23/getting-started/examples/index.html | 22 - .../examples/online-boutique/index.html | 33 - .../first-steps-local/index.html | 97 -- .../getting-started/first-steps/index.html | 90 -- .../2.23/getting-started/install/index.html | 239 ----- .../getting-started/marketplaces/index.html | 21 - pr-preview/pr-4027/2.23/index.html | 33 - .../pr-4027/2.23/overview/clouds/index.html | 57 - .../confidential-kubernetes/index.html | 40 - .../pr-4027/2.23/overview/license/index.html | 23 - .../performance/application/index.html | 55 - .../overview/performance/compute/index.html | 21 - .../2.23/overview/performance/index.html | 25 - .../2.23/overview/performance/io/index.html | 153 --- .../pr-4027/2.23/overview/product/index.html | 25 - .../overview/security-benefits/index.html | 27 - .../pr-4027/2.23/reference/cli/index.html | 331 ------ .../2.23/reference/migration/index.html | 94 -- .../pr-4027/2.23/reference/slsa/index.html | 51 - .../2.23/reference/terraform/index.html | 42 - .../2.23/workflows/cert-manager/index.html | 24 - .../pr-4027/2.23/workflows/config/index.html | 162 --- .../pr-4027/2.23/workflows/create/index.html | 42 - .../pr-4027/2.23/workflows/lb/index.html | 29 - .../2.23/workflows/recovery/index.html | 53 - .../workflows/reproducible-builds/index.html | 61 -- .../pr-4027/2.23/workflows/s3proxy/index.html | 59 -- .../pr-4027/2.23/workflows/sbom/index.html | 42 - .../pr-4027/2.23/workflows/scale/index.html | 71 -- .../pr-4027/2.23/workflows/storage/index.html | 161 --- .../2.23/workflows/terminate/index.html | 24 - .../workflows/terraform-provider/index.html | 62 -- .../2.23/workflows/troubleshooting/index.html | 115 -- .../2.23/workflows/trusted-launch/index.html | 35 - .../pr-4027/2.23/workflows/upgrade/index.html | 73 -- .../2.23/workflows/verify-cli/index.html | 47 - .../2.23/workflows/verify-cluster/index.html | 54 - pr-preview/pr-4027/404.html | 16 - pr-preview/pr-4027/_redirects | 1 - .../architecture/attestation/index.html | 229 ---- .../architecture/encrypted-storage/index.html | 58 - .../pr-4027/architecture/images/index.html | 38 - .../pr-4027/architecture/keys/index.html | 114 -- .../architecture/microservices/index.html | 47 - .../architecture/networking/index.html | 33 - .../architecture/observability/index.html | 59 -- .../architecture/orchestration/index.html | 80 -- .../pr-4027/architecture/overview/index.html | 34 - .../pr-4027/architecture/versions/index.html | 30 - pr-preview/pr-4027/assets/check-sbom.cast | 991 ------------------ .../pr-4027/assets/configure-cluster.cast | 287 ----- pr-preview/pr-4027/assets/create-cluster.cast | 240 ----- .../pr-4027/assets/css/styles.9ca3c5b3.css | 1 - ...re_bw-9294313529fb8cc2c0230b3b581faddb.png | Bin 30975 -> 0 bytes ..._iops-a85caab4031a29df58a3e7175a62b792.png | Bin 29702 -> 0 bytes ...cp_bw-f8739bb79b0e47f896217bcacba14cdf.png | Bin 30401 -> 0 bytes ..._iops-ba4f26c2dd679d3d5e4ad7c7b0c8370e.png | Bin 30221 -> 0 bytes ...azure-fbad5555553d559281f605939f5e26c8.png | Bin 36902 -> 0 bytes ...p_gcp-8ce759468868272c67b53f5db2a3cf88.png | Bin 36961 -> 0 bytes ...azure-823916c53e426752564179c0f7147266.png | Bin 38309 -> 0 bytes ...c_gcp-4ae5b9b8d4317ad9d3005c4243d78367.png | Bin 38395 -> 0 bytes ...ation-f869032711a972295d5ddce42c37995c.svg | 460 -------- ...ncept-d3a09a16a8e7ca14a7bdf274ea7bce40.svg | 201 ---- ...naged-33482ac199f949182872dc32d69bd3bc.svg | 591 ----------- ...ivoto-55d31a6fd0c07e8e44b2b51d55dac60d.jpg | Bin 141236 -> 0 bytes ...tique-c89a9a15b1d4c086d3654bf75843295e.jpg | Bin 263458 -> 0 bytes ...tency-ae0fad7be416fae0d31ab35bb8284234.png | Bin 21327 -> 0 bytes ...tency-4c041d48ebb1b521c92d464040e94031.png | Bin 18809 -> 0 bytes ...tency-87ed51de18ebede26c314ff00d0e8e23.png | Bin 21414 -> 0 bytes ...tency-fd60c7ae80666133370f9b8e47404994.png | Bin 24062 -> 0 bytes ...-link-d31487c5a5e88fbcde9dcc33e876838d.png | Bin 46134 -> 0 bytes .../tcb-424516bbf9d20afe12576bc1305ebc29.svg | 535 ---------- .../pr-4027/assets/js/01f9c0c3.252afaac.js | 1 - .../pr-4027/assets/js/0282ce66.cb3fb8b2.js | 1 - .../pr-4027/assets/js/039005a9.e980c3d6.js | 1 - .../pr-4027/assets/js/0428ff27.9f4bd7a8.js | 1 - .../pr-4027/assets/js/061c4c8e.6d11960a.js | 1 - .../pr-4027/assets/js/073bbd6a.de1348f1.js | 1 - .../pr-4027/assets/js/074359f8.c3c68ee5.js | 1 - .../pr-4027/assets/js/0a66f7ff.c540accf.js | 1 - .../pr-4027/assets/js/0b1ac180.5fc2d03f.js | 1 - .../pr-4027/assets/js/0b338d1c.6cb8df9a.js | 1 - .../pr-4027/assets/js/0b615bd7.252ed8ba.js | 1 - .../pr-4027/assets/js/0bfd0c91.25d5f4dd.js | 1 - .../pr-4027/assets/js/0c363123.1f1d7162.js | 1 - .../pr-4027/assets/js/0c605e3b.36848557.js | 1 - .../pr-4027/assets/js/0cee1087.21f6746b.js | 1 - .../pr-4027/assets/js/0e384e19.e9a6d738.js | 1 - .../pr-4027/assets/js/0eb3e611.16087d6f.js | 1 - pr-preview/pr-4027/assets/js/1000.89c3dd98.js | 1 - .../pr-4027/assets/js/1036ee0b.bc80d0c2.js | 1 - .../pr-4027/assets/js/11b4c29f.5f60ca1d.js | 1 - .../pr-4027/assets/js/11dcff96.801ce7eb.js | 1 - pr-preview/pr-4027/assets/js/1203.72b741a7.js | 1 - .../pr-4027/assets/js/142263a9.262679e8.js | 1 - .../pr-4027/assets/js/14eb3368.770f55ac.js | 1 - .../pr-4027/assets/js/15c6e37c.d85a6cae.js | 1 - .../pr-4027/assets/js/15e5e9ad.32e35ac7.js | 1 - pr-preview/pr-4027/assets/js/165.fdd19a26.js | 2 - .../assets/js/165.fdd19a26.js.LICENSE.txt | 9 - pr-preview/pr-4027/assets/js/1741.d9ca137f.js | 1 - pr-preview/pr-4027/assets/js/1746.4ae2d600.js | 1 - .../pr-4027/assets/js/17896441.bf9de707.js | 1 - pr-preview/pr-4027/assets/js/179.98ad7c3b.js | 1 - .../pr-4027/assets/js/1890268c.ccf2c28e.js | 1 - .../pr-4027/assets/js/1b80620b.8be59223.js | 1 - .../pr-4027/assets/js/1c0e8ae3.89100639.js | 1 - .../pr-4027/assets/js/1c53691b.0108663e.js | 1 - .../pr-4027/assets/js/1e04dd29.b8b7e365.js | 1 - pr-preview/pr-4027/assets/js/2093.f4a3364b.js | 1 - .../pr-4027/assets/js/20a029f4.19707c04.js | 1 - pr-preview/pr-4027/assets/js/2130.b53d8919.js | 1 - pr-preview/pr-4027/assets/js/2235.460f34f9.js | 1 - pr-preview/pr-4027/assets/js/2279.aea29fbb.js | 2 - .../assets/js/2279.aea29fbb.js.LICENSE.txt | 1 - pr-preview/pr-4027/assets/js/2291.abd3c57a.js | 1 - pr-preview/pr-4027/assets/js/2325.4b61ab01.js | 1 - pr-preview/pr-4027/assets/js/2334.ad641aac.js | 1 - .../pr-4027/assets/js/242e7908.2e5b368b.js | 1 - .../pr-4027/assets/js/25e50762.f7764672.js | 1 - .../pr-4027/assets/js/260d3cdf.4f1fe1d9.js | 1 - .../pr-4027/assets/js/269ef64a.cc437b10.js | 1 - pr-preview/pr-4027/assets/js/2821.b92d32c5.js | 1 - .../pr-4027/assets/js/28513d82.46a0c6a0.js | 1 - .../pr-4027/assets/js/28a0f3ab.4e0d0da1.js | 1 - pr-preview/pr-4027/assets/js/291.ab24d400.js | 1 - .../pr-4027/assets/js/294c0512.1a966ee8.js | 1 - .../pr-4027/assets/js/2a05e475.bd72699c.js | 1 - .../pr-4027/assets/js/2a2a0c40.118b00b5.js | 1 - .../pr-4027/assets/js/2a9ad702.a6e81067.js | 1 - .../pr-4027/assets/js/2b3dcc9b.bd88b6ce.js | 1 - .../pr-4027/assets/js/2dc3352a.943010bc.js | 1 - pr-preview/pr-4027/assets/js/3003.ac806f1f.js | 1 - .../pr-4027/assets/js/311067ef.a0fdf84a.js | 1 - .../pr-4027/assets/js/31840164.0097030a.js | 1 - .../pr-4027/assets/js/31cc4483.6741e272.js | 1 - .../pr-4027/assets/js/3305fd99.2ac95a3b.js | 1 - .../pr-4027/assets/js/3324b179.8b5fa325.js | 1 - pr-preview/pr-4027/assets/js/3488.ebdc9158.js | 1 - pr-preview/pr-4027/assets/js/3490.91814865.js | 1 - .../pr-4027/assets/js/358e1fce.78bd25aa.js | 1 - .../pr-4027/assets/js/3607c499.bb98fd49.js | 1 - pr-preview/pr-4027/assets/js/3624.7bf76120.js | 1 - .../pr-4027/assets/js/36f09204.6566cb4d.js | 1 - pr-preview/pr-4027/assets/js/3815.705487db.js | 1 - .../pr-4027/assets/js/3962f62e.52655f48.js | 1 - .../pr-4027/assets/js/3aba4a32.42c67689.js | 1 - .../pr-4027/assets/js/3aca6029.1291f65f.js | 1 - .../pr-4027/assets/js/3b1b22d5.476e1074.js | 1 - .../pr-4027/assets/js/3b28b3cc.94d205c2.js | 1 - .../pr-4027/assets/js/3bcf7932.910a9d7e.js | 1 - .../pr-4027/assets/js/3e0d8e9d.ceac1b01.js | 1 - .../pr-4027/assets/js/3e6faa8e.77fa12c2.js | 1 - .../pr-4027/assets/js/3ee8c4d1.cff371e1.js | 1 - .../pr-4027/assets/js/3fddd266.5afedcea.js | 1 - .../pr-4027/assets/js/3fe7bb19.4ae2f002.js | 1 - .../pr-4027/assets/js/401e1ad9.fd632f9c.js | 1 - .../pr-4027/assets/js/40c738e9.e56e6bc5.js | 1 - .../pr-4027/assets/js/42298223.9ca426d3.js | 1 - pr-preview/pr-4027/assets/js/4250.0d4c2516.js | 1 - .../pr-4027/assets/js/42888a29.52b6655b.js | 1 - pr-preview/pr-4027/assets/js/4379.4c9173a3.js | 1 - .../pr-4027/assets/js/452d9595.8d32ca6b.js | 1 - .../pr-4027/assets/js/462332ca.224a53bd.js | 1 - pr-preview/pr-4027/assets/js/4802.9da541ee.js | 1 - .../pr-4027/assets/js/481538bf.3429f708.js | 1 - .../pr-4027/assets/js/48186bb1.517b63ea.js | 1 - .../pr-4027/assets/js/487d2b28.a63fd0a2.js | 1 - .../pr-4027/assets/js/4967aec5.cea229a8.js | 1 - pr-preview/pr-4027/assets/js/4981.bdd615e7.js | 1 - .../pr-4027/assets/js/4a51e885.f99201b8.js | 1 - .../pr-4027/assets/js/4b669f2d.a0ccaa76.js | 1 - .../pr-4027/assets/js/4bfed142.f1329705.js | 1 - .../pr-4027/assets/js/4c9525de.7cf5dfaf.js | 1 - .../pr-4027/assets/js/4cc5eb92.4f588dea.js | 1 - .../pr-4027/assets/js/4cf171a2.e11e2998.js | 1 - .../pr-4027/assets/js/4f0549e0.456cfea0.js | 1 - .../pr-4027/assets/js/4fce284f.af8f5e7c.js | 1 - .../pr-4027/assets/js/508a7d2f.d99914e5.js | 1 - .../pr-4027/assets/js/533d31d4.7f39540d.js | 1 - .../pr-4027/assets/js/53c1dfd4.9a270882.js | 1 - .../pr-4027/assets/js/543a522f.17585bbf.js | 1 - pr-preview/pr-4027/assets/js/5480.a964935e.js | 1 - .../pr-4027/assets/js/54db543f.c4bc0cc5.js | 1 - .../pr-4027/assets/js/5672ef9d.f3f7d6e3.js | 1 - .../pr-4027/assets/js/56806aed.deac1270.js | 1 - .../pr-4027/assets/js/574ee69f.4e5121f7.js | 1 - pr-preview/pr-4027/assets/js/5901.f3704c6f.js | 1 - .../pr-4027/assets/js/592bfb5e.1f7a9f64.js | 1 - pr-preview/pr-4027/assets/js/5955.645e55a4.js | 1 - pr-preview/pr-4027/assets/js/5996.cdc792ad.js | 1 - .../pr-4027/assets/js/5a6332a4.55cef70a.js | 1 - .../pr-4027/assets/js/5aae01e0.4eb12944.js | 1 - .../pr-4027/assets/js/5bf0e48f.1b0be145.js | 1 - .../pr-4027/assets/js/5d6cdc31.4cfde06b.js | 1 - .../pr-4027/assets/js/5dc5a687.7b3d863e.js | 1 - .../pr-4027/assets/js/5e23635c.096a5bd0.js | 1 - .../pr-4027/assets/js/5e92d76a.c9131055.js | 1 - .../pr-4027/assets/js/5e95c892.8e057c80.js | 1 - .../pr-4027/assets/js/60d3a1b7.20628eac.js | 1 - pr-preview/pr-4027/assets/js/617.55c4d8c0.js | 1 - .../pr-4027/assets/js/619bb71e.87871acc.js | 1 - pr-preview/pr-4027/assets/js/6241.826bee80.js | 1 - pr-preview/pr-4027/assets/js/6319.ec99954f.js | 1 - .../pr-4027/assets/js/633fbb2f.fefad383.js | 1 - pr-preview/pr-4027/assets/js/6366.060304b1.js | 1 - .../pr-4027/assets/js/642ed902.5ef7e201.js | 1 - .../pr-4027/assets/js/64c81f13.d0a432fb.js | 1 - .../pr-4027/assets/js/66852f4d.0306c16e.js | 1 - .../pr-4027/assets/js/66e2533d.3c4f9e07.js | 1 - .../pr-4027/assets/js/6776993e.3d373e8f.js | 1 - .../pr-4027/assets/js/68f29d4c.2d54c93a.js | 1 - pr-preview/pr-4027/assets/js/6992.6bbbbe26.js | 1 - .../pr-4027/assets/js/6c830a9a.2ca9c905.js | 1 - .../pr-4027/assets/js/6d0fae35.5f40d092.js | 1 - .../pr-4027/assets/js/6df30968.12fac903.js | 1 - .../pr-4027/assets/js/6e43ec2e.a12e9194.js | 1 - .../pr-4027/assets/js/6fe48d2e.ad8f8319.js | 1 - .../pr-4027/assets/js/70248ece.ce4c28e6.js | 1 - .../pr-4027/assets/js/70f89ddc.a8ec7c51.js | 1 - .../pr-4027/assets/js/71dfee10.81e5ecaf.js | 1 - .../pr-4027/assets/js/72a880f4.9f7828f1.js | 1 - .../pr-4027/assets/js/72c2c1f0.b96352b6.js | 1 - .../pr-4027/assets/js/74afccd1.fff6f3ba.js | 1 - pr-preview/pr-4027/assets/js/7592.ee6b88a7.js | 1 - .../pr-4027/assets/js/75a3ea9f.4aa32bc7.js | 1 - .../pr-4027/assets/js/76b2ab15.bf48cdb7.js | 1 - .../pr-4027/assets/js/76f884e3.86f1f394.js | 1 - .../pr-4027/assets/js/786b68f5.8a000b59.js | 1 - .../pr-4027/assets/js/786c60fb.d7dfd23a.js | 1 - pr-preview/pr-4027/assets/js/7873.2b83eb4c.js | 1 - pr-preview/pr-4027/assets/js/7928.292d9849.js | 1 - .../pr-4027/assets/js/794987bd.fa5e8276.js | 1 - .../pr-4027/assets/js/797a5fdc.4a0c0d7a.js | 1 - .../pr-4027/assets/js/79e0c113.dcc2b313.js | 1 - .../pr-4027/assets/js/7ae19400.00557006.js | 1 - .../pr-4027/assets/js/7c763686.e696c7b8.js | 1 - .../pr-4027/assets/js/7cae3477.a2bd8629.js | 1 - .../pr-4027/assets/js/80697fb2.341f256e.js | 1 - pr-preview/pr-4027/assets/js/8142.22a8eb00.js | 1 - .../pr-4027/assets/js/8183fba6.e63b4420.js | 1 - pr-preview/pr-4027/assets/js/8249.7b68bdca.js | 1 - .../pr-4027/assets/js/836c9f98.fba690cd.js | 1 - .../pr-4027/assets/js/837f4190.ddddc1c3.js | 1 - .../pr-4027/assets/js/84353103.8406d97f.js | 1 - .../pr-4027/assets/js/8452cbfd.5b138794.js | 1 - .../pr-4027/assets/js/84de5ccf.ae4c6c22.js | 1 - pr-preview/pr-4027/assets/js/8565.6b3d8208.js | 1 - .../pr-4027/assets/js/856c1b4a.b9ee9d40.js | 1 - .../pr-4027/assets/js/86470a9a.ad9a737e.js | 1 - .../pr-4027/assets/js/8713d71c.e522f149.js | 1 - pr-preview/pr-4027/assets/js/8731.ae3eb0c0.js | 1 - pr-preview/pr-4027/assets/js/8756.289e5e3c.js | 1 - pr-preview/pr-4027/assets/js/8948.b0417531.js | 1 - .../pr-4027/assets/js/8a026b6c.c06d830e.js | 1 - .../pr-4027/assets/js/8a589188.5249ea68.js | 1 - .../pr-4027/assets/js/8ca353b4.fbda2fc6.js | 1 - .../pr-4027/assets/js/8d448ad2.cf755472.js | 1 - .../pr-4027/assets/js/8ea786c8.db908d2a.js | 1 - .../pr-4027/assets/js/9010cc91.a4630109.js | 1 - .../pr-4027/assets/js/90e117e3.d0992f85.js | 1 - .../pr-4027/assets/js/911e2eea.bded8e4c.js | 1 - .../pr-4027/assets/js/91c76d4c.1cd3611e.js | 1 - .../pr-4027/assets/js/92236455.90a907d5.js | 1 - .../pr-4027/assets/js/925a7d08.3942d153.js | 1 - .../pr-4027/assets/js/927cf76e.74a50cde.js | 1 - pr-preview/pr-4027/assets/js/9412.3eb2f25f.js | 1 - pr-preview/pr-4027/assets/js/9510.4d014fd7.js | 1 - .../pr-4027/assets/js/95ca3cf4.101fccad.js | 1 - .../pr-4027/assets/js/960959b3.3b66f9f2.js | 1 - .../pr-4027/assets/js/97b147c7.309aa812.js | 1 - .../pr-4027/assets/js/989930da.0bf1c4b6.js | 1 - .../pr-4027/assets/js/9afa113a.a30bc4f8.js | 1 - .../pr-4027/assets/js/9b22caeb.35fb7596.js | 1 - .../pr-4027/assets/js/9ba5d544.2ed729cc.js | 1 - .../pr-4027/assets/js/9bccdd10.e2550a45.js | 1 - .../pr-4027/assets/js/9be9ef65.a4121f91.js | 1 - .../pr-4027/assets/js/9c1ba6d8.45404959.js | 1 - .../pr-4027/assets/js/9cbfbb7f.d905e7bc.js | 1 - .../pr-4027/assets/js/9d4f835b.c5fd6606.js | 1 - .../pr-4027/assets/js/a0c24a7b.92c74a89.js | 1 - .../pr-4027/assets/js/a3183fd7.fe04cf76.js | 1 - .../pr-4027/assets/js/a39aaf1d.36d99927.js | 1 - .../pr-4027/assets/js/a4c009ef.37cd2124.js | 1 - .../pr-4027/assets/js/a5863201.f48869f7.js | 1 - .../pr-4027/assets/js/a631f374.cb614d21.js | 1 - .../pr-4027/assets/js/a6a7cec0.e9c36e1f.js | 1 - .../pr-4027/assets/js/a7bd4aaa.125c3d24.js | 1 - .../pr-4027/assets/js/a7be6a84.cd4ab870.js | 1 - .../pr-4027/assets/js/a7cbe781.1cd695b6.js | 1 - .../pr-4027/assets/js/a7e69b4a.72ef9c11.js | 1 - .../pr-4027/assets/js/a93f81ab.12d75ad1.js | 1 - .../pr-4027/assets/js/a94703ab.2a6d89c3.js | 1 - .../pr-4027/assets/js/aba21aa0.7466539b.js | 1 - .../pr-4027/assets/js/acced080.7d6c4195.js | 1 - .../pr-4027/assets/js/acf362b0.e0ac5608.js | 1 - .../pr-4027/assets/js/adfda302.e01c344d.js | 1 - .../pr-4027/assets/js/ae4682fc.bd09743d.js | 1 - .../pr-4027/assets/js/af08314d.13910ef0.js | 1 - .../pr-4027/assets/js/b28da407.5321d36a.js | 1 - .../pr-4027/assets/js/b29fd7c7.bc2a3e28.js | 1 - .../pr-4027/assets/js/b744c41b.b5d06d0f.js | 1 - .../pr-4027/assets/js/b80e9c3d.370d4b83.js | 1 - .../pr-4027/assets/js/baf93e4b.fe36f378.js | 1 - .../pr-4027/assets/js/bf976132.8fa4d51e.js | 1 - .../pr-4027/assets/js/c2af115c.6aae2899.js | 1 - .../pr-4027/assets/js/c33b0c87.43e2e2a5.js | 1 - .../pr-4027/assets/js/c920f53d.e05afb5e.js | 1 - .../pr-4027/assets/js/ca2d12cf.4f360de1.js | 1 - .../pr-4027/assets/js/ca9f0fb1.84fd3f3c.js | 1 - .../pr-4027/assets/js/cb054e22.1fe4c9a7.js | 1 - .../pr-4027/assets/js/cbcdb048.23aba831.js | 1 - .../pr-4027/assets/js/cda59bb1.59d1e222.js | 1 - .../pr-4027/assets/js/ce803f35.cb1c2349.js | 1 - .../pr-4027/assets/js/cea600d4.27bcd6a1.js | 1 - .../pr-4027/assets/js/d0929cd6.10e4a498.js | 1 - .../pr-4027/assets/js/d12af2ba.d07f7408.js | 1 - .../pr-4027/assets/js/d17f599b.9b1c9ad5.js | 1 - .../pr-4027/assets/js/d2556545.5917dc82.js | 1 - .../pr-4027/assets/js/d4cfdd56.00a30674.js | 1 - .../pr-4027/assets/js/d84515e5.c5d1d300.js | 1 - .../pr-4027/assets/js/d89a6bd5.49be83be.js | 1 - .../pr-4027/assets/js/da6dfe9f.06480c68.js | 1 - .../pr-4027/assets/js/dae6bd30.317266e3.js | 1 - .../pr-4027/assets/js/db1b10df.841d69f7.js | 1 - .../pr-4027/assets/js/dc614479.12c43ec2.js | 1 - .../pr-4027/assets/js/dcc7f694.211d37d3.js | 1 - .../pr-4027/assets/js/de51a3b8.9944225e.js | 1 - .../pr-4027/assets/js/ded7ff97.f6bb64a4.js | 1 - .../pr-4027/assets/js/dfb82530.9fdb1b02.js | 1 - .../pr-4027/assets/js/dfb8a45d.047a71dd.js | 1 - .../pr-4027/assets/js/e0c6aa40.9043ab1e.js | 1 - .../pr-4027/assets/js/e0f39c0b.4e546576.js | 1 - .../pr-4027/assets/js/e12b18ba.4cd83c4c.js | 1 - .../pr-4027/assets/js/e19825b3.868862f3.js | 1 - .../pr-4027/assets/js/e344aa3d.4b5c7ca5.js | 1 - .../pr-4027/assets/js/e61948c8.95e47401.js | 1 - .../pr-4027/assets/js/e7c02e82.81e18f1c.js | 1 - .../pr-4027/assets/js/e8feb497.3097bda1.js | 1 - .../pr-4027/assets/js/e91da414.45776acc.js | 1 - .../pr-4027/assets/js/e97075f3.f1e5a2f5.js | 1 - .../pr-4027/assets/js/eae38991.c73f15f5.js | 1 - .../pr-4027/assets/js/ec7c7126.e5eb60ab.js | 1 - .../pr-4027/assets/js/f03f4c5d.387e7682.js | 1 - .../pr-4027/assets/js/f402a94e.b74542ad.js | 1 - .../pr-4027/assets/js/f8c8aa36.3ddbab78.js | 1 - .../pr-4027/assets/js/fb5790ab.c2bf914e.js | 1 - .../pr-4027/assets/js/fd1d3864.4d1ac871.js | 1 - pr-preview/pr-4027/assets/js/main.6a3f64be.js | 2 - .../assets/js/main.6a3f64be.js.LICENSE.txt | 120 --- .../assets/js/runtime~main.ddabc591.js | 1 - .../pr-4027/assets/terminate-cluster.cast | 146 --- pr-preview/pr-4027/assets/verify-cli.cast | 813 -------------- .../pr-4027/category/architecture/index.html | 16 - pr-preview/pr-4027/category/basics/index.html | 16 - .../category/getting-started/index.html | 16 - .../pr-4027/category/reference/index.html | 16 - .../pr-4027/category/workflows/index.html | 16 - .../examples/emojivoto/index.html | 30 - .../examples/filestash-s3proxy/index.html | 58 - .../examples/horizontal-scaling/index.html | 60 -- .../getting-started/examples/index.html | 22 - .../examples/online-boutique/index.html | 33 - .../first-steps-local/index.html | 97 -- .../getting-started/first-steps/index.html | 90 -- .../getting-started/install/index.html | 239 ----- .../getting-started/marketplaces/index.html | 21 - pr-preview/pr-4027/gtagman.js | 5 - .../img/BannerConstellationanimated.svg | 65 -- pr-preview/pr-4027/img/concept.svg | 201 ---- pr-preview/pr-4027/img/favicon.ico | Bin 15086 -> 0 bytes .../img/logos/constellation_icon_white_bg.png | Bin 66765 -> 0 bytes .../img/logos/constellation_icon_white_bg.svg | 4 - .../img/logos/constellation_oneline.svg | 52 - .../img/logos/constellation_white_bg.svg | 5 - pr-preview/pr-4027/img/shell-windowframe.svg | 340 ------ pr-preview/pr-4027/index.html | 34 - .../next/architecture/attestation/index.html | 229 ---- .../architecture/encrypted-storage/index.html | 58 - .../next/architecture/images/index.html | 38 - .../pr-4027/next/architecture/keys/index.html | 114 -- .../architecture/microservices/index.html | 47 - .../next/architecture/networking/index.html | 33 - .../architecture/observability/index.html | 59 -- .../architecture/orchestration/index.html | 80 -- .../next/architecture/overview/index.html | 34 - .../next/architecture/versions/index.html | 30 - .../next/category/architecture/index.html | 16 - .../pr-4027/next/category/basics/index.html | 16 - .../next/category/getting-started/index.html | 16 - .../next/category/reference/index.html | 16 - .../next/category/workflows/index.html | 16 - .../examples/emojivoto/index.html | 30 - .../examples/filestash-s3proxy/index.html | 58 - .../examples/horizontal-scaling/index.html | 60 -- .../next/getting-started/examples/index.html | 22 - .../examples/online-boutique/index.html | 33 - .../first-steps-local/index.html | 97 -- .../getting-started/first-steps/index.html | 90 -- .../next/getting-started/install/index.html | 239 ----- .../getting-started/marketplaces/index.html | 21 - pr-preview/pr-4027/next/index.html | 34 - .../pr-4027/next/overview/clouds/index.html | 57 - .../confidential-kubernetes/index.html | 40 - .../pr-4027/next/overview/license/index.html | 23 - .../performance/application/index.html | 55 - .../overview/performance/compute/index.html | 21 - .../next/overview/performance/index.html | 25 - .../next/overview/performance/io/index.html | 153 --- .../pr-4027/next/overview/product/index.html | 25 - .../overview/security-benefits/index.html | 27 - .../pr-4027/next/reference/cli/index.html | 331 ------ .../next/reference/migration/index.html | 94 -- .../pr-4027/next/reference/slsa/index.html | 51 - .../next/reference/terraform/index.html | 42 - .../next/workflows/cert-manager/index.html | 24 - .../pr-4027/next/workflows/config/index.html | 162 --- .../pr-4027/next/workflows/create/index.html | 42 - .../pr-4027/next/workflows/lb/index.html | 29 - .../next/workflows/recovery/index.html | 53 - .../workflows/reproducible-builds/index.html | 61 -- .../pr-4027/next/workflows/s3proxy/index.html | 59 -- .../pr-4027/next/workflows/sbom/index.html | 42 - .../pr-4027/next/workflows/scale/index.html | 71 -- .../pr-4027/next/workflows/storage/index.html | 161 --- .../next/workflows/terminate/index.html | 24 - .../workflows/terraform-provider/index.html | 62 -- .../next/workflows/troubleshooting/index.html | 116 -- .../next/workflows/trusted-launch/index.html | 35 - .../pr-4027/next/workflows/upgrade/index.html | 73 -- .../next/workflows/verify-cli/index.html | 47 - .../next/workflows/verify-cluster/index.html | 54 - pr-preview/pr-4027/overview/clouds/index.html | 57 - .../confidential-kubernetes/index.html | 40 - .../pr-4027/overview/license/index.html | 23 - .../performance/application/index.html | 55 - .../overview/performance/compute/index.html | 21 - .../pr-4027/overview/performance/index.html | 25 - .../overview/performance/io/index.html | 153 --- .../pr-4027/overview/product/index.html | 25 - .../overview/security-benefits/index.html | 27 - pr-preview/pr-4027/reference/cli/index.html | 331 ------ .../pr-4027/reference/migration/index.html | 94 -- pr-preview/pr-4027/reference/slsa/index.html | 51 - .../pr-4027/reference/terraform/index.html | 42 - .../search-index-docs-default-2.22.json | 1 - .../search-index-docs-default-2.23.json | 1 - .../search-index-docs-default-2.24.json | 1 - .../search-index-docs-default-current.json | 1 - pr-preview/pr-4027/sitemap.xml | 1 - .../pr-4027/workflows/cert-manager/index.html | 24 - .../pr-4027/workflows/config/index.html | 162 --- .../pr-4027/workflows/create/index.html | 42 - pr-preview/pr-4027/workflows/lb/index.html | 29 - .../pr-4027/workflows/recovery/index.html | 53 - .../workflows/reproducible-builds/index.html | 61 -- .../pr-4027/workflows/s3proxy/index.html | 59 -- pr-preview/pr-4027/workflows/sbom/index.html | 42 - pr-preview/pr-4027/workflows/scale/index.html | 71 -- .../pr-4027/workflows/storage/index.html | 161 --- .../pr-4027/workflows/terminate/index.html | 24 - .../workflows/terraform-provider/index.html | 62 -- .../workflows/troubleshooting/index.html | 116 -- .../workflows/trusted-launch/index.html | 35 - .../pr-4027/workflows/upgrade/index.html | 73 -- .../pr-4027/workflows/verify-cli/index.html | 47 - .../workflows/verify-cluster/index.html | 54 - 540 files changed, 19545 deletions(-) delete mode 100644 pr-preview/pr-4027/2.22/architecture/attestation/index.html delete mode 100644 pr-preview/pr-4027/2.22/architecture/encrypted-storage/index.html delete mode 100644 pr-preview/pr-4027/2.22/architecture/images/index.html delete mode 100644 pr-preview/pr-4027/2.22/architecture/keys/index.html delete mode 100644 pr-preview/pr-4027/2.22/architecture/microservices/index.html delete mode 100644 pr-preview/pr-4027/2.22/architecture/networking/index.html delete mode 100644 pr-preview/pr-4027/2.22/architecture/observability/index.html delete mode 100644 pr-preview/pr-4027/2.22/architecture/orchestration/index.html delete mode 100644 pr-preview/pr-4027/2.22/architecture/overview/index.html delete mode 100644 pr-preview/pr-4027/2.22/architecture/versions/index.html delete mode 100644 pr-preview/pr-4027/2.22/category/architecture/index.html delete mode 100644 pr-preview/pr-4027/2.22/category/basics/index.html delete mode 100644 pr-preview/pr-4027/2.22/category/getting-started/index.html delete mode 100644 pr-preview/pr-4027/2.22/category/reference/index.html delete mode 100644 pr-preview/pr-4027/2.22/category/workflows/index.html delete mode 100644 pr-preview/pr-4027/2.22/getting-started/examples/emojivoto/index.html delete mode 100644 pr-preview/pr-4027/2.22/getting-started/examples/filestash-s3proxy/index.html delete mode 100644 pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scaling/index.html delete mode 100644 pr-preview/pr-4027/2.22/getting-started/examples/index.html delete mode 100644 pr-preview/pr-4027/2.22/getting-started/examples/online-boutique/index.html delete mode 100644 pr-preview/pr-4027/2.22/getting-started/first-steps-local/index.html delete mode 100644 pr-preview/pr-4027/2.22/getting-started/first-steps/index.html delete mode 100644 pr-preview/pr-4027/2.22/getting-started/install/index.html delete mode 100644 pr-preview/pr-4027/2.22/getting-started/marketplaces/index.html delete mode 100644 pr-preview/pr-4027/2.22/index.html delete mode 100644 pr-preview/pr-4027/2.22/overview/clouds/index.html delete mode 100644 pr-preview/pr-4027/2.22/overview/confidential-kubernetes/index.html delete mode 100644 pr-preview/pr-4027/2.22/overview/license/index.html delete mode 100644 pr-preview/pr-4027/2.22/overview/performance/application/index.html delete mode 100644 pr-preview/pr-4027/2.22/overview/performance/compute/index.html delete mode 100644 pr-preview/pr-4027/2.22/overview/performance/index.html delete mode 100644 pr-preview/pr-4027/2.22/overview/performance/io/index.html delete mode 100644 pr-preview/pr-4027/2.22/overview/product/index.html delete mode 100644 pr-preview/pr-4027/2.22/overview/security-benefits/index.html delete mode 100644 pr-preview/pr-4027/2.22/reference/cli/index.html delete mode 100644 pr-preview/pr-4027/2.22/reference/migration/index.html delete mode 100644 pr-preview/pr-4027/2.22/reference/slsa/index.html delete mode 100644 pr-preview/pr-4027/2.22/reference/terraform/index.html delete mode 100644 pr-preview/pr-4027/2.22/workflows/cert-manager/index.html delete mode 100644 pr-preview/pr-4027/2.22/workflows/config/index.html delete mode 100644 pr-preview/pr-4027/2.22/workflows/create/index.html delete mode 100644 pr-preview/pr-4027/2.22/workflows/lb/index.html delete mode 100644 pr-preview/pr-4027/2.22/workflows/recovery/index.html delete mode 100644 pr-preview/pr-4027/2.22/workflows/reproducible-builds/index.html delete mode 100644 pr-preview/pr-4027/2.22/workflows/s3proxy/index.html delete mode 100644 pr-preview/pr-4027/2.22/workflows/sbom/index.html delete mode 100644 pr-preview/pr-4027/2.22/workflows/scale/index.html delete mode 100644 pr-preview/pr-4027/2.22/workflows/storage/index.html delete mode 100644 pr-preview/pr-4027/2.22/workflows/terminate/index.html delete mode 100644 pr-preview/pr-4027/2.22/workflows/terraform-provider/index.html delete mode 100644 pr-preview/pr-4027/2.22/workflows/troubleshooting/index.html delete mode 100644 pr-preview/pr-4027/2.22/workflows/trusted-launch/index.html delete mode 100644 pr-preview/pr-4027/2.22/workflows/upgrade/index.html delete mode 100644 pr-preview/pr-4027/2.22/workflows/verify-cli/index.html delete mode 100644 pr-preview/pr-4027/2.22/workflows/verify-cluster/index.html delete mode 100644 pr-preview/pr-4027/2.23/architecture/attestation/index.html delete mode 100644 pr-preview/pr-4027/2.23/architecture/encrypted-storage/index.html delete mode 100644 pr-preview/pr-4027/2.23/architecture/images/index.html delete mode 100644 pr-preview/pr-4027/2.23/architecture/keys/index.html delete mode 100644 pr-preview/pr-4027/2.23/architecture/microservices/index.html delete mode 100644 pr-preview/pr-4027/2.23/architecture/networking/index.html delete mode 100644 pr-preview/pr-4027/2.23/architecture/observability/index.html delete mode 100644 pr-preview/pr-4027/2.23/architecture/orchestration/index.html delete mode 100644 pr-preview/pr-4027/2.23/architecture/overview/index.html delete mode 100644 pr-preview/pr-4027/2.23/architecture/versions/index.html delete mode 100644 pr-preview/pr-4027/2.23/category/architecture/index.html delete mode 100644 pr-preview/pr-4027/2.23/category/basics/index.html delete mode 100644 pr-preview/pr-4027/2.23/category/getting-started/index.html delete mode 100644 pr-preview/pr-4027/2.23/category/reference/index.html delete mode 100644 pr-preview/pr-4027/2.23/category/workflows/index.html delete mode 100644 pr-preview/pr-4027/2.23/getting-started/examples/emojivoto/index.html delete mode 100644 pr-preview/pr-4027/2.23/getting-started/examples/filestash-s3proxy/index.html delete mode 100644 pr-preview/pr-4027/2.23/getting-started/examples/horizontal-scaling/index.html delete mode 100644 pr-preview/pr-4027/2.23/getting-started/examples/index.html delete mode 100644 pr-preview/pr-4027/2.23/getting-started/examples/online-boutique/index.html delete mode 100644 pr-preview/pr-4027/2.23/getting-started/first-steps-local/index.html delete mode 100644 pr-preview/pr-4027/2.23/getting-started/first-steps/index.html delete mode 100644 pr-preview/pr-4027/2.23/getting-started/install/index.html delete mode 100644 pr-preview/pr-4027/2.23/getting-started/marketplaces/index.html delete mode 100644 pr-preview/pr-4027/2.23/index.html delete mode 100644 pr-preview/pr-4027/2.23/overview/clouds/index.html delete mode 100644 pr-preview/pr-4027/2.23/overview/confidential-kubernetes/index.html delete mode 100644 pr-preview/pr-4027/2.23/overview/license/index.html delete mode 100644 pr-preview/pr-4027/2.23/overview/performance/application/index.html delete mode 100644 pr-preview/pr-4027/2.23/overview/performance/compute/index.html delete mode 100644 pr-preview/pr-4027/2.23/overview/performance/index.html delete mode 100644 pr-preview/pr-4027/2.23/overview/performance/io/index.html delete mode 100644 pr-preview/pr-4027/2.23/overview/product/index.html delete mode 100644 pr-preview/pr-4027/2.23/overview/security-benefits/index.html delete mode 100644 pr-preview/pr-4027/2.23/reference/cli/index.html delete mode 100644 pr-preview/pr-4027/2.23/reference/migration/index.html delete mode 100644 pr-preview/pr-4027/2.23/reference/slsa/index.html delete mode 100644 pr-preview/pr-4027/2.23/reference/terraform/index.html delete mode 100644 pr-preview/pr-4027/2.23/workflows/cert-manager/index.html delete mode 100644 pr-preview/pr-4027/2.23/workflows/config/index.html delete mode 100644 pr-preview/pr-4027/2.23/workflows/create/index.html delete mode 100644 pr-preview/pr-4027/2.23/workflows/lb/index.html delete mode 100644 pr-preview/pr-4027/2.23/workflows/recovery/index.html delete mode 100644 pr-preview/pr-4027/2.23/workflows/reproducible-builds/index.html delete mode 100644 pr-preview/pr-4027/2.23/workflows/s3proxy/index.html delete mode 100644 pr-preview/pr-4027/2.23/workflows/sbom/index.html delete mode 100644 pr-preview/pr-4027/2.23/workflows/scale/index.html delete mode 100644 pr-preview/pr-4027/2.23/workflows/storage/index.html delete mode 100644 pr-preview/pr-4027/2.23/workflows/terminate/index.html delete mode 100644 pr-preview/pr-4027/2.23/workflows/terraform-provider/index.html delete mode 100644 pr-preview/pr-4027/2.23/workflows/troubleshooting/index.html delete mode 100644 pr-preview/pr-4027/2.23/workflows/trusted-launch/index.html delete mode 100644 pr-preview/pr-4027/2.23/workflows/upgrade/index.html delete mode 100644 pr-preview/pr-4027/2.23/workflows/verify-cli/index.html delete mode 100644 pr-preview/pr-4027/2.23/workflows/verify-cluster/index.html delete mode 100644 pr-preview/pr-4027/404.html delete mode 100644 pr-preview/pr-4027/_redirects delete mode 100644 pr-preview/pr-4027/architecture/attestation/index.html delete mode 100644 pr-preview/pr-4027/architecture/encrypted-storage/index.html delete mode 100644 pr-preview/pr-4027/architecture/images/index.html delete mode 100644 pr-preview/pr-4027/architecture/keys/index.html delete mode 100644 pr-preview/pr-4027/architecture/microservices/index.html delete mode 100644 pr-preview/pr-4027/architecture/networking/index.html delete mode 100644 pr-preview/pr-4027/architecture/observability/index.html delete mode 100644 pr-preview/pr-4027/architecture/orchestration/index.html delete mode 100644 pr-preview/pr-4027/architecture/overview/index.html delete mode 100644 pr-preview/pr-4027/architecture/versions/index.html delete mode 100644 pr-preview/pr-4027/assets/check-sbom.cast delete mode 100644 pr-preview/pr-4027/assets/configure-cluster.cast delete mode 100644 pr-preview/pr-4027/assets/create-cluster.cast delete mode 100644 pr-preview/pr-4027/assets/css/styles.9ca3c5b3.css delete mode 100644 pr-preview/pr-4027/assets/images/benchmark_fio_azure_bw-9294313529fb8cc2c0230b3b581faddb.png delete mode 100644 pr-preview/pr-4027/assets/images/benchmark_fio_azure_iops-a85caab4031a29df58a3e7175a62b792.png delete mode 100644 pr-preview/pr-4027/assets/images/benchmark_fio_gcp_bw-f8739bb79b0e47f896217bcacba14cdf.png delete mode 100644 pr-preview/pr-4027/assets/images/benchmark_fio_gcp_iops-ba4f26c2dd679d3d5e4ad7c7b0c8370e.png delete mode 100644 pr-preview/pr-4027/assets/images/benchmark_net_p2p_azure-fbad5555553d559281f605939f5e26c8.png delete mode 100644 pr-preview/pr-4027/assets/images/benchmark_net_p2p_gcp-8ce759468868272c67b53f5db2a3cf88.png delete mode 100644 pr-preview/pr-4027/assets/images/benchmark_net_p2svc_azure-823916c53e426752564179c0f7147266.png delete mode 100644 pr-preview/pr-4027/assets/images/benchmark_net_p2svc_gcp-4ae5b9b8d4317ad9d3005c4243d78367.png delete mode 100644 pr-preview/pr-4027/assets/images/concept-constellation-f869032711a972295d5ddce42c37995c.svg delete mode 100644 pr-preview/pr-4027/assets/images/concept-d3a09a16a8e7ca14a7bdf274ea7bce40.svg delete mode 100644 pr-preview/pr-4027/assets/images/concept-managed-33482ac199f949182872dc32d69bd3bc.svg delete mode 100644 pr-preview/pr-4027/assets/images/example-emojivoto-55d31a6fd0c07e8e44b2b51d55dac60d.jpg delete mode 100644 pr-preview/pr-4027/assets/images/example-online-boutique-c89a9a15b1d4c086d3654bf75843295e.jpg delete mode 100644 pr-preview/pr-4027/assets/images/max_latency-ae0fad7be416fae0d31ab35bb8284234.png delete mode 100644 pr-preview/pr-4027/assets/images/mean_latency-4c041d48ebb1b521c92d464040e94031.png delete mode 100644 pr-preview/pr-4027/assets/images/min_latency-87ed51de18ebede26c314ff00d0e8e23.png delete mode 100644 pr-preview/pr-4027/assets/images/p99_latency-fd60c7ae80666133370f9b8e47404994.png delete mode 100644 pr-preview/pr-4027/assets/images/recovery-gcp-serial-console-link-d31487c5a5e88fbcde9dcc33e876838d.png delete mode 100644 pr-preview/pr-4027/assets/images/tcb-424516bbf9d20afe12576bc1305ebc29.svg delete mode 100644 pr-preview/pr-4027/assets/js/01f9c0c3.252afaac.js delete mode 100644 pr-preview/pr-4027/assets/js/0282ce66.cb3fb8b2.js delete mode 100644 pr-preview/pr-4027/assets/js/039005a9.e980c3d6.js delete mode 100644 pr-preview/pr-4027/assets/js/0428ff27.9f4bd7a8.js delete mode 100644 pr-preview/pr-4027/assets/js/061c4c8e.6d11960a.js delete mode 100644 pr-preview/pr-4027/assets/js/073bbd6a.de1348f1.js delete mode 100644 pr-preview/pr-4027/assets/js/074359f8.c3c68ee5.js delete mode 100644 pr-preview/pr-4027/assets/js/0a66f7ff.c540accf.js delete mode 100644 pr-preview/pr-4027/assets/js/0b1ac180.5fc2d03f.js delete mode 100644 pr-preview/pr-4027/assets/js/0b338d1c.6cb8df9a.js delete mode 100644 pr-preview/pr-4027/assets/js/0b615bd7.252ed8ba.js delete mode 100644 pr-preview/pr-4027/assets/js/0bfd0c91.25d5f4dd.js delete mode 100644 pr-preview/pr-4027/assets/js/0c363123.1f1d7162.js delete mode 100644 pr-preview/pr-4027/assets/js/0c605e3b.36848557.js delete mode 100644 pr-preview/pr-4027/assets/js/0cee1087.21f6746b.js delete mode 100644 pr-preview/pr-4027/assets/js/0e384e19.e9a6d738.js delete mode 100644 pr-preview/pr-4027/assets/js/0eb3e611.16087d6f.js delete mode 100644 pr-preview/pr-4027/assets/js/1000.89c3dd98.js delete mode 100644 pr-preview/pr-4027/assets/js/1036ee0b.bc80d0c2.js delete mode 100644 pr-preview/pr-4027/assets/js/11b4c29f.5f60ca1d.js delete mode 100644 pr-preview/pr-4027/assets/js/11dcff96.801ce7eb.js delete mode 100644 pr-preview/pr-4027/assets/js/1203.72b741a7.js delete mode 100644 pr-preview/pr-4027/assets/js/142263a9.262679e8.js delete mode 100644 pr-preview/pr-4027/assets/js/14eb3368.770f55ac.js delete mode 100644 pr-preview/pr-4027/assets/js/15c6e37c.d85a6cae.js delete mode 100644 pr-preview/pr-4027/assets/js/15e5e9ad.32e35ac7.js delete mode 100644 pr-preview/pr-4027/assets/js/165.fdd19a26.js delete mode 100644 pr-preview/pr-4027/assets/js/165.fdd19a26.js.LICENSE.txt delete mode 100644 pr-preview/pr-4027/assets/js/1741.d9ca137f.js delete mode 100644 pr-preview/pr-4027/assets/js/1746.4ae2d600.js delete mode 100644 pr-preview/pr-4027/assets/js/17896441.bf9de707.js delete mode 100644 pr-preview/pr-4027/assets/js/179.98ad7c3b.js delete mode 100644 pr-preview/pr-4027/assets/js/1890268c.ccf2c28e.js delete mode 100644 pr-preview/pr-4027/assets/js/1b80620b.8be59223.js delete mode 100644 pr-preview/pr-4027/assets/js/1c0e8ae3.89100639.js delete mode 100644 pr-preview/pr-4027/assets/js/1c53691b.0108663e.js delete mode 100644 pr-preview/pr-4027/assets/js/1e04dd29.b8b7e365.js delete mode 100644 pr-preview/pr-4027/assets/js/2093.f4a3364b.js delete mode 100644 pr-preview/pr-4027/assets/js/20a029f4.19707c04.js delete mode 100644 pr-preview/pr-4027/assets/js/2130.b53d8919.js delete mode 100644 pr-preview/pr-4027/assets/js/2235.460f34f9.js delete mode 100644 pr-preview/pr-4027/assets/js/2279.aea29fbb.js delete mode 100644 pr-preview/pr-4027/assets/js/2279.aea29fbb.js.LICENSE.txt delete mode 100644 pr-preview/pr-4027/assets/js/2291.abd3c57a.js delete mode 100644 pr-preview/pr-4027/assets/js/2325.4b61ab01.js delete mode 100644 pr-preview/pr-4027/assets/js/2334.ad641aac.js delete mode 100644 pr-preview/pr-4027/assets/js/242e7908.2e5b368b.js delete mode 100644 pr-preview/pr-4027/assets/js/25e50762.f7764672.js delete mode 100644 pr-preview/pr-4027/assets/js/260d3cdf.4f1fe1d9.js delete mode 100644 pr-preview/pr-4027/assets/js/269ef64a.cc437b10.js delete mode 100644 pr-preview/pr-4027/assets/js/2821.b92d32c5.js delete mode 100644 pr-preview/pr-4027/assets/js/28513d82.46a0c6a0.js delete mode 100644 pr-preview/pr-4027/assets/js/28a0f3ab.4e0d0da1.js delete mode 100644 pr-preview/pr-4027/assets/js/291.ab24d400.js delete mode 100644 pr-preview/pr-4027/assets/js/294c0512.1a966ee8.js delete mode 100644 pr-preview/pr-4027/assets/js/2a05e475.bd72699c.js delete mode 100644 pr-preview/pr-4027/assets/js/2a2a0c40.118b00b5.js delete mode 100644 pr-preview/pr-4027/assets/js/2a9ad702.a6e81067.js delete mode 100644 pr-preview/pr-4027/assets/js/2b3dcc9b.bd88b6ce.js delete mode 100644 pr-preview/pr-4027/assets/js/2dc3352a.943010bc.js delete mode 100644 pr-preview/pr-4027/assets/js/3003.ac806f1f.js delete mode 100644 pr-preview/pr-4027/assets/js/311067ef.a0fdf84a.js delete mode 100644 pr-preview/pr-4027/assets/js/31840164.0097030a.js delete mode 100644 pr-preview/pr-4027/assets/js/31cc4483.6741e272.js delete mode 100644 pr-preview/pr-4027/assets/js/3305fd99.2ac95a3b.js delete mode 100644 pr-preview/pr-4027/assets/js/3324b179.8b5fa325.js delete mode 100644 pr-preview/pr-4027/assets/js/3488.ebdc9158.js delete mode 100644 pr-preview/pr-4027/assets/js/3490.91814865.js delete mode 100644 pr-preview/pr-4027/assets/js/358e1fce.78bd25aa.js delete mode 100644 pr-preview/pr-4027/assets/js/3607c499.bb98fd49.js delete mode 100644 pr-preview/pr-4027/assets/js/3624.7bf76120.js delete mode 100644 pr-preview/pr-4027/assets/js/36f09204.6566cb4d.js delete mode 100644 pr-preview/pr-4027/assets/js/3815.705487db.js delete mode 100644 pr-preview/pr-4027/assets/js/3962f62e.52655f48.js delete mode 100644 pr-preview/pr-4027/assets/js/3aba4a32.42c67689.js delete mode 100644 pr-preview/pr-4027/assets/js/3aca6029.1291f65f.js delete mode 100644 pr-preview/pr-4027/assets/js/3b1b22d5.476e1074.js delete mode 100644 pr-preview/pr-4027/assets/js/3b28b3cc.94d205c2.js delete mode 100644 pr-preview/pr-4027/assets/js/3bcf7932.910a9d7e.js delete mode 100644 pr-preview/pr-4027/assets/js/3e0d8e9d.ceac1b01.js delete mode 100644 pr-preview/pr-4027/assets/js/3e6faa8e.77fa12c2.js delete mode 100644 pr-preview/pr-4027/assets/js/3ee8c4d1.cff371e1.js delete mode 100644 pr-preview/pr-4027/assets/js/3fddd266.5afedcea.js delete mode 100644 pr-preview/pr-4027/assets/js/3fe7bb19.4ae2f002.js delete mode 100644 pr-preview/pr-4027/assets/js/401e1ad9.fd632f9c.js delete mode 100644 pr-preview/pr-4027/assets/js/40c738e9.e56e6bc5.js delete mode 100644 pr-preview/pr-4027/assets/js/42298223.9ca426d3.js delete mode 100644 pr-preview/pr-4027/assets/js/4250.0d4c2516.js delete mode 100644 pr-preview/pr-4027/assets/js/42888a29.52b6655b.js delete mode 100644 pr-preview/pr-4027/assets/js/4379.4c9173a3.js delete mode 100644 pr-preview/pr-4027/assets/js/452d9595.8d32ca6b.js delete mode 100644 pr-preview/pr-4027/assets/js/462332ca.224a53bd.js delete mode 100644 pr-preview/pr-4027/assets/js/4802.9da541ee.js delete mode 100644 pr-preview/pr-4027/assets/js/481538bf.3429f708.js delete mode 100644 pr-preview/pr-4027/assets/js/48186bb1.517b63ea.js delete mode 100644 pr-preview/pr-4027/assets/js/487d2b28.a63fd0a2.js delete mode 100644 pr-preview/pr-4027/assets/js/4967aec5.cea229a8.js delete mode 100644 pr-preview/pr-4027/assets/js/4981.bdd615e7.js delete mode 100644 pr-preview/pr-4027/assets/js/4a51e885.f99201b8.js delete mode 100644 pr-preview/pr-4027/assets/js/4b669f2d.a0ccaa76.js delete mode 100644 pr-preview/pr-4027/assets/js/4bfed142.f1329705.js delete mode 100644 pr-preview/pr-4027/assets/js/4c9525de.7cf5dfaf.js delete mode 100644 pr-preview/pr-4027/assets/js/4cc5eb92.4f588dea.js delete mode 100644 pr-preview/pr-4027/assets/js/4cf171a2.e11e2998.js delete mode 100644 pr-preview/pr-4027/assets/js/4f0549e0.456cfea0.js delete mode 100644 pr-preview/pr-4027/assets/js/4fce284f.af8f5e7c.js delete mode 100644 pr-preview/pr-4027/assets/js/508a7d2f.d99914e5.js delete mode 100644 pr-preview/pr-4027/assets/js/533d31d4.7f39540d.js delete mode 100644 pr-preview/pr-4027/assets/js/53c1dfd4.9a270882.js delete mode 100644 pr-preview/pr-4027/assets/js/543a522f.17585bbf.js delete mode 100644 pr-preview/pr-4027/assets/js/5480.a964935e.js delete mode 100644 pr-preview/pr-4027/assets/js/54db543f.c4bc0cc5.js delete mode 100644 pr-preview/pr-4027/assets/js/5672ef9d.f3f7d6e3.js delete mode 100644 pr-preview/pr-4027/assets/js/56806aed.deac1270.js delete mode 100644 pr-preview/pr-4027/assets/js/574ee69f.4e5121f7.js delete mode 100644 pr-preview/pr-4027/assets/js/5901.f3704c6f.js delete mode 100644 pr-preview/pr-4027/assets/js/592bfb5e.1f7a9f64.js delete mode 100644 pr-preview/pr-4027/assets/js/5955.645e55a4.js delete mode 100644 pr-preview/pr-4027/assets/js/5996.cdc792ad.js delete mode 100644 pr-preview/pr-4027/assets/js/5a6332a4.55cef70a.js delete mode 100644 pr-preview/pr-4027/assets/js/5aae01e0.4eb12944.js delete mode 100644 pr-preview/pr-4027/assets/js/5bf0e48f.1b0be145.js delete mode 100644 pr-preview/pr-4027/assets/js/5d6cdc31.4cfde06b.js delete mode 100644 pr-preview/pr-4027/assets/js/5dc5a687.7b3d863e.js delete mode 100644 pr-preview/pr-4027/assets/js/5e23635c.096a5bd0.js delete mode 100644 pr-preview/pr-4027/assets/js/5e92d76a.c9131055.js delete mode 100644 pr-preview/pr-4027/assets/js/5e95c892.8e057c80.js delete mode 100644 pr-preview/pr-4027/assets/js/60d3a1b7.20628eac.js delete mode 100644 pr-preview/pr-4027/assets/js/617.55c4d8c0.js delete mode 100644 pr-preview/pr-4027/assets/js/619bb71e.87871acc.js delete mode 100644 pr-preview/pr-4027/assets/js/6241.826bee80.js delete mode 100644 pr-preview/pr-4027/assets/js/6319.ec99954f.js delete mode 100644 pr-preview/pr-4027/assets/js/633fbb2f.fefad383.js delete mode 100644 pr-preview/pr-4027/assets/js/6366.060304b1.js delete mode 100644 pr-preview/pr-4027/assets/js/642ed902.5ef7e201.js delete mode 100644 pr-preview/pr-4027/assets/js/64c81f13.d0a432fb.js delete mode 100644 pr-preview/pr-4027/assets/js/66852f4d.0306c16e.js delete mode 100644 pr-preview/pr-4027/assets/js/66e2533d.3c4f9e07.js delete mode 100644 pr-preview/pr-4027/assets/js/6776993e.3d373e8f.js delete mode 100644 pr-preview/pr-4027/assets/js/68f29d4c.2d54c93a.js delete mode 100644 pr-preview/pr-4027/assets/js/6992.6bbbbe26.js delete mode 100644 pr-preview/pr-4027/assets/js/6c830a9a.2ca9c905.js delete mode 100644 pr-preview/pr-4027/assets/js/6d0fae35.5f40d092.js delete mode 100644 pr-preview/pr-4027/assets/js/6df30968.12fac903.js delete mode 100644 pr-preview/pr-4027/assets/js/6e43ec2e.a12e9194.js delete mode 100644 pr-preview/pr-4027/assets/js/6fe48d2e.ad8f8319.js delete mode 100644 pr-preview/pr-4027/assets/js/70248ece.ce4c28e6.js delete mode 100644 pr-preview/pr-4027/assets/js/70f89ddc.a8ec7c51.js delete mode 100644 pr-preview/pr-4027/assets/js/71dfee10.81e5ecaf.js delete mode 100644 pr-preview/pr-4027/assets/js/72a880f4.9f7828f1.js delete mode 100644 pr-preview/pr-4027/assets/js/72c2c1f0.b96352b6.js delete mode 100644 pr-preview/pr-4027/assets/js/74afccd1.fff6f3ba.js delete mode 100644 pr-preview/pr-4027/assets/js/7592.ee6b88a7.js delete mode 100644 pr-preview/pr-4027/assets/js/75a3ea9f.4aa32bc7.js delete mode 100644 pr-preview/pr-4027/assets/js/76b2ab15.bf48cdb7.js delete mode 100644 pr-preview/pr-4027/assets/js/76f884e3.86f1f394.js delete mode 100644 pr-preview/pr-4027/assets/js/786b68f5.8a000b59.js delete mode 100644 pr-preview/pr-4027/assets/js/786c60fb.d7dfd23a.js delete mode 100644 pr-preview/pr-4027/assets/js/7873.2b83eb4c.js delete mode 100644 pr-preview/pr-4027/assets/js/7928.292d9849.js delete mode 100644 pr-preview/pr-4027/assets/js/794987bd.fa5e8276.js delete mode 100644 pr-preview/pr-4027/assets/js/797a5fdc.4a0c0d7a.js delete mode 100644 pr-preview/pr-4027/assets/js/79e0c113.dcc2b313.js delete mode 100644 pr-preview/pr-4027/assets/js/7ae19400.00557006.js delete mode 100644 pr-preview/pr-4027/assets/js/7c763686.e696c7b8.js delete mode 100644 pr-preview/pr-4027/assets/js/7cae3477.a2bd8629.js delete mode 100644 pr-preview/pr-4027/assets/js/80697fb2.341f256e.js delete mode 100644 pr-preview/pr-4027/assets/js/8142.22a8eb00.js delete mode 100644 pr-preview/pr-4027/assets/js/8183fba6.e63b4420.js delete mode 100644 pr-preview/pr-4027/assets/js/8249.7b68bdca.js delete mode 100644 pr-preview/pr-4027/assets/js/836c9f98.fba690cd.js delete mode 100644 pr-preview/pr-4027/assets/js/837f4190.ddddc1c3.js delete mode 100644 pr-preview/pr-4027/assets/js/84353103.8406d97f.js delete mode 100644 pr-preview/pr-4027/assets/js/8452cbfd.5b138794.js delete mode 100644 pr-preview/pr-4027/assets/js/84de5ccf.ae4c6c22.js delete mode 100644 pr-preview/pr-4027/assets/js/8565.6b3d8208.js delete mode 100644 pr-preview/pr-4027/assets/js/856c1b4a.b9ee9d40.js delete mode 100644 pr-preview/pr-4027/assets/js/86470a9a.ad9a737e.js delete mode 100644 pr-preview/pr-4027/assets/js/8713d71c.e522f149.js delete mode 100644 pr-preview/pr-4027/assets/js/8731.ae3eb0c0.js delete mode 100644 pr-preview/pr-4027/assets/js/8756.289e5e3c.js delete mode 100644 pr-preview/pr-4027/assets/js/8948.b0417531.js delete mode 100644 pr-preview/pr-4027/assets/js/8a026b6c.c06d830e.js delete mode 100644 pr-preview/pr-4027/assets/js/8a589188.5249ea68.js delete mode 100644 pr-preview/pr-4027/assets/js/8ca353b4.fbda2fc6.js delete mode 100644 pr-preview/pr-4027/assets/js/8d448ad2.cf755472.js delete mode 100644 pr-preview/pr-4027/assets/js/8ea786c8.db908d2a.js delete mode 100644 pr-preview/pr-4027/assets/js/9010cc91.a4630109.js delete mode 100644 pr-preview/pr-4027/assets/js/90e117e3.d0992f85.js delete mode 100644 pr-preview/pr-4027/assets/js/911e2eea.bded8e4c.js delete mode 100644 pr-preview/pr-4027/assets/js/91c76d4c.1cd3611e.js delete mode 100644 pr-preview/pr-4027/assets/js/92236455.90a907d5.js delete mode 100644 pr-preview/pr-4027/assets/js/925a7d08.3942d153.js delete mode 100644 pr-preview/pr-4027/assets/js/927cf76e.74a50cde.js delete mode 100644 pr-preview/pr-4027/assets/js/9412.3eb2f25f.js delete mode 100644 pr-preview/pr-4027/assets/js/9510.4d014fd7.js delete mode 100644 pr-preview/pr-4027/assets/js/95ca3cf4.101fccad.js delete mode 100644 pr-preview/pr-4027/assets/js/960959b3.3b66f9f2.js delete mode 100644 pr-preview/pr-4027/assets/js/97b147c7.309aa812.js delete mode 100644 pr-preview/pr-4027/assets/js/989930da.0bf1c4b6.js delete mode 100644 pr-preview/pr-4027/assets/js/9afa113a.a30bc4f8.js delete mode 100644 pr-preview/pr-4027/assets/js/9b22caeb.35fb7596.js delete mode 100644 pr-preview/pr-4027/assets/js/9ba5d544.2ed729cc.js delete mode 100644 pr-preview/pr-4027/assets/js/9bccdd10.e2550a45.js delete mode 100644 pr-preview/pr-4027/assets/js/9be9ef65.a4121f91.js delete mode 100644 pr-preview/pr-4027/assets/js/9c1ba6d8.45404959.js delete mode 100644 pr-preview/pr-4027/assets/js/9cbfbb7f.d905e7bc.js delete mode 100644 pr-preview/pr-4027/assets/js/9d4f835b.c5fd6606.js delete mode 100644 pr-preview/pr-4027/assets/js/a0c24a7b.92c74a89.js delete mode 100644 pr-preview/pr-4027/assets/js/a3183fd7.fe04cf76.js delete mode 100644 pr-preview/pr-4027/assets/js/a39aaf1d.36d99927.js delete mode 100644 pr-preview/pr-4027/assets/js/a4c009ef.37cd2124.js delete mode 100644 pr-preview/pr-4027/assets/js/a5863201.f48869f7.js delete mode 100644 pr-preview/pr-4027/assets/js/a631f374.cb614d21.js delete mode 100644 pr-preview/pr-4027/assets/js/a6a7cec0.e9c36e1f.js delete mode 100644 pr-preview/pr-4027/assets/js/a7bd4aaa.125c3d24.js delete mode 100644 pr-preview/pr-4027/assets/js/a7be6a84.cd4ab870.js delete mode 100644 pr-preview/pr-4027/assets/js/a7cbe781.1cd695b6.js delete mode 100644 pr-preview/pr-4027/assets/js/a7e69b4a.72ef9c11.js delete mode 100644 pr-preview/pr-4027/assets/js/a93f81ab.12d75ad1.js delete mode 100644 pr-preview/pr-4027/assets/js/a94703ab.2a6d89c3.js delete mode 100644 pr-preview/pr-4027/assets/js/aba21aa0.7466539b.js delete mode 100644 pr-preview/pr-4027/assets/js/acced080.7d6c4195.js delete mode 100644 pr-preview/pr-4027/assets/js/acf362b0.e0ac5608.js delete mode 100644 pr-preview/pr-4027/assets/js/adfda302.e01c344d.js delete mode 100644 pr-preview/pr-4027/assets/js/ae4682fc.bd09743d.js delete mode 100644 pr-preview/pr-4027/assets/js/af08314d.13910ef0.js delete mode 100644 pr-preview/pr-4027/assets/js/b28da407.5321d36a.js delete mode 100644 pr-preview/pr-4027/assets/js/b29fd7c7.bc2a3e28.js delete mode 100644 pr-preview/pr-4027/assets/js/b744c41b.b5d06d0f.js delete mode 100644 pr-preview/pr-4027/assets/js/b80e9c3d.370d4b83.js delete mode 100644 pr-preview/pr-4027/assets/js/baf93e4b.fe36f378.js delete mode 100644 pr-preview/pr-4027/assets/js/bf976132.8fa4d51e.js delete mode 100644 pr-preview/pr-4027/assets/js/c2af115c.6aae2899.js delete mode 100644 pr-preview/pr-4027/assets/js/c33b0c87.43e2e2a5.js delete mode 100644 pr-preview/pr-4027/assets/js/c920f53d.e05afb5e.js delete mode 100644 pr-preview/pr-4027/assets/js/ca2d12cf.4f360de1.js delete mode 100644 pr-preview/pr-4027/assets/js/ca9f0fb1.84fd3f3c.js delete mode 100644 pr-preview/pr-4027/assets/js/cb054e22.1fe4c9a7.js delete mode 100644 pr-preview/pr-4027/assets/js/cbcdb048.23aba831.js delete mode 100644 pr-preview/pr-4027/assets/js/cda59bb1.59d1e222.js delete mode 100644 pr-preview/pr-4027/assets/js/ce803f35.cb1c2349.js delete mode 100644 pr-preview/pr-4027/assets/js/cea600d4.27bcd6a1.js delete mode 100644 pr-preview/pr-4027/assets/js/d0929cd6.10e4a498.js delete mode 100644 pr-preview/pr-4027/assets/js/d12af2ba.d07f7408.js delete mode 100644 pr-preview/pr-4027/assets/js/d17f599b.9b1c9ad5.js delete mode 100644 pr-preview/pr-4027/assets/js/d2556545.5917dc82.js delete mode 100644 pr-preview/pr-4027/assets/js/d4cfdd56.00a30674.js delete mode 100644 pr-preview/pr-4027/assets/js/d84515e5.c5d1d300.js delete mode 100644 pr-preview/pr-4027/assets/js/d89a6bd5.49be83be.js delete mode 100644 pr-preview/pr-4027/assets/js/da6dfe9f.06480c68.js delete mode 100644 pr-preview/pr-4027/assets/js/dae6bd30.317266e3.js delete mode 100644 pr-preview/pr-4027/assets/js/db1b10df.841d69f7.js delete mode 100644 pr-preview/pr-4027/assets/js/dc614479.12c43ec2.js delete mode 100644 pr-preview/pr-4027/assets/js/dcc7f694.211d37d3.js delete mode 100644 pr-preview/pr-4027/assets/js/de51a3b8.9944225e.js delete mode 100644 pr-preview/pr-4027/assets/js/ded7ff97.f6bb64a4.js delete mode 100644 pr-preview/pr-4027/assets/js/dfb82530.9fdb1b02.js delete mode 100644 pr-preview/pr-4027/assets/js/dfb8a45d.047a71dd.js delete mode 100644 pr-preview/pr-4027/assets/js/e0c6aa40.9043ab1e.js delete mode 100644 pr-preview/pr-4027/assets/js/e0f39c0b.4e546576.js delete mode 100644 pr-preview/pr-4027/assets/js/e12b18ba.4cd83c4c.js delete mode 100644 pr-preview/pr-4027/assets/js/e19825b3.868862f3.js delete mode 100644 pr-preview/pr-4027/assets/js/e344aa3d.4b5c7ca5.js delete mode 100644 pr-preview/pr-4027/assets/js/e61948c8.95e47401.js delete mode 100644 pr-preview/pr-4027/assets/js/e7c02e82.81e18f1c.js delete mode 100644 pr-preview/pr-4027/assets/js/e8feb497.3097bda1.js delete mode 100644 pr-preview/pr-4027/assets/js/e91da414.45776acc.js delete mode 100644 pr-preview/pr-4027/assets/js/e97075f3.f1e5a2f5.js delete mode 100644 pr-preview/pr-4027/assets/js/eae38991.c73f15f5.js delete mode 100644 pr-preview/pr-4027/assets/js/ec7c7126.e5eb60ab.js delete mode 100644 pr-preview/pr-4027/assets/js/f03f4c5d.387e7682.js delete mode 100644 pr-preview/pr-4027/assets/js/f402a94e.b74542ad.js delete mode 100644 pr-preview/pr-4027/assets/js/f8c8aa36.3ddbab78.js delete mode 100644 pr-preview/pr-4027/assets/js/fb5790ab.c2bf914e.js delete mode 100644 pr-preview/pr-4027/assets/js/fd1d3864.4d1ac871.js delete mode 100644 pr-preview/pr-4027/assets/js/main.6a3f64be.js delete mode 100644 pr-preview/pr-4027/assets/js/main.6a3f64be.js.LICENSE.txt delete mode 100644 pr-preview/pr-4027/assets/js/runtime~main.ddabc591.js delete mode 100644 pr-preview/pr-4027/assets/terminate-cluster.cast delete mode 100644 pr-preview/pr-4027/assets/verify-cli.cast delete mode 100644 pr-preview/pr-4027/category/architecture/index.html delete mode 100644 pr-preview/pr-4027/category/basics/index.html delete mode 100644 pr-preview/pr-4027/category/getting-started/index.html delete mode 100644 pr-preview/pr-4027/category/reference/index.html delete mode 100644 pr-preview/pr-4027/category/workflows/index.html delete mode 100644 pr-preview/pr-4027/getting-started/examples/emojivoto/index.html delete mode 100644 pr-preview/pr-4027/getting-started/examples/filestash-s3proxy/index.html delete mode 100644 pr-preview/pr-4027/getting-started/examples/horizontal-scaling/index.html delete mode 100644 pr-preview/pr-4027/getting-started/examples/index.html delete mode 100644 pr-preview/pr-4027/getting-started/examples/online-boutique/index.html delete mode 100644 pr-preview/pr-4027/getting-started/first-steps-local/index.html delete mode 100644 pr-preview/pr-4027/getting-started/first-steps/index.html delete mode 100644 pr-preview/pr-4027/getting-started/install/index.html delete mode 100644 pr-preview/pr-4027/getting-started/marketplaces/index.html delete mode 100644 pr-preview/pr-4027/gtagman.js delete mode 100644 pr-preview/pr-4027/img/BannerConstellationanimated.svg delete mode 100644 pr-preview/pr-4027/img/concept.svg delete mode 100644 pr-preview/pr-4027/img/favicon.ico delete mode 100644 pr-preview/pr-4027/img/logos/constellation_icon_white_bg.png delete mode 100644 pr-preview/pr-4027/img/logos/constellation_icon_white_bg.svg delete mode 100644 pr-preview/pr-4027/img/logos/constellation_oneline.svg delete mode 100644 pr-preview/pr-4027/img/logos/constellation_white_bg.svg delete mode 100644 pr-preview/pr-4027/img/shell-windowframe.svg delete mode 100644 pr-preview/pr-4027/index.html delete mode 100644 pr-preview/pr-4027/next/architecture/attestation/index.html delete mode 100644 pr-preview/pr-4027/next/architecture/encrypted-storage/index.html delete mode 100644 pr-preview/pr-4027/next/architecture/images/index.html delete mode 100644 pr-preview/pr-4027/next/architecture/keys/index.html delete mode 100644 pr-preview/pr-4027/next/architecture/microservices/index.html delete mode 100644 pr-preview/pr-4027/next/architecture/networking/index.html delete mode 100644 pr-preview/pr-4027/next/architecture/observability/index.html delete mode 100644 pr-preview/pr-4027/next/architecture/orchestration/index.html delete mode 100644 pr-preview/pr-4027/next/architecture/overview/index.html delete mode 100644 pr-preview/pr-4027/next/architecture/versions/index.html delete mode 100644 pr-preview/pr-4027/next/category/architecture/index.html delete mode 100644 pr-preview/pr-4027/next/category/basics/index.html delete mode 100644 pr-preview/pr-4027/next/category/getting-started/index.html delete mode 100644 pr-preview/pr-4027/next/category/reference/index.html delete mode 100644 pr-preview/pr-4027/next/category/workflows/index.html delete mode 100644 pr-preview/pr-4027/next/getting-started/examples/emojivoto/index.html delete mode 100644 pr-preview/pr-4027/next/getting-started/examples/filestash-s3proxy/index.html delete mode 100644 pr-preview/pr-4027/next/getting-started/examples/horizontal-scaling/index.html delete mode 100644 pr-preview/pr-4027/next/getting-started/examples/index.html delete mode 100644 pr-preview/pr-4027/next/getting-started/examples/online-boutique/index.html delete mode 100644 pr-preview/pr-4027/next/getting-started/first-steps-local/index.html delete mode 100644 pr-preview/pr-4027/next/getting-started/first-steps/index.html delete mode 100644 pr-preview/pr-4027/next/getting-started/install/index.html delete mode 100644 pr-preview/pr-4027/next/getting-started/marketplaces/index.html delete mode 100644 pr-preview/pr-4027/next/index.html delete mode 100644 pr-preview/pr-4027/next/overview/clouds/index.html delete mode 100644 pr-preview/pr-4027/next/overview/confidential-kubernetes/index.html delete mode 100644 pr-preview/pr-4027/next/overview/license/index.html delete mode 100644 pr-preview/pr-4027/next/overview/performance/application/index.html delete mode 100644 pr-preview/pr-4027/next/overview/performance/compute/index.html delete mode 100644 pr-preview/pr-4027/next/overview/performance/index.html delete mode 100644 pr-preview/pr-4027/next/overview/performance/io/index.html delete mode 100644 pr-preview/pr-4027/next/overview/product/index.html delete mode 100644 pr-preview/pr-4027/next/overview/security-benefits/index.html delete mode 100644 pr-preview/pr-4027/next/reference/cli/index.html delete mode 100644 pr-preview/pr-4027/next/reference/migration/index.html delete mode 100644 pr-preview/pr-4027/next/reference/slsa/index.html delete mode 100644 pr-preview/pr-4027/next/reference/terraform/index.html delete mode 100644 pr-preview/pr-4027/next/workflows/cert-manager/index.html delete mode 100644 pr-preview/pr-4027/next/workflows/config/index.html delete mode 100644 pr-preview/pr-4027/next/workflows/create/index.html delete mode 100644 pr-preview/pr-4027/next/workflows/lb/index.html delete mode 100644 pr-preview/pr-4027/next/workflows/recovery/index.html delete mode 100644 pr-preview/pr-4027/next/workflows/reproducible-builds/index.html delete mode 100644 pr-preview/pr-4027/next/workflows/s3proxy/index.html delete mode 100644 pr-preview/pr-4027/next/workflows/sbom/index.html delete mode 100644 pr-preview/pr-4027/next/workflows/scale/index.html delete mode 100644 pr-preview/pr-4027/next/workflows/storage/index.html delete mode 100644 pr-preview/pr-4027/next/workflows/terminate/index.html delete mode 100644 pr-preview/pr-4027/next/workflows/terraform-provider/index.html delete mode 100644 pr-preview/pr-4027/next/workflows/troubleshooting/index.html delete mode 100644 pr-preview/pr-4027/next/workflows/trusted-launch/index.html delete mode 100644 pr-preview/pr-4027/next/workflows/upgrade/index.html delete mode 100644 pr-preview/pr-4027/next/workflows/verify-cli/index.html delete mode 100644 pr-preview/pr-4027/next/workflows/verify-cluster/index.html delete mode 100644 pr-preview/pr-4027/overview/clouds/index.html delete mode 100644 pr-preview/pr-4027/overview/confidential-kubernetes/index.html delete mode 100644 pr-preview/pr-4027/overview/license/index.html delete mode 100644 pr-preview/pr-4027/overview/performance/application/index.html delete mode 100644 pr-preview/pr-4027/overview/performance/compute/index.html delete mode 100644 pr-preview/pr-4027/overview/performance/index.html delete mode 100644 pr-preview/pr-4027/overview/performance/io/index.html delete mode 100644 pr-preview/pr-4027/overview/product/index.html delete mode 100644 pr-preview/pr-4027/overview/security-benefits/index.html delete mode 100644 pr-preview/pr-4027/reference/cli/index.html delete mode 100644 pr-preview/pr-4027/reference/migration/index.html delete mode 100644 pr-preview/pr-4027/reference/slsa/index.html delete mode 100644 pr-preview/pr-4027/reference/terraform/index.html delete mode 100644 pr-preview/pr-4027/search-index-docs-default-2.22.json delete mode 100644 pr-preview/pr-4027/search-index-docs-default-2.23.json delete mode 100644 pr-preview/pr-4027/search-index-docs-default-2.24.json delete mode 100644 pr-preview/pr-4027/search-index-docs-default-current.json delete mode 100644 pr-preview/pr-4027/sitemap.xml delete mode 100644 pr-preview/pr-4027/workflows/cert-manager/index.html delete mode 100644 pr-preview/pr-4027/workflows/config/index.html delete mode 100644 pr-preview/pr-4027/workflows/create/index.html delete mode 100644 pr-preview/pr-4027/workflows/lb/index.html delete mode 100644 pr-preview/pr-4027/workflows/recovery/index.html delete mode 100644 pr-preview/pr-4027/workflows/reproducible-builds/index.html delete mode 100644 pr-preview/pr-4027/workflows/s3proxy/index.html delete mode 100644 pr-preview/pr-4027/workflows/sbom/index.html delete mode 100644 pr-preview/pr-4027/workflows/scale/index.html delete mode 100644 pr-preview/pr-4027/workflows/storage/index.html delete mode 100644 pr-preview/pr-4027/workflows/terminate/index.html delete mode 100644 pr-preview/pr-4027/workflows/terraform-provider/index.html delete mode 100644 pr-preview/pr-4027/workflows/troubleshooting/index.html delete mode 100644 pr-preview/pr-4027/workflows/trusted-launch/index.html delete mode 100644 pr-preview/pr-4027/workflows/upgrade/index.html delete mode 100644 pr-preview/pr-4027/workflows/verify-cli/index.html delete mode 100644 pr-preview/pr-4027/workflows/verify-cluster/index.html diff --git a/pr-preview/pr-4027/2.22/architecture/attestation/index.html b/pr-preview/pr-4027/2.22/architecture/attestation/index.html deleted file mode 100644 index 0f1c98194..000000000 --- a/pr-preview/pr-4027/2.22/architecture/attestation/index.html +++ /dev/null @@ -1,229 +0,0 @@ - - - - - -Attestation | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Attestation

-

This page explains Constellation's attestation process and highlights the cornerstones of its trust model.

-

Terms

-

The following lists terms and concepts that help to understand the attestation concept of Constellation.

-

Trusted Platform Module (TPM)

-

A TPM chip is a dedicated tamper-resistant crypto-processor. -It can securely store artifacts such as passwords, certificates, encryption keys, or runtime measurements (more on this below). -When a TPM is implemented in software, it's typically called a virtual TPM (vTPM).

-

Runtime measurement

-

A runtime measurement is a cryptographic hash of the memory pages of a so called runtime component. Runtime components of interest typically include a system's bootloader or OS kernel.

-

Platform Configuration Register (PCR)

-

A Platform Configuration Register (PCR) is a memory location in the TPM that has some unique properties. -To store a new value in a PCR, the existing value is extended with a new value as follows:

-
PCR[N] = HASHalg( PCR[N] || ArgumentOfExtend )
-

The PCRs are typically used to store runtime measurements. -The new value of a PCR is always an extension of the existing value. -Thus, storing the measurements of multiple components into the same PCR irreversibly links them together.

-

Measured boot

-

Measured boot builds on the concept of chained runtime measurements. -Each component in the boot chain loads and measures the next component into the PCR before executing it. -By comparing the resulting PCR values against trusted reference values, the integrity of the entire boot chain and thereby the running system can be ensured.

-

Remote attestation (RA)

-

Remote attestation is the process of verifying certain properties of an application or platform, such as integrity and confidentiality, from a remote location. -In the case of a measured boot, the goal is to obtain a signed attestation statement on the PCR values of the boot measurements. -The statement can then be verified and compared to a set of trusted reference values. -This way, the integrity of the platform can be ensured before sharing secrets with it.

-

Confidential virtual machine (CVM)

-

Confidential computing (CC) is the protection of data in-use with hardware-based trusted execution environments (TEEs). -With CVMs, TEEs encapsulate entire virtual machines and isolate them against the hypervisor, other VMs, and direct memory access. -After loading the initial VM image into encrypted memory, the hypervisor calls for a secure processor to measure these initial memory pages. -The secure processor locks these pages and generates an attestation report on the initial page measurements. -CVM memory pages are encrypted with a key that resides inside the secure processor, which makes sure only the guest VM can access them. -The attestation report is signed by the secure processor and can be verified using remote attestation via the certificate authority of the hardware vendor. -Such an attestation statement guarantees the confidentiality and integrity of a CVM.

-

Attested TLS (aTLS)

-

In a CC environment, attested TLS (aTLS) can be used to establish secure connections between two parties using the remote attestation features of the CC components.

-

aTLS modifies the TLS handshake by embedding an attestation statement into the TLS certificate. -Instead of relying on a certificate authority, aTLS uses this attestation statement to establish trust in the certificate.

-

The protocol can be used by clients to verify a server certificate, by a server to verify a client certificate, or for mutual verification (mutual aTLS).

-

Overview

-

The challenge for Constellation is to lift a CVM's attestation statement to the Kubernetes software layer and make it end-to-end verifiable. -From there, Constellation needs to expand the attestation from a single CVM to the entire cluster.

-

The JoinService and VerificationService are where all runs together. -Internally, the JoinService uses remote attestation to securely join CVM nodes to the cluster. -Externally, the VerificationService provides an attestation statement for the cluster's CVMs and configuration.

-

The following explains the details of both steps.

-

Node attestation

-

The idea is that Constellation nodes should have verifiable integrity from the CVM hardware measurement up to the Kubernetes software layer. -The solution is a verifiable boot chain and an integrity-protected runtime environment.

-

Constellation uses measured boot within CVMs, measuring each component in the boot process before executing it. -Outside of CC, this is usually implemented via TPMs. -CVM technologies differ in how they implement runtime measurements, but the general concepts are similar to those of a TPM. -For simplicity, TPM terminology like PCR is used in the following.

-

When a Constellation node image boots inside a CVM, measured boot is used for all stages and components of the boot chain. -This process goes up to the root filesystem. -The root filesystem is mounted read-only with integrity protection. -For the details on the image and boot stages see the image architecture documentation. -Any changes to the image will inevitably also change the corresponding PCR values. -To create a node attestation statement, the Constellation image obtains a CVM attestation statement from the hardware. -This includes the runtime measurements and thereby binds the measured boot results to the CVM hardware measurement.

-

In addition to the image measurements, Constellation extends a PCR during the initialization phase that irrevocably marks the node as initialized. -The measurement is created using the clusterID, tying all future attestation statements to this ID. -Thereby, an attestation statement is unique for every cluster and a node can be identified unambiguously as being initialized.

-

To verify an attestation, the hardware's signature and a statement are verified first to establish trust in the contained runtime measurements. -If successful, the measurements are verified against the trusted values of the particular Constellation release version. -Finally, the measurement of the clusterID can be compared by calculating it with the master secret.

-

Runtime measurements

-

Constellation uses runtime measurements to implement the measured boot approach. -As stated above, the underlying hardware technology and guest firmware differ in their implementations of runtime measurements. -The following gives a detailed description of the available measurements in the different cloud environments.

-

The runtime measurements consist of two types of values:

-
    -
  • -

    Measurements produced by the cloud infrastructure and firmware of the CVM: -These are measurements of closed-source firmware and other values controlled by the cloud provider. -While not being reproducible for the user, some of them can be compared against previously observed values. -Others may change frequently and aren't suitable for verification. -The signed image measurements include measurements that are known, previously observed values.

    -
  • -
  • -

    Measurements produced by the Constellation bootloader and boot chain: -The Constellation Bootloader takes over from the CVM firmware and measures the rest of the boot chain. -The Constellation Bootstrapper is the first user mode component that runs in a Constellation image. -It extends PCR registers with the IDs of the cluster marking a node as initialized.

    -
  • -
-

Constellation allows to specify in the config which measurements should be enforced during the attestation process. -Enforcing non-reproducible measurements controlled by the cloud provider means that changes in these values require manual updates to the cluster's config. -By default, Constellation only enforces measurements that are stable values produced by the infrastructure or by Constellation directly.

-

Constellation uses the vTPM (NitroTPM) feature of the AWS Nitro System on AWS for runtime measurements.

The vTPM adheres to the TPM 2.0 specification. -The VMs are attested by obtaining signed PCR values over the VM's boot configuration from the TPM and comparing them to a known, good state (measured boot).

The following table lists all PCR values of the vTPM and the measured components. -It also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable. -The latter means that the value can be generated offline and compared to the one in the vTPM.

PCRComponentsMeasured byReproducible and verifiable
0FirmwareAWSNo
1FirmwareAWSNo
2FirmwareAWSNo
3FirmwareAWSNo
4Constellation Bootloader, Kernel, initramfs, Kernel command lineAWS, Constellation BootloaderYes
5FirmwareAWSNo
6FirmwareAWSNo
7Secure Boot PolicyAWS, Constellation BootloaderNo
8---
9initramfs, Kernel command lineLinux KernelYes
10User spaceLinux IMANo1
11Unified Kernel Image componentsConstellation BootloaderYes
12Reserved(User space, Constellation Bootloader)Yes
13Reserved(Constellation Bootloader)Yes
14Secure Boot StateConstellation BootloaderNo
15ClusterIDConstellation BootstrapperYes
16–23Unused--
-

CVM verification

-

To verify the integrity of the received attestation statement, a chain of trust from the CVM technology to the interface providing the statement has to be established. -For verification of the CVM technology, Constellation may expose additional options in its config file.

-

On AWS, AMD SEV-SNP is used to provide runtime encryption to the VMs. -An SEV-SNP attestation report is used to establish trust in the VM. -You may customize certain parameters for verification of the attestation statement using the Constellation config file.

    -
  • -

    TCB versions

    -

    You can set the minimum version numbers of components in the SEV-SNP TCB. -Use the latest versions to enforce that only machines with the most recent firmware updates are allowed to join the cluster. -Alternatively, you can set a lower minimum version to allow slightly out-of-date machines to still be able to join the cluster.

    -
  • -
  • -

    AMD Root Key Certificate

    -

    This certificate is the root of trust for verifying the SEV-SNP certificate chain.

    -
  • -
  • -

    AMD Signing Key Certificate

    -

    This is the intermediate certificate for verifying the SEV-SNP report's signature. -If it's not specified, the CLI fetches it from the AMD key distribution server.

    -
  • -
-

Cluster attestation

-

Cluster-facing, Constellation's JoinService verifies each node joining the cluster given the configured ground truth runtime measurements. -User-facing, the VerificationService provides an interface to verify a node using remote attestation. -By verifying the first node during the initialization and configuring the ground truth measurements that are subsequently enforced by the JoinService, the whole cluster is verified in a transitive way.

-

Cluster-facing attestation

-

The JoinService is provided with the runtime measurements of the whitelisted Constellation image version as the ground truth. -During the initialization and the cluster bootstrapping, each node connects to the JoinService using aTLS. -During the handshake, the node transmits an attestation statement including its runtime measurements. -The JoinService verifies that statement and compares the measurements against the ground truth. -For details of the initialization process check the microservice descriptions.

-

After the initialization, every node updates its runtime measurements with the clusterID value, marking it irreversibly as initialized. -When an initialized node tries to join another cluster, its measurements inevitably mismatch the measurements of an uninitialized node and it will be declined.

-

User-facing attestation

-

The VerificationService provides an endpoint for obtaining its hardware-based remote attestation statement, which includes the runtime measurements. -A user can verify this statement and compare the measurements against the configured ground truth and, thus, verify the identity and integrity of all Constellation components and the cluster configuration. Subsequently, the user knows that the entire cluster is in the expected state and is trustworthy.

-

Putting it all together

-

This section puts the aforementioned concepts together and illustrate how trust into a Constellation cluster is established and maintained.

-

CLI and node images

-

It all starts with the CLI executable. The CLI is signed by Edgeless Systems. To ensure non-repudiability for CLI releases, Edgeless Systems publishes corresponding signatures to the public ledger of the sigstore project. There's a step-by-step guide on how to verify CLI signatures based on sigstore.

-

The CLI contains the latest runtime measurements of the Constellation node image for all supported cloud platforms. In case a different version of the node image is to be used, the corresponding runtime measurements can be fetched using the CLI's fetch-measurements command. This command downloads the runtime measurements and the corresponding signature from cdn.confidential.cloud. See for example the following files corresponding to node image v2.16.3:

- -

The CLI contains the long-term public key of Edgeless Systems to verify the signature of downloaded runtime measurements.

-

Cluster creation

-

When a cluster is created, the CLI automatically verifies the runtime measurements of the first node using remote attestation. Based on this, the CLI and the first node set up a temporary TLS connection. This aTLS connection is used for two things:

-
    -
  1. The CLI sends the master secret of the to-be-created cluster to the CLI. The master secret is generated by the first node.
  2. -
  3. The first node sends a kubeconfig file with Kubernetes credentials to the CLI.
  4. -
-

After this, the aTLS connection is closed and the first node bootstraps the Kubernetes cluster. All subsequent interactions between the CLI and the cluster go via the Kubernetes API server running inside the cluster. The CLI (and other tools like kubectl) use the credentials referenced by the kubeconfig file to authenticate themselves towards the Kubernetes API server and to establish a mTLS connection.

-

The CLI connects to the Kubernetes API to write the runtime measurements for the applicable node image to etcd. The JoinService uses these runtime measurements to verify all nodes that join the cluster subsequently.

-

Chain of trust

-

In summary, there's a chain of trust based on cryptographic signatures that goes from the user to the cluster via the CLI. This is illustrated in the following diagram.

- -

Upgrades

-

Whenever a cluster is upgraded to a new version of the node image, the CLI sends the corresponding runtime measurements via the Kubernetes API server. The new runtime measurements are stored in etcd within the cluster and replace any previous runtime measurements. The new runtime measurements are then used automatically by the JoinService for the verification of new nodes.

-

References

- -

Footnotes

-
    -
  1. -

    Linux IMA produces runtime measurements of user-space binaries. -However, these measurements aren't deterministic and thus, PCR[10] can't be compared to a constant value. -Instead, a policy engine must be used to verify the TPM event log against a policy. 2 3 4

    -
  2. -
-
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/architecture/encrypted-storage/index.html b/pr-preview/pr-4027/2.22/architecture/encrypted-storage/index.html deleted file mode 100644 index 24fbd65c8..000000000 --- a/pr-preview/pr-4027/2.22/architecture/encrypted-storage/index.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - -Encrypted persistent storage | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Encrypted persistent storage

-

Confidential VMs provide runtime memory encryption to protect data in use. -In the context of Kubernetes, this is sufficient for the confidentiality and integrity of stateless services. -Consider a front-end web server, for example, that keeps all connection information cached in main memory. -No sensitive data is ever written to an insecure medium. -However, many real-world applications need some form of state or data-lake service that's connected to a persistent storage device and requires encryption at rest. -As described in Use persistent storage, cloud service providers (CSPs) use the container storage interface (CSI) to make their storage solutions available to Kubernetes workloads. -These CSI storage solutions often support some sort of encryption. -For example, Google Cloud encrypts data at rest by default, without any action required by the customer.

-

Cloud provider-managed encryption

-

CSP-managed storage solutions encrypt the data in the cloud backend before writing it physically to disk. -In the context of confidential computing and Constellation, the CSP and its managed services aren't trusted. -Hence, cloud provider-managed encryption protects your data from offline hardware access to physical storage devices. -It doesn't protect it from anyone with infrastructure-level access to the storage backend or a malicious insider in the cloud platform. -Even with "bring your own key" or similar concepts, the CSP performs the encryption process with access to the keys and plaintext data.

-

In the security model of Constellation, securing persistent storage and thereby data at rest requires that all cryptographic operations are performed inside a trusted execution environment. -Consequently, using CSP-managed encryption of persistent storage usually isn't an option.

-

Constellation-managed encryption

-

Constellation provides CSI drivers for storage solutions in all major clouds with built-in encryption support. -Block storage provisioned by the CSP is mapped using the dm-crypt, and optionally the dm-integrity, kernel modules, before it's formatted and accessed by the Kubernetes workloads. -All cryptographic operations happen inside the trusted environment of the confidential Constellation node.

-

Note that for integrity-protected disks, volume expansion isn't supported.

-

By default the driver uses data encryption keys (DEKs) issued by the Constellation KeyService. -The DEKs are in turn derived from the Constellation's key encryption key (KEK), which is directly derived from the master secret. -This is the recommended mode of operation, and also requires the least amount of setup by the cluster administrator.

-

Alternatively, the driver can be configured to use a key management system to store and access KEKs and DEKs.

-

Refer to keys and cryptography for more details on key management in Constellation.

-

Once deployed and configured, the CSI driver ensures transparent encryption and integrity of all persistent volumes provisioned via its storage class. -Data at rest is secured without any additional actions required by the developer.

-

Cryptographic algorithms

-

This section gives an overview of the libraries, cryptographic algorithms, and their configurations, used in Constellation's CSI drivers.

-

dm-crypt

-

To interact with the dm-crypt kernel module, Constellation uses libcryptsetup. -New devices are formatted as LUKS2 partitions with a sector size of 4096 bytes. -The used key derivation function is Argon2id with the recommended parameters for memory-constrained environments of 3 iterations and 64 MiB of memory, utilizing 4 parallel threads. -For encryption Constellation uses AES in XTS-Plain64. The key size is 512 bit.

-

dm-integrity

-

To interact with the dm-integrity kernel module, Constellation uses libcryptsetup. -When enabled, the used data integrity algorithm is HMAC with SHA256 as the hash function. -The tag size is 32 Bytes.

-

Encrypted S3 object storage

-

Constellation comes with a service that you can use to transparently retrofit client-side encryption to existing applications that use S3 (AWS or compatible) for storage. -To learn more, check out the s3proxy documentation.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/architecture/images/index.html b/pr-preview/pr-4027/2.22/architecture/images/index.html deleted file mode 100644 index cd39d7b18..000000000 --- a/pr-preview/pr-4027/2.22/architecture/images/index.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - -Constellation images | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Constellation images

-

Constellation uses a minimal version of Fedora as the operating system running inside confidential VMs. This Linux distribution is optimized for containers and designed to be stateless. -The Constellation images provide measured boot and an immutable filesystem.

-

Measured boot

- -

Measured boot uses a Trusted Platform Module (TPM) to measure every part of the boot process. This allows for verification of the integrity of a running system at any point in time. To ensure correct measurements of every stage, each stage is responsible to measure the next stage before transitioning.

-

Firmware

-

With confidential VMs, the firmware is the root of trust and is measured automatically at boot. After initialization, the firmware will load and measure the bootloader before executing it.

-

Bootloader

-

The bootloader is the first modifiable part of the boot chain. The bootloader is tasked with loading the kernel, initramfs and setting the kernel command line. The Constellation bootloader measures these components before starting the kernel.

-

initramfs

-

The initramfs is a small filesystem loaded to prepare the actual root filesystem. The Constellation initramfs maps the block device containing the root filesystem with dm-verity. The initramfs then mounts the root filesystem from the mapped block device.

-

dm-verity provides integrity checking using a cryptographic hash tree. When a block is read, its integrity is checked by verifying the tree against a trusted root hash. The initramfs reads this root hash from the previously measured kernel command line. Thus, if any block of the root filesystem's device is modified on disk, trying to read the modified block will result in a kernel panic at runtime.

-

After mounting the root filesystem, the initramfs will switch over and start the init process of the integrity-protected root filesystem.

-

State disk

-

In addition to the read-only root filesystem, each Constellation node has a disk for storing state data. -This disk is mounted readable and writable by the initramfs and contains data that should persist across reboots. -Such data can contain sensitive information and, therefore, must be stored securely. -To that end, the state disk is protected by authenticated encryption. -See the section on keys and encryption for more information on the cryptographic primitives in use.

-

Kubernetes components

-

During initialization, the Bootstrapper downloads and verifies the Kubernetes components as configured by the user. -They're stored on the state partition and can be updated once new releases need to be installed.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/architecture/keys/index.html b/pr-preview/pr-4027/2.22/architecture/keys/index.html deleted file mode 100644 index d35ed4759..000000000 --- a/pr-preview/pr-4027/2.22/architecture/keys/index.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - -Key management and cryptographic primitives | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Key management and cryptographic primitives

-

Constellation protects and isolates your cluster and workloads. -To that end, cryptography is the foundation that ensures the confidentiality and integrity of all components. -Evaluating the security and compliance of Constellation requires a precise understanding of the cryptographic primitives and keys used. -The following gives an overview of the architecture and explains the technical details.

-

Confidential VMs

-

Confidential VM (CVM) technology comes with hardware and software components for memory encryption, isolation, and remote attestation. -For details on the implementations and cryptographic soundness, refer to the hardware vendors' documentation and advisories.

-

Master secret

-

The master secret is the cryptographic material used for deriving the clusterID and the key encryption key (KEK) for storage encryption. -It's generated during the bootstrapping of a Constellation cluster. -It can either be managed by Constellation or an external key management system. -In case of recovery, the master secret allows to decrypt the state and recover a Constellation cluster.

-

Cluster identity

-

The identity of a Constellation cluster is represented by cryptographic measurements:

-

The base measurements represent the identity of a valid, uninitialized Constellation node. -They depend on the node image, but are otherwise the same for every Constellation cluster. -On node boot, they're determined using the CVM's attestation mechanism and measured boot up to the read-only root filesystem.

-

The clusterID represents the identity of a single initialized Constellation cluster. -It's derived from the master secret and a cryptographically random salt and unique for every Constellation cluster. -The Bootstrapper measures the clusterID into its own PCR before executing any code not measured as part of the base measurements. -See Node attestation for details.

-

The remote attestation statement of a Constellation cluster combines the base measurements and the clusterID for a verifiable, unspoofable, unique identity.

-

Network encryption

-

Constellation encrypts all cluster network communication using the container network interface (CNI). -See network encryption for more details.

-

The Cilium agent running on each node establishes a secure WireGuard tunnel between it and all other known nodes in the cluster. -Each node creates its own Curve25519 encryption key pair and distributes its public key via Kubernetes. -A node uses another node's public key to decrypt and encrypt traffic from and to Cilium-managed endpoints running on that node. -Connections are always encrypted peer-to-peer using ChaCha20 with Poly1305. -WireGuard implements forward secrecy with key rotation every 2 minutes.

-

Storage encryption

-

Constellation supports transparent encryption of persistent storage. -The Linux kernel's device mapper-based encryption features are used to encrypt the data on the block storage level. -Currently, the following primitives are used for block storage encryption:

- -

Adding primitives for integrity protection in the CVM attacker model are under active development and will be available in a future version of Constellation. -See encrypted storage for more details.

-

As a cluster administrator, when creating a cluster, you can use the Constellation installation program to select one of the following methods for key management:

-
    -
  • Constellation-managed key management
  • -
  • User-managed key management
  • -
-

Constellation-managed key management

-

Key material and key derivation

-

During the creation of a Constellation cluster, the cluster's master secret is used to derive a KEK. -This means creating two clusters with the same master secret will yield the same KEK. -Any data encryption key (DEK) is derived from the KEK via HKDF. -Note that the master secret is recommended to be unique for every cluster and shouldn't be reused (except in case of recovering a cluster).

-

State and storage

-

The KEK is derived from the master secret during the initialization. -Subsequently, all other key material is derived from the KEK. -Given the same KEK, any DEK can be derived deterministically from a given identifier. -Hence, there is no need to store DEKs. They can be derived on demand. -After the KEK was derived, it's stored in memory only and never leaves the CVM context.

-

Availability

-

Constellation-managed key management has the same availability as the underlying Kubernetes cluster. -Therefore, the KEK is stored in the distributed Kubernetes etcd storage to allow for unexpected but non-fatal (control-plane) node failure. -The etcd storage is backed by the encrypted and integrity protected state disk of the nodes.

-

Recovery

-

Constellation clusters can be recovered in the event of a disaster, even when all node machines have been stopped and need to be rebooted. -For details on the process see the recovery workflow.

-

User-managed key management

-

User-managed key management is under active development and will be available soon. -In scenarios where constellation-managed key management isn't an option, this mode allows you to keep full control of your keys. -For example, compliance requirements may force you to keep your KEKs in an on-prem key management system (KMS).

-

During the creation of a Constellation cluster, you specify a KEK present in a remote KMS. -This follows the common scheme of "bring your own key" (BYOK). -Constellation will support several KMSs for managing the storage and access of your KEK. -Initially, it will support the following KMSs:

- -

Storing the keys in Cloud KMS of AWS, Azure, or GCP binds the key usage to the particular cloud identity access management (IAM). -In the future, Constellation will support remote attestation-based access policies for Cloud KMS once available. -Note that using a Cloud KMS limits the isolation and protection to the guarantees of the particular offering.

-

KMIP support allows you to use your KMIP-compatible on-prem KMS and keep full control over your keys. -This follows the common scheme of "hold your own key" (HYOK).

-

The KEK is used to encrypt per-data "data encryption keys" (DEKs). -DEKs are generated to encrypt your data before storing it on persistent storage. -After being encrypted by the KEK, the DEKs are stored on dedicated cloud storage for persistence. -Currently, Constellation supports the following cloud storage options:

- -

The DEKs are only present in plaintext form in the encrypted main memory of the CVMs. -Similarly, the cryptographic operations for encrypting data before writing it to persistent storage are performed in the context of the CVMs.

-

Recovery and migration

-

In the case of a disaster, the KEK can be used to decrypt the DEKs locally and subsequently use them to decrypt and retrieve the data. -In case of migration, configuring the same KEK will provide seamless migration of data. -Thus, only the DEK storage needs to be transferred to the new cluster alongside the encrypted data for seamless migration.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/architecture/microservices/index.html b/pr-preview/pr-4027/2.22/architecture/microservices/index.html deleted file mode 100644 index afd0ec30c..000000000 --- a/pr-preview/pr-4027/2.22/architecture/microservices/index.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - -Microservices | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Microservices

-

Constellation takes care of bootstrapping and initializing a Confidential Kubernetes cluster. -During the lifetime of the cluster, it handles day 2 operations such as key management, remote attestation, and updates. -These features are provided by several microservices:

- -

The relations between microservices are shown in the following diagram:

- -

Bootstrapper

-

The Bootstrapper is the first microservice launched after booting a Constellation node image. -It sets up that machine as a Kubernetes node and integrates that node into the Kubernetes cluster. -To this end, the Bootstrapper first downloads and verifies the Kubernetes components at the configured versions. -The Bootstrapper tries to find an existing cluster and if successful, communicates with the JoinService to join the node. -Otherwise, it waits for an initialization request to create a new Kubernetes cluster.

-

JoinService

-

The JoinService runs as DaemonSet on each control-plane node. -New nodes (at cluster start, or later through autoscaling) send a request to the service over attested TLS (aTLS). -The JoinService verifies the new node's certificate and attestation statement. -If attestation is successful, the new node is supplied with an encryption key from the KeyService for its state disk, and a Kubernetes bootstrap token.

- -

VerificationService

-

The VerificationService runs as DaemonSet on each node. -It provides user-facing functionality for remote attestation during the cluster's lifetime via an endpoint for verifying the cluster. -Read more about the hardware-based attestation feature of Constellation and how to verify a cluster on the client side.

-

KeyService

-

The KeyService runs as DaemonSet on each control-plane node. -It implements the key management for the storage encryption keys in Constellation. These keys are used for the state disk of each node and the transparently encrypted storage for Kubernetes. -Depending on wether the constellation-managed or user-managed mode is used, the KeyService holds the key encryption key (KEK) directly or calls an external key management service (KMS) for key derivation respectively.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/architecture/networking/index.html b/pr-preview/pr-4027/2.22/architecture/networking/index.html deleted file mode 100644 index ba11d5f8c..000000000 --- a/pr-preview/pr-4027/2.22/architecture/networking/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -Network encryption | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Network encryption

-

Constellation encrypts all pod communication using the container network interface (CNI). -To that end, Constellation deploys, configures, and operates the Cilium CNI plugin. -Cilium provides transparent encryption for all cluster traffic using either IPSec or WireGuard. -Currently, Constellation only supports WireGuard as the encryption engine. -You can read more about the cryptographic soundness of WireGuard in their white paper.

-

Cilium is actively working on implementing a feature called host-to-host encryption mode for WireGuard. -With host-to-host, all traffic between nodes will be tunneled via WireGuard (host-to-host, host-to-pod, pod-to-host, pod-to-pod). -Until the host-to-host feature is released, Constellation enables pod-to-pod encryption. -This mode encrypts all traffic between Kubernetes pods using WireGuard tunnels.

-

When using Cilium in the default setup but with encryption enabled, there is a known issue -that can cause pod-to-pod traffic to be unencrypted. -To mitigate this issue, Constellation adds a strict mode to Cilium's pod-to-pod encryption. -This mode changes the default behavior of traffic that's destined for an unknown endpoint to not be send out in plaintext, but instead being dropped. -The strict mode distinguishes between traffic that's send to a pod from traffic that's destined for a cluster-external endpoint by considering the pod's CIDR range.

-

Traffic originating from hosts isn't encrypted yet. -This mainly includes health checks from Kubernetes API server. -Also, traffic proxied over the API server via e.g. kubectl port-forward isn't encrypted.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/architecture/observability/index.html b/pr-preview/pr-4027/2.22/architecture/observability/index.html deleted file mode 100644 index 6014b0f6b..000000000 --- a/pr-preview/pr-4027/2.22/architecture/observability/index.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - -Observability | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Observability

-

In Kubernetes, observability is the ability to gain insight into the behavior and performance of applications. -It helps identify and resolve issues more effectively, ensuring stability and performance of Kubernetes workloads, reducing downtime and outages, and improving efficiency. -The "three pillars of observability" are logs, metrics, and traces.

-

In the context of Confidential Computing, observability is a delicate subject and needs to be applied such that it doesn't leak any sensitive information. -The following gives an overview of where and how you can apply standard observability tools in Constellation.

-

Cloud resource monitoring

-

While inaccessible, Constellation's nodes are still visible as black box VMs to the hypervisor. -Resource consumption, such as memory and CPU utilization, can be monitored from the outside and observed via the cloud platforms directly. -Similarly, other resources, such as storage and network and their respective metrics, are visible via the cloud platform.

-

Metrics

-

Metrics are numeric representations of data measured over intervals of time. They're essential for understanding system health and gaining insights using telemetry signals.

-

By default, Constellation exposes the metrics for Kubernetes system components inside the cluster. -Similarly, the etcd metrics endpoints are exposed inside the cluster. -These metrics endpoints can be disabled.

-

You can collect these cluster-internal metrics via tools such as Prometheus or the Elastic Stack.

-

Constellation's CNI Cilium also supports metrics via Prometheus endpoints. -However, in Constellation, they're disabled by default and must be enabled first.

-

Logs

-

Logs represent discrete events that usually describe what's happening with your service. -The payload is an actual message emitted from your system along with a metadata section containing a timestamp, labels, and tracking identifiers.

-

System logs

-

Detailed system-level logs are accessible via /var/log and journald on the nodes directly. -They can be collected from there, for example, via Filebeat and Logstash, which are tools of the Elastic Stack.

-

In case of an error during the initialization, the CLI automatically collects the Bootstrapper logs and returns these as a file for troubleshooting. Here is an example of such an event:

-
Cluster initialization failed. This error is not recoverable.
Terminate your cluster and try again.
Fetched bootstrapper logs are stored in "constellation-cluster.log"
-

Kubernetes logs

-

Constellation supports the Kubernetes logging architecture. -By default, logs are written to the nodes' encrypted state disks. -These include the Pod and container logs and the system component logs.

-

Constellation services run as Pods inside the kube-system namespace and use the standard container logging mechanism. -The same applies for the Cilium Pods.

-

You can collect logs from within the cluster via tools such as Fluentd, Loki, or the Elastic Stack.

-

Traces

-

Modern systems are implemented as interconnected complex and distributed microservices. Understanding request flows and system communications is challenging, mainly because all systems in a chain need to be modified to propagate tracing information. Distributed tracing is a new approach to increasing observability and understanding performance bottlenecks. A trace represents consecutive events that reflect an end-to-end request path in a distributed system.

-

Constellation supports traces for Kubernetes system components. -By default, they're disabled and need to be enabled first.

-

Similarly, Cilium can be enabled to export traces.

-

You can collect these traces via tools such as Jaeger or Zipkin.

-

Integrations

-

Platforms and SaaS solutions such as Datadog, logz.io, Dynatrace, or New Relic facilitate the observability challenge for Kubernetes and provide all-in-one SaaS solutions. -They install agents into the cluster that collect metrics, logs, and tracing information and upload them into the data lake of the platform. -Technically, the agent-based approach is compatible with Constellation, and attaching these platforms is straightforward. -However, you need to evaluate if the exported data might violate Constellation's compliance and privacy guarantees by uploading them to a third-party platform.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/architecture/orchestration/index.html b/pr-preview/pr-4027/2.22/architecture/orchestration/index.html deleted file mode 100644 index 840afb796..000000000 --- a/pr-preview/pr-4027/2.22/architecture/orchestration/index.html +++ /dev/null @@ -1,80 +0,0 @@ - - - - - -Orchestrating Constellation clusters | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Orchestrating Constellation clusters

-

You can use the CLI to create a cluster on the supported cloud platforms. -The CLI provisions the resources in your cloud environment and initiates the initialization of your cluster. -It uses a set of parameters and an optional configuration file to manage your cluster installation. -The CLI is also used for updating your cluster.

-

Workspaces

-

Each Constellation cluster has an associated workspace. -The workspace is where data such as the Constellation state and config files are stored. -Each workspace is associated with a single cluster and configuration. -The CLI stores state in the local filesystem making the current directory the active workspace. -Multiple clusters require multiple workspaces, hence, multiple directories. -Note that every operation on a cluster always has to be performed from the directory associated with its workspace.

-

You may copy files from the workspace to other locations, -but you shouldn't move or delete them while the cluster is still being used. -The Constellation CLI takes care of managing the workspace. -Only when a cluster was terminated, and you are sure the files aren't needed anymore, should you remove a workspace.

-

Cluster creation process

-

To allow for fine-grained configuration of your cluster and cloud environment, Constellation supports an extensive configuration file with strong defaults. Generating the configuration file is typically the first thing you do in the workspace.

-

Altogether, the following files are generated during the creation of a Constellation cluster and stored in the current workspace:

-
    -
  • a configuration file
  • -
  • a state file
  • -
  • a Base64-encoded master secret
  • -
  • Terraform artifacts, stored in subdirectories
  • -
  • a Kubernetes kubeconfig file.
  • -
-

After the initialization of your cluster, the CLI will provide you with a Kubernetes kubeconfig file. -This file grants you access to your Kubernetes cluster and configures the kubectl tool. -In addition, the cluster's identifier is returned and stored in the state file.

-

Creation process details

-
    -
  1. The CLI apply command first creates the confidential VM (CVM) resources in your cloud environment and configures the network
  2. -
  3. Each CVM boots the Constellation node image and measures every component in the boot chain
  4. -
  5. The first microservice launched in each node is the Bootstrapper
  6. -
  7. The Bootstrapper waits until it either receives an initialization request or discovers an initialized cluster
  8. -
  9. The CLI then connects to the Bootstrapper of a selected node, sends the configuration, and initiates the initialization of the cluster
  10. -
  11. The Bootstrapper of that node initializes the Kubernetes cluster and deploys the other Constellation microservices including the JoinService
  12. -
  13. Subsequently, the Bootstrappers of the other nodes discover the initialized cluster and send join requests to the JoinService
  14. -
  15. As part of the join request each node includes an attestation statement of its boot measurements as authentication
  16. -
  17. The JoinService verifies the attestation statements and joins the nodes to the Kubernetes cluster
  18. -
  19. This process is repeated for every node joining the cluster later (e.g., through autoscaling)
  20. -
-

Post-installation configuration

-

Post-installation the CLI provides a configuration for accessing the cluster using the Kubernetes API. -The kubeconfig file provides the credentials and configuration for connecting and authenticating to the API server. -Once configured, orchestrate the Kubernetes cluster via kubectl.

-

After the initialization, the CLI will present you with a couple of tokens:

-
    -
  • The master secret (stored in the constellation-mastersecret.json file by default)
  • -
  • The clusterID of your cluster in Base64 encoding
  • -
-

You can read more about these values and their meaning in the guide on cluster identity.

-

The master secret must be kept secret and can be used to recover your cluster. -Instead of managing this secret manually, you can use your key management solution of choice with Constellation.

-

The clusterID uniquely identifies a cluster and can be used to verify your cluster.

-

Upgrades

-

Constellation images and microservices may need to be upgraded to new versions during the lifetime of a cluster. -Constellation implements a rolling update mechanism ensuring no downtime of the control or data plane. -You can upgrade a Constellation cluster with a single operation by using the CLI. -For step-by-step instructions on how to do this, refer to Upgrade your cluster.

-

Attestation of upgrades

-

With every new image, corresponding measurements are released. -During an update procedure, the CLI provides new measurements to the JoinService securely. -New measurements for an updated image are automatically pulled and verified by the CLI following the supply chain security concept of Constellation. -The attestation section describes in detail how these measurements are then used by the JoinService for the attestation of nodes.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/architecture/overview/index.html b/pr-preview/pr-4027/2.22/architecture/overview/index.html deleted file mode 100644 index 9872af2ad..000000000 --- a/pr-preview/pr-4027/2.22/architecture/overview/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - -Overview | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Overview

-

Constellation is a cloud-based confidential orchestration platform. -The foundation of Constellation is Kubernetes and therefore shares the same technology stack and architecture principles. -To learn more about Constellation and Kubernetes, see product overview.

-

About orchestration and updates

-

As a cluster administrator, you can use the Constellation CLI to install and deploy a cluster. -Updates are provided in accordance with the support policy.

-

About microservices and attestation

-

Constellation manages the nodes and network in your cluster. All nodes are bootstrapped by the Bootstrapper. They're verified and authenticated by the JoinService before being added to the cluster and the network. Finally, the entire cluster can be verified via the VerificationService using remote attestation.

-

About node images and verified boot

-

Constellation comes with operating system images for Kubernetes control-plane and worker nodes. -They're highly optimized for running containerized workloads and specifically prepared for running inside confidential VMs. -You can learn more about the images and how verified boot ensures their integrity during boot and beyond.

-

About key management and cryptographic primitives

-

Encryption of data at-rest, in-transit, and in-use is the fundamental building block for confidential computing and Constellation. Learn more about the keys and cryptographic primitives used in Constellation, encrypted persistent storage, and network encryption.

-

About observability

-

Observability in Kubernetes refers to the capability to troubleshoot issues using telemetry signals such as logs, metrics, and traces. -In the realm of Confidential Computing, it's crucial that observability aligns with confidentiality, necessitating careful implementation. -Learn more about the observability capabilities in Constellation.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/architecture/versions/index.html b/pr-preview/pr-4027/2.22/architecture/versions/index.html deleted file mode 100644 index d5058671a..000000000 --- a/pr-preview/pr-4027/2.22/architecture/versions/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - -Versions and support policy | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Versions and support policy

-

All components of Constellation use a three-digit version number of the form v<MAJOR>.<MINOR>.<PATCH>. -The components are released in lock step, usually on the first Tuesday of every month. This release primarily introduces new features, but may also include security or performance improvements. The MINOR version will be incremented as part of this release.

-

Additional PATCH releases may be created on demand, to fix security issues or bugs before the next MINOR release window.

-

New releases are published on GitHub.

-

Kubernetes support policy

-

Constellation is aligned to the version support policy of Kubernetes, and therefore usually supports the most recent three minor versions. -When a new minor version of Kubernetes is released, support is added to the next Constellation release, and that version then supports four Kubernetes versions. -Subsequent Constellation releases drop support for the oldest (and deprecated) Kubernetes version.

-

The following Kubernetes versions are currently supported:

-
    -
  • v1.29.15
  • -
  • v1.30.11
  • -
  • v1.31.7
  • -
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/category/architecture/index.html b/pr-preview/pr-4027/2.22/category/architecture/index.html deleted file mode 100644 index 8b741ef1f..000000000 --- a/pr-preview/pr-4027/2.22/category/architecture/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Architecture | Constellation - - - - - - - -
Skip to main content
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/category/basics/index.html b/pr-preview/pr-4027/2.22/category/basics/index.html deleted file mode 100644 index c2a5e554b..000000000 --- a/pr-preview/pr-4027/2.22/category/basics/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Basics | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Basics

📄️ Security benefits

Constellation implements the Confidential Kubernetes concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be verified.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/category/getting-started/index.html b/pr-preview/pr-4027/2.22/category/getting-started/index.html deleted file mode 100644 index 8b845349f..000000000 --- a/pr-preview/pr-4027/2.22/category/getting-started/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Getting started | Constellation - - - - - - - -
Skip to main content
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/category/reference/index.html b/pr-preview/pr-4027/2.22/category/reference/index.html deleted file mode 100644 index f2c61ed43..000000000 --- a/pr-preview/pr-4027/2.22/category/reference/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Reference | Constellation - - - - - - - -
Skip to main content
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/category/workflows/index.html b/pr-preview/pr-4027/2.22/category/workflows/index.html deleted file mode 100644 index 9054f7784..000000000 --- a/pr-preview/pr-4027/2.22/category/workflows/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Workflows | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Workflows

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/getting-started/examples/emojivoto/index.html b/pr-preview/pr-4027/2.22/getting-started/examples/emojivoto/index.html deleted file mode 100644 index 6c5d7a0a2..000000000 --- a/pr-preview/pr-4027/2.22/getting-started/examples/emojivoto/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - -Emojivoto | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Emojivoto

-

Emojivoto is a simple and fun application that's well suited to test the basic functionality of your cluster.

-emojivoto - Web UI -
    -
  1. Deploy the application: -
    kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment
    -
  2. -
  3. Wait until it becomes available: -
    kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments
    -
  4. -
  5. Forward the web service to your machine: -
    kubectl -n emojivoto port-forward svc/web-svc 8080:80
    -
  6. -
  7. Visit http://localhost:8080
  8. -
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/getting-started/examples/filestash-s3proxy/index.html b/pr-preview/pr-4027/2.22/getting-started/examples/filestash-s3proxy/index.html deleted file mode 100644 index 9808f2bcd..000000000 --- a/pr-preview/pr-4027/2.22/getting-started/examples/filestash-s3proxy/index.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - -Deploying Filestash | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Deploying Filestash

-

Filestash is a web frontend for different storage backends, including S3. -It's a useful application to showcase s3proxy in action.

-
    -
  1. Deploy s3proxy as described in Deployment.
  2. -
  3. Create a deployment file for Filestash with one pod:
  4. -
-
cat << EOF > "deployment-filestash.yaml"
apiVersion: apps/v1
kind: Deployment
metadata:
name: filestash
spec:
replicas: 1
selector:
matchLabels:
app: filestash
template:
metadata:
labels:
app: filestash
spec:
hostAliases:
- ip: $(kubectl get svc s3proxy-service -o=jsonpath='{.spec.clusterIP}')
hostnames:
- "s3.us-east-1.amazonaws.com"
- "s3.us-east-2.amazonaws.com"
- "s3.us-west-1.amazonaws.com"
- "s3.us-west-2.amazonaws.com"
- "s3.eu-north-1.amazonaws.com"
- "s3.eu-south-1.amazonaws.com"
- "s3.eu-south-2.amazonaws.com"
- "s3.eu-west-1.amazonaws.com"
- "s3.eu-west-2.amazonaws.com"
- "s3.eu-west-3.amazonaws.com"
- "s3.eu-central-1.amazonaws.com"
- "s3.eu-central-2.amazonaws.com"
- "s3.ap-northeast-1.amazonaws.com"
- "s3.ap-northeast-2.amazonaws.com"
- "s3.ap-northeast-3.amazonaws.com"
- "s3.ap-east-1.amazonaws.com"
- "s3.ap-southeast-1.amazonaws.com"
- "s3.ap-southeast-2.amazonaws.com"
- "s3.ap-southeast-3.amazonaws.com"
- "s3.ap-southeast-4.amazonaws.com"
- "s3.ap-south-1.amazonaws.com"
- "s3.ap-south-2.amazonaws.com"
- "s3.me-south-1.amazonaws.com"
- "s3.me-central-1.amazonaws.com"
- "s3.il-central-1.amazonaws.com"
- "s3.af-south-1.amazonaws.com"
- "s3.ca-central-1.amazonaws.com"
- "s3.sa-east-1.amazonaws.com"
containers:
- name: filestash
image: machines/filestash:latest
ports:
- containerPort: 8334
volumeMounts:
- name: ca-cert
mountPath: /etc/ssl/certs/kube-ca.crt
subPath: kube-ca.crt
volumes:
- name: ca-cert
secret:
secretName: s3proxy-tls
items:
- key: ca.crt
path: kube-ca.crt
EOF
-

The pod spec includes the hostAliases key, which adds an entry to the pod's /etc/hosts. -The entry forwards all requests for any of the currently defined AWS regions to the Kubernetes service s3proxy-service. -If you followed the s3proxy Deployment guide, this service points to a s3proxy pod.

-

The deployment specifies all regions explicitly to prevent accidental data leaks. -If one of your buckets were located in a region that's not part of the hostAliases key, traffic towards those buckets would not be redirected to s3proxy. -Similarly, if you want to exclude data for specific regions from going through s3proxy you can remove those regions from the deployment.

-

The spec also includes a volume mount for the TLS certificate and adds it to the pod's certificate trust store. -The volume is called ca-cert. -The key ca.crt of that volume is mounted to /etc/ssl/certs/kube-ca.crt, which is the default certificate trust store location for that container's OpenSSL library. -Not adding the CA certificate will result in TLS authentication errors.

-
    -
  1. Apply the file: kubectl apply -f deployment-filestash.yaml
  2. -
-

Afterward, you can use a port forward to access the Filestash pod: -kubectl port-forward pod/$(kubectl get pod --selector='app=filestash' -o=jsonpath='{.items[*].metadata.name}') 8334:8334

-
    -
  1. -

    After browsing to localhost:8443, Filestash will ask you to set an administrator password. -After setting it, you can directly leave the admin area by clicking the blue cloud symbol in the top left corner. -Subsequently, you can select S3 as storage backend and enter your credentials. -This will bring you to an overview of your buckets. -If you want to deploy Filestash in production, take a look at its documentation.

    -
  2. -
  3. -

    To see the logs of s3proxy intercepting requests made to S3, run: kubectl logs -f pod/$(kubectl get pod --selector='app=s3proxy' -o=jsonpath='{.items[*].metadata.name}') -Look out for log messages labeled intercepting. -There is one such log message for each message that's encrypted, decrypted, or blocked.

    -
  4. -
  5. -

    Once you have uploaded a file with Filestash, you should be able to view the file in Filestash. -However, if you go to the AWS S3 Web UI and download the file you just uploaded in Filestash, you won't be able to read it. -Another way to spot encrypted files without downloading them is to click on a file, scroll to the Metadata section, and look for the header named x-amz-meta-constellation-encryption. -This header holds the encrypted data encryption key of the object and is only present on objects that are encrypted by s3proxy.

    -
  6. -
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scaling/index.html b/pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scaling/index.html deleted file mode 100644 index 126a8115e..000000000 --- a/pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scaling/index.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - -Horizontal Pod Autoscaling | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Horizontal Pod Autoscaling

-

This example demonstrates Constellation's autoscaling capabilities. It's based on the Kubernetes HorizontalPodAutoscaler Walkthrough. During the following steps, Constellation will spawn new VMs on demand, verify them, add them to the cluster, and delete them again when the load has settled down.

-

Requirements

-

The cluster needs to be initialized with Kubernetes 1.23 or later. In addition, autoscaling must be enabled to enable Constellation to assign new nodes dynamically.

-

Just for this example specifically, the cluster should have as few worker nodes in the beginning as possible. Start with a small cluster with only one low-powered node for the control-plane node and one low-powered worker node.

-
info

We tested the example using instances of types Standard_DC4as_v5 on Azure and n2d-standard-4 on GCP.

-

Setup

-
    -
  1. -

    Install the Kubernetes Metrics Server:

    -
    kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
    -
  2. -
  3. -

    Deploy the HPA example server that's supposed to be scaled under load.

    -

    This manifest is similar to the one from the Kubernetes HPA walkthrough, but with increased CPU limits and requests to facilitate the triggering of node scaling events.

    -
    cat <<EOF | kubectl apply -f -
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: php-apache
    spec:
    selector:
    matchLabels:
    run: php-apache
    replicas: 1
    template:
    metadata:
    labels:
    run: php-apache
    spec:
    containers:
    - name: php-apache
    image: registry.k8s.io/hpa-example
    ports:
    - containerPort: 80
    resources:
    limits:
    cpu: 900m
    requests:
    cpu: 600m
    ---
    apiVersion: v1
    kind: Service
    metadata:
    name: php-apache
    labels:
    run: php-apache
    spec:
    ports:
    - port: 80
    selector:
    run: php-apache
    EOF
    -
  4. -
  5. -

    Create a HorizontalPodAutoscaler.

    -

    Set an average CPU usage across all Pods of 20% to see one additional worker node being created later. Note that the CPU usage isn't related to the host CPU usage, but rather to the requested CPU capacities (20% of 600 milli-cores CPU across all Pods). See the original tutorial for more information on the HPA configuration.

    -
    kubectl autoscale deployment php-apache --cpu-percent=20 --min=1 --max=10
    -
  6. -
  7. -

    Create a Pod that generates load on the server:

    -
    kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while true; do wget -q -O- http://php-apache; done"
    -
  8. -
  9. -

    Wait a few minutes until new nodes are added to the cluster. You can monitor the state of the HorizontalPodAutoscaler, the list of nodes, and the behavior of the autoscaler.

    -
  10. -
  11. -

    To stop the load generator, press CTRL+C and run:

    -
    kubectl delete pod load-generator
    -
  12. -
  13. -

    The cluster-autoscaler checks every few minutes if nodes are underutilized. It will taint such candidates for removal and wait additional 10 minutes before the nodes are eventually removed and deallocated. The whole process can take about 20 minutes.

    -
  14. -
-

Monitoring

-
tip

For better observability, run the listed commands in different tabs in your terminal.

-

You can watch the status of the HorizontalPodAutoscaler with the current CPU usage, the target CPU limit, and the number of replicas created with:

-
kubectl get hpa php-apache --watch
-

From time to time compare the list of nodes to check the behavior of the autoscaler:

-
kubectl get nodes
-

For deeper insights, see the logs of the autoscaler Pod, which contains more details about the scaling decision process:

-
kubectl logs -f deployment/constellation-cluster-autoscaler -n kube-system
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/getting-started/examples/index.html b/pr-preview/pr-4027/2.22/getting-started/examples/index.html deleted file mode 100644 index ff7adb284..000000000 --- a/pr-preview/pr-4027/2.22/getting-started/examples/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - -Examples | Constellation - - - - - - - -
Skip to main content
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/getting-started/examples/online-boutique/index.html b/pr-preview/pr-4027/2.22/getting-started/examples/online-boutique/index.html deleted file mode 100644 index 47c7c10d7..000000000 --- a/pr-preview/pr-4027/2.22/getting-started/examples/online-boutique/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -Online Boutique | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Online Boutique

-

Online Boutique is an e-commerce demo application by Google consisting of 11 separate microservices. In this demo, Constellation automatically sets up a load balancer on your CSP, making it easy to expose services from your confidential cluster.

-Online Boutique - Web UI -
    -
  1. Create a namespace: -
    kubectl create ns boutique
    -
  2. -
  3. Deploy the application: -
    kubectl apply -n boutique -f https://github.com/GoogleCloudPlatform/microservices-demo/raw/main/release/kubernetes-manifests.yaml
    -
  4. -
  5. Wait for all services to become available: -
    kubectl wait --for=condition=available --timeout=300s -n boutique --all deployments
    -
  6. -
  7. Get the frontend's external IP address: -
    $ kubectl get service frontend-external -n boutique | awk '{print $4}'
    EXTERNAL-IP
    <your-ip>
    -(<your-ip> is a placeholder for the IP assigned by your CSP.)
  8. -
  9. Enter the IP from the result in your browser to browse the online shop.
  10. -
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/getting-started/first-steps-local/index.html b/pr-preview/pr-4027/2.22/getting-started/first-steps-local/index.html deleted file mode 100644 index 25edf6a0c..000000000 --- a/pr-preview/pr-4027/2.22/getting-started/first-steps-local/index.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - - -First steps with a local cluster | Constellation - - - - - - - -
Skip to main content
Version: 2.22

First steps with a local cluster

-

A local cluster lets you deploy and test Constellation without a cloud subscription. -You have two options:

-
    -
  • Use MiniConstellation to automatically deploy a two-node cluster.
  • -
  • For more fine-grained control, create the cluster using the QEMU provider.
  • -
-

Both options use virtualization to create a local cluster with control-plane nodes and worker nodes. They don't require hardware with Confidential VM (CVM) support. For attestation, they currently use a software-based vTPM provided by KVM/QEMU.

-

You need an x64 machine with a Linux OS. -You can use a VM, but it needs nested virtualization.

-

Prerequisites

-
    -
  • Machine requirements: -
      -
    • An x86-64 CPU with at least 4 cores (6 cores are recommended)
    • -
    • At least 4 GB RAM (6 GB are recommended)
    • -
    • 20 GB of free disk space
    • -
    • Hardware virtualization enabled in the BIOS/UEFI (often referred to as Intel VT-x or AMD-V/SVM) / nested-virtualization support when using a VM
    • -
    -
  • -
  • Software requirements: - -
  • -
-

Software installation on Ubuntu

-
# install Docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce
# install other dependencies
sudo apt install xsltproc
sudo snap install kubectl --classic
# install Constellation CLI
curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-amd64
sudo install constellation-linux-amd64 /usr/local/bin/constellation
# do not drop forwarded packages
sudo iptables -P FORWARD ACCEPT
-

Create a cluster

-

With the constellation mini command, you can deploy and test Constellation locally. This mode is called MiniConstellation. Conceptually, MiniConstellation is similar to MicroK8s, K3s, and minikube.

caution

MiniConstellation has specific soft- and hardware requirements such as a Linux OS running on an x86-64 CPU. Pay attention to all prerequisites when setting up.

note

Since MiniConstellation runs on your local system, cloud features such as load balancing, -attaching persistent storage, or autoscaling aren't available.

The following creates your MiniConstellation cluster (may take up to 10 minutes to complete):

constellation mini up

This will configure your current directory as the workspace for this cluster. -All constellation commands concerning this cluster need to be issued from this directory.

-

Connect to the cluster

-

Your cluster initially consists of a single control-plane node:

-
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
control-plane-0 Ready control-plane 66s v1.24.6
-

Additional nodes will request to join the cluster shortly. Before each additional node is allowed to join the cluster, its state is verified using remote attestation by the JoinService. -If verification passes successfully, the new node receives keys and certificates to join the cluster.

-

You can follow this process by viewing the logs of the JoinService:

-
$ kubectl logs -n kube-system daemonsets/join-service -f
{"level":"INFO","ts":"2022-10-14T09:32:20Z","caller":"cmd/main.go:48","msg":"Constellation Node Join Service","version":"2.1.0","cloudProvider":"qemu"}
{"level":"INFO","ts":"2022-10-14T09:32:20Z","logger":"validator","caller":"watcher/validator.go:96","msg":"Updating expected measurements"}
...
-

Once all nodes have joined your cluster, it may take a couple of minutes for all resources to become available. -You can check on the state of your cluster by running the following:

-
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
control-plane-0 Ready control-plane 2m59s v1.24.6
worker-0 Ready <none> 32s v1.24.6
-

Deploy a sample application

-
    -
  1. Deploy the emojivoto app
  2. -
-
kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment
-
    -
  1. Expose the frontend service locally
  2. -
-
kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments
kubectl -n emojivoto port-forward svc/web-svc 8080:80 &
curl http://localhost:8080
kill %1
-

Terminate your cluster

-

Once you are done, you can clean up the created resources using the following command:

constellation mini down

This will destroy your cluster and clean up your workspace. -The VM image and cluster configuration file (constellation-conf.yaml) will be kept and may be reused to create new clusters.

-

Troubleshooting

-

Make sure to use the latest release and check out the known issues.

-

VMs have no internet access / CLI remains in "Initializing cluster" state

-

iptables rules may prevent your VMs from accessing the internet. -Make sure your rules aren't dropping forwarded packages.

-

List your rules:

-
sudo iptables -S
-

The output may look similar to the following:

-
-P INPUT ACCEPT
-P FORWARD DROP
-P OUTPUT ACCEPT
-N DOCKER
-N DOCKER-ISOLATION-STAGE-1
-N DOCKER-ISOLATION-STAGE-2
-N DOCKER-USER
-

If your FORWARD chain is set to DROP, you need to update your rules:

-
sudo iptables -P FORWARD ACCEPT
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/getting-started/first-steps/index.html b/pr-preview/pr-4027/2.22/getting-started/first-steps/index.html deleted file mode 100644 index 307d406bb..000000000 --- a/pr-preview/pr-4027/2.22/getting-started/first-steps/index.html +++ /dev/null @@ -1,90 +0,0 @@ - - - - - -First steps with Constellation | Constellation - - - - - - - -
Skip to main content
Version: 2.22

First steps with Constellation

-

The following steps guide you through the process of creating a cluster and deploying a sample app. This example assumes that you have successfully installed and set up Constellation, -and have access to a cloud subscription.

-
tip

If you don't have a cloud subscription, you can also set up a local Constellation cluster using virtualization for testing.

-
note

If you encounter any problem with the following steps, make sure to use the latest release and check out the known issues.

-

Create a cluster

-
    -
  1. -

    Create the configuration file and state file for your cloud provider. If you are following the steps of this guide, there is no need to edit the file.

    -
    constellation config generate aws
    -
  2. -
  3. -

    Create your IAM configuration.

    -
    constellation iam create aws --zone=us-east-2a --prefix=constellTest --update-config

    This command creates IAM configuration for the AWS zone us-east-2a using the prefix constellTest for all named resources being created. It also updates the configuration file constellation-conf.yaml in your current directory with the IAM values filled in.

    Depending on the attestation variant selected on config generation, different regions are available. -AMD SEV-SNP machines (requires the default attestation variant awsSEVSNP) are currently available in the following regions:

      -
    • eu-west-1
    • -
    • us-east-2
    • -

    You can find a list of regions that support AMD SEV-SNP in AWS's documentation.

    NitroTPM machines (requires the attestation variant awsNitroTPM) are available in all regions. -Constellation OS images are currently replicated to the following regions:

      -
    • eu-central-1
    • -
    • eu-west-1
    • -
    • eu-west-3
    • -
    • us-east-2
    • -
    • ap-south-1
    • -

    If you require the OS image to be available in another region, let us know.

    You can find a list of all regions in AWS's documentation.

    -
    tip

    To learn about all options you have for managing IAM resources and Constellation configuration, see the Configuration workflow.

    -
  4. -
-
    -
  1. -

    Create the cluster. constellation apply uses options set in constellation-conf.yaml. -If you want to manually manage your cloud resources, for example by using Terraform, follow the corresponding instructions in the Create workflow.

    -
    tip

    On Azure, you may need to wait 15+ minutes at this point for role assignments to propagate.

    -
    constellation apply -y
    -

    This should look similar to the following:

    -
    $ constellation apply -y
    Checking for infrastructure changes
    The following Constellation cluster will be created:
    3 control-plane nodes of type n2d-standard-4 will be created.
    1 worker node of type n2d-standard-4 will be created.
    Creating
    Cloud infrastructure created successfully
    Your Constellation master secret was successfully written to ./constellation-mastersecret.json
    Connecting
    Initializing cluster
    Installing Kubernetes components
    Your Constellation cluster was successfully initialized.

    Constellation cluster identifier g6iMP5wRU1b7mpOz2WEISlIYSfdAhB0oNaOg6XEwKFY=
    Kubernetes configuration constellation-admin.conf

    You can now connect to your cluster by executing:
    export KUBECONFIG="$PWD/constellation-admin.conf"
    -

    The cluster's identifier will be different in your output. -Keep constellation-mastersecret.json somewhere safe. -This will allow you to recover your cluster in case of a disaster.

    -
    info

    Depending on your CSP and region, constellation apply may take 10+ minutes to complete.

    -
  2. -
  3. -

    Configure kubectl.

    -
    export KUBECONFIG="$PWD/constellation-admin.conf"
    -
  4. -
-

Deploy a sample application

-
    -
  1. -

    Deploy the emojivoto app

    -
    kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment
    -
  2. -
  3. -

    Expose the frontend service locally

    -
    kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments
    kubectl -n emojivoto port-forward svc/web-svc 8080:80 &
    curl http://localhost:8080
    kill %1
    -
  4. -
-

Terminate your cluster

-

Use the CLI to terminate your cluster. If you manually used Terraform to manage your cloud resources, follow the corresponding instructions in the Terminate workflow.

-
constellation terminate
-

This should give the following output:

-
$ constellation terminate
You are about to terminate a Constellation cluster.
All of its associated resources will be DESTROYED.
This action is irreversible and ALL DATA WILL BE LOST.
Do you want to continue? [y/n]:
-

Confirm with y to terminate the cluster:

-
Terminating ...
Your Constellation cluster was terminated successfully.
-

Optionally, you can also delete your IAM resources.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/getting-started/install/index.html b/pr-preview/pr-4027/2.22/getting-started/install/index.html deleted file mode 100644 index 13d381586..000000000 --- a/pr-preview/pr-4027/2.22/getting-started/install/index.html +++ /dev/null @@ -1,234 +0,0 @@ - - - - - -Installation and setup | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Installation and setup

-

Constellation runs entirely in your cloud environment and can be controlled via a dedicated command-line interface (CLI) or a Terraform provider.

-

Prerequisites

-

Make sure the following requirements are met:

-
    -
  • Your machine is running Linux, macOS, or Windows
  • -
  • You have admin rights on your machine
  • -
  • kubectl is installed
  • -
  • Your CSP is Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), or STACKIT
  • -
-

Install the Constellation CLI

-
tip

If you prefer to use Terraform, you can alternatively use the Terraform provider to manage the cluster's lifecycle.

-

The CLI executable is available at GitHub. -Install it with the following commands:

-
    -
  1. Download the CLI:
  2. -
curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-amd64
    -
  1. -

    Verify the signature (optional)

    -
  2. -
  3. -

    Install the CLI to your PATH:

    -
  4. -
sudo install constellation-linux-amd64 /usr/local/bin/constellation
-
tip

The CLI supports autocompletion for various shells. To set it up, run constellation completion and follow the given steps.

-

Set up cloud credentials

-

Constellation makes authenticated calls to the CSP API. Therefore, you need to set up Constellation with the credentials for your CSP.

-
tip

If you don't have a cloud subscription, you can also set up a local Constellation cluster using virtualization for testing.

-

Required permissions

-

To set up a Constellation cluster, you need to perform two tasks that require permissions: create the infrastructure and create roles for cluster nodes. Both of these actions can be performed by different users, e.g., an administrator to create roles and a DevOps engineer to create the infrastructure.

To create the IAM configuration for Constellation, you need the following permissions:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeAccountAttributes",
"iam:AddRoleToInstanceProfile",
"iam:AttachRolePolicy",
"iam:CreateInstanceProfile",
"iam:CreatePolicy",
"iam:CreateRole",
"iam:DeleteInstanceProfile",
"iam:DeletePolicy",
"iam:DeletePolicyVersion",
"iam:DeleteRole",
"iam:DetachRolePolicy",
"iam:GetInstanceProfile",
"iam:GetPolicy",
"iam:GetPolicyVersion",
"iam:GetRole",
"iam:ListAttachedRolePolicies",
"iam:ListInstanceProfilesForRole",
"iam:ListPolicyVersions",
"iam:ListRolePolicies",
"iam:PassRole",
"iam:RemoveRoleFromInstanceProfile",
"sts:GetCallerIdentity"
],
"Resource": "*"
}
]
}

The built-in AdministratorAccess policy is a superset of these permissions.

To create a Constellation cluster, see the permissions of main.tf.

The built-in PowerUserAccess policy is a superset of these permissions.

Follow Amazon's guide on understanding and managing policies.

-

Authentication

-

You need to authenticate with your CSP. The following lists the required steps for testing and production environments.

-
note

The steps for a testing environment are simpler. However, they may expose secrets to the CSP. If in doubt, follow the production steps.

-

Testing

You can use the AWS CloudShell. Make sure you are authorized to use it.

Production

Use the latest version of the AWS CLI on a trusted machine:

aws configure

Options and first steps are described in the AWS CLI documentation.

-

Next steps

-

You are now ready to deploy your first confidential Kubernetes cluster and application.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/getting-started/marketplaces/index.html b/pr-preview/pr-4027/2.22/getting-started/marketplaces/index.html deleted file mode 100644 index 83b7215a6..000000000 --- a/pr-preview/pr-4027/2.22/getting-started/marketplaces/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - -Using Constellation via Cloud Marketplaces | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Using Constellation via Cloud Marketplaces

-

Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please contact us.

-

This document explains how to run Constellation with the dynamically billed cloud marketplace images.

-

To use Constellation's marketplace images, ensure that you are subscribed to the marketplace offering through the web portal.

Then, enable the use of marketplace images in your Constellation constellation-conf.yaml config file:

yq eval -i ".provider.aws.useMarketplaceImage = true" constellation-conf.yaml
-

Ensure that the cluster uses an official release image version (i.e., .image=vX.Y.Z in the constellation-conf.yaml file).

-

From there, you can proceed with the cluster creation as usual.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/index.html b/pr-preview/pr-4027/2.22/index.html deleted file mode 100644 index 160484fee..000000000 --- a/pr-preview/pr-4027/2.22/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -Introduction | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Introduction

-

Welcome to the documentation of Constellation! Constellation is a Kubernetes engine that aims to provide the best possible data security.

-

Constellation concept

-

Constellation shields your entire Kubernetes cluster from the underlying cloud infrastructure. Everything inside is always encrypted, including at runtime in memory. For this, Constellation leverages a technology called confidential computing and more specifically Confidential VMs.

-
tip

See the 📄whitepaper for more information on confidential computing.

-

Goals

-

From a security perspective, Constellation is designed to keep all data always encrypted and to prevent any access from the underlying (cloud) infrastructure. This includes access from datacenter employees, privileged cloud admins, and attackers coming through the infrastructure. Such attackers could be malicious co-tenants escalating their privileges or hackers who managed to compromise a cloud server.

-

From a DevOps perspective, Constellation is designed to work just like what you would expect from a modern Kubernetes engine.

-

Use cases

-

Constellation provides unique security features and benefits. The core use cases are:

-
    -
  • Increasing the overall security of your clusters
  • -
  • Increasing the trustworthiness of your SaaS offerings
  • -
  • Moving sensitive workloads from on-prem to the cloud
  • -
  • Meeting regulatory requirements
  • -
-

Next steps

-

You can learn more about the concept of Confidential Kubernetes, features, security benefits, and performance of Constellation in the Basics section. To jump right into the action head to Getting started.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/overview/clouds/index.html b/pr-preview/pr-4027/2.22/overview/clouds/index.html deleted file mode 100644 index 5b24731b2..000000000 --- a/pr-preview/pr-4027/2.22/overview/clouds/index.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - -Feature status of clouds | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Feature status of clouds

-

What works on which cloud? Currently, Confidential VMs (CVMs) are available in varying quality on the different clouds and software stacks.

-

For Constellation, the ideal environment provides the following:

-
    -
  1. Ability to run arbitrary software and images inside CVMs
  2. -
  3. CVMs based on AMD SEV-SNP (available in EPYC CPUs since the Milan generation) or Intel TDX (available in Xeon CPUs since the Sapphire Rapids generation)
  4. -
  5. Ability for CVM guests to obtain raw hardware attestation statements
  6. -
  7. Reviewable, open-source firmware inside CVMs
  8. -
  9. Capability of the firmware to attest the integrity of the code it passes control to, e.g., with an embedded virtual TPM (vTPM)
  10. -
-

(1) is a functional must-have. (2)--(5) are required for remote attestation that fully keeps the infrastructure/cloud out. Constellation can work without them or with approximations, but won't protect against certain privileged attackers anymore.

-

The following table summarizes the state of features for different infrastructures.

-
FeatureAWSAzureGCPSTACKITOpenStack (Yoga)
1. Custom imagesYesYesYesYesYes
2. SEV-SNP or TDXYesYesYesNoDepends on kernel/HV
3. Raw guest attestationYesYesYesNoDepends on kernel/HV
4. Reviewable firmwareYesNo*NoNoDepends on kernel/HV
5. Confidential measured bootNoYesNoNoDepends on kernel/HV
-

Amazon Web Services (AWS)

-

Amazon EC2 supports AMD SEV-SNP. -Regarding (3), AWS provides direct access to attestation statements. -However, regarding (5), attestation is partially based on the NitroTPM for measured boot, which is a vTPM managed by the Nitro hypervisor. -Hence, the hypervisor is currently part of Constellation's TCB. -Regarding (4), the firmware is open source and can be reproducibly built.

-

Microsoft Azure

-

With its CVM offering, Azure provides the best foundations for Constellation. -Regarding (3), Azure provides direct access to attestation statements. -The firmware runs in an isolated domain inside the CVM and exposes a vTPM (5), but it's closed source (4). -On SEV-SNP, Azure uses VM Privilege Level (VMPL) isolation for the separation of firmware and the rest of the VM; on TDX, they use TD partitioning. -This firmware is signed by Azure. -The signature is reflected in the attestation statements of CVMs. -Thus, the Azure closed-source firmware becomes part of Constellation's trusted computing base (TCB).

-

* Recently, Azure announced the open source paravisor OpenHCL. It's the foundation for fully open source and verifiable CVM firmware. Once Azure provides their CVM firmware with reproducible builds based on OpenHCL, (4) switches from No to Yes. Constellation will support OpenHCL based firmware on Azure in the future.

-

Google Cloud Platform (GCP)

-

The CVMs Generally Available in GCP are based on AMD SEV-ES or SEV-SNP. -Regarding (3), with their SEV-SNP offering Google provides direct access to attestation statements. -However, regarding (5), attestation is partially based on the Shielded VM vTPM for measured boot, which is a vTPM managed by Google's hypervisor. -Hence, the hypervisor is currently part of Constellation's TCB. -Regarding (4), the CVMs still include closed-source firmware.

-

TDX on Google is in public preview. -With it, Constellation would have a similar TCB and attestation flow as with the current SEV-SNP offering.

-

STACKIT

-

STACKIT Compute Engine supports AMD SEV-ES. A vTPM is used for measured boot, which is a vTPM managed by STACKIT's hypervisor. Hence, the hypervisor is currently part of Constellation's TCB.

-

OpenStack

-

OpenStack is an open-source cloud and infrastructure management software. It's used by many smaller CSPs and datacenters. In the latest Yoga version, OpenStack has basic support for CVMs. However, much depends on the employed kernel and hypervisor. Features (2)--(4) are likely to be a Yes with Linux kernel version 6.2. Thus, going forward, OpenStack on corresponding AMD or Intel hardware will be a viable underpinning for Constellation.

-

Conclusion

-

The different clouds and software like the Linux kernel and OpenStack are in the process of building out their support for state-of-the-art CVMs. Azure has already most features in place. For Constellation, the status quo means that the TCB has different shapes on different infrastructures. With broad SEV-SNP support coming to the Linux kernel, we soon expect a normalization of features across infrastructures.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/overview/confidential-kubernetes/index.html b/pr-preview/pr-4027/2.22/overview/confidential-kubernetes/index.html deleted file mode 100644 index 5a39165e5..000000000 --- a/pr-preview/pr-4027/2.22/overview/confidential-kubernetes/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - -Confidential Kubernetes | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Confidential Kubernetes

-

We use the term Confidential Kubernetes to refer to the concept of using confidential-computing technology to shield entire Kubernetes clusters from the infrastructure. The three defining properties of this concept are:

-
    -
  1. Workload shielding: the confidentiality and integrity of all workload-related data and code are enforced.
  2. -
  3. Control plane shielding: the confidentiality and integrity of the cluster's control plane, state, and workload configuration are enforced.
  4. -
  5. Attestation and verifiability: the two properties above can be verified remotely based on hardware-rooted cryptographic certificates.
  6. -
-

Each of the above properties is equally important. Only with all three in conjunction, an entire cluster can be shielded without gaps.

-

Constellation security features

-

Constellation implements the Confidential Kubernetes concept with the following security features.

-
    -
  • Runtime encryption: Constellation runs all Kubernetes nodes inside Confidential VMs (CVMs). This gives runtime encryption for the entire cluster.
  • -
  • Network and storage encryption: Constellation augments this with transparent encryption of the network, persistent storage, and other managed storage like AWS S3. Thus, workloads and control plane are truly end-to-end encrypted: at rest, in transit, and at runtime.
  • -
  • Transparent key management: Constellation manages the corresponding cryptographic keys inside CVMs.
  • -
  • Node attestation and verification: Constellation verifies the integrity of each new CVM-based node using remote attestation. Only "good" nodes receive the cryptographic keys required to access the network and storage of a cluster.
  • -
  • Confidential computing-optimized images: A node is "good" if it's running a signed Constellation node image inside a CVM and is in the expected state. (Node images are hardware-measured during boot. The measurements are reflected in the attestation statements that are produced by nodes and verified by Constellation.)
  • -
  • "Whole cluster" attestation: Towards the DevOps engineer, Constellation provides a single hardware-rooted certificate from which all of the above can be verified.
  • -
-

With the above, Constellation wraps an entire cluster into one coherent and verifiable confidential context. The concept is depicted in the following.

-

Confidential Kubernetes

-

Comparison: Managed Kubernetes with CVMs

-

In comparison, managed Kubernetes with CVMs, as it's for example offered in AKS and GKE, only provides runtime encryption for certain worker nodes. Here, each worker node is a separate (and typically unverified) confidential context. This only provides limited security benefits as it only prevents direct access to a worker node's memory. The large majority of potential attacks through the infrastructure remain unaffected. This includes attacks through the control plane, access to external key management, and the corruption of worker node images. This leaves many problems unsolved. For instance, Node A has no means to verify if Node B is "good" and if it's OK to share data with it. Consequently, this approach leaves a large attack surface, as is depicted in the following.

-

Concept: Managed Kubernetes plus CVMs

-

The following table highlights the key differences in terms of features.

-
Managed Kubernetes with CVMsConfidential Kubernetes (Constellation✨)
Runtime encryptionPartial (data plane only)Yes
Node image verificationNoYes
Full cluster attestationNoYes
Transparent network encryptionNoYes
Transparent storage encryptionNoYes
Confidential key managementNoYes
Cloud agnostic / multi-cloudNoYes
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/overview/license/index.html b/pr-preview/pr-4027/2.22/overview/license/index.html deleted file mode 100644 index 9d14f07eb..000000000 --- a/pr-preview/pr-4027/2.22/overview/license/index.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - -License | Constellation - - - - - - - -
Skip to main content
Version: 2.22

License

-

Source code

-

Constellation's source code is available on GitHub under the GNU Affero General Public License v3.0.

-

Binaries

-

Edgeless Systems provides ready-to-use and signed binaries of Constellation. This includes the CLI and the node images.

-

These binaries may be used free of charge within the bounds of Constellation's Community License. An Enterprise License can be purchased from Edgeless Systems.

-

The Constellation CLI displays relevant license information when you initialize your cluster. You are responsible for staying within the bounds of your respective license. Constellation doesn't enforce any limits so as not to endanger your cluster's availability.

-

Terraform provider

-

Edgeless Systems provides a Terraform provider, which may be used free of charge within the bounds of Constellation's Community License. An Enterprise License can be purchased from Edgeless Systems.

-

You are responsible for staying within the bounds of your respective license. Constellation doesn't enforce any limits so as not to endanger your cluster's availability.

-

Community License

-

You are free to use the Constellation binaries provided by Edgeless Systems to create services for internal consumption, evaluation purposes, or non-commercial use. You must not use the Constellation binaries to provide commercial hosted services to third parties. Edgeless Systems gives no warranties and offers no support.

-

Enterprise License

-

Enterprise Licenses don't have the above limitations and come with support and additional features. Find out more at the product website.

-

Once you have received your Enterprise License file, place it in your Constellation workspace in a file named constellation.license.

-

CSP Marketplaces

-

Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please contact us.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/overview/performance/application/index.html b/pr-preview/pr-4027/2.22/overview/performance/application/index.html deleted file mode 100644 index b1bdda392..000000000 --- a/pr-preview/pr-4027/2.22/overview/performance/application/index.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - -Application benchmarks | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Application benchmarks

-

HashiCorp Vault

-

HashiCorp Vault is a distributed secrets management software that can be deployed to Kubernetes. -HashiCorp maintains a benchmarking tool for vault, vault-benchmark. -Vault-benchmark generates load on a Vault deployment and measures response times.

-

This article describes the results from running vault-benchmark on Constellation, AKS, and GKE. -You can find the setup for producing the data discussed in this article in the vault-benchmarks repository.

-

The Vault API used during benchmarking is the transits secret engine. -This allows services to send data to Vault for encryption, decryption, signing, and verification.

-

Results

-

On each run, vault-benchmark sends requests and measures the latencies. -The measured latencies are aggregated through various statistical features. -After running the benchmark n times, the arithmetic mean over a subset of the reported statistics is calculated. -The selected features are arithmetic mean, 99th percentile, minimum, and maximum.

-

Arithmetic mean gives a general sense of the latency on each target. -The 99th percentile shows performance in (most likely) erroneous states. -Minimum and maximum mark the range within which latency varies each run.

-

The benchmark was configured with 1300 workers and 10 seconds per run. -Those numbers were chosen empirically. -The latency was stabilizing at 10 seconds runtime, not changing with further increase. -Increasing the number of workers beyond 1300 leads to request failures, marking the limit Vault was able to handle in this setup. -All results are based on 100 runs.

-

The following data was generated while running five replicas, one primary, and four standby nodes. -All numbers are in seconds if not indicated otherwise.

-
========== Results AKS ==========
Mean: mean: 1.632200, variance: 0.002057
P99: mean: 5.480679, variance: 2.263700
Max: mean: 6.651001, variance: 2.808401
Min: mean: 0.011415, variance: 0.000133
========== Results GKE ==========
Mean: mean: 1.656435, variance: 0.003615
P99: mean: 6.030807, variance: 3.955051
Max: mean: 7.164843, variance: 3.300004
Min: mean: 0.010233, variance: 0.000111
========== Results C11n ==========
Mean: mean: 1.651549, variance: 0.001610
P99: mean: 5.780422, variance: 3.016106
Max: mean: 6.942997, variance: 3.075796
Min: mean: 0.013774, variance: 0.000228
========== AKS vs C11n ==========
Mean: +1.171577 % (AKS is faster)
P99: +5.185495 % (AKS is faster)
Max: +4.205618 % (AKS is faster)
Min: +17.128781 % (AKS is faster)
========== GKE vs C11n ==========
Mean: -0.295851 % (GKE is slower)
P99: -4.331603 % (GKE is slower)
Max: -3.195248 % (GKE is slower)
Min: +25.710886 % (GKE is faster)
-

Interpretation: Latencies are all within ~5% of each other. -AKS performs slightly better than GKE and Constellation (C11n) in all cases except minimum latency. -Minimum latency is the lowest for GKE. -Compared to GKE, Constellation had slightly lower peak latencies (99th percentile and maximum), indicating that Constellation could have handled slightly more concurrent accesses than GKE. -Overall, performance is at comparable levels across all three distributions. -Based on these numbers, you can use a similarly sized Constellation cluster to run your existing Vault deployment.

-

Visualization

-

The following plots visualize the data presented above as box plots. -The whiskers denote the minimum and maximum. -The box stretches from the 25th to the 75th percentile, with the dividing bar marking the 50th percentile. -The circles outside the whiskers denote outliers.

-
Mean Latency

Mean Latency

-
99th Percentile Latency

99th Percentile Latency

-
Maximum Latency

Maximum Latency

-
Minimum Latency

Minimum Latency

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/overview/performance/compute/index.html b/pr-preview/pr-4027/2.22/overview/performance/compute/index.html deleted file mode 100644 index 59b969cc3..000000000 --- a/pr-preview/pr-4027/2.22/overview/performance/compute/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - -Impact of runtime encryption on compute performance | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Impact of runtime encryption on compute performance

-

All nodes in a Constellation cluster are executed inside Confidential VMs (CVMs). Consequently, the performance of Constellation is inherently linked to the performance of these CVMs.

-

AMD and Azure benchmarking

-

AMD and Azure have collectively released a performance benchmark for CVMs that utilize 3rd Gen AMD EPYC processors (Milan) with SEV-SNP. This benchmark, which included a variety of mostly compute-intensive tests such as SPEC CPU 2017 and CoreMark, demonstrated that CVMs experience only minor performance degradation (ranging from 2% to 8%) when compared to standard VMs. Such results are indicative of the performance that can be expected from compute-intensive workloads running with Constellation on Azure.

-

AMD and Google benchmarking

-

Similarly, AMD and Google have jointly released a performance benchmark for CVMs employing 3rd Gen AMD EPYC processors (Milan) with SEV-SNP. With high-performance computing workloads such as WRF, NAMD, Ansys CFS, and Ansys LS_DYNA, they observed analogous findings, with only minor performance degradation (between 2% and 4%) compared to standard VMs. These outcomes are reflective of the performance that can be expected for compute-intensive workloads running with Constellation on GCP.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/overview/performance/index.html b/pr-preview/pr-4027/2.22/overview/performance/index.html deleted file mode 100644 index 5534f6446..000000000 --- a/pr-preview/pr-4027/2.22/overview/performance/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - -Performance analysis of Constellation | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Performance analysis of Constellation

-

This section provides a comprehensive examination of the performance characteristics of Constellation.

-

Runtime encryption

-

Runtime encryption affects compute performance. Benchmarks by Azure and Google show that the performance degradation of Confidential VMs (CVMs) is small, ranging from 2% to 8% for compute-intensive workloads.

-

I/O performance benchmarks

-

We evaluated the I/O performance of Constellation, utilizing a collection of synthetic benchmarks targeting networking and storage. -We further compared this performance to native managed Kubernetes offerings from various cloud providers, to better understand how Constellation stands in relation to standard practices.

-

Application benchmarking

-

To gauge Constellation's applicability to well-known applications, we performed a benchmark of HashiCorp Vault running on Constellation. -The results were then compared to deployments on the managed Kubernetes offerings from different cloud providers, providing a tangible perspective on Constellation's performance in actual deployment scenarios.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/overview/performance/io/index.html b/pr-preview/pr-4027/2.22/overview/performance/io/index.html deleted file mode 100644 index b1d149028..000000000 --- a/pr-preview/pr-4027/2.22/overview/performance/io/index.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - -I/O performance benchmarks | Constellation - - - - - - - -
Skip to main content
Version: 2.22

I/O performance benchmarks

-

To assess the overall performance of Constellation, this benchmark evaluates Constellation v2.6.0 in terms of storage I/O using fio and network performance using the Kubernetes Network Benchmark.

-

This benchmark tested Constellation on Azure and GCP and compared the results against the managed Kubernetes offerings AKS and GKE.

-

Configurations

-

Constellation

-

The benchmark was conducted with Constellation v2.6.0, Kubernetes v1.25.7, and Cilium v1.12. -It ran on the following infrastructure configurations.

-

Constellation on Azure:

-
    -
  • Nodes: 3 (1 Control-plane, 2 Worker)
  • -
  • Machines: DC4as_v5: 3rd Generation AMD EPYC 7763v (Milan) processor with 4 Cores, 16 GiB memory
  • -
  • CVM: true
  • -
  • Region: West US
  • -
  • Zone: 2
  • -
-

Constellation on GCP:

-
    -
  • Nodes: 3 (1 Control-plane, 2 Worker)
  • -
  • Machines: n2d-standard-4: 2nd Generation AMD EPYC (Rome) processor with 4 Cores, 16 GiB of memory
  • -
  • CVM: true
  • -
  • Zone: europe-west3-b
  • -
-

AKS

-

On AKS, the benchmark used Kubernetes v1.24.9 and nodes with version AKSUbuntu-1804gen2containerd-2023.02.15. -AKS ran with the kubenet CNI and the default CSI driver for Azure Disk.

-

The following infrastructure configurations was used:

-
    -
  • Nodes: 2 (2 Worker)
  • -
  • Machines: D4as_v5: 3rd Generation AMD EPYC 7763v (Milan) processor with 4 Cores, 16 GiB memory
  • -
  • CVM: false
  • -
  • Region: West US
  • -
  • Zone: 2
  • -
-

GKE

-

On GKE, the benchmark used Kubernetes v1.24.9 and nodes with version 1.24.9-gke.3200. -GKE ran with the kubenet CNI and the default CSI driver for Compute Engine persistent disk.

-

The following infrastructure configurations was used:

-
    -
  • Nodes: 2 (2 Worker)
  • -
  • Machines: n2d-standard-4 2nd Generation AMD EPYC (Rome) processor with 4 Cores, 16 GiB of memory
  • -
  • CVM: false
  • -
  • Zone: europe-west3-b
  • -
-

Results

-

Network

-

This section gives a thorough analysis of the network performance of Constellation, specifically focusing on measuring TCP and UDP bandwidth. -The benchmark measured the bandwidth of pod-to-pod and pod-to-service connections between two different nodes using iperf.

-

GKE and Constellation on GCP had a maximum network bandwidth of 10 Gbps. -AKS with Standard_D4as_v5 machines a maximum network bandwidth of 12.5 Gbps. -The Confidential VM equivalent Standard_DC4as_v5 currently has a network bandwidth of 1.25 Gbps. -Therefore, to make the test comparable, both AKS and Constellation on Azure were running with Standard_DC4as_v5 machines and 1.25 Gbps bandwidth.

-

Constellation on Azure and AKS used an MTU of 1500. -Constellation on GCP used an MTU of 8896. GKE used an MTU of 1450.

-

The difference in network bandwidth can largely be attributed to two factors.

- -

Pod-to-Pod

-

In this scenario, the client Pod connects directly to the server pod via its IP address.

- -

The results for "Pod-to-Pod" on Azure are as follows:

-

Network Pod2Pod Azure benchmark graph

-

The results for "Pod-to-Pod" on GCP are as follows:

-

Network Pod2Pod GCP benchmark graph

-

Pod-to-Service

-

In this scenario, the client Pod connects to the server Pod via a ClusterIP service. This is more relevant to real-world use cases.

- -

The results for "Pod-to-Pod" on Azure are as follows:

-

Network Pod2SVC Azure benchmark graph

-

The results for "Pod-to-Pod" on GCP are as follows:

-

Network Pod2SVC GCP benchmark graph

-

In our recent comparison of Constellation on GCP with GKE, Constellation has 58% less TCP bandwidth. However, UDP bandwidth was slightly better with Constellation, thanks to its higher MTU.

-

Similarly, when comparing Constellation on Azure with AKS using CVMs, Constellation achieved approximately 10% less TCP and 40% less UDP bandwidth.

-

Storage I/O

-

Azure and GCP offer persistent storage for their Kubernetes services AKS and GKE via the Container Storage Interface (CSI). CSI storage in Kubernetes is available via PersistentVolumes (PV) and consumed via PersistentVolumeClaims (PVC). -Upon requesting persistent storage through a PVC, GKE and AKS will provision a PV as defined by a default storage class. -Constellation provides persistent storage on Azure and GCP that's encrypted on the CSI layer. -Similarly, upon a PVC request, Constellation will provision a PV via a default storage class.

-

For Constellation on Azure and AKS, the benchmark ran with Azure Disk storage Standard SSD of 400 GiB size. -The DC4as machine type with four cores provides the following maximum performance:

-
    -
  • 6400 (20000 burst) IOPS
  • -
  • 144 MB/s (600 MB/s burst) throughput
  • -
-

However, the performance is bound by the capabilities of the 512 GiB Standard SSD size (the size class of 400 GiB volumes):

-
    -
  • 500 (600 burst) IOPS
  • -
  • 60 MB/s (150 MB/s burst) throughput
  • -
-

For Constellation on GCP and GKE, the benchmark ran with Compute Engine Persistent Disk Storage pd-balanced of 400 GiB size. -The N2D machine type with four cores and pd-balanced provides the following maximum performance:

-
    -
  • 3,000 read IOPS
  • -
  • 15,000 write IOPS
  • -
  • 240 MB/s read throughput
  • -
  • 240 MB/s write throughput
  • -
-

However, the performance is bound by the capabilities of a Zonal balanced PD with 400 GiB size:

-
    -
  • 2400 read IOPS
  • -
  • 2400 write IOPS
  • -
  • 112 MB/s read throughput
  • -
  • 112 MB/s write throughput
  • -
-

The fio benchmark consists of several tests. -The benchmark used Kubestr to run fio in Kubernetes. -The default test performs randomized access patterns that accurately depict worst-case I/O scenarios for most applications.

-

The following fio settings were used:

-
    -
  • No Cloud caching
  • -
  • No OS caching
  • -
  • Single CPU
  • -
  • 60 seconds runtime
  • -
  • 10 seconds ramp-up time
  • -
  • 10 GiB file
  • -
  • IOPS: 4 KB blocks and 128 iodepth
  • -
  • Bandwidth: 1024 KB blocks and 128 iodepth
  • -
-

For more details, see the fio test configuration.

-

The results for IOPS on Azure are as follows:

-

I/O IOPS Azure benchmark graph

-

The results for IOPS on GCP are as follows:

-

I/O IOPS GCP benchmark graph

-

The results for bandwidth on Azure are as follows:

-

I/O bandwidth Azure benchmark graph

-

The results for bandwidth on GCP are as follows:

-

I/O bandwidth GCP benchmark graph

-

On GCP, the results exceed the maximum performance guarantees of the chosen disk type. There are two possible explanations for this. The first is that there may be cloud caching in place that isn't configurable. Alternatively, the underlying provisioned disk size may be larger than what was requested, resulting in higher performance boundaries.

-

When comparing Constellation on GCP with GKE, Constellation has similar bandwidth but about 10% less IOPS performance. On Azure, Constellation has similar IOPS performance compared to AKS, where both likely hit the maximum storage performance. However, Constellation has approximately 15% less read and write bandwidth.

-

Conclusion

-

Despite the added security benefits that Constellation provides, it only incurs a slight performance overhead when compared to managed Kubernetes offerings such as AKS and GKE. In most compute benchmarks, Constellation is on par with it's alternatives. -While it may be slightly slower in certain I/O scenarios due to network and storage encryption, there is ongoing work to reduce this overhead to single digits.

-

For instance, storage encryption only adds between 10% to 15% overhead in terms of bandwidth and IOPS. -Meanwhile, the biggest performance impact that Constellation currently faces is network encryption, which can incur up to 58% overhead on a 10 Gbps network. -However, the Cilium team has conducted benchmarks with Cilium using WireGuard encryption on a 100 Gbps network that yielded over 15 Gbps. -We're confident that Constellation will provide a similar level of performance with an upcoming release.

-

Overall, Constellation strikes a great balance between security and performance, and we're continuously working to improve its performance capabilities while maintaining its high level of security.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/overview/product/index.html b/pr-preview/pr-4027/2.22/overview/product/index.html deleted file mode 100644 index 84d4a663e..000000000 --- a/pr-preview/pr-4027/2.22/overview/product/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - -Product features | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Product features

-

Constellation is a Kubernetes engine that aims to provide the best possible data security in combination with enterprise-grade scalability and reliability features---and a smooth user experience.

-

From a security perspective, Constellation implements the Confidential Kubernetes concept and corresponding security features, which shield your entire cluster from the underlying infrastructure.

-

From an operational perspective, Constellation provides the following key features:

-
    -
  • Native support for different clouds: Constellation works on Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), and STACKIT. Support for OpenStack-based environments is coming with a future release. Constellation securely interfaces with the cloud infrastructure to provide cluster autoscaling, dynamic persistent volumes, and service load balancing.
  • -
  • High availability: Constellation uses a multi-master architecture with a stacked etcd topology to ensure high availability.
  • -
  • Integrated Day-2 operations: Constellation lets you securely upgrade your cluster to a new release. It also lets you securely recover a failed cluster. Both with a single command.
  • -
  • Support for Terraform: Constellation includes a Terraform provider that lets you manage the full lifecycle of your cluster via Terraform.
  • -
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/overview/security-benefits/index.html b/pr-preview/pr-4027/2.22/overview/security-benefits/index.html deleted file mode 100644 index 0d1118d85..000000000 --- a/pr-preview/pr-4027/2.22/overview/security-benefits/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - -Security benefits and threat model | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Security benefits and threat model

-

Constellation implements the Confidential Kubernetes concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be verified.

-

TCB comparison

-

Given this background, the following describes the concrete threat classes that Constellation addresses.

-

Insider access

-

Employees and third-party contractors of cloud service providers (CSPs) have access to different layers of the cloud infrastructure. -This opens up a large attack surface where workloads and data can be read, copied, or manipulated. With Constellation, Kubernetes deployments are shielded from the infrastructure and thus such accesses are prevented.

-

Infrastructure-based attacks

-

Malicious cloud users ("hackers") may break out of their tenancy and access other tenants' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. Analogously to the insider access scenario, Constellation also prevents access to a deployment's data in this scenario.

-

Supply chain attacks

-

Supply chain security is receiving lots of attention recently due to an increasing number of recorded attacks. For instance, a malicious actor could attempt to tamper Constellation node images (including Kubernetes and other software) before they're loaded in the confidential VMs of a cluster. Constellation uses remote attestation in conjunction with public transparency logs to prevent this.

-

In the future, Constellation will extend this feature to customer workloads. This will enable cluster owners to create auditable policies that precisely define which containers can run in a given deployment.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/reference/cli/index.html b/pr-preview/pr-4027/2.22/reference/cli/index.html deleted file mode 100644 index fe62ff5e5..000000000 --- a/pr-preview/pr-4027/2.22/reference/cli/index.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - -CLI reference | Constellation - - - - - - - -
Skip to main content
Version: 2.22

CLI reference

-

Use the Constellation CLI to create and manage your clusters.

-

Usage:

-
constellation [command]
-

Commands:

-
    -
  • config: Work with the Constellation configuration file -
      -
    • generate: Generate a default configuration and state file
    • -
    • fetch-measurements: Fetch measurements for configured cloud provider and image
    • -
    • instance-types: Print the supported instance types for all cloud providers
    • -
    • kubernetes-versions: Print the Kubernetes versions supported by this CLI
    • -
    • migrate: Migrate a configuration file to a new version
    • -
    -
  • -
  • create: Create instances on a cloud platform for your Constellation cluster
  • -
  • apply: Apply a configuration to a Constellation cluster
  • -
  • mini: Manage MiniConstellation clusters -
      -
    • up: Create and initialize a new MiniConstellation cluster
    • -
    • down: Destroy a MiniConstellation cluster
    • -
    -
  • -
  • status: Show status of a Constellation cluster
  • -
  • verify: Verify the confidential properties of a Constellation cluster
  • -
  • upgrade: Find and apply upgrades to your Constellation cluster -
      -
    • check: Check for possible upgrades
    • -
    • apply: Apply an upgrade to a Constellation cluster
    • -
    -
  • -
  • recover: Recover a completely stopped Constellation cluster
  • -
  • terminate: Terminate a Constellation cluster
  • -
  • iam: Work with the IAM configuration on your cloud provider -
      -
    • create: Create IAM configuration on a cloud platform for your Constellation cluster -
        -
      • aws: Create IAM configuration on AWS for your Constellation cluster
      • -
      • azure: Create IAM configuration on Microsoft Azure for your Constellation cluster
      • -
      • gcp: Create IAM configuration on GCP for your Constellation cluster
      • -
      -
    • -
    • destroy: Destroy an IAM configuration and delete local Terraform files
    • -
    • upgrade: Find and apply upgrades to your IAM profile -
        -
      • apply: Apply an upgrade to an IAM profile
      • -
      -
    • -
    -
  • -
  • version: Display version of this CLI
  • -
  • init: Initialize the Constellation cluster
  • -
  • ssh: Generate a certificate for emergency SSH access
  • -
-

constellation config

-

Work with the Constellation configuration file

-

Synopsis

-

Work with the Constellation configuration file.

-

Options

-
  -h, --help   help for config
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation config generate

-

Generate a default configuration and state file

-

Synopsis

-

Generate a default configuration and state file for your selected cloud provider.

-
constellation config generate {aws|azure|gcp|openstack|qemu|stackit} [flags]
-

Options

-
  -a, --attestation string   attestation variant to use {aws-sev-snp|aws-nitro-tpm|azure-sev-snp|azure-tdx|azure-trustedlaunch|gcp-sev-snp|gcp-sev-es|qemu-vtpm}. If not specified, the default for the cloud provider is used
-h, --help help for generate
-k, --kubernetes string Kubernetes version to use in format MAJOR.MINOR (default "v1.30")
-t, --tags strings additional tags for created resources given a list of key=value
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation config fetch-measurements

-

Fetch measurements for configured cloud provider and image

-

Synopsis

-

Fetch measurements for configured cloud provider and image.

-

A config needs to be generated first.

-
constellation config fetch-measurements [flags]
-

Options

-
  -h, --help                   help for fetch-measurements
-s, --signature-url string alternative URL to fetch measurements' signature from
-u, --url string alternative URL to fetch measurements from
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation config instance-types

-

Print the supported instance types for all cloud providers

-

Synopsis

-

Print the supported instance types for all cloud providers.

-
constellation config instance-types [flags]
-

Options

-
  -h, --help   help for instance-types
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation config kubernetes-versions

-

Print the Kubernetes versions supported by this CLI

-

Synopsis

-

Print the Kubernetes versions supported by this CLI.

-
constellation config kubernetes-versions [flags]
-

Options

-
  -h, --help   help for kubernetes-versions
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation config migrate

-

Migrate a configuration file to a new version

-

Synopsis

-

Migrate a configuration file to a new version.

-
constellation config migrate [flags]
-

Options

-
  -h, --help   help for migrate
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation create

-

Create instances on a cloud platform for your Constellation cluster

-

Synopsis

-

Create instances on a cloud platform for your Constellation cluster.

-
constellation create [flags]
-

Options

-
  -h, --help   help for create
-y, --yes create the cluster without further confirmation
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation apply

-

Apply a configuration to a Constellation cluster

-

Synopsis

-

Apply a configuration to a Constellation cluster to initialize or upgrade the cluster.

-
constellation apply [flags]
-

Options

-
      --conformance           enable conformance mode
-h, --help help for apply
--merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config
--skip-helm-wait install helm charts without waiting for deployments to be ready
--skip-phases strings comma-separated list of upgrade phases to skip
one or multiple of { infrastructure | init | attestationconfig | certsans | helm | image | k8s }
-y, --yes run command without further confirmation
WARNING: the command might delete or update existing resources without additional checks. Please read the docs.

-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation mini

-

Manage MiniConstellation clusters

-

Synopsis

-

Manage MiniConstellation clusters.

-

Options

-
  -h, --help   help for mini
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation mini up

-

Create and initialize a new MiniConstellation cluster

-

Synopsis

-

Create and initialize a new MiniConstellation cluster.

-

A mini cluster consists of a single control-plane and worker node, hosted using QEMU/KVM.

-
constellation mini up [flags]
-

Options

-
  -h, --help               help for up
--merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config (default true)
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation mini down

-

Destroy a MiniConstellation cluster

-

Synopsis

-

Destroy a MiniConstellation cluster.

-
constellation mini down [flags]
-

Options

-
  -h, --help   help for down
-y, --yes terminate the cluster without further confirmation
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation status

-

Show status of a Constellation cluster

-

Synopsis

-

Show the status of a constellation cluster.

-

Shows microservice, image, and Kubernetes versions installed in the cluster. Also shows status of current version upgrades.

-
constellation status [flags]
-

Options

-
  -h, --help   help for status
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation verify

-

Verify the confidential properties of a Constellation cluster

-

Synopsis

-

Verify the confidential properties of a Constellation cluster. -If arguments aren't specified, values are read from constellation-state.yaml.

-
constellation verify [flags]
-

Options

-
      --cluster-id string      expected cluster identifier
-h, --help help for verify
-e, --node-endpoint string endpoint of the node to verify, passed as HOST[:PORT]
-o, --output string print the attestation document in the output format {json|raw}
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation upgrade

-

Find and apply upgrades to your Constellation cluster

-

Synopsis

-

Find and apply upgrades to your Constellation cluster.

-

Options

-
  -h, --help   help for upgrade
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation upgrade check

-

Check for possible upgrades

-

Synopsis

-

Check which upgrades can be applied to your Constellation Cluster.

-
constellation upgrade check [flags]
-

Options

-
  -h, --help            help for check
--ref string the reference to use for querying new versions (default "-")
--stream string the stream to use for querying new versions (default "stable")
-u, --update-config update the specified config file with the suggested versions
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation upgrade apply

-

Apply an upgrade to a Constellation cluster

-

Synopsis

-

Apply an upgrade to a Constellation cluster by applying the chosen configuration.

-
constellation upgrade apply [flags]
-

Options

-
      --conformance           enable conformance mode
-h, --help help for apply
--skip-helm-wait install helm charts without waiting for deployments to be ready
--skip-phases strings comma-separated list of upgrade phases to skip
one or multiple of { infrastructure | helm | image | k8s }
-y, --yes run upgrades without further confirmation
WARNING: might delete your resources in case you are using cert-manager in your cluster. Please read the docs.
WARNING: might unintentionally overwrite measurements in the running cluster.
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation recover

-

Recover a completely stopped Constellation cluster

-

Synopsis

-

Recover a Constellation cluster by sending a recovery key to an instance in the boot stage.

-

This is only required if instances restart without other instances available for bootstrapping.

-
constellation recover [flags]
-

Options

-
  -e, --endpoint string   endpoint of the instance, passed as HOST[:PORT]
-h, --help help for recover
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation terminate

-

Terminate a Constellation cluster

-

Synopsis

-

Terminate a Constellation cluster.

-

The cluster can't be started again, and all persistent storage will be lost.

-
constellation terminate [flags]
-

Options

-
  -h, --help   help for terminate
-y, --yes terminate the cluster without further confirmation
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation iam

-

Work with the IAM configuration on your cloud provider

-

Synopsis

-

Work with the IAM configuration on your cloud provider.

-

Options

-
  -h, --help   help for iam
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation iam create

-

Create IAM configuration on a cloud platform for your Constellation cluster

-

Synopsis

-

Create IAM configuration on a cloud platform for your Constellation cluster.

-

Options

-
  -h, --help            help for create
--update-config update the config file with the specific IAM information
-y, --yes create the IAM configuration without further confirmation
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation iam create aws

-

Create IAM configuration on AWS for your Constellation cluster

-

Synopsis

-

Create IAM configuration on AWS for your Constellation cluster.

-
constellation iam create aws [flags]
-

Options

-
  -h, --help            help for aws
--prefix string name prefix for all resources (required)
--zone string AWS availability zone the resources will be created in, e.g., us-east-2a (required)
See the Constellation docs for a list of currently supported regions.
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
--update-config update the config file with the specific IAM information
-C, --workspace string path to the Constellation workspace
-y, --yes create the IAM configuration without further confirmation
-

constellation iam create azure

-

Create IAM configuration on Microsoft Azure for your Constellation cluster

-

Synopsis

-

Create IAM configuration on Microsoft Azure for your Constellation cluster.

-
constellation iam create azure [flags]
-

Options

-
  -h, --help                      help for azure
--region string region the resources will be created in, e.g., westus (required)
--resourceGroup string name prefix of the two resource groups your cluster / IAM resources will be created in (required)
--servicePrincipal string name of the service principal that will be created (required)
--subscriptionID string subscription ID of the Azure account. Required if the 'ARM_SUBSCRIPTION_ID' environment variable is not set
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
--update-config update the config file with the specific IAM information
-C, --workspace string path to the Constellation workspace
-y, --yes create the IAM configuration without further confirmation
-

constellation iam create gcp

-

Create IAM configuration on GCP for your Constellation cluster

-

Synopsis

-

Create IAM configuration on GCP for your Constellation cluster.

-
constellation iam create gcp [flags]
-

Options

-
  -h, --help               help for gcp
--prefix string Prefix for the service account ID and VM ID that will be created (required)
Must be letters, digits, or hyphens.
--projectID string ID of the GCP project the configuration will be created in (required)
Find it on the welcome screen of your project: https://console.cloud.google.com/welcome
--zone string GCP zone the cluster will be deployed in (required)
Find a list of available zones here: https://cloud.google.com/compute/docs/regions-zones#available
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
--update-config update the config file with the specific IAM information
-C, --workspace string path to the Constellation workspace
-y, --yes create the IAM configuration without further confirmation
-

constellation iam destroy

-

Destroy an IAM configuration and delete local Terraform files

-

Synopsis

-

Destroy an IAM configuration and delete local Terraform files.

-
constellation iam destroy [flags]
-

Options

-
  -h, --help   help for destroy
-y, --yes destroy the IAM configuration without asking for confirmation
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation iam upgrade

-

Find and apply upgrades to your IAM profile

-

Synopsis

-

Find and apply upgrades to your IAM profile.

-

Options

-
  -h, --help   help for upgrade
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation iam upgrade apply

-

Apply an upgrade to an IAM profile

-

Synopsis

-

Apply an upgrade to an IAM profile.

-
constellation iam upgrade apply [flags]
-

Options

-
  -h, --help   help for apply
-y, --yes run upgrades without further confirmation
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation version

-

Display version of this CLI

-

Synopsis

-

Display version of this CLI.

-
constellation version [flags]
-

Options

-
  -h, --help   help for version
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation init

-

Initialize the Constellation cluster

-

Synopsis

-

Initialize the Constellation cluster.

-

Start your confidential Kubernetes.

-
constellation init [flags]
-

Options

-
      --conformance        enable conformance mode
-h, --help help for init
--merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config
--skip-helm-wait install helm charts without waiting for deployments to be ready
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation ssh

-

Generate a certificate for emergency SSH access

-

Synopsis

-

Generate a certificate for emergency SSH access to your SSH-enabled constellation cluster.

-
constellation ssh [flags]
-

Options

-
  -h, --help         help for ssh
--key string the path to an existing SSH public key
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/reference/migration/index.html b/pr-preview/pr-4027/2.22/reference/migration/index.html deleted file mode 100644 index c6c6e1b57..000000000 --- a/pr-preview/pr-4027/2.22/reference/migration/index.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - - -Migrations | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Migrations

-

This document describes breaking changes and migrations between Constellation releases. -Use constellation config migrate to automatically update an old config file to a new format.

-

Migrations to v2.19.1

-

Azure

-
    -
  • During the upgrade, security rules are migrated and the old ones need to be cleaned up manually by the user. The below script shows how to delete them through the Azure CLI:
  • -
-
#!/usr/bin/env bash
name="<insert>" # the name provided in the config
uid="<insert>" # the cluster id can be retrieved via `yq '.infrastructure.uid' constellation-state.yaml`
resource_group="<insert>" # the RG can be retrieved via `yq '.provider.azure.resourceGroup' constellation-conf.yaml`

rules=(
"kubernetes"
"bootstrapper"
"verify"
"recovery"
"join"
"debugd"
"konnectivity"
)

for rule in "${rules[@]}"; do
echo "Deleting rule: ${rule}"
az network nsg rule delete \
--resource-group "${resource_group}" \
--nsg-name "${name}-${uid}" \
--name "${rule}"
done

echo "All specified rules have been deleted."
-

Migrating from CLI versions before 2.21.1

-

AWS

-
    -
  • AWS clusters that use LoadBalancer resources require more IAM permissions. Please upgrade your IAM roles using constellation iam upgrade apply. This will show necessary changes and apply them, if desired.
  • -
-

Migrating from CLI versions before 2.19.0

-

Azure

-
    -
  • To allow seamless upgrades on Azure when Kubernetes services of type LoadBalancer are deployed, the target -load balancer in which the cloud-controller-manager creates load balancing rules was changed. Instead of using the load balancer -created and maintained by the CLI's Terraform code, the cloud-controller-manager now creates its own load balancer in Azure. -If your Constellation has services of type LoadBalancer, please remove them before the upgrade and re-apply them -afterward.
  • -
-

Migrating from CLI versions before 2.18.0

-
    -
  • The provider.azure.appClientID and provider.azure.appClientSecret fields are no longer supported and should be removed.
  • -
  • To keep using an existing UAMI, add the Owner permission with the scope of your resourceGroup.
  • -
  • Otherwise, simply create new Constellation IAM credentials and use the created UAMI.
  • -
  • To migrate the authentication for an existing cluster on Azure to an UAMI with the necessary permissions: -
      -
    1. Remove the aadClientId and aadClientSecret from the azureconfig secret.
    2. -
    3. Set useManagedIdentityExtension to true and use the userAssignedIdentity from the Constellation config for the value of userAssignedIdentityID.
    4. -
    5. Restart the CSI driver, cloud controller manager, cluster autoscaler, and Constellation operator pods.
    6. -
    -
  • -
-

Migrating from CLI versions before 2.10

-
    -
  • AWS cluster upgrades require additional IAM permissions for the newly introduced aws-load-balancer-controller. Please upgrade your IAM roles using iam upgrade apply. This will show necessary changes and apply them, if desired.
  • -
  • The global nodeGroups field was added.
  • -
  • The fields instanceType, stateDiskSizeGB, and stateDiskType for each cloud provider are now part of the configuration of individual node groups.
  • -
  • The constellation create command no longer uses the flags --control-plane-count and --worker-count. Instead, the initial node count is configured per node group in the nodeGroups field.
  • -
-

Migrating from CLI versions before 2.9

-
    -
  • The provider.azure.appClientID and provider.azure.clientSecretValue fields were removed to enforce migration to managed identity authentication
  • -
-

Migrating from CLI versions before 2.8

-
    -
  • The measurements field for each cloud service provider was replaced with a global attestation field.
  • -
  • The confidentialVM, idKeyDigest, and enforceIdKeyDigest fields for the Azure cloud service provider were removed in favor of using the global attestation field.
  • -
  • The optional global field attestationVariant was replaced by the now required attestation field.
  • -
-

Migrating from CLI versions before 2.3

-
    -
  • -

    The sshUsers field was deprecated in v2.2 and has been removed from the configuration in v2.3. -As an alternative for SSH, check the workflow section Connect to nodes.

    -
  • -
  • -

    The image field for each cloud service provider has been replaced with a global image field. Use the following mapping to migrate your configuration:

    -
    Show all
    CSPold imagenew image
    AWSami-06b8cbf4837a0a57cv2.2.2
    AWSami-02e96dc04a9e438cdv2.2.2
    AWSami-028ead928a9034b2fv2.2.2
    AWSami-032ac10dd8d8266e3v2.2.1
    AWSami-032e0d57cc4395088v2.2.1
    AWSami-053c3e49e19b96bddv2.2.1
    AWSami-0e27ebcefc38f648bv2.2.0
    AWSami-098cd37f66523b7c3v2.2.0
    AWSami-04a87d302e2509aadv2.2.0
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.2v2.2.2
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.2v2.2.2
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.1v2.2.1
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.1v2.2.1
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.0v2.2.0
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.0v2.2.0
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.1.0v2.1.0
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.1.0v2.1.0
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.0.0v2.0.0
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.0.0v2.0.0
    GCPprojects/constellation-images/global/images/constellation-v2-2-2v2.2.2
    GCPprojects/constellation-images/global/images/constellation-v2-2-1v2.2.1
    GCPprojects/constellation-images/global/images/constellation-v2-2-0v2.2.0
    GCPprojects/constellation-images/global/images/constellation-v2-1-0v2.1.0
    GCPprojects/constellation-images/global/images/constellation-v2-0-0v2.0.0
    -
  • -
  • -

    The enforcedMeasurements field has been removed and merged with the measurements field.

    -
      -
    • -

      To migrate your config containing a new image (v2.3 or greater), remove the old measurements and enforcedMeasurements entries from your config and run constellation fetch-measurements

      -
    • -
    • -

      To migrate your config containing an image older than v2.3, remove the enforcedMeasurements entry and replace the entries in measurements as shown in the example below:

      -
      measurements:
      - 0: DzXCFGCNk8em5ornNZtKi+Wg6Z7qkQfs5CfE3qTkOc8=
      + 0:
      + expected: DzXCFGCNk8em5ornNZtKi+Wg6Z7qkQfs5CfE3qTkOc8=
      + warnOnly: true
      - 8: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
      + 8:
      + expected: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
      + warnOnly: false
      -enforcedMeasurements:
      - - 8
      -
    • -
    -
  • -
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/reference/slsa/index.html b/pr-preview/pr-4027/2.22/reference/slsa/index.html deleted file mode 100644 index 66993ecb2..000000000 --- a/pr-preview/pr-4027/2.22/reference/slsa/index.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - -Supply chain levels for software artifacts (SLSA) adoption | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Supply chain levels for software artifacts (SLSA) adoption

-

Supply chain Levels for Software Artifacts, or SLSA (salsa) is a framework for improving and grading a project's build system and engineering processes. SLSA focuses on security improvements for source code storage as well as build system definition, execution, and observation. SLSA is structured in four levels. This page describes the adoption of SLSA for Constellation.

-
info

SLSA is still in alpha status. The presented levels and their requirements might change in the future. We will adopt any changes into our engineering processes, as they get defined.

-

Level 1 - Adopted

-

Build - Scripted

-

All build steps are automated via Bazel and GitHub Actions.

-

Provenance - Available

-

Provenance for the CLI is generated using the slsa-github-generator.

-

Level 2 - Adopted

-

Source - Version Controlled

-

Constellation is hosted on GitHub using git.

-

Build - Build Service

-

All builds are carried out by GitHub Actions.

-

Provenance - Authenticated

-

Provenance for the CLI is signed using the slsa-github-generator. Learn how to verify the CLI using the signed provenance, before using it for the first time.

-

Provenance - Service Generated

-

Provenance for the CLI is generated using the slsa-github-generator in GitHub Actions.

-

Level 3 - Adopted

-

Source - Verified History

-

The Edgeless Systems GitHub organization requires two-factor authentication for all members.

-

Source - Retained Indefinitely

-

Since we use GitHub to host the repository, an external person can't modify or delete the history. Before a pull request can be merged, an explicit approval from an Edgeless Systems team member is required.

-

The same holds true for changes proposed by team members. Each change to main needs to be proposed via a pull request and requires at least one approval.

-

The Edgeless Systems GitHub organization admins control these settings and are able to make changes to the repository's history should legal requirements necessitate it. These changes require two-party approval following the obliterate policy.

-

Build - Build as Code

-

All build files for Constellation are stored in the same repository.

-

Build - Ephemeral Environment

-

All GitHub Action workflows are executed on GitHub-hosted runners. These runners are only available during workflow.

-

We currently don't use self-hosted runners.

-

Build - Isolated

-

As outlined in the previous section, we use GitHub-hosted runners, which provide a new, isolated and ephemeral environment for each build.

-

Additionally, the SLSA GitHub generator itself is run in an isolated workflow with the artifact hash as defined inputs.

-

Provenance - Non-falsifiable

-

As outlined by SLSA GitHub generator it already fulfills the non-falsifiable requirements for SLSA Level 3. The generated provenance is signed using sigstore with an OIDC based proof of identity.

-

Level 4 - In Progress

-

We strive to adopt certain aspect of SLSA Level 4 that support our engineering process. At the same time, SLSA is still in alpha status and the biggest changes to SLSA are expected to be around Level 4.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/reference/terraform/index.html b/pr-preview/pr-4027/2.22/reference/terraform/index.html deleted file mode 100644 index 2b50b2db5..000000000 --- a/pr-preview/pr-4027/2.22/reference/terraform/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -Terraform usage | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Terraform usage

-

Terraform is an Infrastructure as Code (IaC) framework to manage cloud resources. This page explains how Constellation uses it internally and how advanced users may manually use it to have more control over the resource creation.

-
info

Information on this page is intended for users who are familiar with Terraform. -It's not required for common usage of Constellation. -See the Terraform documentation if you want to learn more about it.

-

Terraform state files

-

Constellation keeps Terraform state files in subdirectories of the workspace together with the corresponding Terraform configuration files and metadata. -The subdirectories are created on the first Constellation CLI action that uses Terraform internally.

-

Currently, these subdirectories are:

-
    -
  • constellation-terraform - Terraform state files for the resources of the Constellation cluster
  • -
  • constellation-iam-terraform - Terraform state files for IAM configuration
  • -
-

As with all commands, commands that work with these files (e.g., apply, terminate, iam) have to be executed from the root of the cluster's workspace directory. You usually don't need and shouldn't manipulate or delete the subdirectories manually.

-

Interacting with Terraform manually

-

Manual interaction with Terraform state created by Constellation (i.e., via the Terraform CLI) should only be performed by experienced users. It may lead to unrecoverable loss of cloud resources. For the majority of users and use cases, the interaction done by the Constellation CLI is sufficient.

-

Terraform debugging

-

To debug Terraform issues, the Constellation CLI offers the tf-log flag. You can set it to any of Terraform's log levels:

-
    -
  • JSON (JSON-formatted logs at TRACE level)
  • -
  • TRACE
  • -
  • DEBUG
  • -
  • INFO
  • -
  • WARN
  • -
  • ERROR
  • -
-

The log output is written to the terraform.log file in the workspace directory. The output is appended to the file on each run.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/workflows/cert-manager/index.html b/pr-preview/pr-4027/2.22/workflows/cert-manager/index.html deleted file mode 100644 index ae1d2098c..000000000 --- a/pr-preview/pr-4027/2.22/workflows/cert-manager/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - -Install cert-manager | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Install cert-manager

-
caution

If you want to use cert-manager with Constellation, pay attention to the following to avoid potential pitfalls.

-

Constellation ships with cert-manager preinstalled. -The default installation is part of the kube-system namespace, as all other Constellation-managed microservices. -You are free to install more instances of cert-manager into other namespaces. -However, be aware that any new installation needs to use the same version as the one installed with Constellation or rely on the same CRD versions. -Also remember to set the installCRDs value to false when installing new cert-manager instances. -It will create problems if you have two installations of cert-manager depending on different versions of the installed CRDs. -CRDs are cluster-wide resources and cert-manager depends on specific versions of those CRDs for each release.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/workflows/config/index.html b/pr-preview/pr-4027/2.22/workflows/config/index.html deleted file mode 100644 index df6a98ef9..000000000 --- a/pr-preview/pr-4027/2.22/workflows/config/index.html +++ /dev/null @@ -1,162 +0,0 @@ - - - - - -Configure your cluster | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Configure your cluster

-
info

This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details.

-
Loading asciinema cast...
-
-

Before you can create your cluster, you need to configure the identity and access management (IAM) for your cloud service provider (CSP) and choose machine types for the nodes.

-

Creating the configuration file

-

You can generate a configuration file for your CSP by using the following CLI command:

-
constellation config generate aws
-

This creates the file constellation-conf.yaml in the current directory.

-

Choosing a VM type

-

Constellation supports the following VM types:

-

By default, Constellation uses m6a.xlarge VMs (4 vCPUs, 16 GB RAM) to create your cluster. -Optionally, you can switch to a different VM type by modifying instanceType in the configuration file. -If you are using the default attestation variant awsSEVSNP, you can use the instance types described in AWS's AMD SEV-SNP docs. -Please mind the region restrictions mentioned in the Getting started section.

If you are using the attestation variant awsNitroTPM, you can choose any of the nitroTPM-enabled instance types.

The Constellation CLI can also print the supported instance types with: constellation config instance-types.

-

Fill the desired VM type into the instanceType fields in the constellation-conf.yml file.

-

Creating additional node groups

-

By default, Constellation creates the node groups control_plane_default and worker_default for control-plane nodes and workers, respectively. -If you require additional control-plane or worker groups with different instance types, zone placements, or disk sizes, you can add additional node groups to the constellation-conf.yml file. -Each node group can be scaled individually.

-

Consider the following example for AWS:

-
nodeGroups:
control_plane_default:
role: control-plane
instanceType: c6a.xlarge
stateDiskSizeGB: 30
stateDiskType: gp3
zone: eu-west-1c
initialCount: 3
worker_default:
role: worker
instanceType: c6a.xlarge
stateDiskSizeGB: 30
stateDiskType: gp3
zone: eu-west-1c
initialCount: 2
high_cpu:
role: worker
instanceType: c6a.24xlarge
stateDiskSizeGB: 128
stateDiskType: gp3
zone: eu-west-1c
initialCount: 1
-

This configuration creates an additional node group high_cpu with a larger instance type and disk.

-

You can use the field zone to specify what availability zone nodes of the group are placed in. -On Azure, this field is empty by default and nodes are automatically spread across availability zones. -STACKIT currently offers SEV-enabled CPUs in the eu01-1, eu01-2, and eu01-3 zones. -Consult the documentation of your cloud provider for more information:

- -

Choosing a Kubernetes version

-

To learn which Kubernetes versions can be installed with your current CLI, you can run constellation config kubernetes-versions. -See also Constellation's Kubernetes support policy.

-

Creating an IAM configuration

-

You can create an IAM configuration for your cluster automatically using the constellation iam create command. -If you already have a Constellation configuration file, you can add the --update-config flag to the command. This writes the needed IAM fields into your configuration. Furthermore, the flag updates the zone/region of the configuration if it hasn't been set yet.

-

You must be authenticated with the AWS CLI in the shell session with a user that has the required permissions for IAM creation.

constellation iam create aws --zone=us-east-2a --prefix=constellTest

This command creates IAM configuration for the AWS zone us-east-2a using the prefix constellTest for all named resources being created.

Constellation OS images are currently replicated to the following regions:

    -
  • eu-central-1
  • -
  • eu-west-1
  • -
  • eu-west-3
  • -
  • us-east-2
  • -
  • ap-south-1
  • -

If you require the OS image to be available in another region, let us know.

You can find a list of all regions in AWS's documentation.

Paste the output into the corresponding fields of the constellation-conf.yaml file.

-
Alternatively, you can manually create the IAM configuration on your CSP.

The following describes the configuration fields and how you obtain the required information or create the required resources.

    -
  • -

    region: The name of your chosen AWS data center region, e.g., us-east-2.

    -

    Constellation OS images are currently replicated to the following regions:

    -
      -
    • eu-central-1
    • -
    • eu-west-1
    • -
    • eu-west-3
    • -
    • us-east-2
    • -
    • ap-south-1
    • -
    -

    If you require the OS image to be available in another region, let us know.

    -

    You can find a list of all regions in AWS's documentation.

    -
  • -
  • -

    zone: The name of your chosen AWS data center availability zone, e.g., us-east-2a.

    -

    Learn more about availability zones in AWS's documentation.

    -
  • -
  • -

    iamProfileControlPlane: The name of an IAM instance profile attached to all control-plane nodes.

    -

    You can create the resource with Terraform. For that, use the provided Terraform script to generate the necessary profile. The profile name will be provided as Terraform output value: control_plane_instance_profile_name.

    -

    Alternatively, you can create the AWS profile with a tool of your choice. Use the JSON policy in main.tf in the resource aws_iam_policy.control_plane_policy.

    -
  • -
  • -

    iamProfileWorkerNodes: The name of an IAM instance profile attached to all worker nodes.

    -

    You can create the resource with Terraform. For that, use the provided Terraform script to generate the necessary profile. The profile name will be provided as Terraform output value: worker_nodes_instance_profile_name.

    -

    Alternatively, you can create the AWS profile with a tool of your choice. Use the JSON policy in main.tf in the resource aws_iam_policy.worker_node_policy.

    -
  • -
-

Now that you've configured your CSP, you can create your cluster.

-

Deleting an IAM configuration

-

You can keep a created IAM configuration and reuse it for new clusters. Alternatively, you can also delete it if you don't want to use it anymore.

-

Delete the IAM configuration by executing the following command in the same directory where you executed constellation iam create (the directory that contains constellation-iam-terraform as a subdirectory):

-
constellation iam destroy
-
caution

For Azure, deleting the IAM configuration by executing constellation iam destroy will delete the whole resource group created by constellation iam create. -This also includes any additional resources in the resource group that weren't created by Constellation.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/workflows/create/index.html b/pr-preview/pr-4027/2.22/workflows/create/index.html deleted file mode 100644 index 8fd9d54b1..000000000 --- a/pr-preview/pr-4027/2.22/workflows/create/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -Create your cluster | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Create your cluster

-
info

This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details.

-
Loading asciinema cast...
-
-

Creating your cluster happens through multiple phases. -The most significant ones are:

-
    -
  1. Creating the necessary resources in your cloud environment
  2. -
  3. Bootstrapping the Constellation cluster and setting up a connection
  4. -
  5. Installing the necessary Kubernetes components
  6. -
-

constellation apply handles all this in a single command. -You can use the --skip-phases flag to skip specific phases of the process. -For example, if you created the infrastructure manually, you can skip the cloud resource creation phase.

-

See the architecture section for details on the inner workings of this process.

-
tip

If you don't have a cloud subscription, you can also set up a local Constellation cluster using virtualization for testing.

-

Before you create the cluster, make sure to have a valid configuration file.

-
constellation apply

apply stores the state of your cluster's cloud resources in a constellation-terraform directory in your workspace.

-

Finally, configure kubectl for your cluster:

-
export KUBECONFIG="$PWD/constellation-admin.conf"
-

🏁 That's it. You've successfully created a Constellation cluster.

-

Troubleshooting

-

In case apply fails, the CLI collects logs from the bootstrapping instance and stores them inside constellation-cluster.log.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/workflows/lb/index.html b/pr-preview/pr-4027/2.22/workflows/lb/index.html deleted file mode 100644 index 394839f75..000000000 --- a/pr-preview/pr-4027/2.22/workflows/lb/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - -Expose a service | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Expose a service

-

Constellation integrates the native load balancers of each CSP. Therefore, to expose a service simply create a service of type LoadBalancer.

-

Internet-facing LB service on AWS

-

To expose your application service externally you might want to use a Kubernetes Service of type LoadBalancer. On AWS, load-balancing is achieved through the AWS Load Balancer Controller as in the managed EKS.

-

Since recent versions, the controller deploy an internal LB by default requiring to set an annotation service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing to have an internet-facing LB. For more details, see the official docs.

-

For general information on LB with AWS see Network load balancing on Amazon EKS.

-
caution

Before terminating the cluster, all LB backed services should be deleted, so that the controller can cleanup the related resources.

-

Ingress on AWS

-

The AWS Load Balancer Controller also provisions Ingress resources of class alb. -AWS Application Load Balancers (ALBs) can be configured with a target-type. -The target type ip requires using the EKS container network solution, which makes it incompatible with Constellation. -If a service can be exposed on a NodePort, the target type instance can be used.

-

See Application load balancing on Amazon EKS for more information.

-
caution

Ingress handlers backed by AWS ALBs reside outside the Constellation cluster, so they shouldn't be handling sensitive traffic!

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/workflows/recovery/index.html b/pr-preview/pr-4027/2.22/workflows/recovery/index.html deleted file mode 100644 index b93ddd9b6..000000000 --- a/pr-preview/pr-4027/2.22/workflows/recovery/index.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - -Recover your cluster | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Recover your cluster

-

Recovery of a Constellation cluster means getting it back into a healthy state after too many concurrent node failures in the control plane. -Reasons for an unhealthy cluster can vary from a power outage, or planned reboot, to migration of nodes and regions. -Recovery events are rare, because Constellation is built for high availability and automatically and securely replaces failed nodes. When a node is replaced, Constellation's control plane first verifies the new node before it sends the node the cryptographic keys required to decrypt its state disk.

-

Constellation provides a recovery mechanism for cases where the control plane has failed and is unable to replace nodes. -The constellation recover command securely connects to all nodes in need of recovery using attested TLS and provides them with the keys to decrypt their state disks and continue booting.

-

Identify unhealthy clusters

-

The first step to recovery is identifying when a cluster becomes unhealthy. -Usually, this can be first observed when the Kubernetes API server becomes unresponsive.

-

You can check the health status of the nodes via the cloud service provider (CSP). -Constellation provides logging information on the boot process and status via serial console output. -In the following, you'll find detailed descriptions for identifying clusters stuck in recovery for each CSP.

-

First, open the AWS console to view all Auto Scaling Groups (ASGs) in the region of your cluster. Select the ASG of the control plane <cluster-name>-<UID>-control-plane and check that enough members are in a Running state.

Second, check the boot logs of these Instances. In the ASG's Instance management view, select each desired instance. In the upper right corner, select Action > Monitor and troubleshoot > Get system log.

In the serial console output, search for Waiting for decryption key. -Similar output to the following means your node was restarted and needs to decrypt the state disk:

{"level":"INFO","ts":"2022-09-08T10:21:53Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"gcp"}
{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}
{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}
{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}

The node will then try to connect to the JoinService and obtain the decryption key. -If this fails due to an unhealthy control plane, you will see log messages similar to the following:

{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["192.168.178.4:30090","192.168.178.2:30090"]}
{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.4:30090"}
{"level":"WARN","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing dial tcp 192.168.178.4:30090: connect: connection refused\"","endpoint":"192.168.178.4:30090"}
{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.2:30090"}
{"level":"WARN","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing dial tcp 192.168.178.2:30090: i/o timeout\"","endpoint":"192.168.178.2:30090"}
{"level":"ERROR","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}

This means that you have to recover the node manually.

-

Recover a cluster

-

Recovering a cluster requires the following parameters:

-
    -
  • The constellation-state.yaml file in your working directory or the cluster's endpoint
  • -
  • The master secret of the cluster
  • -
-

A cluster can be recovered like this:

-
$ constellation recover
Pushed recovery key.
Pushed recovery key.
Pushed recovery key.
Recovered 3 control-plane nodes.
-

In the serial console output of the node you'll see a similar output to the following:

-
{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer","caller":"recoveryserver/server.go:93","msg":"Received recover call"}
{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer","caller":"recoveryserver/server.go:125","msg":"Received state disk key and measurement secret, shutting down server"}
{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer.gRPC","caller":"zap/server_interceptors.go:61","msg":"finished streaming call with code OK","grpc.start_time":"2022-09-08T10:26:59Z","system":"grpc","span.kind":"server","grpc.service":"recoverproto.API","grpc.method":"Recover","peer.address":"192.0.2.3:41752","grpc.code":"OK","grpc.time_ms":15.701}
{"level":"INFO","ts":"2022-09-08T10:27:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:87","msg":"RejoinClient stopped"}
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/workflows/reproducible-builds/index.html b/pr-preview/pr-4027/2.22/workflows/reproducible-builds/index.html deleted file mode 100644 index 961a2639e..000000000 --- a/pr-preview/pr-4027/2.22/workflows/reproducible-builds/index.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - -Reproduce released artifacts | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Reproduce released artifacts

-

Constellation has first-class support for reproducible builds. -Reproducing the released artifacts is an alternative to signature verification that doesn't require trusting Edgeless Systems' release process. -The following sections describe how to rebuild an artifact and how Constellation ensures that the rebuild reproduces the artifacts bit-by-bit.

-

Build environment prerequisites

-

The build systems used by Constellation - Bazel and Nix - are designed for deterministic, reproducible builds. -These two dependencies should be the only prerequisites for a successful build. -However, it can't be ruled out completely that peculiarities of the host affect the build result. -Thus, we recommend the following host setup for best results:

-
    -
  1. A Linux operating system not older than v5.4.
  2. -
  3. The GNU C library not older than v2.31 (avoid musl).
  4. -
  5. GNU coreutils not older than v8.30 (avoid busybox).
  6. -
  7. An ext4 filesystem for building.
  8. -
  9. AppArmor turned off.
  10. -
-

This is given, for example, on an Ubuntu 22.04 system, which is also used for reproducibility tests.

-
note

To avoid any backwards-compatibility issues, the host software versions should also not be much newer than the Constellation release.

-

Run the build

-

The following instructions outline qualitatively how to reproduce a build. -Constellation implements these instructions in the Reproducible Builds workflow, which continuously tests for reproducibility. -The workflow is a good place to look up specific version numbers and build steps.

-
    -
  1. -

    Check out the Constellation repository at the tag corresponding to the release.

    -
    git clone https://github.com/edgelesssys/constellation.git
    cd constellation
    git checkout v2.20.0
    -
  2. -
  3. -

    Install the Bazel release specified in .bazelversion.

    -
  4. -
  5. -

    Install Nix (any recent version should do).

    -
  6. -
  7. -

    Run the build with bazel build $target for one of the following targets of interest:

    -
    //cli:cli_enterprise_darwin_amd64
    //cli:cli_enterprise_darwin_arm64
    //cli:cli_enterprise_linux_amd64
    //cli:cli_enterprise_linux_arm64
    //cli:cli_enterprise_windows_amd64
    -
  8. -
  9. -

    Compare the build result with the downloaded release artifact.

    -
  10. -
-

Feedback

-

Reproduction failures often indicate a bug in the build system or in the build definitions. -Therefore, we're interested in any reproducibility issues you might encounter. -Start a bug report and describe the details of your build environment. -Make sure to include your result binary or a diffoscope report, if possible.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/workflows/s3proxy/index.html b/pr-preview/pr-4027/2.22/workflows/s3proxy/index.html deleted file mode 100644 index 397a04503..000000000 --- a/pr-preview/pr-4027/2.22/workflows/s3proxy/index.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - -Install s3proxy | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Install s3proxy

-

Constellation includes a transparent client-side encryption proxy for AWS S3 and compatible stores. -s3proxy encrypts objects before sending them to S3 and automatically decrypts them on retrieval, without requiring changes to your application. -With s3proxy, you can use S3 for storage in a confidential way without having to trust the storage provider.

-

Limitations

-

Currently, s3proxy has the following limitations:

-
    -
  • Only PutObject and GetObject requests are encrypted/decrypted by s3proxy. -By default, s3proxy will block requests that may expose unencrypted data to S3 (e.g. UploadPart). -The allow-multipart flag disables request blocking for evaluation purposes.
  • -
  • Using the Range header on GetObject is currently not supported and will result in an error.
  • -
-

These limitations will be removed with future iterations of s3proxy. -If you want to use s3proxy but these limitations stop you from doing so, consider opening an issue.

-

Deployment

-

You can add the s3proxy to your Constellation cluster as follows:

-
    -
  1. Add the Edgeless Systems chart repository: -
    helm repo add edgeless https://helm.edgeless.systems/stable
    helm repo update
    -
  2. -
  3. Set ACCESS_KEY and ACCESS_SECRET to valid credentials you want s3proxy to use to interact with S3.
  4. -
  5. Deploy s3proxy: -
    helm install s3proxy edgeless/s3proxy --set awsAccessKeyID="$ACCESS_KEY" --set awsSecretAccessKey="$ACCESS_SECRET"
    -
  6. -
-

If you want to run a demo application, check out the Filestash with s3proxy example.

-

Technical details

-

Encryption

-

s3proxy relies on Google's Tink Cryptographic Library to implement cryptographic operations securely. -The used cryptographic primitives are NIST SP 800 38f for key wrapping and AES-GCM with 256 bit keys for data encryption.

-

s3proxy uses envelope encryption to encrypt objects. -This means s3proxy uses a key encryption key (KEK) issued by the KeyService to encrypt data encryption keys (DEKs). -Each S3 object is encrypted with its own DEK. -The encrypted DEK is then saved as metadata of the encrypted object. -This enables key rotation of the KEK without re-encrypting the data in S3. -The approach also allows access to objects from different locations, as long as each location has access to the KEK.

-

Traffic interception

-

To use s3proxy, you have to redirect your outbound S3 traffic to s3proxy. -This can either be done by modifying your client application or by changing the deployment of your application.

-

The necessary deployment modifications are to add DNS redirection and a trusted TLS certificate to the client's trust store. -DNS redirection can be defined for each pod, allowing you to use s3proxy for one application without changing other applications in the same cluster. -Adding a trusted TLS certificate is necessary as clients communicate with s3proxy via HTTPS. -To have your client application trust s3proxy's TLS certificate, the certificate has to be added to the client's certificate trust store. -The Filestash with s3proxy example shows how to do this.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/workflows/sbom/index.html b/pr-preview/pr-4027/2.22/workflows/sbom/index.html deleted file mode 100644 index d4f2c5863..000000000 --- a/pr-preview/pr-4027/2.22/workflows/sbom/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -Consume software bill of materials (SBOMs) | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Consume software bill of materials (SBOMs)

-
Loading asciinema cast...
-
-

Constellation builds produce a software bill of materials (SBOM) for each generated artifact. -You can use SBOMs to make informed decisions about dependencies and vulnerabilities in a given application. Enterprises rely on SBOMs to maintain an inventory of used applications, which allows them to take data-driven approaches to managing risks related to vulnerabilities.

-

SBOMs for Constellation are generated using Syft, signed using Cosign, and stored with the produced artifact.

-
note

The public key for Edgeless Systems' long-term code-signing key is:

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT
JmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==
-----END PUBLIC KEY-----

The public key is also available for download at https://edgeless.systems/es.pub and in the Twitter profile @EdgelessSystems.

Make sure the key is available in a file named cosign.pub to execute the following examples.

-

Verify and download SBOMs

-

The following sections detail how to work with each type of artifact to verify and extract the SBOM.

-

Constellation CLI

-

The SBOM for Constellation CLI is made available on the GitHub release page. The SBOM (constellation.spdx.sbom) and corresponding signature (constellation.spdx.sbom.sig) are valid for each Constellation CLI for a given version, regardless of architecture and operating system.

-
curl -LO https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom
curl -LO https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom.sig
cosign verify-blob --key cosign.pub --signature constellation.spdx.sbom.sig constellation.spdx.sbom
-

Container Images

-

SBOMs for container images are attached to the image using Cosign and uploaded to the same registry.

-

As a consumer, use cosign to download and verify the SBOM:

-
# Verify and download the attestation statement
cosign verify-attestation ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --type 'https://cyclonedx.org/bom' --key cosign.pub --output-file verification-service.att.json
# Extract SBOM from attestation statement
jq -r .payload verification-service.att.json | base64 -d > verification-service.cyclonedx.sbom
-

A successful verification should result in similar output:

-
$ cosign verify-attestation ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --type 'https://cyclonedx.org/bom' --key cosign.pub --output-file verification-service.sbom

Verification for ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key
$ jq -r .payload verification-service.sbom | base64 -d > verification-service.cyclonedx.sbom
-
note

This example considers only the verification-service. The same approach works for all containers in the Constellation container registry.

-

Vulnerability scanning

-

You can use a plethora of tools to consume SBOMs. This section provides suggestions for tools that are popular and known to produce reliable results, but any tool that consumes SPDX or CycloneDX files should work.

-

Syft is able to convert between the two formats in case you require a specific type.

-

Grype

-

Grype is a CLI tool that lends itself well for integration into CI/CD systems or local developer machines. It's also able to consume the signed attestation statement directly and does the verification in one go.

-
grype att:verification-service.sbom --key cosign.pub --add-cpes-if-none -q
-

Dependency Track

-

Dependency Track is one of the oldest and most mature solutions when it comes to managing software inventory and vulnerabilities. Once imported, it continuously scans SBOMs for new vulnerabilities. It supports the CycloneDX format and provides direct guidance on how to comply with U.S. Executive Order 14028.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/workflows/scale/index.html b/pr-preview/pr-4027/2.22/workflows/scale/index.html deleted file mode 100644 index 1ec8fd6d6..000000000 --- a/pr-preview/pr-4027/2.22/workflows/scale/index.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - -Scale your cluster | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Scale your cluster

-

Constellation provides all features of a Kubernetes cluster including scaling and autoscaling.

-

Worker node scaling

-

Autoscaling

-

Constellation comes with autoscaling disabled by default. To enable autoscaling, find the scaling group of -worker nodes:

-
kubectl get scalinggroups -o json | yq '.items | .[] | select(.spec.role == "Worker") | [{"name": .metadata.name, "nodeGoupName": .spec.nodeGroupName}]'
-

This will output a list of scaling groups with the corresponding cloud provider name (name) and the cloud provider agnostic name of the node group (nodeGroupName).

-

Then, patch the autoscaling field of the scaling group resource with the desired name to true:

-
# Replace <name> with the name of the scaling group you want to enable autoscaling for
worker_group=<name>
kubectl patch scalinggroups $worker_group --patch '{"spec":{"autoscaling": true}}' --type='merge'
kubectl get scalinggroup $worker_group -o jsonpath='{.spec}' | yq -P
-

The cluster autoscaler now automatically provisions additional worker nodes so that all pods have a place to run. -You can configure the minimum and maximum number of worker nodes in the scaling group by patching the min or -max fields of the scaling group resource:

-
kubectl patch scalinggroups $worker_group --patch '{"spec":{"max": 5}}' --type='merge'
kubectl get scalinggroup $worker_group -o jsonpath='{.spec}' | yq -P
-

The cluster autoscaler will now never provision more than 5 worker nodes.

-

If you want to see the autoscaling in action, try to add a deployment with a lot of replicas, like the -following Nginx deployment. The number of replicas needed to trigger the autoscaling depends on the size of -and count of your worker nodes. Wait for the rollout of the deployment to finish and compare the number of -worker nodes before and after the deployment:

-
kubectl create deployment nginx --image=nginx --replicas 150
kubectl -n kube-system get nodes
kubectl rollout status deployment nginx
kubectl -n kube-system get nodes
-

Manual scaling

-

Alternatively, you can manually scale your cluster up or down:

-
    -
  1. Go to Auto Scaling Groups and select the worker ASG to scale up.
  2. -
  3. Click Edit
  4. -
  5. Set the new (increased) Desired capacity and Update.
  6. -
-

Control-plane node scaling

-

Control-plane nodes can only be scaled manually and only scaled up!

-

To increase the number of control-plane nodes, follow these steps:

-
    -
  1. Go to Auto Scaling Groups and select the control-plane ASG to scale up.
  2. -
  3. Click Edit
  4. -
  5. Set the new (increased) Desired capacity and Update.
  6. -
-

If you scale down the number of control-planes nodes, the removed nodes won't be able to exit the etcd cluster correctly. This will endanger the quorum that's required to run a stable Kubernetes control plane.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/workflows/storage/index.html b/pr-preview/pr-4027/2.22/workflows/storage/index.html deleted file mode 100644 index a4d8bd900..000000000 --- a/pr-preview/pr-4027/2.22/workflows/storage/index.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - -Use persistent storage | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Use persistent storage

-

Persistent storage in Kubernetes requires cloud-specific configuration. -For abstraction of container storage, Kubernetes offers volumes, -allowing users to mount storage solutions directly into containers. -The Container Storage Interface (CSI) is the standard interface for exposing arbitrary block and file storage systems into containers in Kubernetes. -Cloud service providers (CSPs) offer their own CSI-based solutions for cloud storage.

-

Confidential storage

-

Most cloud storage solutions support encryption, such as GCE Persistent Disks (PD). -Constellation supports the available CSI-based storage options for Kubernetes engines in AWS, Azure, GCP, and STACKIT. -However, their encryption takes place in the storage backend and is managed by the CSP. -Thus, using the default CSI drivers for these storage types means trusting the CSP with your persistent data.

-

To address this, Constellation provides CSI drivers for AWS EBS, Azure Disk, GCE PD, and OpenStack Cinder, offering encryption on the node level. They enable transparent encryption for persistent volumes without needing to trust the cloud backend. Plaintext data never leaves the confidential VM context, offering you confidential storage.

-

For more details see encrypted persistent storage.

-

CSI drivers

-

Constellation supports the following drivers, which offer node-level encryption and optional integrity protection.

-

Constellation CSI driver for AWS Elastic Block Store -Mount Elastic Block Store storage volumes into your Constellation cluster. -Follow the instructions on how to install the Constellation CSI driver or check out the repository for more information.

-

Note that in case the options above aren't a suitable solution for you, Constellation is compatible with all other CSI-based storage options. For example, you can use AWS EFS, Azure Files, or GCP Filestore with Constellation out of the box. Constellation is just not providing transparent encryption on the node level for these storage types yet.

-

Installation

-

The Constellation CLI automatically installs Constellation's CSI driver for the selected CSP in your cluster. -If you don't need a CSI driver or wish to deploy your own, you can disable the automatic installation by setting deployCSIDriver to false in your Constellation config file.

-

AWS comes with two storage classes by default.

    -
  • encrypted-rwo -
      -
    • Uses SSDs of gp3 type
    • -
    • ext-4 filesystem
    • -
    • Encryption of all data written to disk
    • -
    -
  • -
  • integrity-encrypted-rwo -
      -
    • Uses SSDs of gp3 type
    • -
    • ext-4 filesystem
    • -
    • Encryption of all data written to disk
    • -
    • Integrity protection of data written to disk
    • -
    -
  • -

For more information on encryption algorithms and key sizes, refer to cryptographic algorithms.

info

The default storage class is set to encrypted-rwo for performance reasons. -If you want integrity-protected storage, set the storageClassName parameter of your persistent volume claim to integrity-encrypted-rwo.

Alternatively, you can create your own storage class with integrity protection enabled by adding csi.storage.k8s.io/fstype: ext4-integrity to the class parameters. -Or use another filesystem by specifying another file system type with the suffix -integrity, e.g., csi.storage.k8s.io/fstype: xfs-integrity.

Note that volume expansion isn't supported for integrity-protected disks.

-
    -
  1. -

    Create a persistent volume

    -

    A persistent volume claim is a request for storage with certain properties. -It can refer to a storage class. -The following creates a persistent volume claim, requesting 20 GB of storage via the encrypted-rwo storage class:

    -
    cat <<EOF | kubectl apply -f -
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
    name: pvc-example
    namespace: default
    spec:
    accessModes:
    - ReadWriteOnce
    storageClassName: encrypted-rwo
    resources:
    requests:
    storage: 20Gi
    EOF
    -
  2. -
  3. -

    Create a Pod with persistent storage

    -

    You can assign a persistent volume claim to an application in need of persistent storage. -The mounted volume will persist restarts. -The following creates a pod that uses the previously created persistent volume claim:

    -
    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Pod
    metadata:
    name: web-server
    namespace: default
    spec:
    containers:
    - name: web-server
    image: nginx
    volumeMounts:
    - mountPath: /var/lib/www/html
    name: mypvc
    volumes:
    - name: mypvc
    persistentVolumeClaim:
    claimName: pvc-example
    readOnly: false
    EOF
    -
  4. -
-

Change the default storage class

-

The default storage class is responsible for all persistent volume claims that don't explicitly request storageClassName. -Constellation creates a storage class with encryption enabled and sets this as the default class. -In case you wish to change it, follow the steps below:

-
    -
  1. -

    List the storage classes in your cluster:

    -
    kubectl get storageclass
    -

    The output is similar to this:

    -
    NAME                      PROVISIONER                         RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
    encrypted-rwo (default) {your-csp}.csi.confidential.cloud Delete Immediate true 1d
    integrity-encrypted-rwo {your-csp}.csi.confidential.cloud Delete Immediate false 1d
    -

    The default storage class is marked by (default).

    -
  2. -
  3. -

    Mark old default storage class as non default

    -

    If you previously used another storage class as the default, you will have to remove that annotation:

    -
    kubectl patch storageclass encrypted-rwo -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
    -
  4. -
  5. -

    Mark new class as the default

    -
    kubectl patch storageclass integrity-encrypted-rwo -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
    -
  6. -
  7. -

    Verify that your chosen storage class is default:

    -
    kubectl get storageclass
    -

    The output is similar to this:

    -
    NAME                                PROVISIONER                         RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
    encrypted-rwo {your-csp}.csi.confidential.cloud Delete Immediate true 1d
    integrity-encrypted-rwo (default) {your-csp}.csi.confidential.cloud Delete Immediate false 1d
    -
  8. -
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/workflows/terminate/index.html b/pr-preview/pr-4027/2.22/workflows/terminate/index.html deleted file mode 100644 index 83fceb2a2..000000000 --- a/pr-preview/pr-4027/2.22/workflows/terminate/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - -Terminate your cluster | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Terminate your cluster

-
info

This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details.

-
Loading asciinema cast...
-
-

You can terminate your cluster using the CLI. For this, you need the Terraform state directory named constellation-terraform in the current directory.

-
danger

All ephemeral storage and state of your cluster will be lost. Make sure any data is safely stored in persistent storage. Constellation can recreate your cluster and the associated encryption keys, but won't backup your application data automatically.

-

Terminate the cluster by running:

constellation terminate

Or without confirmation (e.g., for automation purposes):

constellation terminate --yes

This deletes all resources created by Constellation in your cloud environment. -All local files created by the apply command are deleted as well, except for constellation-mastersecret.json and the configuration file.

caution

Termination can fail if additional resources have been created that depend on the ones managed by Constellation. In this case, you need to delete these additional -resources manually. Just run the terminate command again afterward to continue the termination process of the cluster.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/workflows/terraform-provider/index.html b/pr-preview/pr-4027/2.22/workflows/terraform-provider/index.html deleted file mode 100644 index ede97f898..000000000 --- a/pr-preview/pr-4027/2.22/workflows/terraform-provider/index.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - -Use the Terraform provider | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Use the Terraform provider

-

The Constellation Terraform provider allows to manage the full lifecycle of a Constellation cluster (namely creation, upgrades, and deletion) via Terraform. -The provider is available through the Terraform registry and is released in lock-step with Constellation releases.

-

Prerequisites

-
    -
  • a Linux / Mac operating system (ARM64/AMD64)
  • -
  • a Terraform installation of version v1.4.4 or above
  • -
-

Quick setup

-

This example shows how to set up a Constellation cluster with the reference IAM and infrastructure setup. This setup is also used when creating a Constellation cluster through the Constellation CLI. You can either consume the IAM / infrastructure modules through a remote source (recommended) or local files. The latter requires downloading the infrastructure and IAM modules for the corresponding CSP from terraform-modules.zip on the Constellation release page and placing them in the Terraform workspace directory.

-
    -
  1. Create a directory (workspace) for your Constellation cluster.
  2. -
-
mkdir constellation-workspace
cd constellation-workspace
-
    -
  1. Use one of the example configurations for using the Constellation Terraform provider or create a main.tf file and fill it with the resources you want to create. The Constellation Terraform provider documentation offers thorough documentation on the resources and their attributes.
  2. -
  3. Initialize and apply the Terraform configuration.
  4. -
-

Initialize the providers and apply the configuration.

terraform init
terraform apply

Optionally, you can prefix the terraform apply command with TF_LOG=INFO to collect Terraform logs while applying the configuration. This may provide helpful output in debugging scenarios.

-
    -
  1. Connect to the cluster.
  2. -
-
terraform output -raw kubeconfig > constellation-admin.conf
export KUBECONFIG=$(realpath constellation-admin.conf)
-

Bringing your own infrastructure

-

Instead of using the example infrastructure used in the quick setup, you can also provide your own infrastructure. -If you need a starting point for a custom infrastructure setup, you can download the infrastructure / IAM Terraform modules for the respective CSP from the Constellation GitHub releases. You can modify and extend the modules per your requirements, while keeping the basic functionality intact. -The module contains:

-
    -
  • {csp}: cloud resources the cluster runs on
  • -
  • iam/{csp}: IAM resources used within the cluster
  • -
-

When upgrading your cluster, make sure to check the Constellation release notes for potential breaking changes in the reference infrastructure / IAM modules that need to be considered.

-

Cluster upgrades

- -

The steps for applying the upgrade are as follows:

-
    -
  1. Update the version constraint of the Constellation Terraform provider in the required_providers block in your Terraform configuration.
  2. -
  3. If you explicitly set any of the version attributes of the provider's resources and data sources (e.g. image_version or constellation_microservice_version), make sure to update them too. Refer to Constellation's version support policy for more information on how each Constellation version and its dependencies are supported.
  4. -
  5. Update the IAM / infrastructure configuration. - -
  6. -
  7. Upgrade the Terraform module and provider dependencies and apply the targeted configuration.
  8. -
-
  terraform init -upgrade
terraform apply
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/workflows/troubleshooting/index.html b/pr-preview/pr-4027/2.22/workflows/troubleshooting/index.html deleted file mode 100644 index a1be74b19..000000000 --- a/pr-preview/pr-4027/2.22/workflows/troubleshooting/index.html +++ /dev/null @@ -1,115 +0,0 @@ - - - - - -Troubleshooting | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Troubleshooting

-

This section aids you in finding problems when working with Constellation.

-

Common issues

-

Issues with creating new clusters

-

When you create a new cluster, you should always use the latest release. -If something doesn't work, check out the known issues.

-

Azure: Resource Providers can't be registered

-

On Azure, you may receive the following error when running apply or terminate with limited IAM permissions:

-
Error: Error ensuring Resource Providers are registered.

Terraform automatically attempts to register the Resource Providers it supports to
ensure it's able to provision resources.

If you don't have permission to register Resource Providers you may wish to use the
"skip_provider_registration" flag in the Provider block to disable this functionality.

[...]
-

To continue, please ensure that the required resource providers have been registered in your subscription by your administrator.

-

Afterward, set ARM_SKIP_PROVIDER_REGISTRATION=true as an environment variable and either run apply or terminate again. -For example:

-
ARM_SKIP_PROVIDER_REGISTRATION=true constellation apply
-

Or alternatively, for terminate:

-
ARM_SKIP_PROVIDER_REGISTRATION=true constellation terminate
-

Azure: Can't update attestation policy

-

On Azure, you may receive the following error when running apply from within an Azure environment, e.g., an Azure VM:

-
An error occurred: patching policies: updating attestation policy: unexpected status code: 403 Forbidden
-

The problem occurs because the Azure SDK we use internally attempts to authenticate towards the Azure API with the managed identity of your current environment instead of the Azure CLI token.

-

We decided not to deviate from this behavior and comply with the ordering of credentials.

-

A solution is to add the required permissions to the managed identity of your environment. For example, the managed identity of your Azure VM, instead of the account that you've authenticated with in the Azure CLI.

-

If your setup requires a change in the ordering of credentials, please open an issue and explain your desired behavior.

-

Nodes fail to join with error untrusted measurement value

-

This error indicates that a node's attestation statement contains measurements that don't match the trusted values expected by the JoinService. -This may for example happen if the cloud provider updates the VM's firmware such that it influences the runtime measurements in an unforeseen way. -A failed upgrade due to an erroneous attestation config can also cause this error. -You can change the expected measurements to resolve the failure.

-
caution

Attestation and trusted measurements are crucial for the security of your cluster. -Be extra careful when manually changing these settings. -When in doubt, check if the encountered issue is known or contact support.

-
tip

During an upgrade with modified attestation config, a backup of the current configuration is stored in the join-config config map in the kube-system namespace under the attestationConfig_backup key. To restore the old attestation config after a failed upgrade, replace the value of attestationConfig with the value from attestationConfig_backup:

kubectl patch configmaps -n kube-system join-config -p "{\"data\":{\"attestationConfig\":\"$(kubectl get configmaps -n kube-system join-config -o "jsonpath={.data.attestationConfig_backup}")\"}}"
-

You can use the apply command to change measurements of a running cluster:

-
    -
  1. Modify the measurements key in your local constellation-conf.yaml to the expected values.
  2. -
  3. Run constellation apply.
  4. -
-

Keep in mind that running apply also applies any version changes from your config to the cluster.

-

You can run these commands to learn about the versions currently configured in the cluster:

-
    -
  • Kubernetes API server version: kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.kubernetesClusterVersion
  • -
  • image version: kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.imageVersion
  • -
  • microservices versions: helm list --filter 'constellation-services' -n kube-system
  • -
-

Upgrading Kubernetes resources fails

-

Constellation manages its Kubernetes resources using Helm. -When applying an upgrade, the charts that are about to be installed, and a values override file overrides.yaml, -are saved to disk in your current workspace under constellation-upgrade/upgrade-<timestamp>/helm-charts/. -If upgrading the charts using the Constellation CLI fails, you can review these charts and try to manually apply the upgrade.

-
caution

Changing and manually applying the charts may destroy cluster resources and can lead to broken Constellation deployments. -Proceed with caution and when in doubt, -check if the encountered issue is known or contact support.

-

Diagnosing issues

-

Logs

-

To get started on diagnosing issues with Constellation, it's often helpful to collect logs from nodes, pods, or other resources in the cluster. Most logs are available through Kubernetes' standard -logging interfaces.

-

To debug issues occurring at boot time of the nodes, you can use the serial console interface of the CSP while the machine boots to get a read-only view of the boot logs.

-

Apart from that, Constellation also offers further observability integrations.

-

Node shell access

-

Debugging via a shell on a node is directly supported by Kubernetes.

-
    -
  1. -

    Figure out which node to connect to:

    -
    kubectl get nodes
    # or to see more information, such as IPs:
    kubectl get nodes -o wide
    -
  2. -
  3. -

    Connect to the node:

    -
    kubectl debug node/constell-worker-xksa0-000000 -it --image=busybox
    -

    You will be presented with a prompt.

    -

    The nodes file system is mounted at /host.

    -
  4. -
  5. -

    Once finished, clean up the debug pod:

    -
    kubectl delete pod node-debugger-constell-worker-xksa0-000000-bjthj
    -
  6. -
-

Emergency SSH access

-

Emergency SSH access to nodes can be useful to diagnose issues or download important data even if the Kubernetes API isn't reachable anymore.

-
    -
  1. -

    Enter the constellation-terraform directory in your Constellation workspace and enable emergency SSH access to the cluster:

    -
     cd constellation-terraform
    echo "emergency_ssh = true" >> ./terraform.tfvars
    terraform apply
    -
  2. -
  3. -

    Sign an existing SSH key with your master secret:

    -
    cd ../ # go back to your Constellation workspace
    constellation ssh --key your_public_key.pub
    -

    A certificate is written to constellation_cert.pub.

    -

    The certificate is valid for 24 hours and enables you to access your Constellation nodes using -certificate based authentication.

    -
  4. -
  5. -

    Now you can connect to any Constellation node using your certificate and your private key.

    -
    ssh -o CertificateFile=constellation_cert.pub -i <your private key> root@<ip of constellation node>
    -

    Normally, you don't have access to the Constellation nodes since they reside in a private network. -To access those nodes anyways, you can use your Constellation load balancer as a proxy jump host. -For this, use something along the following SSH client configuration:

    -
    Host <LB domain name>
    ProxyJump none

    Host *
    IdentityFile <your private key>
    PreferredAuthentications publickey
    CertificateFile=constellation_cert.pub
    User root
    ProxyJump <LB domain name>
    -

    With this configuration you can connect to a Constellation node using ssh -F <this config> <private node IP>. -You can obtain the private node IP and the domain name of the load balancer using your CSP's web UI.

    -
  6. -
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/workflows/trusted-launch/index.html b/pr-preview/pr-4027/2.22/workflows/trusted-launch/index.html deleted file mode 100644 index c5e8f6b5f..000000000 --- a/pr-preview/pr-4027/2.22/workflows/trusted-launch/index.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - -Use Azure trusted launch VMs | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Use Azure trusted launch VMs

-

Constellation also supports trusted launch VMs on Microsoft Azure. Trusted launch VMs don't offer the same level of security as Confidential VMs, but are available in more regions and in larger quantities. The main difference between trusted launch VMs and normal VMs is that the former offer vTPM-based remote attestation. When used with trusted launch VMs, Constellation relies on vTPM-based remote attestation to verify nodes.

-
caution

Trusted launch VMs don't provide runtime encryption and don't keep the cloud service provider (CSP) out of your trusted computing base.

-

Constellation supports trusted launch VMs with instance types Standard_D*_v4 and Standard_E*_v4. Run constellation config instance-types for a list of all supported instance types.

-

VM images

-

Azure currently doesn't support community galleries for trusted launch VMs. Thus, you need to manually import the Constellation node image into your cloud subscription.

-

The latest image is available at https://cdn.confidential.cloud/constellation/images/azure/trusted-launch/v2.2.0/constellation.img. Simply adjust the version number to download a newer version.

-

After you've downloaded the image, create a resource group constellation-images in your Azure subscription and import the image. -You can use a script to do this:

-
wget https://raw.githubusercontent.com/edgelesssys/constellation/main/hack/importAzure.sh
chmod +x importAzure.sh
AZURE_IMAGE_VERSION=2.2.0 AZURE_RESOURCE_GROUP_NAME=constellation-images AZURE_IMAGE_FILE=./constellation.img ./importAzure.sh
-

The script creates the following resources:

-
    -
  1. A new image gallery with the default name constellation-import
  2. -
  3. A new image definition with the default name constellation
  4. -
  5. The actual image with the provided version. In this case 2.2.0
  6. -
-

Once the import is completed, use the ID of the image version in your constellation-conf.yaml for the image field. Set confidentialVM to false.

-

Fetch the image measurements:

-
IMAGE_VERSION=2.2.0
URL=https://public-edgeless-constellation.s3.us-east-2.amazonaws.com//communitygalleries/constellationcvm-b3782fa0-0df7-4f2f-963e-fc7fc42663df/images/constellation/versions/$IMAGE_VERSION/measurements.yaml
constellation config fetch-measurements -u$URL -s$URL.sig
-
info

The constellation apply command will issue a warning because manually imported images aren't recognized as production grade images:

Configured image doesn't look like a released production image. Double check image before deploying to production.

Please ignore this warning.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/workflows/upgrade/index.html b/pr-preview/pr-4027/2.22/workflows/upgrade/index.html deleted file mode 100644 index 371505733..000000000 --- a/pr-preview/pr-4027/2.22/workflows/upgrade/index.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - - -Upgrade your cluster | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Upgrade your cluster

-

Constellation provides an easy way to upgrade all components of your cluster, without disrupting its availability. -Specifically, you can upgrade the Kubernetes version, the nodes' image, and the Constellation microservices. -You configure the desired versions in your local Constellation configuration and trigger upgrades with the apply command. -To learn about available versions you use the upgrade check command. -Which versions are available depends on the CLI version you are using.

-

Update the CLI

-

Each CLI comes with a set of supported microservice and Kubernetes versions. -Most importantly, a given CLI version can only upgrade a cluster of the previous minor version, but not older ones. -This means that you have to upgrade your CLI and cluster one minor version at a time.

-

For example, if you are currently on CLI version v2.6 and the latest version is v2.8, you should

-
    -
  • upgrade the CLI to v2.7,
  • -
  • upgrade the cluster to v2.7,
  • -
  • and only then continue upgrading the CLI (and the cluster) to v2.8 after.
  • -
-

Also note that if your current Kubernetes version isn't supported by the next CLI version, use your current CLI to upgrade to a newer Kubernetes version first.

-

To learn which Kubernetes versions are supported by a particular CLI, run constellation config kubernetes-versions.

-

Migrate the configuration

-

The Constellation configuration file is located in the file constellation-conf.yaml in your workspace. -Refer to the migration reference to check if you need to update fields in your configuration file. -Use constellation config migrate to automatically update an old config file to a new format.

-

Check for upgrades

-

To learn which versions the current CLI can upgrade to and what's installed in your cluster, run:

-
# Show possible upgrades
constellation upgrade check

# Show possible upgrades and write them to config file
constellation upgrade check --update-config
-

You can either enter the reported target versions into your config manually or run the above command with the --update-config flag. -When using this flag, the kubernetesVersion, image, microserviceVersion, and attestation fields are overwritten with the smallest available upgrade.

-

Apply the upgrade

-

Once you updated your config with the desired versions, you can trigger the upgrade with this command:

-
constellation apply
-

Microservice upgrades will be finished within a few minutes, depending on the cluster size. -If you are interested, you can monitor pods restarting in the kube-system namespace with your tool of choice.

-

Image and Kubernetes upgrades take longer. -For each node in your cluster, a new node has to be created and joined. -The process usually takes up to ten minutes per node.

-

When applying an upgrade, the Helm charts for the upgrade as well as backup files of Constellation-managed Custom Resource Definitions, Custom Resources, and Terraform state are created. -You can use the Terraform state backup to restore previous resources in case an upgrade misconfigured or erroneously deleted a resource. -You can use the Custom Resource (Definition) backup files to restore Custom Resources and Definitions manually (e.g., via kubectl apply) if the automatic migration of those resources fails. -You can use the Helm charts to manually apply upgrades to the Kubernetes resources, should an upgrade fail.

-
note

For advanced users: the upgrade consists of several phases that can be individually skipped through the --skip-phases flag. -The phases are infrastracture for the cloud resource management through Terraform, helm for the chart management of the microservices, image for OS image upgrades, and k8s for Kubernetes version upgrades.

-

Check the status

-

Upgrades are asynchronous operations. -After you run apply, it will take a while until the upgrade has completed. -To understand if an upgrade is finished, you can run:

-
constellation status
-

This command displays the following information:

-
    -
  • The installed services and their versions
  • -
  • The image and Kubernetes version the cluster is expecting on each node
  • -
  • How many nodes are up to date
  • -
-

Here's an example output:

-
Target versions:
Image: v2.6.0
Kubernetes: v1.25.8
Service versions:
Cilium: v1.12.1
cert-manager: v1.10.0
constellation-operators: v2.6.0
constellation-services: v2.6.0
Cluster status: Some node versions are out of date
Image: 23/25
Kubernetes: 25/25
-

This output indicates that the cluster is running Kubernetes version 1.25.8, and all nodes have the appropriate binaries installed. -23 out of 25 nodes have already upgraded to the targeted image version of 2.6.0, while two are still in progress.

-

Apply further upgrades

-

After the upgrade is finished, you can run constellation upgrade check again to see if there are more upgrades available. If so, repeat the process.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/workflows/verify-cli/index.html b/pr-preview/pr-4027/2.22/workflows/verify-cli/index.html deleted file mode 100644 index a80e87ba5..000000000 --- a/pr-preview/pr-4027/2.22/workflows/verify-cli/index.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - -Verify the CLI | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Verify the CLI

-
info

This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details.

-
Loading asciinema cast...
-
-

Edgeless Systems uses sigstore and SLSA to ensure supply-chain security for the Constellation CLI and node images ("artifacts"). sigstore consists of three components: Cosign, Rekor, and Fulcio. Edgeless Systems uses Cosign to sign artifacts. All signatures are uploaded to the public Rekor transparency log, which resides at https://rekor.sigstore.dev.

-
note

The public key for Edgeless Systems' long-term code-signing key is:

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT
JmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==
-----END PUBLIC KEY-----

The public key is also available for download at https://edgeless.systems/es.pub and in the Twitter profile @EdgelessSystems.

-

The Rekor transparency log is a public append-only ledger that verifies and records signatures and associated metadata. The Rekor transparency log enables everyone to observe the sequence of (software) signatures issued by Edgeless Systems and many other parties. The transparency log allows for the public identification of dubious or malicious signatures.

-

You should always ensure that (1) your CLI executable was signed with the private key corresponding to the above public key and that (2) there is a corresponding entry in the Rekor transparency log. Both can be done as described in the following.

-
info

You don't need to verify the Constellation node images. This is done automatically by your CLI and the rest of Constellation.

-

Verify the signature

-
info

This guide assumes Linux on an amd64 processor. The exact steps for other platforms differ slightly.

-

First, install the Cosign CLI. Next, download and verify the signature that accompanies your CLI executable, for example:

-
$ cosign verify-blob --key https://edgeless.systems/es.pub --signature constellation-linux-amd64.sig constellation-linux-amd64

Verified OK
-

The above performs an offline verification of the provided public key, signature, and executable. To also verify that a corresponding entry exists in the public Rekor transparency log, add the variable COSIGN_EXPERIMENTAL=1:

-
$ COSIGN_EXPERIMENTAL=1 cosign verify-blob --key https://edgeless.systems/es.pub --signature constellation-linux-amd64.sig constellation-linux-amd64

tlog entry verified with uuid: afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13 index: 3477047
Verified OK
-

🏁 You now know that your CLI executable was officially released and signed by Edgeless Systems.

-

Optional: Manually inspect the transparency log

-

To further inspect the public Rekor transparency log, install the Rekor CLI. A search for the CLI executable should give a single UUID. (Note that this UUID contains the UUID from the previous cosign command.)

-
$ rekor-cli search --artifact constellation-linux-amd64

Found matching entries (listed by UUID):
362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13
-

With this UUID you can get the full entry from the transparency log:

-
$ rekor-cli get --uuid=362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13

LogID: c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d
Index: 3477047
IntegratedTime: 2022-09-12T22:28:16Z
UUID: afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13
Body: {
"HashedRekordObj": {
"data": {
"hash": {
"algorithm": "sha256",
"value": "40e137b9b9b8204d672642fd1e181c6d5ccb50cfc5cc7fcbb06a8c2c78f44aff"
}
},
"signature": {
"content": "MEUCIQCSER3mGj+j5Pr2kOXTlCIHQC3gT30I7qkLr9Awt6eUUQIgcLUKRIlY50UN8JGwVeNgkBZyYD8HMxwC/LFRWoMn180=",
"publicKey": {
"content": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFZjhGMWhwbXdFK1lDRlh6akd0YVFjckw2WFpWVApKbUVlNWlTTHZHMVN5UVNBZXc3V2RNS0Y2bzl0OGUyVEZ1Q2t6bE9oaGx3czJPSFdiaUZabkZXQ0Z3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=="
}
}
}
}
-

The field publicKey should contain Edgeless Systems' public key in Base64 encoding.

-

You can get an exhaustive list of artifact signatures issued by Edgeless Systems via the following command:

-
rekor-cli search --public-key https://edgeless.systems/es.pub --pki-format x509
-

Edgeless Systems monitors this list to detect potential unauthorized use of its private key.

-

Verify the provenance

-

Provenance attests that a software artifact was produced by a specific repository and build system invocation. For more information on provenance visit slsa.dev and learn about the adoption of SLSA for Constellation.

-

Just as checking its signature proves that the CLI hasn't been manipulated, checking the provenance proves that the artifact was produced by the expected build process and hasn't been tampered with.

-

To verify the provenance, first install the slsa-verifier. Then make sure you have the provenance file (constellation.intoto.jsonl) and Constellation CLI downloaded. Both are available on the GitHub release page.

-
info

The same provenance file is valid for all Constellation CLI executables of a given version independent of the target platform.

-

Use the verifier to perform the check:

-
$ slsa-verifier verify-artifact constellation-linux-amd64 \
--provenance-path constellation.intoto.jsonl \
--source-uri github.com/edgelesssys/constellation

Verified signature against tlog entry index 7771317 at URL: https://rekor.sigstore.dev/api/v1/log/entries/24296fb24b8ad77af2c04c8b4ae0d5bc5...
Verified build using builder https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v1.2.2 at commit 18e9924b416323c37b9cdfd6cc728de8a947424a
PASSED: Verified SLSA provenance
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.22/workflows/verify-cluster/index.html b/pr-preview/pr-4027/2.22/workflows/verify-cluster/index.html deleted file mode 100644 index 58b98e34e..000000000 --- a/pr-preview/pr-4027/2.22/workflows/verify-cluster/index.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - -Verify your cluster | Constellation - - - - - - - -
Skip to main content
Version: 2.22

Verify your cluster

-

Constellation's attestation feature allows you, or a third party, to verify the integrity and confidentiality of your Constellation cluster.

-

Fetch measurements

-

To verify the integrity of Constellation you need trusted measurements to verify against. For each node image released by Edgeless Systems, there are signed measurements, which you can download using the CLI:

-
constellation config fetch-measurements
-

This command performs the following steps:

-
    -
  1. Download the signed measurements for the configured image. By default, this will use Edgeless Systems' public measurement registry.
  2. -
  3. Verify the signature of the measurements. This will use Edgeless Systems' public key.
  4. -
  5. Write measurements into configuration file.
  6. -
-

The configuration file then contains a list of measurements similar to the following:

-
# ...
measurements:
0:
expected: "0f35c214608d93c7a6e68ae7359b4a8be5a0e99eea9107ece427c4dea4e439cf"
warnOnly: false
4:
expected: "02c7a67c01ec70ffaf23d73a12f749ab150a8ac6dc529bda2fe1096a98bf42ea"
warnOnly: false
5:
expected: "e6949026b72e5045706cd1318889b3874480f7a3f7c5c590912391a2d15e6975"
warnOnly: true
8:
expected: "0000000000000000000000000000000000000000000000000000000000000000"
warnOnly: false
9:
expected: "f0a6e8601b00e2fdc57195686cd4ef45eb43a556ac1209b8e25d993213d68384"
warnOnly: false
11:
expected: "0000000000000000000000000000000000000000000000000000000000000000"
warnOnly: false
12:
expected: "da99eb6cf7c7fbb692067c87fd5ca0b7117dc293578e4fea41f95d3d3d6af5e2"
warnOnly: false
13:
expected: "0000000000000000000000000000000000000000000000000000000000000000"
warnOnly: false
14:
expected: "d7c4cc7ff7933022f013e03bdee875b91720b5b86cf1753cad830f95e791926f"
warnOnly: true
15:
expected: "0000000000000000000000000000000000000000000000000000000000000000"
warnOnly: false
# ...
-

Each entry specifies the expected value of the Constellation node, and whether the measurement should be enforced (warnOnly: false), or only a warning should be logged (warnOnly: true). -By default, the subset of the available measurements that can be locally reproduced and verified is enforced.

-

During attestation, the validating side (CLI or join service) compares each measurement reported by the issuing side (first node or joining node) individually. -For mismatching measurements that have set warnOnly to true only a warning is emitted. -For mismatching measurements that have set warnOnly to false an error is emitted and attestation fails. -If attestation fails for a new node, it isn't permitted to join the cluster.

-

The verify command

-
note

The steps below are purely optional. They're automatically executed by constellation apply when you initialize your cluster. The constellation verify command mostly has an illustrative purpose.

-

The verify command obtains and verifies an attestation statement from a running Constellation cluster.

-
constellation verify [--cluster-id ...]
-

From the attestation statement, the command verifies the following properties:

-
    -
  • The cluster is using the correct Confidential VM (CVM) type.
  • -
  • Inside the CVMs, the correct node images are running. The node images are identified through the measurements obtained in the previous step.
  • -
  • The unique ID of the cluster matches the one from your constellation-state.yaml file or passed in via --cluster-id.
  • -
-

Once the above properties are verified, you know that you are talking to the right Constellation cluster and it's in a good and trustworthy shape.

-

Custom arguments

-

The verify command also allows you to verify any Constellation deployment that you have network access to. For this you need the following:

-
    -
  • The IP address of a running Constellation cluster's VerificationService. The VerificationService is exposed via a NodePort service using the external IP address of your cluster. Run kubectl get nodes -o wide and look for EXTERNAL-IP.
  • -
  • The cluster's clusterID. See cluster identity for more details.
  • -
  • A constellation-conf.yaml file with the expected measurements of the cluster in your working directory.
  • -
-

For example:

-
constellation verify -e 192.0.2.1 --cluster-id Q29uc3RlbGxhdGlvbkRvY3VtZW50YXRpb25TZWNyZXQ=
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/architecture/attestation/index.html b/pr-preview/pr-4027/2.23/architecture/attestation/index.html deleted file mode 100644 index cd50dcebe..000000000 --- a/pr-preview/pr-4027/2.23/architecture/attestation/index.html +++ /dev/null @@ -1,229 +0,0 @@ - - - - - -Attestation | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Attestation

-

This page explains Constellation's attestation process and highlights the cornerstones of its trust model.

-

Terms

-

The following lists terms and concepts that help to understand the attestation concept of Constellation.

-

Trusted Platform Module (TPM)

-

A TPM chip is a dedicated tamper-resistant crypto-processor. -It can securely store artifacts such as passwords, certificates, encryption keys, or runtime measurements (more on this below). -When a TPM is implemented in software, it's typically called a virtual TPM (vTPM).

-

Runtime measurement

-

A runtime measurement is a cryptographic hash of the memory pages of a so called runtime component. Runtime components of interest typically include a system's bootloader or OS kernel.

-

Platform Configuration Register (PCR)

-

A Platform Configuration Register (PCR) is a memory location in the TPM that has some unique properties. -To store a new value in a PCR, the existing value is extended with a new value as follows:

-
PCR[N] = HASHalg( PCR[N] || ArgumentOfExtend )
-

The PCRs are typically used to store runtime measurements. -The new value of a PCR is always an extension of the existing value. -Thus, storing the measurements of multiple components into the same PCR irreversibly links them together.

-

Measured boot

-

Measured boot builds on the concept of chained runtime measurements. -Each component in the boot chain loads and measures the next component into the PCR before executing it. -By comparing the resulting PCR values against trusted reference values, the integrity of the entire boot chain and thereby the running system can be ensured.

-

Remote attestation (RA)

-

Remote attestation is the process of verifying certain properties of an application or platform, such as integrity and confidentiality, from a remote location. -In the case of a measured boot, the goal is to obtain a signed attestation statement on the PCR values of the boot measurements. -The statement can then be verified and compared to a set of trusted reference values. -This way, the integrity of the platform can be ensured before sharing secrets with it.

-

Confidential virtual machine (CVM)

-

Confidential computing (CC) is the protection of data in-use with hardware-based trusted execution environments (TEEs). -With CVMs, TEEs encapsulate entire virtual machines and isolate them against the hypervisor, other VMs, and direct memory access. -After loading the initial VM image into encrypted memory, the hypervisor calls for a secure processor to measure these initial memory pages. -The secure processor locks these pages and generates an attestation report on the initial page measurements. -CVM memory pages are encrypted with a key that resides inside the secure processor, which makes sure only the guest VM can access them. -The attestation report is signed by the secure processor and can be verified using remote attestation via the certificate authority of the hardware vendor. -Such an attestation statement guarantees the confidentiality and integrity of a CVM.

-

Attested TLS (aTLS)

-

In a CC environment, attested TLS (aTLS) can be used to establish secure connections between two parties using the remote attestation features of the CC components.

-

aTLS modifies the TLS handshake by embedding an attestation statement into the TLS certificate. -Instead of relying on a certificate authority, aTLS uses this attestation statement to establish trust in the certificate.

-

The protocol can be used by clients to verify a server certificate, by a server to verify a client certificate, or for mutual verification (mutual aTLS).

-

Overview

-

The challenge for Constellation is to lift a CVM's attestation statement to the Kubernetes software layer and make it end-to-end verifiable. -From there, Constellation needs to expand the attestation from a single CVM to the entire cluster.

-

The JoinService and VerificationService are where all runs together. -Internally, the JoinService uses remote attestation to securely join CVM nodes to the cluster. -Externally, the VerificationService provides an attestation statement for the cluster's CVMs and configuration.

-

The following explains the details of both steps.

-

Node attestation

-

The idea is that Constellation nodes should have verifiable integrity from the CVM hardware measurement up to the Kubernetes software layer. -The solution is a verifiable boot chain and an integrity-protected runtime environment.

-

Constellation uses measured boot within CVMs, measuring each component in the boot process before executing it. -Outside of CC, this is usually implemented via TPMs. -CVM technologies differ in how they implement runtime measurements, but the general concepts are similar to those of a TPM. -For simplicity, TPM terminology like PCR is used in the following.

-

When a Constellation node image boots inside a CVM, measured boot is used for all stages and components of the boot chain. -This process goes up to the root filesystem. -The root filesystem is mounted read-only with integrity protection. -For the details on the image and boot stages see the image architecture documentation. -Any changes to the image will inevitably also change the corresponding PCR values. -To create a node attestation statement, the Constellation image obtains a CVM attestation statement from the hardware. -This includes the runtime measurements and thereby binds the measured boot results to the CVM hardware measurement.

-

In addition to the image measurements, Constellation extends a PCR during the initialization phase that irrevocably marks the node as initialized. -The measurement is created using the clusterID, tying all future attestation statements to this ID. -Thereby, an attestation statement is unique for every cluster and a node can be identified unambiguously as being initialized.

-

To verify an attestation, the hardware's signature and a statement are verified first to establish trust in the contained runtime measurements. -If successful, the measurements are verified against the trusted values of the particular Constellation release version. -Finally, the measurement of the clusterID can be compared by calculating it with the master secret.

-

Runtime measurements

-

Constellation uses runtime measurements to implement the measured boot approach. -As stated above, the underlying hardware technology and guest firmware differ in their implementations of runtime measurements. -The following gives a detailed description of the available measurements in the different cloud environments.

-

The runtime measurements consist of two types of values:

-
    -
  • -

    Measurements produced by the cloud infrastructure and firmware of the CVM: -These are measurements of closed-source firmware and other values controlled by the cloud provider. -While not being reproducible for the user, some of them can be compared against previously observed values. -Others may change frequently and aren't suitable for verification. -The signed image measurements include measurements that are known, previously observed values.

    -
  • -
  • -

    Measurements produced by the Constellation bootloader and boot chain: -The Constellation Bootloader takes over from the CVM firmware and measures the rest of the boot chain. -The Constellation Bootstrapper is the first user mode component that runs in a Constellation image. -It extends PCR registers with the IDs of the cluster marking a node as initialized.

    -
  • -
-

Constellation allows to specify in the config which measurements should be enforced during the attestation process. -Enforcing non-reproducible measurements controlled by the cloud provider means that changes in these values require manual updates to the cluster's config. -By default, Constellation only enforces measurements that are stable values produced by the infrastructure or by Constellation directly.

-

Constellation uses the vTPM (NitroTPM) feature of the AWS Nitro System on AWS for runtime measurements.

The vTPM adheres to the TPM 2.0 specification. -The VMs are attested by obtaining signed PCR values over the VM's boot configuration from the TPM and comparing them to a known, good state (measured boot).

The following table lists all PCR values of the vTPM and the measured components. -It also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable. -The latter means that the value can be generated offline and compared to the one in the vTPM.

PCRComponentsMeasured byReproducible and verifiable
0FirmwareAWSNo
1FirmwareAWSNo
2FirmwareAWSNo
3FirmwareAWSNo
4Constellation Bootloader, Kernel, initramfs, Kernel command lineAWS, Constellation BootloaderYes
5FirmwareAWSNo
6FirmwareAWSNo
7Secure Boot PolicyAWS, Constellation BootloaderNo
8---
9initramfs, Kernel command lineLinux KernelYes
10User spaceLinux IMANo1
11Unified Kernel Image componentsConstellation BootloaderYes
12Reserved(User space, Constellation Bootloader)Yes
13Reserved(Constellation Bootloader)Yes
14Secure Boot StateConstellation BootloaderNo
15ClusterIDConstellation BootstrapperYes
16–23Unused--
-

CVM verification

-

To verify the integrity of the received attestation statement, a chain of trust from the CVM technology to the interface providing the statement has to be established. -For verification of the CVM technology, Constellation may expose additional options in its config file.

-

On AWS, AMD SEV-SNP is used to provide runtime encryption to the VMs. -An SEV-SNP attestation report is used to establish trust in the VM. -You may customize certain parameters for verification of the attestation statement using the Constellation config file.

    -
  • -

    TCB versions

    -

    You can set the minimum version numbers of components in the SEV-SNP TCB. -Use the latest versions to enforce that only machines with the most recent firmware updates are allowed to join the cluster. -Alternatively, you can set a lower minimum version to allow slightly out-of-date machines to still be able to join the cluster.

    -
  • -
  • -

    AMD Root Key Certificate

    -

    This certificate is the root of trust for verifying the SEV-SNP certificate chain.

    -
  • -
  • -

    AMD Signing Key Certificate

    -

    This is the intermediate certificate for verifying the SEV-SNP report's signature. -If it's not specified, the CLI fetches it from the AMD key distribution server.

    -
  • -
-

Cluster attestation

-

Cluster-facing, Constellation's JoinService verifies each node joining the cluster given the configured ground truth runtime measurements. -User-facing, the VerificationService provides an interface to verify a node using remote attestation. -By verifying the first node during the initialization and configuring the ground truth measurements that are subsequently enforced by the JoinService, the whole cluster is verified in a transitive way.

-

Cluster-facing attestation

-

The JoinService is provided with the runtime measurements of the whitelisted Constellation image version as the ground truth. -During the initialization and the cluster bootstrapping, each node connects to the JoinService using aTLS. -During the handshake, the node transmits an attestation statement including its runtime measurements. -The JoinService verifies that statement and compares the measurements against the ground truth. -For details of the initialization process check the microservice descriptions.

-

After the initialization, every node updates its runtime measurements with the clusterID value, marking it irreversibly as initialized. -When an initialized node tries to join another cluster, its measurements inevitably mismatch the measurements of an uninitialized node and it will be declined.

-

User-facing attestation

-

The VerificationService provides an endpoint for obtaining its hardware-based remote attestation statement, which includes the runtime measurements. -A user can verify this statement and compare the measurements against the configured ground truth and, thus, verify the identity and integrity of all Constellation components and the cluster configuration. Subsequently, the user knows that the entire cluster is in the expected state and is trustworthy.

-

Putting it all together

-

This section puts the aforementioned concepts together and illustrate how trust into a Constellation cluster is established and maintained.

-

CLI and node images

-

It all starts with the CLI executable. The CLI is signed by Edgeless Systems. To ensure non-repudiability for CLI releases, Edgeless Systems publishes corresponding signatures to the public ledger of the sigstore project. There's a step-by-step guide on how to verify CLI signatures based on sigstore.

-

The CLI contains the latest runtime measurements of the Constellation node image for all supported cloud platforms. In case a different version of the node image is to be used, the corresponding runtime measurements can be fetched using the CLI's fetch-measurements command. This command downloads the runtime measurements and the corresponding signature from cdn.confidential.cloud. See for example the following files corresponding to node image v2.16.3:

- -

The CLI contains the long-term public key of Edgeless Systems to verify the signature of downloaded runtime measurements.

-

Cluster creation

-

When a cluster is created, the CLI automatically verifies the runtime measurements of the first node using remote attestation. Based on this, the CLI and the first node set up a temporary TLS connection. This aTLS connection is used for two things:

-
    -
  1. The CLI sends the master secret of the to-be-created cluster to the CLI. The master secret is generated by the first node.
  2. -
  3. The first node sends a kubeconfig file with Kubernetes credentials to the CLI.
  4. -
-

After this, the aTLS connection is closed and the first node bootstraps the Kubernetes cluster. All subsequent interactions between the CLI and the cluster go via the Kubernetes API server running inside the cluster. The CLI (and other tools like kubectl) use the credentials referenced by the kubeconfig file to authenticate themselves towards the Kubernetes API server and to establish a mTLS connection.

-

The CLI connects to the Kubernetes API to write the runtime measurements for the applicable node image to etcd. The JoinService uses these runtime measurements to verify all nodes that join the cluster subsequently.

-

Chain of trust

-

In summary, there's a chain of trust based on cryptographic signatures that goes from the user to the cluster via the CLI. This is illustrated in the following diagram.

- -

Upgrades

-

Whenever a cluster is upgraded to a new version of the node image, the CLI sends the corresponding runtime measurements via the Kubernetes API server. The new runtime measurements are stored in etcd within the cluster and replace any previous runtime measurements. The new runtime measurements are then used automatically by the JoinService for the verification of new nodes.

-

References

- -

Footnotes

-
    -
  1. -

    Linux IMA produces runtime measurements of user-space binaries. -However, these measurements aren't deterministic and thus, PCR[10] can't be compared to a constant value. -Instead, a policy engine must be used to verify the TPM event log against a policy. 2 3 4

    -
  2. -
-
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/architecture/encrypted-storage/index.html b/pr-preview/pr-4027/2.23/architecture/encrypted-storage/index.html deleted file mode 100644 index edc13e56c..000000000 --- a/pr-preview/pr-4027/2.23/architecture/encrypted-storage/index.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - -Encrypted persistent storage | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Encrypted persistent storage

-

Confidential VMs provide runtime memory encryption to protect data in use. -In the context of Kubernetes, this is sufficient for the confidentiality and integrity of stateless services. -Consider a front-end web server, for example, that keeps all connection information cached in main memory. -No sensitive data is ever written to an insecure medium. -However, many real-world applications need some form of state or data-lake service that's connected to a persistent storage device and requires encryption at rest. -As described in Use persistent storage, cloud service providers (CSPs) use the container storage interface (CSI) to make their storage solutions available to Kubernetes workloads. -These CSI storage solutions often support some sort of encryption. -For example, Google Cloud encrypts data at rest by default, without any action required by the customer.

-

Cloud provider-managed encryption

-

CSP-managed storage solutions encrypt the data in the cloud backend before writing it physically to disk. -In the context of confidential computing and Constellation, the CSP and its managed services aren't trusted. -Hence, cloud provider-managed encryption protects your data from offline hardware access to physical storage devices. -It doesn't protect it from anyone with infrastructure-level access to the storage backend or a malicious insider in the cloud platform. -Even with "bring your own key" or similar concepts, the CSP performs the encryption process with access to the keys and plaintext data.

-

In the security model of Constellation, securing persistent storage and thereby data at rest requires that all cryptographic operations are performed inside a trusted execution environment. -Consequently, using CSP-managed encryption of persistent storage usually isn't an option.

-

Constellation-managed encryption

-

Constellation provides CSI drivers for storage solutions in all major clouds with built-in encryption support. -Block storage provisioned by the CSP is mapped using the dm-crypt, and optionally the dm-integrity, kernel modules, before it's formatted and accessed by the Kubernetes workloads. -All cryptographic operations happen inside the trusted environment of the confidential Constellation node.

-

Note that for integrity-protected disks, volume expansion isn't supported.

-

By default the driver uses data encryption keys (DEKs) issued by the Constellation KeyService. -The DEKs are in turn derived from the Constellation's key encryption key (KEK), which is directly derived from the master secret. -This is the recommended mode of operation, and also requires the least amount of setup by the cluster administrator.

-

Alternatively, the driver can be configured to use a key management system to store and access KEKs and DEKs.

-

Refer to keys and cryptography for more details on key management in Constellation.

-

Once deployed and configured, the CSI driver ensures transparent encryption and integrity of all persistent volumes provisioned via its storage class. -Data at rest is secured without any additional actions required by the developer.

-

Cryptographic algorithms

-

This section gives an overview of the libraries, cryptographic algorithms, and their configurations, used in Constellation's CSI drivers.

-

dm-crypt

-

To interact with the dm-crypt kernel module, Constellation uses libcryptsetup. -New devices are formatted as LUKS2 partitions with a sector size of 4096 bytes. -The used key derivation function is Argon2id with the recommended parameters for memory-constrained environments of 3 iterations and 64 MiB of memory, utilizing 4 parallel threads. -For encryption Constellation uses AES in XTS-Plain64. The key size is 512 bit.

-

dm-integrity

-

To interact with the dm-integrity kernel module, Constellation uses libcryptsetup. -When enabled, the used data integrity algorithm is HMAC with SHA256 as the hash function. -The tag size is 32 Bytes.

-

Encrypted S3 object storage

-

Constellation comes with a service that you can use to transparently retrofit client-side encryption to existing applications that use S3 (AWS or compatible) for storage. -To learn more, check out the s3proxy documentation.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/architecture/images/index.html b/pr-preview/pr-4027/2.23/architecture/images/index.html deleted file mode 100644 index 0f3185a03..000000000 --- a/pr-preview/pr-4027/2.23/architecture/images/index.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - -Constellation images | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Constellation images

-

Constellation uses a minimal version of Fedora as the operating system running inside confidential VMs. This Linux distribution is optimized for containers and designed to be stateless. -The Constellation images provide measured boot and an immutable filesystem.

-

Measured boot

- -

Measured boot uses a Trusted Platform Module (TPM) to measure every part of the boot process. This allows for verification of the integrity of a running system at any point in time. To ensure correct measurements of every stage, each stage is responsible to measure the next stage before transitioning.

-

Firmware

-

With confidential VMs, the firmware is the root of trust and is measured automatically at boot. After initialization, the firmware will load and measure the bootloader before executing it.

-

Bootloader

-

The bootloader is the first modifiable part of the boot chain. The bootloader is tasked with loading the kernel, initramfs and setting the kernel command line. The Constellation bootloader measures these components before starting the kernel.

-

initramfs

-

The initramfs is a small filesystem loaded to prepare the actual root filesystem. The Constellation initramfs maps the block device containing the root filesystem with dm-verity. The initramfs then mounts the root filesystem from the mapped block device.

-

dm-verity provides integrity checking using a cryptographic hash tree. When a block is read, its integrity is checked by verifying the tree against a trusted root hash. The initramfs reads this root hash from the previously measured kernel command line. Thus, if any block of the root filesystem's device is modified on disk, trying to read the modified block will result in a kernel panic at runtime.

-

After mounting the root filesystem, the initramfs will switch over and start the init process of the integrity-protected root filesystem.

-

State disk

-

In addition to the read-only root filesystem, each Constellation node has a disk for storing state data. -This disk is mounted readable and writable by the initramfs and contains data that should persist across reboots. -Such data can contain sensitive information and, therefore, must be stored securely. -To that end, the state disk is protected by authenticated encryption. -See the section on keys and encryption for more information on the cryptographic primitives in use.

-

Kubernetes components

-

During initialization, the Bootstrapper downloads and verifies the Kubernetes components as configured by the user. -They're stored on the state partition and can be updated once new releases need to be installed.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/architecture/keys/index.html b/pr-preview/pr-4027/2.23/architecture/keys/index.html deleted file mode 100644 index 01b33e661..000000000 --- a/pr-preview/pr-4027/2.23/architecture/keys/index.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - -Key management and cryptographic primitives | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Key management and cryptographic primitives

-

Constellation protects and isolates your cluster and workloads. -To that end, cryptography is the foundation that ensures the confidentiality and integrity of all components. -Evaluating the security and compliance of Constellation requires a precise understanding of the cryptographic primitives and keys used. -The following gives an overview of the architecture and explains the technical details.

-

Confidential VMs

-

Confidential VM (CVM) technology comes with hardware and software components for memory encryption, isolation, and remote attestation. -For details on the implementations and cryptographic soundness, refer to the hardware vendors' documentation and advisories.

-

Master secret

-

The master secret is the cryptographic material used for deriving the clusterID and the key encryption key (KEK) for storage encryption. -It's generated during the bootstrapping of a Constellation cluster. -It can either be managed by Constellation or an external key management system. -In case of recovery, the master secret allows to decrypt the state and recover a Constellation cluster.

-

Cluster identity

-

The identity of a Constellation cluster is represented by cryptographic measurements:

-

The base measurements represent the identity of a valid, uninitialized Constellation node. -They depend on the node image, but are otherwise the same for every Constellation cluster. -On node boot, they're determined using the CVM's attestation mechanism and measured boot up to the read-only root filesystem.

-

The clusterID represents the identity of a single initialized Constellation cluster. -It's derived from the master secret and a cryptographically random salt and unique for every Constellation cluster. -The Bootstrapper measures the clusterID into its own PCR before executing any code not measured as part of the base measurements. -See Node attestation for details.

-

The remote attestation statement of a Constellation cluster combines the base measurements and the clusterID for a verifiable, unspoofable, unique identity.

-

Network encryption

-

Constellation encrypts all cluster network communication using the container network interface (CNI). -See network encryption for more details.

-

The Cilium agent running on each node establishes a secure WireGuard tunnel between it and all other known nodes in the cluster. -Each node creates its own Curve25519 encryption key pair and distributes its public key via Kubernetes. -A node uses another node's public key to decrypt and encrypt traffic from and to Cilium-managed endpoints running on that node. -Connections are always encrypted peer-to-peer using ChaCha20 with Poly1305. -WireGuard implements forward secrecy with key rotation every 2 minutes.

-

Storage encryption

-

Constellation supports transparent encryption of persistent storage. -The Linux kernel's device mapper-based encryption features are used to encrypt the data on the block storage level. -Currently, the following primitives are used for block storage encryption:

- -

Adding primitives for integrity protection in the CVM attacker model are under active development and will be available in a future version of Constellation. -See encrypted storage for more details.

-

As a cluster administrator, when creating a cluster, you can use the Constellation installation program to select one of the following methods for key management:

-
    -
  • Constellation-managed key management
  • -
  • User-managed key management
  • -
-

Constellation-managed key management

-

Key material and key derivation

-

During the creation of a Constellation cluster, the cluster's master secret is used to derive a KEK. -This means creating two clusters with the same master secret will yield the same KEK. -Any data encryption key (DEK) is derived from the KEK via HKDF. -Note that the master secret is recommended to be unique for every cluster and shouldn't be reused (except in case of recovering a cluster).

-

State and storage

-

The KEK is derived from the master secret during the initialization. -Subsequently, all other key material is derived from the KEK. -Given the same KEK, any DEK can be derived deterministically from a given identifier. -Hence, there is no need to store DEKs. They can be derived on demand. -After the KEK was derived, it's stored in memory only and never leaves the CVM context.

-

Availability

-

Constellation-managed key management has the same availability as the underlying Kubernetes cluster. -Therefore, the KEK is stored in the distributed Kubernetes etcd storage to allow for unexpected but non-fatal (control-plane) node failure. -The etcd storage is backed by the encrypted and integrity protected state disk of the nodes.

-

Recovery

-

Constellation clusters can be recovered in the event of a disaster, even when all node machines have been stopped and need to be rebooted. -For details on the process see the recovery workflow.

-

User-managed key management

-

User-managed key management is under active development and will be available soon. -In scenarios where constellation-managed key management isn't an option, this mode allows you to keep full control of your keys. -For example, compliance requirements may force you to keep your KEKs in an on-prem key management system (KMS).

-

During the creation of a Constellation cluster, you specify a KEK present in a remote KMS. -This follows the common scheme of "bring your own key" (BYOK). -Constellation will support several KMSs for managing the storage and access of your KEK. -Initially, it will support the following KMSs:

- -

Storing the keys in Cloud KMS of AWS, Azure, or GCP binds the key usage to the particular cloud identity access management (IAM). -In the future, Constellation will support remote attestation-based access policies for Cloud KMS once available. -Note that using a Cloud KMS limits the isolation and protection to the guarantees of the particular offering.

-

KMIP support allows you to use your KMIP-compatible on-prem KMS and keep full control over your keys. -This follows the common scheme of "hold your own key" (HYOK).

-

The KEK is used to encrypt per-data "data encryption keys" (DEKs). -DEKs are generated to encrypt your data before storing it on persistent storage. -After being encrypted by the KEK, the DEKs are stored on dedicated cloud storage for persistence. -Currently, Constellation supports the following cloud storage options:

- -

The DEKs are only present in plaintext form in the encrypted main memory of the CVMs. -Similarly, the cryptographic operations for encrypting data before writing it to persistent storage are performed in the context of the CVMs.

-

Recovery and migration

-

In the case of a disaster, the KEK can be used to decrypt the DEKs locally and subsequently use them to decrypt and retrieve the data. -In case of migration, configuring the same KEK will provide seamless migration of data. -Thus, only the DEK storage needs to be transferred to the new cluster alongside the encrypted data for seamless migration.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/architecture/microservices/index.html b/pr-preview/pr-4027/2.23/architecture/microservices/index.html deleted file mode 100644 index cce1cd936..000000000 --- a/pr-preview/pr-4027/2.23/architecture/microservices/index.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - -Microservices | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Microservices

-

Constellation takes care of bootstrapping and initializing a Confidential Kubernetes cluster. -During the lifetime of the cluster, it handles day 2 operations such as key management, remote attestation, and updates. -These features are provided by several microservices:

- -

The relations between microservices are shown in the following diagram:

- -

Bootstrapper

-

The Bootstrapper is the first microservice launched after booting a Constellation node image. -It sets up that machine as a Kubernetes node and integrates that node into the Kubernetes cluster. -To this end, the Bootstrapper first downloads and verifies the Kubernetes components at the configured versions. -The Bootstrapper tries to find an existing cluster and if successful, communicates with the JoinService to join the node. -Otherwise, it waits for an initialization request to create a new Kubernetes cluster.

-

JoinService

-

The JoinService runs as DaemonSet on each control-plane node. -New nodes (at cluster start, or later through autoscaling) send a request to the service over attested TLS (aTLS). -The JoinService verifies the new node's certificate and attestation statement. -If attestation is successful, the new node is supplied with an encryption key from the KeyService for its state disk, and a Kubernetes bootstrap token.

- -

VerificationService

-

The VerificationService runs as DaemonSet on each node. -It provides user-facing functionality for remote attestation during the cluster's lifetime via an endpoint for verifying the cluster. -Read more about the hardware-based attestation feature of Constellation and how to verify a cluster on the client side.

-

KeyService

-

The KeyService runs as DaemonSet on each control-plane node. -It implements the key management for the storage encryption keys in Constellation. These keys are used for the state disk of each node and the transparently encrypted storage for Kubernetes. -Depending on wether the constellation-managed or user-managed mode is used, the KeyService holds the key encryption key (KEK) directly or calls an external key management service (KMS) for key derivation respectively.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/architecture/networking/index.html b/pr-preview/pr-4027/2.23/architecture/networking/index.html deleted file mode 100644 index d2252c8ff..000000000 --- a/pr-preview/pr-4027/2.23/architecture/networking/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -Network encryption | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Network encryption

-

Constellation encrypts all pod communication using the container network interface (CNI). -To that end, Constellation deploys, configures, and operates the Cilium CNI plugin. -Cilium provides transparent encryption for all cluster traffic using either IPSec or WireGuard. -Currently, Constellation only supports WireGuard as the encryption engine. -You can read more about the cryptographic soundness of WireGuard in their white paper.

-

Cilium is actively working on implementing a feature called host-to-host encryption mode for WireGuard. -With host-to-host, all traffic between nodes will be tunneled via WireGuard (host-to-host, host-to-pod, pod-to-host, pod-to-pod). -Until the host-to-host feature is released, Constellation enables pod-to-pod encryption. -This mode encrypts all traffic between Kubernetes pods using WireGuard tunnels.

-

When using Cilium in the default setup but with encryption enabled, there is a known issue -that can cause pod-to-pod traffic to be unencrypted. -To mitigate this issue, Constellation adds a strict mode to Cilium's pod-to-pod encryption. -This mode changes the default behavior of traffic that's destined for an unknown endpoint to not be send out in plaintext, but instead being dropped. -The strict mode distinguishes between traffic that's send to a pod from traffic that's destined for a cluster-external endpoint by considering the pod's CIDR range.

-

Traffic originating from hosts isn't encrypted yet. -This mainly includes health checks from Kubernetes API server. -Also, traffic proxied over the API server via e.g. kubectl port-forward isn't encrypted.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/architecture/observability/index.html b/pr-preview/pr-4027/2.23/architecture/observability/index.html deleted file mode 100644 index cee0be133..000000000 --- a/pr-preview/pr-4027/2.23/architecture/observability/index.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - -Observability | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Observability

-

In Kubernetes, observability is the ability to gain insight into the behavior and performance of applications. -It helps identify and resolve issues more effectively, ensuring stability and performance of Kubernetes workloads, reducing downtime and outages, and improving efficiency. -The "three pillars of observability" are logs, metrics, and traces.

-

In the context of Confidential Computing, observability is a delicate subject and needs to be applied such that it doesn't leak any sensitive information. -The following gives an overview of where and how you can apply standard observability tools in Constellation.

-

Cloud resource monitoring

-

While inaccessible, Constellation's nodes are still visible as black box VMs to the hypervisor. -Resource consumption, such as memory and CPU utilization, can be monitored from the outside and observed via the cloud platforms directly. -Similarly, other resources, such as storage and network and their respective metrics, are visible via the cloud platform.

-

Metrics

-

Metrics are numeric representations of data measured over intervals of time. They're essential for understanding system health and gaining insights using telemetry signals.

-

By default, Constellation exposes the metrics for Kubernetes system components inside the cluster. -Similarly, the etcd metrics endpoints are exposed inside the cluster. -These metrics endpoints can be disabled.

-

You can collect these cluster-internal metrics via tools such as Prometheus or the Elastic Stack.

-

Constellation's CNI Cilium also supports metrics via Prometheus endpoints. -However, in Constellation, they're disabled by default and must be enabled first.

-

Logs

-

Logs represent discrete events that usually describe what's happening with your service. -The payload is an actual message emitted from your system along with a metadata section containing a timestamp, labels, and tracking identifiers.

-

System logs

-

Detailed system-level logs are accessible via /var/log and journald on the nodes directly. -They can be collected from there, for example, via Filebeat and Logstash, which are tools of the Elastic Stack.

-

In case of an error during the initialization, the CLI automatically collects the Bootstrapper logs and returns these as a file for troubleshooting. Here is an example of such an event:

-
Cluster initialization failed. This error is not recoverable.
Terminate your cluster and try again.
Fetched bootstrapper logs are stored in "constellation-cluster.log"
-

Kubernetes logs

-

Constellation supports the Kubernetes logging architecture. -By default, logs are written to the nodes' encrypted state disks. -These include the Pod and container logs and the system component logs.

-

Constellation services run as Pods inside the kube-system namespace and use the standard container logging mechanism. -The same applies for the Cilium Pods.

-

You can collect logs from within the cluster via tools such as Fluentd, Loki, or the Elastic Stack.

-

Traces

-

Modern systems are implemented as interconnected complex and distributed microservices. Understanding request flows and system communications is challenging, mainly because all systems in a chain need to be modified to propagate tracing information. Distributed tracing is a new approach to increasing observability and understanding performance bottlenecks. A trace represents consecutive events that reflect an end-to-end request path in a distributed system.

-

Constellation supports traces for Kubernetes system components. -By default, they're disabled and need to be enabled first.

-

Similarly, Cilium can be enabled to export traces.

-

You can collect these traces via tools such as Jaeger or Zipkin.

-

Integrations

-

Platforms and SaaS solutions such as Datadog, logz.io, Dynatrace, or New Relic facilitate the observability challenge for Kubernetes and provide all-in-one SaaS solutions. -They install agents into the cluster that collect metrics, logs, and tracing information and upload them into the data lake of the platform. -Technically, the agent-based approach is compatible with Constellation, and attaching these platforms is straightforward. -However, you need to evaluate if the exported data might violate Constellation's compliance and privacy guarantees by uploading them to a third-party platform.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/architecture/orchestration/index.html b/pr-preview/pr-4027/2.23/architecture/orchestration/index.html deleted file mode 100644 index 0eb5dc194..000000000 --- a/pr-preview/pr-4027/2.23/architecture/orchestration/index.html +++ /dev/null @@ -1,80 +0,0 @@ - - - - - -Orchestrating Constellation clusters | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Orchestrating Constellation clusters

-

You can use the CLI to create a cluster on the supported cloud platforms. -The CLI provisions the resources in your cloud environment and initiates the initialization of your cluster. -It uses a set of parameters and an optional configuration file to manage your cluster installation. -The CLI is also used for updating your cluster.

-

Workspaces

-

Each Constellation cluster has an associated workspace. -The workspace is where data such as the Constellation state and config files are stored. -Each workspace is associated with a single cluster and configuration. -The CLI stores state in the local filesystem making the current directory the active workspace. -Multiple clusters require multiple workspaces, hence, multiple directories. -Note that every operation on a cluster always has to be performed from the directory associated with its workspace.

-

You may copy files from the workspace to other locations, -but you shouldn't move or delete them while the cluster is still being used. -The Constellation CLI takes care of managing the workspace. -Only when a cluster was terminated, and you are sure the files aren't needed anymore, should you remove a workspace.

-

Cluster creation process

-

To allow for fine-grained configuration of your cluster and cloud environment, Constellation supports an extensive configuration file with strong defaults. Generating the configuration file is typically the first thing you do in the workspace.

-

Altogether, the following files are generated during the creation of a Constellation cluster and stored in the current workspace:

-
    -
  • a configuration file
  • -
  • a state file
  • -
  • a Base64-encoded master secret
  • -
  • Terraform artifacts, stored in subdirectories
  • -
  • a Kubernetes kubeconfig file.
  • -
-

After the initialization of your cluster, the CLI will provide you with a Kubernetes kubeconfig file. -This file grants you access to your Kubernetes cluster and configures the kubectl tool. -In addition, the cluster's identifier is returned and stored in the state file.

-

Creation process details

-
    -
  1. The CLI apply command first creates the confidential VM (CVM) resources in your cloud environment and configures the network
  2. -
  3. Each CVM boots the Constellation node image and measures every component in the boot chain
  4. -
  5. The first microservice launched in each node is the Bootstrapper
  6. -
  7. The Bootstrapper waits until it either receives an initialization request or discovers an initialized cluster
  8. -
  9. The CLI then connects to the Bootstrapper of a selected node, sends the configuration, and initiates the initialization of the cluster
  10. -
  11. The Bootstrapper of that node initializes the Kubernetes cluster and deploys the other Constellation microservices including the JoinService
  12. -
  13. Subsequently, the Bootstrappers of the other nodes discover the initialized cluster and send join requests to the JoinService
  14. -
  15. As part of the join request each node includes an attestation statement of its boot measurements as authentication
  16. -
  17. The JoinService verifies the attestation statements and joins the nodes to the Kubernetes cluster
  18. -
  19. This process is repeated for every node joining the cluster later (e.g., through autoscaling)
  20. -
-

Post-installation configuration

-

Post-installation the CLI provides a configuration for accessing the cluster using the Kubernetes API. -The kubeconfig file provides the credentials and configuration for connecting and authenticating to the API server. -Once configured, orchestrate the Kubernetes cluster via kubectl.

-

After the initialization, the CLI will present you with a couple of tokens:

-
    -
  • The master secret (stored in the constellation-mastersecret.json file by default)
  • -
  • The clusterID of your cluster in Base64 encoding
  • -
-

You can read more about these values and their meaning in the guide on cluster identity.

-

The master secret must be kept secret and can be used to recover your cluster. -Instead of managing this secret manually, you can use your key management solution of choice with Constellation.

-

The clusterID uniquely identifies a cluster and can be used to verify your cluster.

-

Upgrades

-

Constellation images and microservices may need to be upgraded to new versions during the lifetime of a cluster. -Constellation implements a rolling update mechanism ensuring no downtime of the control or data plane. -You can upgrade a Constellation cluster with a single operation by using the CLI. -For step-by-step instructions on how to do this, refer to Upgrade your cluster.

-

Attestation of upgrades

-

With every new image, corresponding measurements are released. -During an update procedure, the CLI provides new measurements to the JoinService securely. -New measurements for an updated image are automatically pulled and verified by the CLI following the supply chain security concept of Constellation. -The attestation section describes in detail how these measurements are then used by the JoinService for the attestation of nodes.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/architecture/overview/index.html b/pr-preview/pr-4027/2.23/architecture/overview/index.html deleted file mode 100644 index b59e0f28b..000000000 --- a/pr-preview/pr-4027/2.23/architecture/overview/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - -Overview | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Overview

-

Constellation is a cloud-based confidential orchestration platform. -The foundation of Constellation is Kubernetes and therefore shares the same technology stack and architecture principles. -To learn more about Constellation and Kubernetes, see product overview.

-

About orchestration and updates

-

As a cluster administrator, you can use the Constellation CLI to install and deploy a cluster. -Updates are provided in accordance with the support policy.

-

About microservices and attestation

-

Constellation manages the nodes and network in your cluster. All nodes are bootstrapped by the Bootstrapper. They're verified and authenticated by the JoinService before being added to the cluster and the network. Finally, the entire cluster can be verified via the VerificationService using remote attestation.

-

About node images and verified boot

-

Constellation comes with operating system images for Kubernetes control-plane and worker nodes. -They're highly optimized for running containerized workloads and specifically prepared for running inside confidential VMs. -You can learn more about the images and how verified boot ensures their integrity during boot and beyond.

-

About key management and cryptographic primitives

-

Encryption of data at-rest, in-transit, and in-use is the fundamental building block for confidential computing and Constellation. Learn more about the keys and cryptographic primitives used in Constellation, encrypted persistent storage, and network encryption.

-

About observability

-

Observability in Kubernetes refers to the capability to troubleshoot issues using telemetry signals such as logs, metrics, and traces. -In the realm of Confidential Computing, it's crucial that observability aligns with confidentiality, necessitating careful implementation. -Learn more about the observability capabilities in Constellation.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/architecture/versions/index.html b/pr-preview/pr-4027/2.23/architecture/versions/index.html deleted file mode 100644 index 822d8b4c1..000000000 --- a/pr-preview/pr-4027/2.23/architecture/versions/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - -Versions and support policy | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Versions and support policy

-

All components of Constellation use a three-digit version number of the form v<MAJOR>.<MINOR>.<PATCH>. -The components are released in lock step, usually on the first Tuesday of every month. This release primarily introduces new features, but may also include security or performance improvements. The MINOR version will be incremented as part of this release.

-

Additional PATCH releases may be created on demand, to fix security issues or bugs before the next MINOR release window.

-

New releases are published on GitHub.

-

Kubernetes support policy

-

Constellation is aligned to the version support policy of Kubernetes, and therefore usually supports the most recent three minor versions. -When a new minor version of Kubernetes is released, support is added to the next Constellation release, and that version then supports four Kubernetes versions. -Subsequent Constellation releases drop support for the oldest (and deprecated) Kubernetes version.

-

The following Kubernetes versions are currently supported:

-
    -
  • v1.29.15
  • -
  • v1.30.12
  • -
  • v1.31.8
  • -
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/category/architecture/index.html b/pr-preview/pr-4027/2.23/category/architecture/index.html deleted file mode 100644 index 71898a400..000000000 --- a/pr-preview/pr-4027/2.23/category/architecture/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Architecture | Constellation - - - - - - - -
Skip to main content
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/category/basics/index.html b/pr-preview/pr-4027/2.23/category/basics/index.html deleted file mode 100644 index 4f8d658b3..000000000 --- a/pr-preview/pr-4027/2.23/category/basics/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Basics | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Basics

📄️ Security benefits

Constellation implements the Confidential Kubernetes concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be verified.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/category/getting-started/index.html b/pr-preview/pr-4027/2.23/category/getting-started/index.html deleted file mode 100644 index 865920980..000000000 --- a/pr-preview/pr-4027/2.23/category/getting-started/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Getting started | Constellation - - - - - - - -
Skip to main content
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/category/reference/index.html b/pr-preview/pr-4027/2.23/category/reference/index.html deleted file mode 100644 index 28c4b8373..000000000 --- a/pr-preview/pr-4027/2.23/category/reference/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Reference | Constellation - - - - - - - -
Skip to main content
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/category/workflows/index.html b/pr-preview/pr-4027/2.23/category/workflows/index.html deleted file mode 100644 index 09981047b..000000000 --- a/pr-preview/pr-4027/2.23/category/workflows/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Workflows | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Workflows

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/getting-started/examples/emojivoto/index.html b/pr-preview/pr-4027/2.23/getting-started/examples/emojivoto/index.html deleted file mode 100644 index d48da9a5a..000000000 --- a/pr-preview/pr-4027/2.23/getting-started/examples/emojivoto/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - -Emojivoto | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Emojivoto

-

Emojivoto is a simple and fun application that's well suited to test the basic functionality of your cluster.

-emojivoto - Web UI -
    -
  1. Deploy the application: -
    kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment
    -
  2. -
  3. Wait until it becomes available: -
    kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments
    -
  4. -
  5. Forward the web service to your machine: -
    kubectl -n emojivoto port-forward svc/web-svc 8080:80
    -
  6. -
  7. Visit http://localhost:8080
  8. -
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/getting-started/examples/filestash-s3proxy/index.html b/pr-preview/pr-4027/2.23/getting-started/examples/filestash-s3proxy/index.html deleted file mode 100644 index 3e79b5770..000000000 --- a/pr-preview/pr-4027/2.23/getting-started/examples/filestash-s3proxy/index.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - -Deploying Filestash | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Deploying Filestash

-

Filestash is a web frontend for different storage backends, including S3. -It's a useful application to showcase s3proxy in action.

-
    -
  1. Deploy s3proxy as described in Deployment.
  2. -
  3. Create a deployment file for Filestash with one pod:
  4. -
-
cat << EOF > "deployment-filestash.yaml"
apiVersion: apps/v1
kind: Deployment
metadata:
name: filestash
spec:
replicas: 1
selector:
matchLabels:
app: filestash
template:
metadata:
labels:
app: filestash
spec:
hostAliases:
- ip: $(kubectl get svc s3proxy-service -o=jsonpath='{.spec.clusterIP}')
hostnames:
- "s3.us-east-1.amazonaws.com"
- "s3.us-east-2.amazonaws.com"
- "s3.us-west-1.amazonaws.com"
- "s3.us-west-2.amazonaws.com"
- "s3.eu-north-1.amazonaws.com"
- "s3.eu-south-1.amazonaws.com"
- "s3.eu-south-2.amazonaws.com"
- "s3.eu-west-1.amazonaws.com"
- "s3.eu-west-2.amazonaws.com"
- "s3.eu-west-3.amazonaws.com"
- "s3.eu-central-1.amazonaws.com"
- "s3.eu-central-2.amazonaws.com"
- "s3.ap-northeast-1.amazonaws.com"
- "s3.ap-northeast-2.amazonaws.com"
- "s3.ap-northeast-3.amazonaws.com"
- "s3.ap-east-1.amazonaws.com"
- "s3.ap-southeast-1.amazonaws.com"
- "s3.ap-southeast-2.amazonaws.com"
- "s3.ap-southeast-3.amazonaws.com"
- "s3.ap-southeast-4.amazonaws.com"
- "s3.ap-south-1.amazonaws.com"
- "s3.ap-south-2.amazonaws.com"
- "s3.me-south-1.amazonaws.com"
- "s3.me-central-1.amazonaws.com"
- "s3.il-central-1.amazonaws.com"
- "s3.af-south-1.amazonaws.com"
- "s3.ca-central-1.amazonaws.com"
- "s3.sa-east-1.amazonaws.com"
containers:
- name: filestash
image: machines/filestash:latest
ports:
- containerPort: 8334
volumeMounts:
- name: ca-cert
mountPath: /etc/ssl/certs/kube-ca.crt
subPath: kube-ca.crt
volumes:
- name: ca-cert
secret:
secretName: s3proxy-tls
items:
- key: ca.crt
path: kube-ca.crt
EOF
-

The pod spec includes the hostAliases key, which adds an entry to the pod's /etc/hosts. -The entry forwards all requests for any of the currently defined AWS regions to the Kubernetes service s3proxy-service. -If you followed the s3proxy Deployment guide, this service points to a s3proxy pod.

-

The deployment specifies all regions explicitly to prevent accidental data leaks. -If one of your buckets were located in a region that's not part of the hostAliases key, traffic towards those buckets would not be redirected to s3proxy. -Similarly, if you want to exclude data for specific regions from going through s3proxy you can remove those regions from the deployment.

-

The spec also includes a volume mount for the TLS certificate and adds it to the pod's certificate trust store. -The volume is called ca-cert. -The key ca.crt of that volume is mounted to /etc/ssl/certs/kube-ca.crt, which is the default certificate trust store location for that container's OpenSSL library. -Not adding the CA certificate will result in TLS authentication errors.

-
    -
  1. Apply the file: kubectl apply -f deployment-filestash.yaml
  2. -
-

Afterward, you can use a port forward to access the Filestash pod: -kubectl port-forward pod/$(kubectl get pod --selector='app=filestash' -o=jsonpath='{.items[*].metadata.name}') 8334:8334

-
    -
  1. -

    After browsing to localhost:8443, Filestash will ask you to set an administrator password. -After setting it, you can directly leave the admin area by clicking the blue cloud symbol in the top left corner. -Subsequently, you can select S3 as storage backend and enter your credentials. -This will bring you to an overview of your buckets. -If you want to deploy Filestash in production, take a look at its documentation.

    -
  2. -
  3. -

    To see the logs of s3proxy intercepting requests made to S3, run: kubectl logs -f pod/$(kubectl get pod --selector='app=s3proxy' -o=jsonpath='{.items[*].metadata.name}') -Look out for log messages labeled intercepting. -There is one such log message for each message that's encrypted, decrypted, or blocked.

    -
  4. -
  5. -

    Once you have uploaded a file with Filestash, you should be able to view the file in Filestash. -However, if you go to the AWS S3 Web UI and download the file you just uploaded in Filestash, you won't be able to read it. -Another way to spot encrypted files without downloading them is to click on a file, scroll to the Metadata section, and look for the header named x-amz-meta-constellation-encryption. -This header holds the encrypted data encryption key of the object and is only present on objects that are encrypted by s3proxy.

    -
  6. -
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/getting-started/examples/horizontal-scaling/index.html b/pr-preview/pr-4027/2.23/getting-started/examples/horizontal-scaling/index.html deleted file mode 100644 index 186a07fa2..000000000 --- a/pr-preview/pr-4027/2.23/getting-started/examples/horizontal-scaling/index.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - -Horizontal Pod Autoscaling | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Horizontal Pod Autoscaling

-

This example demonstrates Constellation's autoscaling capabilities. It's based on the Kubernetes HorizontalPodAutoscaler Walkthrough. During the following steps, Constellation will spawn new VMs on demand, verify them, add them to the cluster, and delete them again when the load has settled down.

-

Requirements

-

The cluster needs to be initialized with Kubernetes 1.23 or later. In addition, autoscaling must be enabled to enable Constellation to assign new nodes dynamically.

-

Just for this example specifically, the cluster should have as few worker nodes in the beginning as possible. Start with a small cluster with only one low-powered node for the control-plane node and one low-powered worker node.

-
info

We tested the example using instances of types Standard_DC4as_v5 on Azure and n2d-standard-4 on GCP.

-

Setup

-
    -
  1. -

    Install the Kubernetes Metrics Server:

    -
    kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
    -
  2. -
  3. -

    Deploy the HPA example server that's supposed to be scaled under load.

    -

    This manifest is similar to the one from the Kubernetes HPA walkthrough, but with increased CPU limits and requests to facilitate the triggering of node scaling events.

    -
    cat <<EOF | kubectl apply -f -
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: php-apache
    spec:
    selector:
    matchLabels:
    run: php-apache
    replicas: 1
    template:
    metadata:
    labels:
    run: php-apache
    spec:
    containers:
    - name: php-apache
    image: registry.k8s.io/hpa-example
    ports:
    - containerPort: 80
    resources:
    limits:
    cpu: 900m
    requests:
    cpu: 600m
    ---
    apiVersion: v1
    kind: Service
    metadata:
    name: php-apache
    labels:
    run: php-apache
    spec:
    ports:
    - port: 80
    selector:
    run: php-apache
    EOF
    -
  4. -
  5. -

    Create a HorizontalPodAutoscaler.

    -

    Set an average CPU usage across all Pods of 20% to see one additional worker node being created later. Note that the CPU usage isn't related to the host CPU usage, but rather to the requested CPU capacities (20% of 600 milli-cores CPU across all Pods). See the original tutorial for more information on the HPA configuration.

    -
    kubectl autoscale deployment php-apache --cpu-percent=20 --min=1 --max=10
    -
  6. -
  7. -

    Create a Pod that generates load on the server:

    -
    kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while true; do wget -q -O- http://php-apache; done"
    -
  8. -
  9. -

    Wait a few minutes until new nodes are added to the cluster. You can monitor the state of the HorizontalPodAutoscaler, the list of nodes, and the behavior of the autoscaler.

    -
  10. -
  11. -

    To stop the load generator, press CTRL+C and run:

    -
    kubectl delete pod load-generator
    -
  12. -
  13. -

    The cluster-autoscaler checks every few minutes if nodes are underutilized. It will taint such candidates for removal and wait additional 10 minutes before the nodes are eventually removed and deallocated. The whole process can take about 20 minutes.

    -
  14. -
-

Monitoring

-
tip

For better observability, run the listed commands in different tabs in your terminal.

-

You can watch the status of the HorizontalPodAutoscaler with the current CPU usage, the target CPU limit, and the number of replicas created with:

-
kubectl get hpa php-apache --watch
-

From time to time compare the list of nodes to check the behavior of the autoscaler:

-
kubectl get nodes
-

For deeper insights, see the logs of the autoscaler Pod, which contains more details about the scaling decision process:

-
kubectl logs -f deployment/constellation-cluster-autoscaler -n kube-system
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/getting-started/examples/index.html b/pr-preview/pr-4027/2.23/getting-started/examples/index.html deleted file mode 100644 index 1c12ab082..000000000 --- a/pr-preview/pr-4027/2.23/getting-started/examples/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - -Examples | Constellation - - - - - - - -
Skip to main content
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/getting-started/examples/online-boutique/index.html b/pr-preview/pr-4027/2.23/getting-started/examples/online-boutique/index.html deleted file mode 100644 index ca823e2dd..000000000 --- a/pr-preview/pr-4027/2.23/getting-started/examples/online-boutique/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -Online Boutique | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Online Boutique

-

Online Boutique is an e-commerce demo application by Google consisting of 11 separate microservices. In this demo, Constellation automatically sets up a load balancer on your CSP, making it easy to expose services from your confidential cluster.

-Online Boutique - Web UI -
    -
  1. Create a namespace: -
    kubectl create ns boutique
    -
  2. -
  3. Deploy the application: -
    kubectl apply -n boutique -f https://github.com/GoogleCloudPlatform/microservices-demo/raw/main/release/kubernetes-manifests.yaml
    -
  4. -
  5. Wait for all services to become available: -
    kubectl wait --for=condition=available --timeout=300s -n boutique --all deployments
    -
  6. -
  7. Get the frontend's external IP address: -
    $ kubectl get service frontend-external -n boutique | awk '{print $4}'
    EXTERNAL-IP
    <your-ip>
    -(<your-ip> is a placeholder for the IP assigned by your CSP.)
  8. -
  9. Enter the IP from the result in your browser to browse the online shop.
  10. -
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/getting-started/first-steps-local/index.html b/pr-preview/pr-4027/2.23/getting-started/first-steps-local/index.html deleted file mode 100644 index 4df5c6dbe..000000000 --- a/pr-preview/pr-4027/2.23/getting-started/first-steps-local/index.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - - -First steps with a local cluster | Constellation - - - - - - - -
Skip to main content
Version: 2.23

First steps with a local cluster

-

A local cluster lets you deploy and test Constellation without a cloud subscription. -You have two options:

-
    -
  • Use MiniConstellation to automatically deploy a two-node cluster.
  • -
  • For more fine-grained control, create the cluster using the QEMU provider.
  • -
-

Both options use virtualization to create a local cluster with control-plane nodes and worker nodes. They don't require hardware with Confidential VM (CVM) support. For attestation, they currently use a software-based vTPM provided by KVM/QEMU.

-

You need an x64 machine with a Linux OS. -You can use a VM, but it needs nested virtualization.

-

Prerequisites

-
    -
  • Machine requirements: -
      -
    • An x86-64 CPU with at least 4 cores (6 cores are recommended)
    • -
    • At least 4 GB RAM (6 GB are recommended)
    • -
    • 20 GB of free disk space
    • -
    • Hardware virtualization enabled in the BIOS/UEFI (often referred to as Intel VT-x or AMD-V/SVM) / nested-virtualization support when using a VM
    • -
    -
  • -
  • Software requirements: - -
  • -
-

Software installation on Ubuntu

-
# install Docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce
# install other dependencies
sudo apt install xsltproc
sudo snap install kubectl --classic
# install Constellation CLI
curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-amd64
sudo install constellation-linux-amd64 /usr/local/bin/constellation
# do not drop forwarded packages
sudo iptables -P FORWARD ACCEPT
-

Create a cluster

-

With the constellation mini command, you can deploy and test Constellation locally. This mode is called MiniConstellation. Conceptually, MiniConstellation is similar to MicroK8s, K3s, and minikube.

caution

MiniConstellation has specific soft- and hardware requirements such as a Linux OS running on an x86-64 CPU. Pay attention to all prerequisites when setting up.

note

Since MiniConstellation runs on your local system, cloud features such as load balancing, -attaching persistent storage, or autoscaling aren't available.

The following creates your MiniConstellation cluster (may take up to 10 minutes to complete):

constellation mini up

This will configure your current directory as the workspace for this cluster. -All constellation commands concerning this cluster need to be issued from this directory.

-

Connect to the cluster

-

Your cluster initially consists of a single control-plane node:

-
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
control-plane-0 Ready control-plane 66s v1.24.6
-

Additional nodes will request to join the cluster shortly. Before each additional node is allowed to join the cluster, its state is verified using remote attestation by the JoinService. -If verification passes successfully, the new node receives keys and certificates to join the cluster.

-

You can follow this process by viewing the logs of the JoinService:

-
$ kubectl logs -n kube-system daemonsets/join-service -f
{"level":"INFO","ts":"2022-10-14T09:32:20Z","caller":"cmd/main.go:48","msg":"Constellation Node Join Service","version":"2.1.0","cloudProvider":"qemu"}
{"level":"INFO","ts":"2022-10-14T09:32:20Z","logger":"validator","caller":"watcher/validator.go:96","msg":"Updating expected measurements"}
...
-

Once all nodes have joined your cluster, it may take a couple of minutes for all resources to become available. -You can check on the state of your cluster by running the following:

-
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
control-plane-0 Ready control-plane 2m59s v1.24.6
worker-0 Ready <none> 32s v1.24.6
-

Deploy a sample application

-
    -
  1. Deploy the emojivoto app
  2. -
-
kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment
-
    -
  1. Expose the frontend service locally
  2. -
-
kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments
kubectl -n emojivoto port-forward svc/web-svc 8080:80 &
curl http://localhost:8080
kill %1
-

Terminate your cluster

-

Once you are done, you can clean up the created resources using the following command:

constellation mini down

This will destroy your cluster and clean up your workspace. -The VM image and cluster configuration file (constellation-conf.yaml) will be kept and may be reused to create new clusters.

-

Troubleshooting

-

Make sure to use the latest release and check out the known issues.

-

VMs have no internet access / CLI remains in "Initializing cluster" state

-

iptables rules may prevent your VMs from accessing the internet. -Make sure your rules aren't dropping forwarded packages.

-

List your rules:

-
sudo iptables -S
-

The output may look similar to the following:

-
-P INPUT ACCEPT
-P FORWARD DROP
-P OUTPUT ACCEPT
-N DOCKER
-N DOCKER-ISOLATION-STAGE-1
-N DOCKER-ISOLATION-STAGE-2
-N DOCKER-USER
-

If your FORWARD chain is set to DROP, you need to update your rules:

-
sudo iptables -P FORWARD ACCEPT
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/getting-started/first-steps/index.html b/pr-preview/pr-4027/2.23/getting-started/first-steps/index.html deleted file mode 100644 index ac1c69217..000000000 --- a/pr-preview/pr-4027/2.23/getting-started/first-steps/index.html +++ /dev/null @@ -1,90 +0,0 @@ - - - - - -First steps with Constellation | Constellation - - - - - - - -
Skip to main content
Version: 2.23

First steps with Constellation

-

The following steps guide you through the process of creating a cluster and deploying a sample app. This example assumes that you have successfully installed and set up Constellation, -and have access to a cloud subscription.

-
tip

If you don't have a cloud subscription, you can also set up a local Constellation cluster using virtualization for testing.

-
note

If you encounter any problem with the following steps, make sure to use the latest release and check out the known issues.

-

Create a cluster

-
    -
  1. -

    Create the configuration file and state file for your cloud provider. If you are following the steps of this guide, there is no need to edit the file.

    -
    constellation config generate aws
    -
  2. -
  3. -

    Create your IAM configuration.

    -
    constellation iam create aws --zone=us-east-2a --prefix=constellTest --update-config

    This command creates IAM configuration for the AWS zone us-east-2a using the prefix constellTest for all named resources being created. It also updates the configuration file constellation-conf.yaml in your current directory with the IAM values filled in.

    Depending on the attestation variant selected on config generation, different regions are available. -AMD SEV-SNP machines (requires the default attestation variant awsSEVSNP) are currently available in the following regions:

      -
    • eu-west-1
    • -
    • us-east-2
    • -

    You can find a list of regions that support AMD SEV-SNP in AWS's documentation.

    NitroTPM machines (requires the attestation variant awsNitroTPM) are available in all regions. -Constellation OS images are currently replicated to the following regions:

      -
    • eu-central-1
    • -
    • eu-west-1
    • -
    • eu-west-3
    • -
    • us-east-2
    • -
    • ap-south-1
    • -

    If you require the OS image to be available in another region, let us know.

    You can find a list of all regions in AWS's documentation.

    -
    tip

    To learn about all options you have for managing IAM resources and Constellation configuration, see the Configuration workflow.

    -
  4. -
-
    -
  1. -

    Create the cluster. constellation apply uses options set in constellation-conf.yaml. -If you want to manually manage your cloud resources, for example by using Terraform, follow the corresponding instructions in the Create workflow.

    -
    tip

    On Azure, you may need to wait 15+ minutes at this point for role assignments to propagate.

    -
    constellation apply -y
    -

    This should look similar to the following:

    -
    $ constellation apply -y
    Checking for infrastructure changes
    The following Constellation cluster will be created:
    3 control-plane nodes of type n2d-standard-4 will be created.
    1 worker node of type n2d-standard-4 will be created.
    Creating
    Cloud infrastructure created successfully
    Your Constellation master secret was successfully written to ./constellation-mastersecret.json
    Connecting
    Initializing cluster
    Installing Kubernetes components
    Your Constellation cluster was successfully initialized.

    Constellation cluster identifier g6iMP5wRU1b7mpOz2WEISlIYSfdAhB0oNaOg6XEwKFY=
    Kubernetes configuration constellation-admin.conf

    You can now connect to your cluster by executing:
    export KUBECONFIG="$PWD/constellation-admin.conf"
    -

    The cluster's identifier will be different in your output. -Keep constellation-mastersecret.json somewhere safe. -This will allow you to recover your cluster in case of a disaster.

    -
    info

    Depending on your CSP and region, constellation apply may take 10+ minutes to complete.

    -
  2. -
  3. -

    Configure kubectl.

    -
    export KUBECONFIG="$PWD/constellation-admin.conf"
    -
  4. -
-

Deploy a sample application

-
    -
  1. -

    Deploy the emojivoto app

    -
    kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment
    -
  2. -
  3. -

    Expose the frontend service locally

    -
    kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments
    kubectl -n emojivoto port-forward svc/web-svc 8080:80 &
    curl http://localhost:8080
    kill %1
    -
  4. -
-

Terminate your cluster

-

Use the CLI to terminate your cluster. If you manually used Terraform to manage your cloud resources, follow the corresponding instructions in the Terminate workflow.

-
constellation terminate
-

This should give the following output:

-
$ constellation terminate
You are about to terminate a Constellation cluster.
All of its associated resources will be DESTROYED.
This action is irreversible and ALL DATA WILL BE LOST.
Do you want to continue? [y/n]:
-

Confirm with y to terminate the cluster:

-
Terminating ...
Your Constellation cluster was terminated successfully.
-

Optionally, you can also delete your IAM resources.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/getting-started/install/index.html b/pr-preview/pr-4027/2.23/getting-started/install/index.html deleted file mode 100644 index ce1e94f17..000000000 --- a/pr-preview/pr-4027/2.23/getting-started/install/index.html +++ /dev/null @@ -1,239 +0,0 @@ - - - - - -Installation and setup | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Installation and setup

-

Constellation runs entirely in your cloud environment and can be controlled via a dedicated command-line interface (CLI) or a Terraform provider.

-

Prerequisites

-

Make sure the following requirements are met:

-
    -
  • Your machine is running Linux, macOS, or Windows
  • -
  • You have admin rights on your machine
  • -
  • kubectl is installed
  • -
  • Your CSP is Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), or STACKIT
  • -
-

Install the Constellation CLI

-
tip

If you prefer to use Terraform, you can alternatively use the Terraform provider to manage the cluster's lifecycle.

-

The CLI executable is available at GitHub. -Install it with the following commands:

-
    -
  1. Download the CLI:
  2. -
curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-amd64
    -
  1. -

    Verify the signature (optional)

    -
  2. -
  3. -

    Install the CLI to your PATH:

    -
  4. -
sudo install constellation-linux-amd64 /usr/local/bin/constellation
-
tip

The CLI supports autocompletion for various shells. To set it up, run constellation completion and follow the given steps.

-

Set up cloud credentials

-

Constellation makes authenticated calls to the CSP API. Therefore, you need to set up Constellation with the credentials for your CSP.

-
tip

If you don't have a cloud subscription, you can also set up a local Constellation cluster using virtualization for testing.

-

Required permissions

-

To set up a Constellation cluster, you need to perform two tasks that require permissions: create the infrastructure and create roles for cluster nodes. Both of these actions can be performed by different users, e.g., an administrator to create roles and a DevOps engineer to create the infrastructure.

To create the IAM configuration for Constellation, you need the following permissions:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeAccountAttributes",
"iam:AddRoleToInstanceProfile",
"iam:AttachRolePolicy",
"iam:CreateInstanceProfile",
"iam:CreatePolicy",
"iam:CreateRole",
"iam:DeleteInstanceProfile",
"iam:DeletePolicy",
"iam:DeletePolicyVersion",
"iam:DeleteRole",
"iam:DetachRolePolicy",
"iam:GetInstanceProfile",
"iam:GetPolicy",
"iam:GetPolicyVersion",
"iam:GetRole",
"iam:ListAttachedRolePolicies",
"iam:ListInstanceProfilesForRole",
"iam:ListPolicyVersions",
"iam:ListRolePolicies",
"iam:PassRole",
"iam:RemoveRoleFromInstanceProfile",
"sts:GetCallerIdentity"
],
"Resource": "*"
}
]
}

The built-in AdministratorAccess policy is a superset of these permissions.

To create a Constellation cluster, see the permissions of main.tf.

The built-in PowerUserAccess policy is a superset of these permissions.

Follow Amazon's guide on understanding and managing policies.

-

Authentication

-

You need to authenticate with your CSP. The following lists the required steps for testing and production environments.

-
note

The steps for a testing environment are simpler. However, they may expose secrets to the CSP. If in doubt, follow the production steps.

-

Testing

You can use the AWS CloudShell. Make sure you are authorized to use it.

Production

Use the latest version of the AWS CLI on a trusted machine:

aws configure

Options and first steps are described in the AWS CLI documentation.

-

Next steps

-

You are now ready to deploy your first confidential Kubernetes cluster and application.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/getting-started/marketplaces/index.html b/pr-preview/pr-4027/2.23/getting-started/marketplaces/index.html deleted file mode 100644 index 8d5aa43cc..000000000 --- a/pr-preview/pr-4027/2.23/getting-started/marketplaces/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - -Using Constellation via Cloud Marketplaces | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Using Constellation via Cloud Marketplaces

-

Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please contact us.

-

This document explains how to run Constellation with the dynamically billed cloud marketplace images.

-

To use Constellation's marketplace images, ensure that you are subscribed to the marketplace offering through the web portal.

Then, enable the use of marketplace images in your Constellation constellation-conf.yaml config file:

yq eval -i ".provider.aws.useMarketplaceImage = true" constellation-conf.yaml
-

Ensure that the cluster uses an official release image version (i.e., .image=vX.Y.Z in the constellation-conf.yaml file).

-

From there, you can proceed with the cluster creation as usual.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/index.html b/pr-preview/pr-4027/2.23/index.html deleted file mode 100644 index b89a8aa7c..000000000 --- a/pr-preview/pr-4027/2.23/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -Introduction | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Introduction

-

Welcome to the documentation of Constellation! Constellation is a Kubernetes engine that aims to provide the best possible data security.

-

Constellation concept

-

Constellation shields your entire Kubernetes cluster from the underlying cloud infrastructure. Everything inside is always encrypted, including at runtime in memory. For this, Constellation leverages a technology called confidential computing and more specifically Confidential VMs.

-
tip

See the 📄whitepaper for more information on confidential computing.

-

Goals

-

From a security perspective, Constellation is designed to keep all data always encrypted and to prevent any access from the underlying (cloud) infrastructure. This includes access from datacenter employees, privileged cloud admins, and attackers coming through the infrastructure. Such attackers could be malicious co-tenants escalating their privileges or hackers who managed to compromise a cloud server.

-

From a DevOps perspective, Constellation is designed to work just like what you would expect from a modern Kubernetes engine.

-

Use cases

-

Constellation provides unique security features and benefits. The core use cases are:

-
    -
  • Increasing the overall security of your clusters
  • -
  • Increasing the trustworthiness of your SaaS offerings
  • -
  • Moving sensitive workloads from on-prem to the cloud
  • -
  • Meeting regulatory requirements
  • -
-

Next steps

-

You can learn more about the concept of Confidential Kubernetes, features, security benefits, and performance of Constellation in the Basics section. To jump right into the action head to Getting started.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/overview/clouds/index.html b/pr-preview/pr-4027/2.23/overview/clouds/index.html deleted file mode 100644 index b570f80e8..000000000 --- a/pr-preview/pr-4027/2.23/overview/clouds/index.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - -Feature status of clouds | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Feature status of clouds

-

What works on which cloud? Currently, Confidential VMs (CVMs) are available in varying quality on the different clouds and software stacks.

-

For Constellation, the ideal environment provides the following:

-
    -
  1. Ability to run arbitrary software and images inside CVMs
  2. -
  3. CVMs based on AMD SEV-SNP (available in EPYC CPUs since the Milan generation) or Intel TDX (available in Xeon CPUs since the Sapphire Rapids generation)
  4. -
  5. Ability for CVM guests to obtain raw hardware attestation statements
  6. -
  7. Reviewable, open-source firmware inside CVMs
  8. -
  9. Capability of the firmware to attest the integrity of the code it passes control to, e.g., with an embedded virtual TPM (vTPM)
  10. -
-

(1) is a functional must-have. (2)--(5) are required for remote attestation that fully keeps the infrastructure/cloud out. Constellation can work without them or with approximations, but won't protect against certain privileged attackers anymore.

-

The following table summarizes the state of features for different infrastructures.

-
FeatureAWSAzureGCPSTACKITOpenStack (Yoga)
1. Custom imagesYesYesYesYesYes
2. SEV-SNP or TDXYesYesYesNoDepends on kernel/HV
3. Raw guest attestationYesYesYesNoDepends on kernel/HV
4. Reviewable firmwareYesNo*NoNoDepends on kernel/HV
5. Confidential measured bootNoYesNoNoDepends on kernel/HV
-

Amazon Web Services (AWS)

-

Amazon EC2 supports AMD SEV-SNP. -Regarding (3), AWS provides direct access to attestation statements. -However, regarding (5), attestation is partially based on the NitroTPM for measured boot, which is a vTPM managed by the Nitro hypervisor. -Hence, the hypervisor is currently part of Constellation's TCB. -Regarding (4), the firmware is open source and can be reproducibly built.

-

Microsoft Azure

-

With its CVM offering, Azure provides the best foundations for Constellation. -Regarding (3), Azure provides direct access to attestation statements. -The firmware runs in an isolated domain inside the CVM and exposes a vTPM (5), but it's closed source (4). -On SEV-SNP, Azure uses VM Privilege Level (VMPL) isolation for the separation of firmware and the rest of the VM; on TDX, they use TD partitioning. -This firmware is signed by Azure. -The signature is reflected in the attestation statements of CVMs. -Thus, the Azure closed-source firmware becomes part of Constellation's trusted computing base (TCB).

-

* Recently, Azure announced the open source paravisor OpenHCL. It's the foundation for fully open source and verifiable CVM firmware. Once Azure provides their CVM firmware with reproducible builds based on OpenHCL, (4) switches from No to Yes. Constellation will support OpenHCL based firmware on Azure in the future.

-

Google Cloud Platform (GCP)

-

The CVMs Generally Available in GCP are based on AMD SEV-ES or SEV-SNP. -Regarding (3), with their SEV-SNP offering Google provides direct access to attestation statements. -However, regarding (5), attestation is partially based on the Shielded VM vTPM for measured boot, which is a vTPM managed by Google's hypervisor. -Hence, the hypervisor is currently part of Constellation's TCB. -Regarding (4), the CVMs still include closed-source firmware.

-

TDX on Google is in public preview. -With it, Constellation would have a similar TCB and attestation flow as with the current SEV-SNP offering.

-

STACKIT

-

STACKIT Compute Engine supports AMD SEV-ES. A vTPM is used for measured boot, which is a vTPM managed by STACKIT's hypervisor. Hence, the hypervisor is currently part of Constellation's TCB.

-

OpenStack

-

OpenStack is an open-source cloud and infrastructure management software. It's used by many smaller CSPs and datacenters. In the latest Yoga version, OpenStack has basic support for CVMs. However, much depends on the employed kernel and hypervisor. Features (2)--(4) are likely to be a Yes with Linux kernel version 6.2. Thus, going forward, OpenStack on corresponding AMD or Intel hardware will be a viable underpinning for Constellation.

-

Conclusion

-

The different clouds and software like the Linux kernel and OpenStack are in the process of building out their support for state-of-the-art CVMs. Azure has already most features in place. For Constellation, the status quo means that the TCB has different shapes on different infrastructures. With broad SEV-SNP support coming to the Linux kernel, we soon expect a normalization of features across infrastructures.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/overview/confidential-kubernetes/index.html b/pr-preview/pr-4027/2.23/overview/confidential-kubernetes/index.html deleted file mode 100644 index 9b87636e8..000000000 --- a/pr-preview/pr-4027/2.23/overview/confidential-kubernetes/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - -Confidential Kubernetes | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Confidential Kubernetes

-

We use the term Confidential Kubernetes to refer to the concept of using confidential-computing technology to shield entire Kubernetes clusters from the infrastructure. The three defining properties of this concept are:

-
    -
  1. Workload shielding: the confidentiality and integrity of all workload-related data and code are enforced.
  2. -
  3. Control plane shielding: the confidentiality and integrity of the cluster's control plane, state, and workload configuration are enforced.
  4. -
  5. Attestation and verifiability: the two properties above can be verified remotely based on hardware-rooted cryptographic certificates.
  6. -
-

Each of the above properties is equally important. Only with all three in conjunction, an entire cluster can be shielded without gaps.

-

Constellation security features

-

Constellation implements the Confidential Kubernetes concept with the following security features.

-
    -
  • Runtime encryption: Constellation runs all Kubernetes nodes inside Confidential VMs (CVMs). This gives runtime encryption for the entire cluster.
  • -
  • Network and storage encryption: Constellation augments this with transparent encryption of the network, persistent storage, and other managed storage like AWS S3. Thus, workloads and control plane are truly end-to-end encrypted: at rest, in transit, and at runtime.
  • -
  • Transparent key management: Constellation manages the corresponding cryptographic keys inside CVMs.
  • -
  • Node attestation and verification: Constellation verifies the integrity of each new CVM-based node using remote attestation. Only "good" nodes receive the cryptographic keys required to access the network and storage of a cluster.
  • -
  • Confidential computing-optimized images: A node is "good" if it's running a signed Constellation node image inside a CVM and is in the expected state. (Node images are hardware-measured during boot. The measurements are reflected in the attestation statements that are produced by nodes and verified by Constellation.)
  • -
  • "Whole cluster" attestation: Towards the DevOps engineer, Constellation provides a single hardware-rooted certificate from which all of the above can be verified.
  • -
-

With the above, Constellation wraps an entire cluster into one coherent and verifiable confidential context. The concept is depicted in the following.

-

Confidential Kubernetes

-

Comparison: Managed Kubernetes with CVMs

-

In comparison, managed Kubernetes with CVMs, as it's for example offered in AKS and GKE, only provides runtime encryption for certain worker nodes. Here, each worker node is a separate (and typically unverified) confidential context. This only provides limited security benefits as it only prevents direct access to a worker node's memory. The large majority of potential attacks through the infrastructure remain unaffected. This includes attacks through the control plane, access to external key management, and the corruption of worker node images. This leaves many problems unsolved. For instance, Node A has no means to verify if Node B is "good" and if it's OK to share data with it. Consequently, this approach leaves a large attack surface, as is depicted in the following.

-

Concept: Managed Kubernetes plus CVMs

-

The following table highlights the key differences in terms of features.

-
Managed Kubernetes with CVMsConfidential Kubernetes (Constellation✨)
Runtime encryptionPartial (data plane only)Yes
Node image verificationNoYes
Full cluster attestationNoYes
Transparent network encryptionNoYes
Transparent storage encryptionNoYes
Confidential key managementNoYes
Cloud agnostic / multi-cloudNoYes
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/overview/license/index.html b/pr-preview/pr-4027/2.23/overview/license/index.html deleted file mode 100644 index d8319c386..000000000 --- a/pr-preview/pr-4027/2.23/overview/license/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - -License | Constellation - - - - - - - -
Skip to main content
Version: 2.23

License

-

Constellation is available under the Business Source License 1.1.

-

You may use it free of charge for non-production use ("Community License").

-

Enterprise License

-

Enterprise Licenses permit production use and come with support and additional features. Find out more at the product website.

-

Once you have received your Enterprise License file, place it in your Constellation workspace in a file named constellation.license.

-

CSP Marketplaces

-

Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please contact us.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/overview/performance/application/index.html b/pr-preview/pr-4027/2.23/overview/performance/application/index.html deleted file mode 100644 index 415954f80..000000000 --- a/pr-preview/pr-4027/2.23/overview/performance/application/index.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - -Application benchmarks | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Application benchmarks

-

HashiCorp Vault

-

HashiCorp Vault is a distributed secrets management software that can be deployed to Kubernetes. -HashiCorp maintains a benchmarking tool for vault, vault-benchmark. -Vault-benchmark generates load on a Vault deployment and measures response times.

-

This article describes the results from running vault-benchmark on Constellation, AKS, and GKE. -You can find the setup for producing the data discussed in this article in the vault-benchmarks repository.

-

The Vault API used during benchmarking is the transits secret engine. -This allows services to send data to Vault for encryption, decryption, signing, and verification.

-

Results

-

On each run, vault-benchmark sends requests and measures the latencies. -The measured latencies are aggregated through various statistical features. -After running the benchmark n times, the arithmetic mean over a subset of the reported statistics is calculated. -The selected features are arithmetic mean, 99th percentile, minimum, and maximum.

-

Arithmetic mean gives a general sense of the latency on each target. -The 99th percentile shows performance in (most likely) erroneous states. -Minimum and maximum mark the range within which latency varies each run.

-

The benchmark was configured with 1300 workers and 10 seconds per run. -Those numbers were chosen empirically. -The latency was stabilizing at 10 seconds runtime, not changing with further increase. -Increasing the number of workers beyond 1300 leads to request failures, marking the limit Vault was able to handle in this setup. -All results are based on 100 runs.

-

The following data was generated while running five replicas, one primary, and four standby nodes. -All numbers are in seconds if not indicated otherwise.

-
========== Results AKS ==========
Mean: mean: 1.632200, variance: 0.002057
P99: mean: 5.480679, variance: 2.263700
Max: mean: 6.651001, variance: 2.808401
Min: mean: 0.011415, variance: 0.000133
========== Results GKE ==========
Mean: mean: 1.656435, variance: 0.003615
P99: mean: 6.030807, variance: 3.955051
Max: mean: 7.164843, variance: 3.300004
Min: mean: 0.010233, variance: 0.000111
========== Results C11n ==========
Mean: mean: 1.651549, variance: 0.001610
P99: mean: 5.780422, variance: 3.016106
Max: mean: 6.942997, variance: 3.075796
Min: mean: 0.013774, variance: 0.000228
========== AKS vs C11n ==========
Mean: +1.171577 % (AKS is faster)
P99: +5.185495 % (AKS is faster)
Max: +4.205618 % (AKS is faster)
Min: +17.128781 % (AKS is faster)
========== GKE vs C11n ==========
Mean: -0.295851 % (GKE is slower)
P99: -4.331603 % (GKE is slower)
Max: -3.195248 % (GKE is slower)
Min: +25.710886 % (GKE is faster)
-

Interpretation: Latencies are all within ~5% of each other. -AKS performs slightly better than GKE and Constellation (C11n) in all cases except minimum latency. -Minimum latency is the lowest for GKE. -Compared to GKE, Constellation had slightly lower peak latencies (99th percentile and maximum), indicating that Constellation could have handled slightly more concurrent accesses than GKE. -Overall, performance is at comparable levels across all three distributions. -Based on these numbers, you can use a similarly sized Constellation cluster to run your existing Vault deployment.

-

Visualization

-

The following plots visualize the data presented above as box plots. -The whiskers denote the minimum and maximum. -The box stretches from the 25th to the 75th percentile, with the dividing bar marking the 50th percentile. -The circles outside the whiskers denote outliers.

-
Mean Latency

Mean Latency

-
99th Percentile Latency

99th Percentile Latency

-
Maximum Latency

Maximum Latency

-
Minimum Latency

Minimum Latency

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/overview/performance/compute/index.html b/pr-preview/pr-4027/2.23/overview/performance/compute/index.html deleted file mode 100644 index 0b1286db7..000000000 --- a/pr-preview/pr-4027/2.23/overview/performance/compute/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - -Impact of runtime encryption on compute performance | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Impact of runtime encryption on compute performance

-

All nodes in a Constellation cluster are executed inside Confidential VMs (CVMs). Consequently, the performance of Constellation is inherently linked to the performance of these CVMs.

-

AMD and Azure benchmarking

-

AMD and Azure have collectively released a performance benchmark for CVMs that utilize 3rd Gen AMD EPYC processors (Milan) with SEV-SNP. This benchmark, which included a variety of mostly compute-intensive tests such as SPEC CPU 2017 and CoreMark, demonstrated that CVMs experience only minor performance degradation (ranging from 2% to 8%) when compared to standard VMs. Such results are indicative of the performance that can be expected from compute-intensive workloads running with Constellation on Azure.

-

AMD and Google benchmarking

-

Similarly, AMD and Google have jointly released a performance benchmark for CVMs employing 3rd Gen AMD EPYC processors (Milan) with SEV-SNP. With high-performance computing workloads such as WRF, NAMD, Ansys CFS, and Ansys LS_DYNA, they observed analogous findings, with only minor performance degradation (between 2% and 4%) compared to standard VMs. These outcomes are reflective of the performance that can be expected for compute-intensive workloads running with Constellation on GCP.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/overview/performance/index.html b/pr-preview/pr-4027/2.23/overview/performance/index.html deleted file mode 100644 index 950155ce2..000000000 --- a/pr-preview/pr-4027/2.23/overview/performance/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - -Performance analysis of Constellation | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Performance analysis of Constellation

-

This section provides a comprehensive examination of the performance characteristics of Constellation.

-

Runtime encryption

-

Runtime encryption affects compute performance. Benchmarks by Azure and Google show that the performance degradation of Confidential VMs (CVMs) is small, ranging from 2% to 8% for compute-intensive workloads.

-

I/O performance benchmarks

-

We evaluated the I/O performance of Constellation, utilizing a collection of synthetic benchmarks targeting networking and storage. -We further compared this performance to native managed Kubernetes offerings from various cloud providers, to better understand how Constellation stands in relation to standard practices.

-

Application benchmarking

-

To gauge Constellation's applicability to well-known applications, we performed a benchmark of HashiCorp Vault running on Constellation. -The results were then compared to deployments on the managed Kubernetes offerings from different cloud providers, providing a tangible perspective on Constellation's performance in actual deployment scenarios.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/overview/performance/io/index.html b/pr-preview/pr-4027/2.23/overview/performance/io/index.html deleted file mode 100644 index 21d6ccc0e..000000000 --- a/pr-preview/pr-4027/2.23/overview/performance/io/index.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - -I/O performance benchmarks | Constellation - - - - - - - -
Skip to main content
Version: 2.23

I/O performance benchmarks

-

To assess the overall performance of Constellation, this benchmark evaluates Constellation v2.6.0 in terms of storage I/O using fio and network performance using the Kubernetes Network Benchmark.

-

This benchmark tested Constellation on Azure and GCP and compared the results against the managed Kubernetes offerings AKS and GKE.

-

Configurations

-

Constellation

-

The benchmark was conducted with Constellation v2.6.0, Kubernetes v1.25.7, and Cilium v1.12. -It ran on the following infrastructure configurations.

-

Constellation on Azure:

-
    -
  • Nodes: 3 (1 Control-plane, 2 Worker)
  • -
  • Machines: DC4as_v5: 3rd Generation AMD EPYC 7763v (Milan) processor with 4 Cores, 16 GiB memory
  • -
  • CVM: true
  • -
  • Region: West US
  • -
  • Zone: 2
  • -
-

Constellation on GCP:

-
    -
  • Nodes: 3 (1 Control-plane, 2 Worker)
  • -
  • Machines: n2d-standard-4: 2nd Generation AMD EPYC (Rome) processor with 4 Cores, 16 GiB of memory
  • -
  • CVM: true
  • -
  • Zone: europe-west3-b
  • -
-

AKS

-

On AKS, the benchmark used Kubernetes v1.24.9 and nodes with version AKSUbuntu-1804gen2containerd-2023.02.15. -AKS ran with the kubenet CNI and the default CSI driver for Azure Disk.

-

The following infrastructure configurations was used:

-
    -
  • Nodes: 2 (2 Worker)
  • -
  • Machines: D4as_v5: 3rd Generation AMD EPYC 7763v (Milan) processor with 4 Cores, 16 GiB memory
  • -
  • CVM: false
  • -
  • Region: West US
  • -
  • Zone: 2
  • -
-

GKE

-

On GKE, the benchmark used Kubernetes v1.24.9 and nodes with version 1.24.9-gke.3200. -GKE ran with the kubenet CNI and the default CSI driver for Compute Engine persistent disk.

-

The following infrastructure configurations was used:

-
    -
  • Nodes: 2 (2 Worker)
  • -
  • Machines: n2d-standard-4 2nd Generation AMD EPYC (Rome) processor with 4 Cores, 16 GiB of memory
  • -
  • CVM: false
  • -
  • Zone: europe-west3-b
  • -
-

Results

-

Network

-

This section gives a thorough analysis of the network performance of Constellation, specifically focusing on measuring TCP and UDP bandwidth. -The benchmark measured the bandwidth of pod-to-pod and pod-to-service connections between two different nodes using iperf.

-

GKE and Constellation on GCP had a maximum network bandwidth of 10 Gbps. -AKS with Standard_D4as_v5 machines a maximum network bandwidth of 12.5 Gbps. -The Confidential VM equivalent Standard_DC4as_v5 currently has a network bandwidth of 1.25 Gbps. -Therefore, to make the test comparable, both AKS and Constellation on Azure were running with Standard_DC4as_v5 machines and 1.25 Gbps bandwidth.

-

Constellation on Azure and AKS used an MTU of 1500. -Constellation on GCP used an MTU of 8896. GKE used an MTU of 1450.

-

The difference in network bandwidth can largely be attributed to two factors.

- -

Pod-to-Pod

-

In this scenario, the client Pod connects directly to the server pod via its IP address.

- -

The results for "Pod-to-Pod" on Azure are as follows:

-

Network Pod2Pod Azure benchmark graph

-

The results for "Pod-to-Pod" on GCP are as follows:

-

Network Pod2Pod GCP benchmark graph

-

Pod-to-Service

-

In this scenario, the client Pod connects to the server Pod via a ClusterIP service. This is more relevant to real-world use cases.

- -

The results for "Pod-to-Pod" on Azure are as follows:

-

Network Pod2SVC Azure benchmark graph

-

The results for "Pod-to-Pod" on GCP are as follows:

-

Network Pod2SVC GCP benchmark graph

-

In our recent comparison of Constellation on GCP with GKE, Constellation has 58% less TCP bandwidth. However, UDP bandwidth was slightly better with Constellation, thanks to its higher MTU.

-

Similarly, when comparing Constellation on Azure with AKS using CVMs, Constellation achieved approximately 10% less TCP and 40% less UDP bandwidth.

-

Storage I/O

-

Azure and GCP offer persistent storage for their Kubernetes services AKS and GKE via the Container Storage Interface (CSI). CSI storage in Kubernetes is available via PersistentVolumes (PV) and consumed via PersistentVolumeClaims (PVC). -Upon requesting persistent storage through a PVC, GKE and AKS will provision a PV as defined by a default storage class. -Constellation provides persistent storage on Azure and GCP that's encrypted on the CSI layer. -Similarly, upon a PVC request, Constellation will provision a PV via a default storage class.

-

For Constellation on Azure and AKS, the benchmark ran with Azure Disk storage Standard SSD of 400 GiB size. -The DC4as machine type with four cores provides the following maximum performance:

-
    -
  • 6400 (20000 burst) IOPS
  • -
  • 144 MB/s (600 MB/s burst) throughput
  • -
-

However, the performance is bound by the capabilities of the 512 GiB Standard SSD size (the size class of 400 GiB volumes):

-
    -
  • 500 (600 burst) IOPS
  • -
  • 60 MB/s (150 MB/s burst) throughput
  • -
-

For Constellation on GCP and GKE, the benchmark ran with Compute Engine Persistent Disk Storage pd-balanced of 400 GiB size. -The N2D machine type with four cores and pd-balanced provides the following maximum performance:

-
    -
  • 3,000 read IOPS
  • -
  • 15,000 write IOPS
  • -
  • 240 MB/s read throughput
  • -
  • 240 MB/s write throughput
  • -
-

However, the performance is bound by the capabilities of a Zonal balanced PD with 400 GiB size:

-
    -
  • 2400 read IOPS
  • -
  • 2400 write IOPS
  • -
  • 112 MB/s read throughput
  • -
  • 112 MB/s write throughput
  • -
-

The fio benchmark consists of several tests. -The benchmark used Kubestr to run fio in Kubernetes. -The default test performs randomized access patterns that accurately depict worst-case I/O scenarios for most applications.

-

The following fio settings were used:

-
    -
  • No Cloud caching
  • -
  • No OS caching
  • -
  • Single CPU
  • -
  • 60 seconds runtime
  • -
  • 10 seconds ramp-up time
  • -
  • 10 GiB file
  • -
  • IOPS: 4 KB blocks and 128 iodepth
  • -
  • Bandwidth: 1024 KB blocks and 128 iodepth
  • -
-

For more details, see the fio test configuration.

-

The results for IOPS on Azure are as follows:

-

I/O IOPS Azure benchmark graph

-

The results for IOPS on GCP are as follows:

-

I/O IOPS GCP benchmark graph

-

The results for bandwidth on Azure are as follows:

-

I/O bandwidth Azure benchmark graph

-

The results for bandwidth on GCP are as follows:

-

I/O bandwidth GCP benchmark graph

-

On GCP, the results exceed the maximum performance guarantees of the chosen disk type. There are two possible explanations for this. The first is that there may be cloud caching in place that isn't configurable. Alternatively, the underlying provisioned disk size may be larger than what was requested, resulting in higher performance boundaries.

-

When comparing Constellation on GCP with GKE, Constellation has similar bandwidth but about 10% less IOPS performance. On Azure, Constellation has similar IOPS performance compared to AKS, where both likely hit the maximum storage performance. However, Constellation has approximately 15% less read and write bandwidth.

-

Conclusion

-

Despite the added security benefits that Constellation provides, it only incurs a slight performance overhead when compared to managed Kubernetes offerings such as AKS and GKE. In most compute benchmarks, Constellation is on par with it's alternatives. -While it may be slightly slower in certain I/O scenarios due to network and storage encryption, there is ongoing work to reduce this overhead to single digits.

-

For instance, storage encryption only adds between 10% to 15% overhead in terms of bandwidth and IOPS. -Meanwhile, the biggest performance impact that Constellation currently faces is network encryption, which can incur up to 58% overhead on a 10 Gbps network. -However, the Cilium team has conducted benchmarks with Cilium using WireGuard encryption on a 100 Gbps network that yielded over 15 Gbps. -We're confident that Constellation will provide a similar level of performance with an upcoming release.

-

Overall, Constellation strikes a great balance between security and performance, and we're continuously working to improve its performance capabilities while maintaining its high level of security.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/overview/product/index.html b/pr-preview/pr-4027/2.23/overview/product/index.html deleted file mode 100644 index 85d382fd6..000000000 --- a/pr-preview/pr-4027/2.23/overview/product/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - -Product features | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Product features

-

Constellation is a Kubernetes engine that aims to provide the best possible data security in combination with enterprise-grade scalability and reliability features---and a smooth user experience.

-

From a security perspective, Constellation implements the Confidential Kubernetes concept and corresponding security features, which shield your entire cluster from the underlying infrastructure.

-

From an operational perspective, Constellation provides the following key features:

-
    -
  • Native support for different clouds: Constellation works on Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), and STACKIT. Support for OpenStack-based environments is coming with a future release. Constellation securely interfaces with the cloud infrastructure to provide cluster autoscaling, dynamic persistent volumes, and service load balancing.
  • -
  • High availability: Constellation uses a multi-master architecture with a stacked etcd topology to ensure high availability.
  • -
  • Integrated Day-2 operations: Constellation lets you securely upgrade your cluster to a new release. It also lets you securely recover a failed cluster. Both with a single command.
  • -
  • Support for Terraform: Constellation includes a Terraform provider that lets you manage the full lifecycle of your cluster via Terraform.
  • -
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/overview/security-benefits/index.html b/pr-preview/pr-4027/2.23/overview/security-benefits/index.html deleted file mode 100644 index cc80e0131..000000000 --- a/pr-preview/pr-4027/2.23/overview/security-benefits/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - -Security benefits and threat model | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Security benefits and threat model

-

Constellation implements the Confidential Kubernetes concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be verified.

-

TCB comparison

-

Given this background, the following describes the concrete threat classes that Constellation addresses.

-

Insider access

-

Employees and third-party contractors of cloud service providers (CSPs) have access to different layers of the cloud infrastructure. -This opens up a large attack surface where workloads and data can be read, copied, or manipulated. With Constellation, Kubernetes deployments are shielded from the infrastructure and thus such accesses are prevented.

-

Infrastructure-based attacks

-

Malicious cloud users ("hackers") may break out of their tenancy and access other tenants' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. Analogously to the insider access scenario, Constellation also prevents access to a deployment's data in this scenario.

-

Supply chain attacks

-

Supply chain security is receiving lots of attention recently due to an increasing number of recorded attacks. For instance, a malicious actor could attempt to tamper Constellation node images (including Kubernetes and other software) before they're loaded in the confidential VMs of a cluster. Constellation uses remote attestation in conjunction with public transparency logs to prevent this.

-

In the future, Constellation will extend this feature to customer workloads. This will enable cluster owners to create auditable policies that precisely define which containers can run in a given deployment.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/reference/cli/index.html b/pr-preview/pr-4027/2.23/reference/cli/index.html deleted file mode 100644 index 8dbf5172e..000000000 --- a/pr-preview/pr-4027/2.23/reference/cli/index.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - -CLI reference | Constellation - - - - - - - -
Skip to main content
Version: 2.23

CLI reference

-

Use the Constellation CLI to create and manage your clusters.

-

Usage:

-
constellation [command]
-

Commands:

-
    -
  • config: Work with the Constellation configuration file -
      -
    • generate: Generate a default configuration and state file
    • -
    • fetch-measurements: Fetch measurements for configured cloud provider and image
    • -
    • instance-types: Print the supported instance types for all cloud providers
    • -
    • kubernetes-versions: Print the Kubernetes versions supported by this CLI
    • -
    • migrate: Migrate a configuration file to a new version
    • -
    -
  • -
  • create: Create instances on a cloud platform for your Constellation cluster
  • -
  • apply: Apply a configuration to a Constellation cluster
  • -
  • mini: Manage MiniConstellation clusters -
      -
    • up: Create and initialize a new MiniConstellation cluster
    • -
    • down: Destroy a MiniConstellation cluster
    • -
    -
  • -
  • status: Show status of a Constellation cluster
  • -
  • verify: Verify the confidential properties of a Constellation cluster
  • -
  • upgrade: Find and apply upgrades to your Constellation cluster -
      -
    • check: Check for possible upgrades
    • -
    • apply: Apply an upgrade to a Constellation cluster
    • -
    -
  • -
  • recover: Recover a completely stopped Constellation cluster
  • -
  • terminate: Terminate a Constellation cluster
  • -
  • iam: Work with the IAM configuration on your cloud provider -
      -
    • create: Create IAM configuration on a cloud platform for your Constellation cluster -
        -
      • aws: Create IAM configuration on AWS for your Constellation cluster
      • -
      • azure: Create IAM configuration on Microsoft Azure for your Constellation cluster
      • -
      • gcp: Create IAM configuration on GCP for your Constellation cluster
      • -
      -
    • -
    • destroy: Destroy an IAM configuration and delete local Terraform files
    • -
    • upgrade: Find and apply upgrades to your IAM profile -
        -
      • apply: Apply an upgrade to an IAM profile
      • -
      -
    • -
    -
  • -
  • version: Display version of this CLI
  • -
  • init: Initialize the Constellation cluster
  • -
  • ssh: Generate a certificate for emergency SSH access
  • -
-

constellation config

-

Work with the Constellation configuration file

-

Synopsis

-

Work with the Constellation configuration file.

-

Options

-
  -h, --help   help for config
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation config generate

-

Generate a default configuration and state file

-

Synopsis

-

Generate a default configuration and state file for your selected cloud provider.

-
constellation config generate {aws|azure|gcp|openstack|qemu|stackit} [flags]
-

Options

-
  -a, --attestation string   attestation variant to use {aws-sev-snp|aws-nitro-tpm|azure-sev-snp|azure-tdx|azure-trustedlaunch|gcp-sev-snp|gcp-sev-es|qemu-vtpm}. If not specified, the default for the cloud provider is used
-h, --help help for generate
-k, --kubernetes string Kubernetes version to use in format MAJOR.MINOR (default "v1.30")
-t, --tags strings additional tags for created resources given a list of key=value
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation config fetch-measurements

-

Fetch measurements for configured cloud provider and image

-

Synopsis

-

Fetch measurements for configured cloud provider and image.

-

A config needs to be generated first.

-
constellation config fetch-measurements [flags]
-

Options

-
  -h, --help                   help for fetch-measurements
-s, --signature-url string alternative URL to fetch measurements' signature from
-u, --url string alternative URL to fetch measurements from
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation config instance-types

-

Print the supported instance types for all cloud providers

-

Synopsis

-

Print the supported instance types for all cloud providers.

-
constellation config instance-types [flags]
-

Options

-
  -h, --help   help for instance-types
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation config kubernetes-versions

-

Print the Kubernetes versions supported by this CLI

-

Synopsis

-

Print the Kubernetes versions supported by this CLI.

-
constellation config kubernetes-versions [flags]
-

Options

-
  -h, --help   help for kubernetes-versions
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation config migrate

-

Migrate a configuration file to a new version

-

Synopsis

-

Migrate a configuration file to a new version.

-
constellation config migrate [flags]
-

Options

-
  -h, --help   help for migrate
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation create

-

Create instances on a cloud platform for your Constellation cluster

-

Synopsis

-

Create instances on a cloud platform for your Constellation cluster.

-
constellation create [flags]
-

Options

-
  -h, --help   help for create
-y, --yes create the cluster without further confirmation
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation apply

-

Apply a configuration to a Constellation cluster

-

Synopsis

-

Apply a configuration to a Constellation cluster to initialize or upgrade the cluster.

-
constellation apply [flags]
-

Options

-
      --conformance           enable conformance mode
-h, --help help for apply
--merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config
--skip-helm-wait install helm charts without waiting for deployments to be ready
--skip-phases strings comma-separated list of upgrade phases to skip
one or multiple of { infrastructure | init | attestationconfig | certsans | helm | image | k8s }
-y, --yes run command without further confirmation
WARNING: the command might delete or update existing resources without additional checks. Please read the docs.

-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation mini

-

Manage MiniConstellation clusters

-

Synopsis

-

Manage MiniConstellation clusters.

-

Options

-
  -h, --help   help for mini
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation mini up

-

Create and initialize a new MiniConstellation cluster

-

Synopsis

-

Create and initialize a new MiniConstellation cluster.

-

A mini cluster consists of a single control-plane and worker node, hosted using QEMU/KVM.

-
constellation mini up [flags]
-

Options

-
  -h, --help               help for up
--merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config (default true)
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation mini down

-

Destroy a MiniConstellation cluster

-

Synopsis

-

Destroy a MiniConstellation cluster.

-
constellation mini down [flags]
-

Options

-
  -h, --help   help for down
-y, --yes terminate the cluster without further confirmation
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation status

-

Show status of a Constellation cluster

-

Synopsis

-

Show the status of a constellation cluster.

-

Shows microservice, image, and Kubernetes versions installed in the cluster. Also shows status of current version upgrades.

-
constellation status [flags]
-

Options

-
  -h, --help   help for status
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation verify

-

Verify the confidential properties of a Constellation cluster

-

Synopsis

-

Verify the confidential properties of a Constellation cluster. -If arguments aren't specified, values are read from constellation-state.yaml.

-
constellation verify [flags]
-

Options

-
      --cluster-id string      expected cluster identifier
-h, --help help for verify
-e, --node-endpoint string endpoint of the node to verify, passed as HOST[:PORT]
-o, --output string print the attestation document in the output format {json|raw}
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation upgrade

-

Find and apply upgrades to your Constellation cluster

-

Synopsis

-

Find and apply upgrades to your Constellation cluster.

-

Options

-
  -h, --help   help for upgrade
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation upgrade check

-

Check for possible upgrades

-

Synopsis

-

Check which upgrades can be applied to your Constellation Cluster.

-
constellation upgrade check [flags]
-

Options

-
  -h, --help            help for check
--ref string the reference to use for querying new versions (default "-")
--stream string the stream to use for querying new versions (default "stable")
-u, --update-config update the specified config file with the suggested versions
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation upgrade apply

-

Apply an upgrade to a Constellation cluster

-

Synopsis

-

Apply an upgrade to a Constellation cluster by applying the chosen configuration.

-
constellation upgrade apply [flags]
-

Options

-
      --conformance           enable conformance mode
-h, --help help for apply
--skip-helm-wait install helm charts without waiting for deployments to be ready
--skip-phases strings comma-separated list of upgrade phases to skip
one or multiple of { infrastructure | helm | image | k8s }
-y, --yes run upgrades without further confirmation
WARNING: might delete your resources in case you are using cert-manager in your cluster. Please read the docs.
WARNING: might unintentionally overwrite measurements in the running cluster.
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation recover

-

Recover a completely stopped Constellation cluster

-

Synopsis

-

Recover a Constellation cluster by sending a recovery key to an instance in the boot stage.

-

This is only required if instances restart without other instances available for bootstrapping.

-
constellation recover [flags]
-

Options

-
  -e, --endpoint string   endpoint of the instance, passed as HOST[:PORT]
-h, --help help for recover
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation terminate

-

Terminate a Constellation cluster

-

Synopsis

-

Terminate a Constellation cluster.

-

The cluster can't be started again, and all persistent storage will be lost.

-
constellation terminate [flags]
-

Options

-
  -h, --help   help for terminate
-y, --yes terminate the cluster without further confirmation
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation iam

-

Work with the IAM configuration on your cloud provider

-

Synopsis

-

Work with the IAM configuration on your cloud provider.

-

Options

-
  -h, --help   help for iam
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation iam create

-

Create IAM configuration on a cloud platform for your Constellation cluster

-

Synopsis

-

Create IAM configuration on a cloud platform for your Constellation cluster.

-

Options

-
  -h, --help            help for create
--update-config update the config file with the specific IAM information
-y, --yes create the IAM configuration without further confirmation
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation iam create aws

-

Create IAM configuration on AWS for your Constellation cluster

-

Synopsis

-

Create IAM configuration on AWS for your Constellation cluster.

-
constellation iam create aws [flags]
-

Options

-
  -h, --help            help for aws
--prefix string name prefix for all resources (required)
--zone string AWS availability zone the resources will be created in, e.g., us-east-2a (required)
See the Constellation docs for a list of currently supported regions.
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
--update-config update the config file with the specific IAM information
-C, --workspace string path to the Constellation workspace
-y, --yes create the IAM configuration without further confirmation
-

constellation iam create azure

-

Create IAM configuration on Microsoft Azure for your Constellation cluster

-

Synopsis

-

Create IAM configuration on Microsoft Azure for your Constellation cluster.

-
constellation iam create azure [flags]
-

Options

-
  -h, --help                      help for azure
--region string region the resources will be created in, e.g., westus (required)
--resourceGroup string name prefix of the two resource groups your cluster / IAM resources will be created in (required)
--servicePrincipal string name of the service principal that will be created (required)
--subscriptionID string subscription ID of the Azure account. Required if the 'ARM_SUBSCRIPTION_ID' environment variable is not set
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
--update-config update the config file with the specific IAM information
-C, --workspace string path to the Constellation workspace
-y, --yes create the IAM configuration without further confirmation
-

constellation iam create gcp

-

Create IAM configuration on GCP for your Constellation cluster

-

Synopsis

-

Create IAM configuration on GCP for your Constellation cluster.

-
constellation iam create gcp [flags]
-

Options

-
  -h, --help               help for gcp
--prefix string Prefix for the service account ID and VM ID that will be created (required)
Must be letters, digits, or hyphens.
--projectID string ID of the GCP project the configuration will be created in (required)
Find it on the welcome screen of your project: https://console.cloud.google.com/welcome
--zone string GCP zone the cluster will be deployed in (required)
Find a list of available zones here: https://cloud.google.com/compute/docs/regions-zones#available
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
--update-config update the config file with the specific IAM information
-C, --workspace string path to the Constellation workspace
-y, --yes create the IAM configuration without further confirmation
-

constellation iam destroy

-

Destroy an IAM configuration and delete local Terraform files

-

Synopsis

-

Destroy an IAM configuration and delete local Terraform files.

-
constellation iam destroy [flags]
-

Options

-
  -h, --help   help for destroy
-y, --yes destroy the IAM configuration without asking for confirmation
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation iam upgrade

-

Find and apply upgrades to your IAM profile

-

Synopsis

-

Find and apply upgrades to your IAM profile.

-

Options

-
  -h, --help   help for upgrade
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation iam upgrade apply

-

Apply an upgrade to an IAM profile

-

Synopsis

-

Apply an upgrade to an IAM profile.

-
constellation iam upgrade apply [flags]
-

Options

-
  -h, --help   help for apply
-y, --yes run upgrades without further confirmation
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation version

-

Display version of this CLI

-

Synopsis

-

Display version of this CLI.

-
constellation version [flags]
-

Options

-
  -h, --help   help for version
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation init

-

Initialize the Constellation cluster

-

Synopsis

-

Initialize the Constellation cluster.

-

Start your confidential Kubernetes.

-
constellation init [flags]
-

Options

-
      --conformance        enable conformance mode
-h, --help help for init
--merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config
--skip-helm-wait install helm charts without waiting for deployments to be ready
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
-

constellation ssh

-

Generate a certificate for emergency SSH access

-

Synopsis

-

Generate a certificate for emergency SSH access to your SSH-enabled constellation cluster.

-
constellation ssh [flags]
-

Options

-
  -h, --help         help for ssh
--key string the path to an existing SSH public key
-

Options inherited from parent commands

-
      --debug              enable debug logging
--force disable version compatibility checks - might result in corrupted clusters
--tf-log string Terraform log level (default "NONE")
-C, --workspace string path to the Constellation workspace
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/reference/migration/index.html b/pr-preview/pr-4027/2.23/reference/migration/index.html deleted file mode 100644 index 994a19cfd..000000000 --- a/pr-preview/pr-4027/2.23/reference/migration/index.html +++ /dev/null @@ -1,94 +0,0 @@ - - - - - -Migrations | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Migrations

-

This document describes breaking changes and migrations between Constellation releases. -Use constellation config migrate to automatically update an old config file to a new format.

-

Migrations to v2.23.0

-

GCP

-

GCP will require the additional permission compute.forwardingRules.list. Please update your IAM roles using constellation iam upgrade apply.

-

Migrations to v2.19.1

-

Azure

-
    -
  • During the upgrade, security rules are migrated and the old ones need to be cleaned up manually by the user. The below script shows how to delete them through the Azure CLI:
  • -
-
#!/usr/bin/env bash
name="<insert>" # the name provided in the config
uid="<insert>" # the cluster id can be retrieved via `yq '.infrastructure.uid' constellation-state.yaml`
resource_group="<insert>" # the RG can be retrieved via `yq '.provider.azure.resourceGroup' constellation-conf.yaml`

rules=(
"kubernetes"
"bootstrapper"
"verify"
"recovery"
"join"
"debugd"
"konnectivity"
)

for rule in "${rules[@]}"; do
echo "Deleting rule: ${rule}"
az network nsg rule delete \
--resource-group "${resource_group}" \
--nsg-name "${name}-${uid}" \
--name "${rule}"
done

echo "All specified rules have been deleted."
-

Migrating from CLI versions before 2.21.1

-

AWS

-
    -
  • AWS clusters that use LoadBalancer resources require more IAM permissions. Please upgrade your IAM roles using constellation iam upgrade apply. This will show necessary changes and apply them, if desired.
  • -
-

Migrating from CLI versions before 2.19.0

-

Azure

-
    -
  • To allow seamless upgrades on Azure when Kubernetes services of type LoadBalancer are deployed, the target -load balancer in which the cloud-controller-manager creates load balancing rules was changed. Instead of using the load balancer -created and maintained by the CLI's Terraform code, the cloud-controller-manager now creates its own load balancer in Azure. -If your Constellation has services of type LoadBalancer, please remove them before the upgrade and re-apply them -afterward.
  • -
-

Migrating from CLI versions before 2.18.0

-
    -
  • The provider.azure.appClientID and provider.azure.appClientSecret fields are no longer supported and should be removed.
  • -
  • To keep using an existing UAMI, add the Owner permission with the scope of your resourceGroup.
  • -
  • Otherwise, simply create new Constellation IAM credentials and use the created UAMI.
  • -
  • To migrate the authentication for an existing cluster on Azure to an UAMI with the necessary permissions: -
      -
    1. Remove the aadClientId and aadClientSecret from the azureconfig secret.
    2. -
    3. Set useManagedIdentityExtension to true and use the userAssignedIdentity from the Constellation config for the value of userAssignedIdentityID.
    4. -
    5. Restart the CSI driver, cloud controller manager, cluster autoscaler, and Constellation operator pods.
    6. -
    -
  • -
-

Migrating from CLI versions before 2.10

-
    -
  • AWS cluster upgrades require additional IAM permissions for the newly introduced aws-load-balancer-controller. Please upgrade your IAM roles using iam upgrade apply. This will show necessary changes and apply them, if desired.
  • -
  • The global nodeGroups field was added.
  • -
  • The fields instanceType, stateDiskSizeGB, and stateDiskType for each cloud provider are now part of the configuration of individual node groups.
  • -
  • The constellation create command no longer uses the flags --control-plane-count and --worker-count. Instead, the initial node count is configured per node group in the nodeGroups field.
  • -
-

Migrating from CLI versions before 2.9

-
    -
  • The provider.azure.appClientID and provider.azure.clientSecretValue fields were removed to enforce migration to managed identity authentication
  • -
-

Migrating from CLI versions before 2.8

-
    -
  • The measurements field for each cloud service provider was replaced with a global attestation field.
  • -
  • The confidentialVM, idKeyDigest, and enforceIdKeyDigest fields for the Azure cloud service provider were removed in favor of using the global attestation field.
  • -
  • The optional global field attestationVariant was replaced by the now required attestation field.
  • -
-

Migrating from CLI versions before 2.3

-
    -
  • -

    The sshUsers field was deprecated in v2.2 and has been removed from the configuration in v2.3. -As an alternative for SSH, check the workflow section Connect to nodes.

    -
  • -
  • -

    The image field for each cloud service provider has been replaced with a global image field. Use the following mapping to migrate your configuration:

    -
    Show all
    CSPold imagenew image
    AWSami-06b8cbf4837a0a57cv2.2.2
    AWSami-02e96dc04a9e438cdv2.2.2
    AWSami-028ead928a9034b2fv2.2.2
    AWSami-032ac10dd8d8266e3v2.2.1
    AWSami-032e0d57cc4395088v2.2.1
    AWSami-053c3e49e19b96bddv2.2.1
    AWSami-0e27ebcefc38f648bv2.2.0
    AWSami-098cd37f66523b7c3v2.2.0
    AWSami-04a87d302e2509aadv2.2.0
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.2v2.2.2
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.2v2.2.2
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.1v2.2.1
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.1v2.2.1
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.0v2.2.0
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.0v2.2.0
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.1.0v2.1.0
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.1.0v2.1.0
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.0.0v2.0.0
    Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.0.0v2.0.0
    GCPprojects/constellation-images/global/images/constellation-v2-2-2v2.2.2
    GCPprojects/constellation-images/global/images/constellation-v2-2-1v2.2.1
    GCPprojects/constellation-images/global/images/constellation-v2-2-0v2.2.0
    GCPprojects/constellation-images/global/images/constellation-v2-1-0v2.1.0
    GCPprojects/constellation-images/global/images/constellation-v2-0-0v2.0.0
    -
  • -
  • -

    The enforcedMeasurements field has been removed and merged with the measurements field.

    -
      -
    • -

      To migrate your config containing a new image (v2.3 or greater), remove the old measurements and enforcedMeasurements entries from your config and run constellation fetch-measurements

      -
    • -
    • -

      To migrate your config containing an image older than v2.3, remove the enforcedMeasurements entry and replace the entries in measurements as shown in the example below:

      -
      measurements:
      - 0: DzXCFGCNk8em5ornNZtKi+Wg6Z7qkQfs5CfE3qTkOc8=
      + 0:
      + expected: DzXCFGCNk8em5ornNZtKi+Wg6Z7qkQfs5CfE3qTkOc8=
      + warnOnly: true
      - 8: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
      + 8:
      + expected: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
      + warnOnly: false
      -enforcedMeasurements:
      - - 8
      -
    • -
    -
  • -
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/reference/slsa/index.html b/pr-preview/pr-4027/2.23/reference/slsa/index.html deleted file mode 100644 index 4963775a1..000000000 --- a/pr-preview/pr-4027/2.23/reference/slsa/index.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - -Supply chain levels for software artifacts (SLSA) adoption | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Supply chain levels for software artifacts (SLSA) adoption

-

Supply chain Levels for Software Artifacts, or SLSA (salsa) is a framework for improving and grading a project's build system and engineering processes. SLSA focuses on security improvements for source code storage as well as build system definition, execution, and observation. SLSA is structured in four levels. This page describes the adoption of SLSA for Constellation.

-
info

SLSA is still in alpha status. The presented levels and their requirements might change in the future. We will adopt any changes into our engineering processes, as they get defined.

-

Level 1 - Adopted

-

Build - Scripted

-

All build steps are automated via Bazel and GitHub Actions.

-

Provenance - Available

-

Provenance for the CLI is generated using the slsa-github-generator.

-

Level 2 - Adopted

-

Source - Version Controlled

-

Constellation is hosted on GitHub using git.

-

Build - Build Service

-

All builds are carried out by GitHub Actions.

-

Provenance - Authenticated

-

Provenance for the CLI is signed using the slsa-github-generator. Learn how to verify the CLI using the signed provenance, before using it for the first time.

-

Provenance - Service Generated

-

Provenance for the CLI is generated using the slsa-github-generator in GitHub Actions.

-

Level 3 - Adopted

-

Source - Verified History

-

The Edgeless Systems GitHub organization requires two-factor authentication for all members.

-

Source - Retained Indefinitely

-

Since we use GitHub to host the repository, an external person can't modify or delete the history. Before a pull request can be merged, an explicit approval from an Edgeless Systems team member is required.

-

The same holds true for changes proposed by team members. Each change to main needs to be proposed via a pull request and requires at least one approval.

-

The Edgeless Systems GitHub organization admins control these settings and are able to make changes to the repository's history should legal requirements necessitate it. These changes require two-party approval following the obliterate policy.

-

Build - Build as Code

-

All build files for Constellation are stored in the same repository.

-

Build - Ephemeral Environment

-

All GitHub Action workflows are executed on GitHub-hosted runners. These runners are only available during workflow.

-

We currently don't use self-hosted runners.

-

Build - Isolated

-

As outlined in the previous section, we use GitHub-hosted runners, which provide a new, isolated and ephemeral environment for each build.

-

Additionally, the SLSA GitHub generator itself is run in an isolated workflow with the artifact hash as defined inputs.

-

Provenance - Non-falsifiable

-

As outlined by SLSA GitHub generator it already fulfills the non-falsifiable requirements for SLSA Level 3. The generated provenance is signed using sigstore with an OIDC based proof of identity.

-

Level 4 - In Progress

-

We strive to adopt certain aspect of SLSA Level 4 that support our engineering process. At the same time, SLSA is still in alpha status and the biggest changes to SLSA are expected to be around Level 4.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/reference/terraform/index.html b/pr-preview/pr-4027/2.23/reference/terraform/index.html deleted file mode 100644 index 0891350ff..000000000 --- a/pr-preview/pr-4027/2.23/reference/terraform/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -Terraform usage | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Terraform usage

-

Terraform is an Infrastructure as Code (IaC) framework to manage cloud resources. This page explains how Constellation uses it internally and how advanced users may manually use it to have more control over the resource creation.

-
info

Information on this page is intended for users who are familiar with Terraform. -It's not required for common usage of Constellation. -See the Terraform documentation if you want to learn more about it.

-

Terraform state files

-

Constellation keeps Terraform state files in subdirectories of the workspace together with the corresponding Terraform configuration files and metadata. -The subdirectories are created on the first Constellation CLI action that uses Terraform internally.

-

Currently, these subdirectories are:

-
    -
  • constellation-terraform - Terraform state files for the resources of the Constellation cluster
  • -
  • constellation-iam-terraform - Terraform state files for IAM configuration
  • -
-

As with all commands, commands that work with these files (e.g., apply, terminate, iam) have to be executed from the root of the cluster's workspace directory. You usually don't need and shouldn't manipulate or delete the subdirectories manually.

-

Interacting with Terraform manually

-

Manual interaction with Terraform state created by Constellation (i.e., via the Terraform CLI) should only be performed by experienced users. It may lead to unrecoverable loss of cloud resources. For the majority of users and use cases, the interaction done by the Constellation CLI is sufficient.

-

Terraform debugging

-

To debug Terraform issues, the Constellation CLI offers the tf-log flag. You can set it to any of Terraform's log levels:

-
    -
  • JSON (JSON-formatted logs at TRACE level)
  • -
  • TRACE
  • -
  • DEBUG
  • -
  • INFO
  • -
  • WARN
  • -
  • ERROR
  • -
-

The log output is written to the terraform.log file in the workspace directory. The output is appended to the file on each run.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/workflows/cert-manager/index.html b/pr-preview/pr-4027/2.23/workflows/cert-manager/index.html deleted file mode 100644 index 5743b9875..000000000 --- a/pr-preview/pr-4027/2.23/workflows/cert-manager/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - -Install cert-manager | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Install cert-manager

-
caution

If you want to use cert-manager with Constellation, pay attention to the following to avoid potential pitfalls.

-

Constellation ships with cert-manager preinstalled. -The default installation is part of the kube-system namespace, as all other Constellation-managed microservices. -You are free to install more instances of cert-manager into other namespaces. -However, be aware that any new installation needs to use the same version as the one installed with Constellation or rely on the same CRD versions. -Also remember to set the installCRDs value to false when installing new cert-manager instances. -It will create problems if you have two installations of cert-manager depending on different versions of the installed CRDs. -CRDs are cluster-wide resources and cert-manager depends on specific versions of those CRDs for each release.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/workflows/config/index.html b/pr-preview/pr-4027/2.23/workflows/config/index.html deleted file mode 100644 index 37246a680..000000000 --- a/pr-preview/pr-4027/2.23/workflows/config/index.html +++ /dev/null @@ -1,162 +0,0 @@ - - - - - -Configure your cluster | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Configure your cluster

-
info

This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details.

-
Loading asciinema cast...
-
-

Before you can create your cluster, you need to configure the identity and access management (IAM) for your cloud service provider (CSP) and choose machine types for the nodes.

-

Creating the configuration file

-

You can generate a configuration file for your CSP by using the following CLI command:

-
constellation config generate aws
-

This creates the file constellation-conf.yaml in the current directory.

-

Choosing a VM type

-

Constellation supports the following VM types:

-

By default, Constellation uses m6a.xlarge VMs (4 vCPUs, 16 GB RAM) to create your cluster. -Optionally, you can switch to a different VM type by modifying instanceType in the configuration file. -If you are using the default attestation variant awsSEVSNP, you can use the instance types described in AWS's AMD SEV-SNP docs. -Please mind the region restrictions mentioned in the Getting started section.

If you are using the attestation variant awsNitroTPM, you can choose any of the nitroTPM-enabled instance types.

The Constellation CLI can also print the supported instance types with: constellation config instance-types.

-

Fill the desired VM type into the instanceType fields in the constellation-conf.yml file.

-

Creating additional node groups

-

By default, Constellation creates the node groups control_plane_default and worker_default for control-plane nodes and workers, respectively. -If you require additional control-plane or worker groups with different instance types, zone placements, or disk sizes, you can add additional node groups to the constellation-conf.yml file. -Each node group can be scaled individually.

-

Consider the following example for AWS:

-
nodeGroups:
control_plane_default:
role: control-plane
instanceType: c6a.xlarge
stateDiskSizeGB: 30
stateDiskType: gp3
zone: eu-west-1c
initialCount: 3
worker_default:
role: worker
instanceType: c6a.xlarge
stateDiskSizeGB: 30
stateDiskType: gp3
zone: eu-west-1c
initialCount: 2
high_cpu:
role: worker
instanceType: c6a.24xlarge
stateDiskSizeGB: 128
stateDiskType: gp3
zone: eu-west-1c
initialCount: 1
-

This configuration creates an additional node group high_cpu with a larger instance type and disk.

-

You can use the field zone to specify what availability zone nodes of the group are placed in. -On Azure, this field is empty by default and nodes are automatically spread across availability zones. -STACKIT currently offers SEV-enabled CPUs in the eu01-1, eu01-2, and eu01-3 zones. -Consult the documentation of your cloud provider for more information:

- -

Choosing a Kubernetes version

-

To learn which Kubernetes versions can be installed with your current CLI, you can run constellation config kubernetes-versions. -See also Constellation's Kubernetes support policy.

-

Creating an IAM configuration

-

You can create an IAM configuration for your cluster automatically using the constellation iam create command. -If you already have a Constellation configuration file, you can add the --update-config flag to the command. This writes the needed IAM fields into your configuration. Furthermore, the flag updates the zone/region of the configuration if it hasn't been set yet.

-

You must be authenticated with the AWS CLI in the shell session with a user that has the required permissions for IAM creation.

constellation iam create aws --zone=us-east-2a --prefix=constellTest

This command creates IAM configuration for the AWS zone us-east-2a using the prefix constellTest for all named resources being created.

Constellation OS images are currently replicated to the following regions:

    -
  • eu-central-1
  • -
  • eu-west-1
  • -
  • eu-west-3
  • -
  • us-east-2
  • -
  • ap-south-1
  • -

If you require the OS image to be available in another region, let us know.

You can find a list of all regions in AWS's documentation.

Paste the output into the corresponding fields of the constellation-conf.yaml file.

-
Alternatively, you can manually create the IAM configuration on your CSP.

The following describes the configuration fields and how you obtain the required information or create the required resources.

    -
  • -

    region: The name of your chosen AWS data center region, e.g., us-east-2.

    -

    Constellation OS images are currently replicated to the following regions:

    -
      -
    • eu-central-1
    • -
    • eu-west-1
    • -
    • eu-west-3
    • -
    • us-east-2
    • -
    • ap-south-1
    • -
    -

    If you require the OS image to be available in another region, let us know.

    -

    You can find a list of all regions in AWS's documentation.

    -
  • -
  • -

    zone: The name of your chosen AWS data center availability zone, e.g., us-east-2a.

    -

    Learn more about availability zones in AWS's documentation.

    -
  • -
  • -

    iamProfileControlPlane: The name of an IAM instance profile attached to all control-plane nodes.

    -

    You can create the resource with Terraform. For that, use the provided Terraform script to generate the necessary profile. The profile name will be provided as Terraform output value: control_plane_instance_profile_name.

    -

    Alternatively, you can create the AWS profile with a tool of your choice. Use the JSON policy in main.tf in the resource aws_iam_policy.control_plane_policy.

    -
  • -
  • -

    iamProfileWorkerNodes: The name of an IAM instance profile attached to all worker nodes.

    -

    You can create the resource with Terraform. For that, use the provided Terraform script to generate the necessary profile. The profile name will be provided as Terraform output value: worker_nodes_instance_profile_name.

    -

    Alternatively, you can create the AWS profile with a tool of your choice. Use the JSON policy in main.tf in the resource aws_iam_policy.worker_node_policy.

    -
  • -
-

Now that you've configured your CSP, you can create your cluster.

-

Deleting an IAM configuration

-

You can keep a created IAM configuration and reuse it for new clusters. Alternatively, you can also delete it if you don't want to use it anymore.

-

Delete the IAM configuration by executing the following command in the same directory where you executed constellation iam create (the directory that contains constellation-iam-terraform as a subdirectory):

-
constellation iam destroy
-
caution

For Azure, deleting the IAM configuration by executing constellation iam destroy will delete the whole resource group created by constellation iam create. -This also includes any additional resources in the resource group that weren't created by Constellation.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/workflows/create/index.html b/pr-preview/pr-4027/2.23/workflows/create/index.html deleted file mode 100644 index ab2c9d660..000000000 --- a/pr-preview/pr-4027/2.23/workflows/create/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -Create your cluster | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Create your cluster

-
info

This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details.

-
Loading asciinema cast...
-
-

Creating your cluster happens through multiple phases. -The most significant ones are:

-
    -
  1. Creating the necessary resources in your cloud environment
  2. -
  3. Bootstrapping the Constellation cluster and setting up a connection
  4. -
  5. Installing the necessary Kubernetes components
  6. -
-

constellation apply handles all this in a single command. -You can use the --skip-phases flag to skip specific phases of the process. -For example, if you created the infrastructure manually, you can skip the cloud resource creation phase.

-

See the architecture section for details on the inner workings of this process.

-
tip

If you don't have a cloud subscription, you can also set up a local Constellation cluster using virtualization for testing.

-

Before you create the cluster, make sure to have a valid configuration file.

-
constellation apply

apply stores the state of your cluster's cloud resources in a constellation-terraform directory in your workspace.

-

Finally, configure kubectl for your cluster:

-
export KUBECONFIG="$PWD/constellation-admin.conf"
-

🏁 That's it. You've successfully created a Constellation cluster.

-

Troubleshooting

-

In case apply fails, the CLI collects logs from the bootstrapping instance and stores them inside constellation-cluster.log.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/workflows/lb/index.html b/pr-preview/pr-4027/2.23/workflows/lb/index.html deleted file mode 100644 index 0b864eb3b..000000000 --- a/pr-preview/pr-4027/2.23/workflows/lb/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - -Expose a service | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Expose a service

-

Constellation integrates the native load balancers of each CSP. Therefore, to expose a service simply create a service of type LoadBalancer.

-

Internet-facing LB service on AWS

-

To expose your application service externally you might want to use a Kubernetes Service of type LoadBalancer. On AWS, load-balancing is achieved through the AWS Load Balancer Controller as in the managed EKS.

-

Since recent versions, the controller deploy an internal LB by default requiring to set an annotation service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing to have an internet-facing LB. For more details, see the official docs.

-

For general information on LB with AWS see Network load balancing on Amazon EKS.

-
caution

Before terminating the cluster, all LB backed services should be deleted, so that the controller can cleanup the related resources.

-

Ingress on AWS

-

The AWS Load Balancer Controller also provisions Ingress resources of class alb. -AWS Application Load Balancers (ALBs) can be configured with a target-type. -The target type ip requires using the EKS container network solution, which makes it incompatible with Constellation. -If a service can be exposed on a NodePort, the target type instance can be used.

-

See Application load balancing on Amazon EKS for more information.

-
caution

Ingress handlers backed by AWS ALBs reside outside the Constellation cluster, so they shouldn't be handling sensitive traffic!

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/workflows/recovery/index.html b/pr-preview/pr-4027/2.23/workflows/recovery/index.html deleted file mode 100644 index a38365a12..000000000 --- a/pr-preview/pr-4027/2.23/workflows/recovery/index.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - -Recover your cluster | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Recover your cluster

-

Recovery of a Constellation cluster means getting it back into a healthy state after too many concurrent node failures in the control plane. -Reasons for an unhealthy cluster can vary from a power outage, or planned reboot, to migration of nodes and regions. -Recovery events are rare, because Constellation is built for high availability and automatically and securely replaces failed nodes. When a node is replaced, Constellation's control plane first verifies the new node before it sends the node the cryptographic keys required to decrypt its state disk.

-

Constellation provides a recovery mechanism for cases where the control plane has failed and is unable to replace nodes. -The constellation recover command securely connects to all nodes in need of recovery using attested TLS and provides them with the keys to decrypt their state disks and continue booting.

-

Identify unhealthy clusters

-

The first step to recovery is identifying when a cluster becomes unhealthy. -Usually, this can be first observed when the Kubernetes API server becomes unresponsive.

-

You can check the health status of the nodes via the cloud service provider (CSP). -Constellation provides logging information on the boot process and status via serial console output. -In the following, you'll find detailed descriptions for identifying clusters stuck in recovery for each CSP.

-

First, open the AWS console to view all Auto Scaling Groups (ASGs) in the region of your cluster. Select the ASG of the control plane <cluster-name>-<UID>-control-plane and check that enough members are in a Running state.

Second, check the boot logs of these Instances. In the ASG's Instance management view, select each desired instance. In the upper right corner, select Action > Monitor and troubleshoot > Get system log.

In the serial console output, search for Waiting for decryption key. -Similar output to the following means your node was restarted and needs to decrypt the state disk:

{"level":"INFO","ts":"2022-09-08T10:21:53Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"gcp"}
{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}
{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}
{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}

The node will then try to connect to the JoinService and obtain the decryption key. -If this fails due to an unhealthy control plane, you will see log messages similar to the following:

{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["192.168.178.4:30090","192.168.178.2:30090"]}
{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.4:30090"}
{"level":"WARN","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing dial tcp 192.168.178.4:30090: connect: connection refused\"","endpoint":"192.168.178.4:30090"}
{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.2:30090"}
{"level":"WARN","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing dial tcp 192.168.178.2:30090: i/o timeout\"","endpoint":"192.168.178.2:30090"}
{"level":"ERROR","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}

This means that you have to recover the node manually.

-

Recover a cluster

-

Recovering a cluster requires the following parameters:

-
    -
  • The constellation-state.yaml file in your working directory or the cluster's endpoint
  • -
  • The master secret of the cluster
  • -
-

A cluster can be recovered like this:

-
$ constellation recover
Pushed recovery key.
Pushed recovery key.
Pushed recovery key.
Recovered 3 control-plane nodes.
-

In the serial console output of the node you'll see a similar output to the following:

-
{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer","caller":"recoveryserver/server.go:93","msg":"Received recover call"}
{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer","caller":"recoveryserver/server.go:125","msg":"Received state disk key and measurement secret, shutting down server"}
{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer.gRPC","caller":"zap/server_interceptors.go:61","msg":"finished streaming call with code OK","grpc.start_time":"2022-09-08T10:26:59Z","system":"grpc","span.kind":"server","grpc.service":"recoverproto.API","grpc.method":"Recover","peer.address":"192.0.2.3:41752","grpc.code":"OK","grpc.time_ms":15.701}
{"level":"INFO","ts":"2022-09-08T10:27:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:87","msg":"RejoinClient stopped"}
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/workflows/reproducible-builds/index.html b/pr-preview/pr-4027/2.23/workflows/reproducible-builds/index.html deleted file mode 100644 index 5d5658c5d..000000000 --- a/pr-preview/pr-4027/2.23/workflows/reproducible-builds/index.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - -Reproduce released artifacts | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Reproduce released artifacts

-

Constellation has first-class support for reproducible builds. -Reproducing the released artifacts is an alternative to signature verification that doesn't require trusting Edgeless Systems' release process. -The following sections describe how to rebuild an artifact and how Constellation ensures that the rebuild reproduces the artifacts bit-by-bit.

-

Build environment prerequisites

-

The build systems used by Constellation - Bazel and Nix - are designed for deterministic, reproducible builds. -These two dependencies should be the only prerequisites for a successful build. -However, it can't be ruled out completely that peculiarities of the host affect the build result. -Thus, we recommend the following host setup for best results:

-
    -
  1. A Linux operating system not older than v5.4.
  2. -
  3. The GNU C library not older than v2.31 (avoid musl).
  4. -
  5. GNU coreutils not older than v8.30 (avoid busybox).
  6. -
  7. An ext4 filesystem for building.
  8. -
  9. AppArmor turned off.
  10. -
-

This is given, for example, on an Ubuntu 22.04 system, which is also used for reproducibility tests.

-
note

To avoid any backwards-compatibility issues, the host software versions should also not be much newer than the Constellation release.

-

Run the build

-

The following instructions outline qualitatively how to reproduce a build. -Constellation implements these instructions in the Reproducible Builds workflow, which continuously tests for reproducibility. -The workflow is a good place to look up specific version numbers and build steps.

-
    -
  1. -

    Check out the Constellation repository at the tag corresponding to the release.

    -
    git clone https://github.com/edgelesssys/constellation.git
    cd constellation
    git checkout v2.20.0
    -
  2. -
  3. -

    Install the Bazel release specified in .bazelversion.

    -
  4. -
  5. -

    Install Nix (any recent version should do).

    -
  6. -
  7. -

    Run the build with bazel build $target for one of the following targets of interest:

    -
    //cli:cli_enterprise_darwin_amd64
    //cli:cli_enterprise_darwin_arm64
    //cli:cli_enterprise_linux_amd64
    //cli:cli_enterprise_linux_arm64
    //cli:cli_enterprise_windows_amd64
    -
  8. -
  9. -

    Compare the build result with the downloaded release artifact.

    -
  10. -
-

Feedback

-

Reproduction failures often indicate a bug in the build system or in the build definitions. -Therefore, we're interested in any reproducibility issues you might encounter. -Start a bug report and describe the details of your build environment. -Make sure to include your result binary or a diffoscope report, if possible.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/workflows/s3proxy/index.html b/pr-preview/pr-4027/2.23/workflows/s3proxy/index.html deleted file mode 100644 index a7c82d6d2..000000000 --- a/pr-preview/pr-4027/2.23/workflows/s3proxy/index.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - -Install s3proxy | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Install s3proxy

-

Constellation includes a transparent client-side encryption proxy for AWS S3 and compatible stores. -s3proxy encrypts objects before sending them to S3 and automatically decrypts them on retrieval, without requiring changes to your application. -With s3proxy, you can use S3 for storage in a confidential way without having to trust the storage provider.

-

Limitations

-

Currently, s3proxy has the following limitations:

-
    -
  • Only PutObject and GetObject requests are encrypted/decrypted by s3proxy. -By default, s3proxy will block requests that may expose unencrypted data to S3 (e.g. UploadPart). -The allow-multipart flag disables request blocking for evaluation purposes.
  • -
  • Using the Range header on GetObject is currently not supported and will result in an error.
  • -
-

These limitations will be removed with future iterations of s3proxy. -If you want to use s3proxy but these limitations stop you from doing so, consider opening an issue.

-

Deployment

-

You can add the s3proxy to your Constellation cluster as follows:

-
    -
  1. Add the Edgeless Systems chart repository: -
    helm repo add edgeless https://helm.edgeless.systems/stable
    helm repo update
    -
  2. -
  3. Set ACCESS_KEY and ACCESS_SECRET to valid credentials you want s3proxy to use to interact with S3.
  4. -
  5. Deploy s3proxy: -
    helm install s3proxy edgeless/s3proxy --set awsAccessKeyID="$ACCESS_KEY" --set awsSecretAccessKey="$ACCESS_SECRET"
    -
  6. -
-

If you want to run a demo application, check out the Filestash with s3proxy example.

-

Technical details

-

Encryption

-

s3proxy relies on Google's Tink Cryptographic Library to implement cryptographic operations securely. -The used cryptographic primitives are NIST SP 800 38f for key wrapping and AES-GCM with 256 bit keys for data encryption.

-

s3proxy uses envelope encryption to encrypt objects. -This means s3proxy uses a key encryption key (KEK) issued by the KeyService to encrypt data encryption keys (DEKs). -Each S3 object is encrypted with its own DEK. -The encrypted DEK is then saved as metadata of the encrypted object. -This enables key rotation of the KEK without re-encrypting the data in S3. -The approach also allows access to objects from different locations, as long as each location has access to the KEK.

-

Traffic interception

-

To use s3proxy, you have to redirect your outbound S3 traffic to s3proxy. -This can either be done by modifying your client application or by changing the deployment of your application.

-

The necessary deployment modifications are to add DNS redirection and a trusted TLS certificate to the client's trust store. -DNS redirection can be defined for each pod, allowing you to use s3proxy for one application without changing other applications in the same cluster. -Adding a trusted TLS certificate is necessary as clients communicate with s3proxy via HTTPS. -To have your client application trust s3proxy's TLS certificate, the certificate has to be added to the client's certificate trust store. -The Filestash with s3proxy example shows how to do this.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/workflows/sbom/index.html b/pr-preview/pr-4027/2.23/workflows/sbom/index.html deleted file mode 100644 index 74aad23f5..000000000 --- a/pr-preview/pr-4027/2.23/workflows/sbom/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -Consume software bill of materials (SBOMs) | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Consume software bill of materials (SBOMs)

-
Loading asciinema cast...
-
-

Constellation builds produce a software bill of materials (SBOM) for each generated artifact. -You can use SBOMs to make informed decisions about dependencies and vulnerabilities in a given application. Enterprises rely on SBOMs to maintain an inventory of used applications, which allows them to take data-driven approaches to managing risks related to vulnerabilities.

-

SBOMs for Constellation are generated using Syft, signed using Cosign, and stored with the produced artifact.

-
note

The public key for Edgeless Systems' long-term code-signing key is:

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT
JmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==
-----END PUBLIC KEY-----

The public key is also available for download at https://edgeless.systems/es.pub and in the Twitter profile @EdgelessSystems.

Make sure the key is available in a file named cosign.pub to execute the following examples.

-

Verify and download SBOMs

-

The following sections detail how to work with each type of artifact to verify and extract the SBOM.

-

Constellation CLI

-

The SBOM for Constellation CLI is made available on the GitHub release page. The SBOM (constellation.spdx.sbom) and corresponding signature (constellation.spdx.sbom.sig) are valid for each Constellation CLI for a given version, regardless of architecture and operating system.

-
curl -LO https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom
curl -LO https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom.sig
cosign verify-blob --key cosign.pub --signature constellation.spdx.sbom.sig constellation.spdx.sbom
-

Container Images

-

SBOMs for container images are attached to the image using Cosign and uploaded to the same registry.

-

As a consumer, use cosign to download and verify the SBOM:

-
# Verify and download the attestation statement
cosign verify-attestation ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --type 'https://cyclonedx.org/bom' --key cosign.pub --output-file verification-service.att.json
# Extract SBOM from attestation statement
jq -r .payload verification-service.att.json | base64 -d > verification-service.cyclonedx.sbom
-

A successful verification should result in similar output:

-
$ cosign verify-attestation ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --type 'https://cyclonedx.org/bom' --key cosign.pub --output-file verification-service.sbom

Verification for ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key
$ jq -r .payload verification-service.sbom | base64 -d > verification-service.cyclonedx.sbom
-
note

This example considers only the verification-service. The same approach works for all containers in the Constellation container registry.

-

Vulnerability scanning

-

You can use a plethora of tools to consume SBOMs. This section provides suggestions for tools that are popular and known to produce reliable results, but any tool that consumes SPDX or CycloneDX files should work.

-

Syft is able to convert between the two formats in case you require a specific type.

-

Grype

-

Grype is a CLI tool that lends itself well for integration into CI/CD systems or local developer machines. It's also able to consume the signed attestation statement directly and does the verification in one go.

-
grype att:verification-service.sbom --key cosign.pub --add-cpes-if-none -q
-

Dependency Track

-

Dependency Track is one of the oldest and most mature solutions when it comes to managing software inventory and vulnerabilities. Once imported, it continuously scans SBOMs for new vulnerabilities. It supports the CycloneDX format and provides direct guidance on how to comply with U.S. Executive Order 14028.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/workflows/scale/index.html b/pr-preview/pr-4027/2.23/workflows/scale/index.html deleted file mode 100644 index 71a9cf29f..000000000 --- a/pr-preview/pr-4027/2.23/workflows/scale/index.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - -Scale your cluster | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Scale your cluster

-

Constellation provides all features of a Kubernetes cluster including scaling and autoscaling.

-

Worker node scaling

-

Autoscaling

-

Constellation comes with autoscaling disabled by default. To enable autoscaling, find the scaling group of -worker nodes:

-
kubectl get scalinggroups -o json | yq '.items | .[] | select(.spec.role == "Worker") | [{"name": .metadata.name, "nodeGoupName": .spec.nodeGroupName}]'
-

This will output a list of scaling groups with the corresponding cloud provider name (name) and the cloud provider agnostic name of the node group (nodeGroupName).

-

Then, patch the autoscaling field of the scaling group resource with the desired name to true:

-
# Replace <name> with the name of the scaling group you want to enable autoscaling for
worker_group=<name>
kubectl patch scalinggroups $worker_group --patch '{"spec":{"autoscaling": true}}' --type='merge'
kubectl get scalinggroup $worker_group -o jsonpath='{.spec}' | yq -P
-

The cluster autoscaler now automatically provisions additional worker nodes so that all pods have a place to run. -You can configure the minimum and maximum number of worker nodes in the scaling group by patching the min or -max fields of the scaling group resource:

-
kubectl patch scalinggroups $worker_group --patch '{"spec":{"max": 5}}' --type='merge'
kubectl get scalinggroup $worker_group -o jsonpath='{.spec}' | yq -P
-

The cluster autoscaler will now never provision more than 5 worker nodes.

-

If you want to see the autoscaling in action, try to add a deployment with a lot of replicas, like the -following Nginx deployment. The number of replicas needed to trigger the autoscaling depends on the size of -and count of your worker nodes. Wait for the rollout of the deployment to finish and compare the number of -worker nodes before and after the deployment:

-
kubectl create deployment nginx --image=nginx --replicas 150
kubectl -n kube-system get nodes
kubectl rollout status deployment nginx
kubectl -n kube-system get nodes
-

Manual scaling

-

Alternatively, you can manually scale your cluster up or down:

-
    -
  1. Go to Auto Scaling Groups and select the worker ASG to scale up.
  2. -
  3. Click Edit
  4. -
  5. Set the new (increased) Desired capacity and Update.
  6. -
-

Control-plane node scaling

-

Control-plane nodes can only be scaled manually and only scaled up!

-

To increase the number of control-plane nodes, follow these steps:

-
    -
  1. Go to Auto Scaling Groups and select the control-plane ASG to scale up.
  2. -
  3. Click Edit
  4. -
  5. Set the new (increased) Desired capacity and Update.
  6. -
-

If you scale down the number of control-planes nodes, the removed nodes won't be able to exit the etcd cluster correctly. This will endanger the quorum that's required to run a stable Kubernetes control plane.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/workflows/storage/index.html b/pr-preview/pr-4027/2.23/workflows/storage/index.html deleted file mode 100644 index ecc331b8b..000000000 --- a/pr-preview/pr-4027/2.23/workflows/storage/index.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - -Use persistent storage | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Use persistent storage

-

Persistent storage in Kubernetes requires cloud-specific configuration. -For abstraction of container storage, Kubernetes offers volumes, -allowing users to mount storage solutions directly into containers. -The Container Storage Interface (CSI) is the standard interface for exposing arbitrary block and file storage systems into containers in Kubernetes. -Cloud service providers (CSPs) offer their own CSI-based solutions for cloud storage.

-

Confidential storage

-

Most cloud storage solutions support encryption, such as GCE Persistent Disks (PD). -Constellation supports the available CSI-based storage options for Kubernetes engines in AWS, Azure, GCP, and STACKIT. -However, their encryption takes place in the storage backend and is managed by the CSP. -Thus, using the default CSI drivers for these storage types means trusting the CSP with your persistent data.

-

To address this, Constellation provides CSI drivers for AWS EBS, Azure Disk, GCE PD, and OpenStack Cinder, offering encryption on the node level. They enable transparent encryption for persistent volumes without needing to trust the cloud backend. Plaintext data never leaves the confidential VM context, offering you confidential storage.

-

For more details see encrypted persistent storage.

-

CSI drivers

-

Constellation supports the following drivers, which offer node-level encryption and optional integrity protection.

-

Constellation CSI driver for AWS Elastic Block Store -Mount Elastic Block Store storage volumes into your Constellation cluster. -Follow the instructions on how to install the Constellation CSI driver or check out the repository for more information.

-

Note that in case the options above aren't a suitable solution for you, Constellation is compatible with all other CSI-based storage options. For example, you can use AWS EFS, Azure Files, or GCP Filestore with Constellation out of the box. Constellation is just not providing transparent encryption on the node level for these storage types yet.

-

Installation

-

The Constellation CLI automatically installs Constellation's CSI driver for the selected CSP in your cluster. -If you don't need a CSI driver or wish to deploy your own, you can disable the automatic installation by setting deployCSIDriver to false in your Constellation config file.

-

AWS comes with two storage classes by default.

    -
  • encrypted-rwo -
      -
    • Uses SSDs of gp3 type
    • -
    • ext-4 filesystem
    • -
    • Encryption of all data written to disk
    • -
    -
  • -
  • integrity-encrypted-rwo -
      -
    • Uses SSDs of gp3 type
    • -
    • ext-4 filesystem
    • -
    • Encryption of all data written to disk
    • -
    • Integrity protection of data written to disk
    • -
    -
  • -

For more information on encryption algorithms and key sizes, refer to cryptographic algorithms.

info

The default storage class is set to encrypted-rwo for performance reasons. -If you want integrity-protected storage, set the storageClassName parameter of your persistent volume claim to integrity-encrypted-rwo.

Alternatively, you can create your own storage class with integrity protection enabled by adding csi.storage.k8s.io/fstype: ext4-integrity to the class parameters. -Or use another filesystem by specifying another file system type with the suffix -integrity, e.g., csi.storage.k8s.io/fstype: xfs-integrity.

Note that volume expansion isn't supported for integrity-protected disks.

-
    -
  1. -

    Create a persistent volume

    -

    A persistent volume claim is a request for storage with certain properties. -It can refer to a storage class. -The following creates a persistent volume claim, requesting 20 GB of storage via the encrypted-rwo storage class:

    -
    cat <<EOF | kubectl apply -f -
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
    name: pvc-example
    namespace: default
    spec:
    accessModes:
    - ReadWriteOnce
    storageClassName: encrypted-rwo
    resources:
    requests:
    storage: 20Gi
    EOF
    -
  2. -
  3. -

    Create a Pod with persistent storage

    -

    You can assign a persistent volume claim to an application in need of persistent storage. -The mounted volume will persist restarts. -The following creates a pod that uses the previously created persistent volume claim:

    -
    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Pod
    metadata:
    name: web-server
    namespace: default
    spec:
    containers:
    - name: web-server
    image: nginx
    volumeMounts:
    - mountPath: /var/lib/www/html
    name: mypvc
    volumes:
    - name: mypvc
    persistentVolumeClaim:
    claimName: pvc-example
    readOnly: false
    EOF
    -
  4. -
-

Change the default storage class

-

The default storage class is responsible for all persistent volume claims that don't explicitly request storageClassName. -Constellation creates a storage class with encryption enabled and sets this as the default class. -In case you wish to change it, follow the steps below:

-
    -
  1. -

    List the storage classes in your cluster:

    -
    kubectl get storageclass
    -

    The output is similar to this:

    -
    NAME                      PROVISIONER                         RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
    encrypted-rwo (default) {your-csp}.csi.confidential.cloud Delete Immediate true 1d
    integrity-encrypted-rwo {your-csp}.csi.confidential.cloud Delete Immediate false 1d
    -

    The default storage class is marked by (default).

    -
  2. -
  3. -

    Mark old default storage class as non default

    -

    If you previously used another storage class as the default, you will have to remove that annotation:

    -
    kubectl patch storageclass encrypted-rwo -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
    -
  4. -
  5. -

    Mark new class as the default

    -
    kubectl patch storageclass integrity-encrypted-rwo -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
    -
  6. -
  7. -

    Verify that your chosen storage class is default:

    -
    kubectl get storageclass
    -

    The output is similar to this:

    -
    NAME                                PROVISIONER                         RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
    encrypted-rwo {your-csp}.csi.confidential.cloud Delete Immediate true 1d
    integrity-encrypted-rwo (default) {your-csp}.csi.confidential.cloud Delete Immediate false 1d
    -
  8. -
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/workflows/terminate/index.html b/pr-preview/pr-4027/2.23/workflows/terminate/index.html deleted file mode 100644 index e1ae7013a..000000000 --- a/pr-preview/pr-4027/2.23/workflows/terminate/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - -Terminate your cluster | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Terminate your cluster

-
info

This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details.

-
Loading asciinema cast...
-
-

You can terminate your cluster using the CLI. For this, you need the Terraform state directory named constellation-terraform in the current directory.

-
danger

All ephemeral storage and state of your cluster will be lost. Make sure any data is safely stored in persistent storage. Constellation can recreate your cluster and the associated encryption keys, but won't backup your application data automatically.

-

Terminate the cluster by running:

constellation terminate

Or without confirmation (e.g., for automation purposes):

constellation terminate --yes

This deletes all resources created by Constellation in your cloud environment. -All local files created by the apply command are deleted as well, except for constellation-mastersecret.json and the configuration file.

caution

Termination can fail if additional resources have been created that depend on the ones managed by Constellation. In this case, you need to delete these additional -resources manually. Just run the terminate command again afterward to continue the termination process of the cluster.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/workflows/terraform-provider/index.html b/pr-preview/pr-4027/2.23/workflows/terraform-provider/index.html deleted file mode 100644 index 0c32460c3..000000000 --- a/pr-preview/pr-4027/2.23/workflows/terraform-provider/index.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - -Use the Terraform provider | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Use the Terraform provider

-

The Constellation Terraform provider allows to manage the full lifecycle of a Constellation cluster (namely creation, upgrades, and deletion) via Terraform. -The provider is available through the Terraform registry and is released in lock-step with Constellation releases.

-

Prerequisites

-
    -
  • a Linux / Mac operating system (ARM64/AMD64)
  • -
  • a Terraform installation of version v1.4.4 or above
  • -
-

Quick setup

-

This example shows how to set up a Constellation cluster with the reference IAM and infrastructure setup. This setup is also used when creating a Constellation cluster through the Constellation CLI. You can either consume the IAM / infrastructure modules through a remote source (recommended) or local files. The latter requires downloading the infrastructure and IAM modules for the corresponding CSP from terraform-modules.zip on the Constellation release page and placing them in the Terraform workspace directory.

-
    -
  1. Create a directory (workspace) for your Constellation cluster.
  2. -
-
mkdir constellation-workspace
cd constellation-workspace
-
    -
  1. Use one of the example configurations for using the Constellation Terraform provider or create a main.tf file and fill it with the resources you want to create. The Constellation Terraform provider documentation offers thorough documentation on the resources and their attributes.
  2. -
  3. Initialize and apply the Terraform configuration.
  4. -
-

Initialize the providers and apply the configuration.

terraform init
terraform apply

Optionally, you can prefix the terraform apply command with TF_LOG=INFO to collect Terraform logs while applying the configuration. This may provide helpful output in debugging scenarios.

-
    -
  1. Connect to the cluster.
  2. -
-
terraform output -raw kubeconfig > constellation-admin.conf
export KUBECONFIG=$(realpath constellation-admin.conf)
-

Bringing your own infrastructure

-

Instead of using the example infrastructure used in the quick setup, you can also provide your own infrastructure. -If you need a starting point for a custom infrastructure setup, you can download the infrastructure / IAM Terraform modules for the respective CSP from the Constellation GitHub releases. You can modify and extend the modules per your requirements, while keeping the basic functionality intact. -The module contains:

-
    -
  • {csp}: cloud resources the cluster runs on
  • -
  • iam/{csp}: IAM resources used within the cluster
  • -
-

When upgrading your cluster, make sure to check the Constellation release notes for potential breaking changes in the reference infrastructure / IAM modules that need to be considered.

-

Cluster upgrades

- -

The steps for applying the upgrade are as follows:

-
    -
  1. Update the version constraint of the Constellation Terraform provider in the required_providers block in your Terraform configuration.
  2. -
  3. If you explicitly set any of the version attributes of the provider's resources and data sources (e.g. image_version or constellation_microservice_version), make sure to update them too. Refer to Constellation's version support policy for more information on how each Constellation version and its dependencies are supported.
  4. -
  5. Update the IAM / infrastructure configuration. - -
  6. -
  7. Upgrade the Terraform module and provider dependencies and apply the targeted configuration.
  8. -
-
  terraform init -upgrade
terraform apply
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/workflows/troubleshooting/index.html b/pr-preview/pr-4027/2.23/workflows/troubleshooting/index.html deleted file mode 100644 index f7090d931..000000000 --- a/pr-preview/pr-4027/2.23/workflows/troubleshooting/index.html +++ /dev/null @@ -1,115 +0,0 @@ - - - - - -Troubleshooting | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Troubleshooting

-

This section aids you in finding problems when working with Constellation.

-

Common issues

-

Issues with creating new clusters

-

When you create a new cluster, you should always use the latest release. -If something doesn't work, check out the known issues.

-

Azure: Resource Providers can't be registered

-

On Azure, you may receive the following error when running apply or terminate with limited IAM permissions:

-
Error: Error ensuring Resource Providers are registered.

Terraform automatically attempts to register the Resource Providers it supports to
ensure it's able to provision resources.

If you don't have permission to register Resource Providers you may wish to use the
"skip_provider_registration" flag in the Provider block to disable this functionality.

[...]
-

To continue, please ensure that the required resource providers have been registered in your subscription by your administrator.

-

Afterward, set ARM_SKIP_PROVIDER_REGISTRATION=true as an environment variable and either run apply or terminate again. -For example:

-
ARM_SKIP_PROVIDER_REGISTRATION=true constellation apply
-

Or alternatively, for terminate:

-
ARM_SKIP_PROVIDER_REGISTRATION=true constellation terminate
-

Azure: Can't update attestation policy

-

On Azure, you may receive the following error when running apply from within an Azure environment, e.g., an Azure VM:

-
An error occurred: patching policies: updating attestation policy: unexpected status code: 403 Forbidden
-

The problem occurs because the Azure SDK we use internally attempts to authenticate towards the Azure API with the managed identity of your current environment instead of the Azure CLI token.

-

We decided not to deviate from this behavior and comply with the ordering of credentials.

-

A solution is to add the required permissions to the managed identity of your environment. For example, the managed identity of your Azure VM, instead of the account that you've authenticated with in the Azure CLI.

-

If your setup requires a change in the ordering of credentials, please open an issue and explain your desired behavior.

-

Nodes fail to join with error untrusted measurement value

-

This error indicates that a node's attestation statement contains measurements that don't match the trusted values expected by the JoinService. -This may for example happen if the cloud provider updates the VM's firmware such that it influences the runtime measurements in an unforeseen way. -A failed upgrade due to an erroneous attestation config can also cause this error. -You can change the expected measurements to resolve the failure.

-
caution

Attestation and trusted measurements are crucial for the security of your cluster. -Be extra careful when manually changing these settings. -When in doubt, check if the encountered issue is known or contact support.

-
tip

During an upgrade with modified attestation config, a backup of the current configuration is stored in the join-config config map in the kube-system namespace under the attestationConfig_backup key. To restore the old attestation config after a failed upgrade, replace the value of attestationConfig with the value from attestationConfig_backup:

kubectl patch configmaps -n kube-system join-config -p "{\"data\":{\"attestationConfig\":\"$(kubectl get configmaps -n kube-system join-config -o "jsonpath={.data.attestationConfig_backup}")\"}}"
-

You can use the apply command to change measurements of a running cluster:

-
    -
  1. Modify the measurements key in your local constellation-conf.yaml to the expected values.
  2. -
  3. Run constellation apply.
  4. -
-

Keep in mind that running apply also applies any version changes from your config to the cluster.

-

You can run these commands to learn about the versions currently configured in the cluster:

-
    -
  • Kubernetes API server version: kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.kubernetesClusterVersion
  • -
  • image version: kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.imageVersion
  • -
  • microservices versions: helm list --filter 'constellation-services' -n kube-system
  • -
-

Upgrading Kubernetes resources fails

-

Constellation manages its Kubernetes resources using Helm. -When applying an upgrade, the charts that are about to be installed, and a values override file overrides.yaml, -are saved to disk in your current workspace under constellation-upgrade/upgrade-<timestamp>/helm-charts/. -If upgrading the charts using the Constellation CLI fails, you can review these charts and try to manually apply the upgrade.

-
caution

Changing and manually applying the charts may destroy cluster resources and can lead to broken Constellation deployments. -Proceed with caution and when in doubt, -check if the encountered issue is known or contact support.

-

Diagnosing issues

-

Logs

-

To get started on diagnosing issues with Constellation, it's often helpful to collect logs from nodes, pods, or other resources in the cluster. Most logs are available through Kubernetes' standard -logging interfaces.

-

To debug issues occurring at boot time of the nodes, you can use the serial console interface of the CSP while the machine boots to get a read-only view of the boot logs.

-

Apart from that, Constellation also offers further observability integrations.

-

Node shell access

-

Debugging via a shell on a node is directly supported by Kubernetes.

-
    -
  1. -

    Figure out which node to connect to:

    -
    kubectl get nodes
    # or to see more information, such as IPs:
    kubectl get nodes -o wide
    -
  2. -
  3. -

    Connect to the node:

    -
    kubectl debug node/constell-worker-xksa0-000000 -it --image=busybox
    -

    You will be presented with a prompt.

    -

    The nodes file system is mounted at /host.

    -
  4. -
  5. -

    Once finished, clean up the debug pod:

    -
    kubectl delete pod node-debugger-constell-worker-xksa0-000000-bjthj
    -
  6. -
-

Emergency SSH access

-

Emergency SSH access to nodes can be useful to diagnose issues or download important data even if the Kubernetes API isn't reachable anymore.

-
    -
  1. -

    Enter the constellation-terraform directory in your Constellation workspace and enable emergency SSH access to the cluster:

    -
     cd constellation-terraform
    echo "emergency_ssh = true" >> ./terraform.tfvars
    terraform apply
    -
  2. -
  3. -

    Sign an existing SSH key with your master secret:

    -
    cd ../ # go back to your Constellation workspace
    constellation ssh --key your_public_key.pub
    -

    A certificate is written to constellation_cert.pub.

    -

    The certificate is valid for 24 hours and enables you to access your Constellation nodes using -certificate based authentication.

    -
  4. -
  5. -

    Now you can connect to any Constellation node using your certificate and your private key.

    -
    ssh -o CertificateFile=constellation_cert.pub -i <your private key> root@<ip of constellation node>
    -

    Normally, you don't have access to the Constellation nodes since they reside in a private network. -To access those nodes anyways, you can use your Constellation load balancer as a proxy jump host. -For this, use something along the following SSH client configuration:

    -
    Host <LB domain name>
    ProxyJump none

    Host *
    IdentityFile <your private key>
    PreferredAuthentications publickey
    CertificateFile=constellation_cert.pub
    User root
    ProxyJump <LB domain name>
    -

    With this configuration you can connect to a Constellation node using ssh -F <this config> <private node IP>. -You can obtain the private node IP and the domain name of the load balancer using your CSP's web UI.

    -
  6. -
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/workflows/trusted-launch/index.html b/pr-preview/pr-4027/2.23/workflows/trusted-launch/index.html deleted file mode 100644 index 4a31e4e01..000000000 --- a/pr-preview/pr-4027/2.23/workflows/trusted-launch/index.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - -Use Azure trusted launch VMs | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Use Azure trusted launch VMs

-

Constellation also supports trusted launch VMs on Microsoft Azure. Trusted launch VMs don't offer the same level of security as Confidential VMs, but are available in more regions and in larger quantities. The main difference between trusted launch VMs and normal VMs is that the former offer vTPM-based remote attestation. When used with trusted launch VMs, Constellation relies on vTPM-based remote attestation to verify nodes.

-
caution

Trusted launch VMs don't provide runtime encryption and don't keep the cloud service provider (CSP) out of your trusted computing base.

-

Constellation supports trusted launch VMs with instance types Standard_D*_v4 and Standard_E*_v4. Run constellation config instance-types for a list of all supported instance types.

-

VM images

-

Azure currently doesn't support community galleries for trusted launch VMs. Thus, you need to manually import the Constellation node image into your cloud subscription.

-

The latest image is available at https://cdn.confidential.cloud/constellation/images/azure/trusted-launch/v2.2.0/constellation.img. Simply adjust the version number to download a newer version.

-

After you've downloaded the image, create a resource group constellation-images in your Azure subscription and import the image. -You can use a script to do this:

-
wget https://raw.githubusercontent.com/edgelesssys/constellation/main/hack/importAzure.sh
chmod +x importAzure.sh
AZURE_IMAGE_VERSION=2.2.0 AZURE_RESOURCE_GROUP_NAME=constellation-images AZURE_IMAGE_FILE=./constellation.img ./importAzure.sh
-

The script creates the following resources:

-
    -
  1. A new image gallery with the default name constellation-import
  2. -
  3. A new image definition with the default name constellation
  4. -
  5. The actual image with the provided version. In this case 2.2.0
  6. -
-

Once the import is completed, use the ID of the image version in your constellation-conf.yaml for the image field. Set confidentialVM to false.

-

Fetch the image measurements:

-
IMAGE_VERSION=2.2.0
URL=https://public-edgeless-constellation.s3.us-east-2.amazonaws.com//communitygalleries/constellationcvm-b3782fa0-0df7-4f2f-963e-fc7fc42663df/images/constellation/versions/$IMAGE_VERSION/measurements.yaml
constellation config fetch-measurements -u$URL -s$URL.sig
-
info

The constellation apply command will issue a warning because manually imported images aren't recognized as production grade images:

Configured image doesn't look like a released production image. Double check image before deploying to production.

Please ignore this warning.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/workflows/upgrade/index.html b/pr-preview/pr-4027/2.23/workflows/upgrade/index.html deleted file mode 100644 index de4c6fe69..000000000 --- a/pr-preview/pr-4027/2.23/workflows/upgrade/index.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - - -Upgrade your cluster | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Upgrade your cluster

-

Constellation provides an easy way to upgrade all components of your cluster, without disrupting its availability. -Specifically, you can upgrade the Kubernetes version, the nodes' image, and the Constellation microservices. -You configure the desired versions in your local Constellation configuration and trigger upgrades with the apply command. -To learn about available versions you use the upgrade check command. -Which versions are available depends on the CLI version you are using.

-

Update the CLI

-

Each CLI comes with a set of supported microservice and Kubernetes versions. -Most importantly, a given CLI version can only upgrade a cluster of the previous minor version, but not older ones. -This means that you have to upgrade your CLI and cluster one minor version at a time.

-

For example, if you are currently on CLI version v2.6 and the latest version is v2.8, you should

-
    -
  • upgrade the CLI to v2.7,
  • -
  • upgrade the cluster to v2.7,
  • -
  • and only then continue upgrading the CLI (and the cluster) to v2.8 after.
  • -
-

Also note that if your current Kubernetes version isn't supported by the next CLI version, use your current CLI to upgrade to a newer Kubernetes version first.

-

To learn which Kubernetes versions are supported by a particular CLI, run constellation config kubernetes-versions.

-

Migrate the configuration

-

The Constellation configuration file is located in the file constellation-conf.yaml in your workspace. -Refer to the migration reference to check if you need to update fields in your configuration file. -Use constellation config migrate to automatically update an old config file to a new format.

-

Check for upgrades

-

To learn which versions the current CLI can upgrade to and what's installed in your cluster, run:

-
# Show possible upgrades
constellation upgrade check

# Show possible upgrades and write them to config file
constellation upgrade check --update-config
-

You can either enter the reported target versions into your config manually or run the above command with the --update-config flag. -When using this flag, the kubernetesVersion, image, microserviceVersion, and attestation fields are overwritten with the smallest available upgrade.

-

Apply the upgrade

-

Once you updated your config with the desired versions, you can trigger the upgrade with this command:

-
constellation apply
-

Microservice upgrades will be finished within a few minutes, depending on the cluster size. -If you are interested, you can monitor pods restarting in the kube-system namespace with your tool of choice.

-

Image and Kubernetes upgrades take longer. -For each node in your cluster, a new node has to be created and joined. -The process usually takes up to ten minutes per node.

-

When applying an upgrade, the Helm charts for the upgrade as well as backup files of Constellation-managed Custom Resource Definitions, Custom Resources, and Terraform state are created. -You can use the Terraform state backup to restore previous resources in case an upgrade misconfigured or erroneously deleted a resource. -You can use the Custom Resource (Definition) backup files to restore Custom Resources and Definitions manually (e.g., via kubectl apply) if the automatic migration of those resources fails. -You can use the Helm charts to manually apply upgrades to the Kubernetes resources, should an upgrade fail.

-
note

For advanced users: the upgrade consists of several phases that can be individually skipped through the --skip-phases flag. -The phases are infrastracture for the cloud resource management through Terraform, helm for the chart management of the microservices, image for OS image upgrades, and k8s for Kubernetes version upgrades.

-

Check the status

-

Upgrades are asynchronous operations. -After you run apply, it will take a while until the upgrade has completed. -To understand if an upgrade is finished, you can run:

-
constellation status
-

This command displays the following information:

-
    -
  • The installed services and their versions
  • -
  • The image and Kubernetes version the cluster is expecting on each node
  • -
  • How many nodes are up to date
  • -
-

Here's an example output:

-
Target versions:
Image: v2.6.0
Kubernetes: v1.25.8
Service versions:
Cilium: v1.12.1
cert-manager: v1.10.0
constellation-operators: v2.6.0
constellation-services: v2.6.0
Cluster status: Some node versions are out of date
Image: 23/25
Kubernetes: 25/25
-

This output indicates that the cluster is running Kubernetes version 1.25.8, and all nodes have the appropriate binaries installed. -23 out of 25 nodes have already upgraded to the targeted image version of 2.6.0, while two are still in progress.

-

Apply further upgrades

-

After the upgrade is finished, you can run constellation upgrade check again to see if there are more upgrades available. If so, repeat the process.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/workflows/verify-cli/index.html b/pr-preview/pr-4027/2.23/workflows/verify-cli/index.html deleted file mode 100644 index c0d6d0d35..000000000 --- a/pr-preview/pr-4027/2.23/workflows/verify-cli/index.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - -Verify the CLI | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Verify the CLI

-
info

This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details.

-
Loading asciinema cast...
-
-

Edgeless Systems uses sigstore and SLSA to ensure supply-chain security for the Constellation CLI and node images ("artifacts"). sigstore consists of three components: Cosign, Rekor, and Fulcio. Edgeless Systems uses Cosign to sign artifacts. All signatures are uploaded to the public Rekor transparency log, which resides at https://rekor.sigstore.dev.

-
note

The public key for Edgeless Systems' long-term code-signing key is:

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT
JmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==
-----END PUBLIC KEY-----

The public key is also available for download at https://edgeless.systems/es.pub and in the Twitter profile @EdgelessSystems.

-

The Rekor transparency log is a public append-only ledger that verifies and records signatures and associated metadata. The Rekor transparency log enables everyone to observe the sequence of (software) signatures issued by Edgeless Systems and many other parties. The transparency log allows for the public identification of dubious or malicious signatures.

-

You should always ensure that (1) your CLI executable was signed with the private key corresponding to the above public key and that (2) there is a corresponding entry in the Rekor transparency log. Both can be done as described in the following.

-
info

You don't need to verify the Constellation node images. This is done automatically by your CLI and the rest of Constellation.

-

Verify the signature

-
info

This guide assumes Linux on an amd64 processor. The exact steps for other platforms differ slightly.

-

First, install the Cosign CLI. Next, download and verify the signature that accompanies your CLI executable, for example:

-
$ cosign verify-blob --key https://edgeless.systems/es.pub --signature constellation-linux-amd64.sig constellation-linux-amd64

Verified OK
-

The above performs an offline verification of the provided public key, signature, and executable. To also verify that a corresponding entry exists in the public Rekor transparency log, add the variable COSIGN_EXPERIMENTAL=1:

-
$ COSIGN_EXPERIMENTAL=1 cosign verify-blob --key https://edgeless.systems/es.pub --signature constellation-linux-amd64.sig constellation-linux-amd64

tlog entry verified with uuid: afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13 index: 3477047
Verified OK
-

🏁 You now know that your CLI executable was officially released and signed by Edgeless Systems.

-

Optional: Manually inspect the transparency log

-

To further inspect the public Rekor transparency log, install the Rekor CLI. A search for the CLI executable should give a single UUID. (Note that this UUID contains the UUID from the previous cosign command.)

-
$ rekor-cli search --artifact constellation-linux-amd64

Found matching entries (listed by UUID):
362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13
-

With this UUID you can get the full entry from the transparency log:

-
$ rekor-cli get --uuid=362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13

LogID: c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d
Index: 3477047
IntegratedTime: 2022-09-12T22:28:16Z
UUID: afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13
Body: {
"HashedRekordObj": {
"data": {
"hash": {
"algorithm": "sha256",
"value": "40e137b9b9b8204d672642fd1e181c6d5ccb50cfc5cc7fcbb06a8c2c78f44aff"
}
},
"signature": {
"content": "MEUCIQCSER3mGj+j5Pr2kOXTlCIHQC3gT30I7qkLr9Awt6eUUQIgcLUKRIlY50UN8JGwVeNgkBZyYD8HMxwC/LFRWoMn180=",
"publicKey": {
"content": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFZjhGMWhwbXdFK1lDRlh6akd0YVFjckw2WFpWVApKbUVlNWlTTHZHMVN5UVNBZXc3V2RNS0Y2bzl0OGUyVEZ1Q2t6bE9oaGx3czJPSFdiaUZabkZXQ0Z3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=="
}
}
}
}
-

The field publicKey should contain Edgeless Systems' public key in Base64 encoding.

-

You can get an exhaustive list of artifact signatures issued by Edgeless Systems via the following command:

-
rekor-cli search --public-key https://edgeless.systems/es.pub --pki-format x509
-

Edgeless Systems monitors this list to detect potential unauthorized use of its private key.

-

Verify the provenance

-

Provenance attests that a software artifact was produced by a specific repository and build system invocation. For more information on provenance visit slsa.dev and learn about the adoption of SLSA for Constellation.

-

Just as checking its signature proves that the CLI hasn't been manipulated, checking the provenance proves that the artifact was produced by the expected build process and hasn't been tampered with.

-

To verify the provenance, first install the slsa-verifier. Then make sure you have the provenance file (constellation.intoto.jsonl) and Constellation CLI downloaded. Both are available on the GitHub release page.

-
info

The same provenance file is valid for all Constellation CLI executables of a given version independent of the target platform.

-

Use the verifier to perform the check:

-
$ slsa-verifier verify-artifact constellation-linux-amd64 \
--provenance-path constellation.intoto.jsonl \
--source-uri github.com/edgelesssys/constellation

Verified signature against tlog entry index 7771317 at URL: https://rekor.sigstore.dev/api/v1/log/entries/24296fb24b8ad77af2c04c8b4ae0d5bc5...
Verified build using builder https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v1.2.2 at commit 18e9924b416323c37b9cdfd6cc728de8a947424a
PASSED: Verified SLSA provenance
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/2.23/workflows/verify-cluster/index.html b/pr-preview/pr-4027/2.23/workflows/verify-cluster/index.html deleted file mode 100644 index 7696c98ab..000000000 --- a/pr-preview/pr-4027/2.23/workflows/verify-cluster/index.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - -Verify your cluster | Constellation - - - - - - - -
Skip to main content
Version: 2.23

Verify your cluster

-

Constellation's attestation feature allows you, or a third party, to verify the integrity and confidentiality of your Constellation cluster.

-

Fetch measurements

-

To verify the integrity of Constellation you need trusted measurements to verify against. For each node image released by Edgeless Systems, there are signed measurements, which you can download using the CLI:

-
constellation config fetch-measurements
-

This command performs the following steps:

-
    -
  1. Download the signed measurements for the configured image. By default, this will use Edgeless Systems' public measurement registry.
  2. -
  3. Verify the signature of the measurements. This will use Edgeless Systems' public key.
  4. -
  5. Write measurements into configuration file.
  6. -
-

The configuration file then contains a list of measurements similar to the following:

-
# ...
measurements:
0:
expected: "0f35c214608d93c7a6e68ae7359b4a8be5a0e99eea9107ece427c4dea4e439cf"
warnOnly: false
4:
expected: "02c7a67c01ec70ffaf23d73a12f749ab150a8ac6dc529bda2fe1096a98bf42ea"
warnOnly: false
5:
expected: "e6949026b72e5045706cd1318889b3874480f7a3f7c5c590912391a2d15e6975"
warnOnly: true
8:
expected: "0000000000000000000000000000000000000000000000000000000000000000"
warnOnly: false
9:
expected: "f0a6e8601b00e2fdc57195686cd4ef45eb43a556ac1209b8e25d993213d68384"
warnOnly: false
11:
expected: "0000000000000000000000000000000000000000000000000000000000000000"
warnOnly: false
12:
expected: "da99eb6cf7c7fbb692067c87fd5ca0b7117dc293578e4fea41f95d3d3d6af5e2"
warnOnly: false
13:
expected: "0000000000000000000000000000000000000000000000000000000000000000"
warnOnly: false
14:
expected: "d7c4cc7ff7933022f013e03bdee875b91720b5b86cf1753cad830f95e791926f"
warnOnly: true
15:
expected: "0000000000000000000000000000000000000000000000000000000000000000"
warnOnly: false
# ...
-

Each entry specifies the expected value of the Constellation node, and whether the measurement should be enforced (warnOnly: false), or only a warning should be logged (warnOnly: true). -By default, the subset of the available measurements that can be locally reproduced and verified is enforced.

-

During attestation, the validating side (CLI or join service) compares each measurement reported by the issuing side (first node or joining node) individually. -For mismatching measurements that have set warnOnly to true only a warning is emitted. -For mismatching measurements that have set warnOnly to false an error is emitted and attestation fails. -If attestation fails for a new node, it isn't permitted to join the cluster.

-

The verify command

-
note

The steps below are purely optional. They're automatically executed by constellation apply when you initialize your cluster. The constellation verify command mostly has an illustrative purpose.

-

The verify command obtains and verifies an attestation statement from a running Constellation cluster.

-
constellation verify [--cluster-id ...]
-

From the attestation statement, the command verifies the following properties:

-
    -
  • The cluster is using the correct Confidential VM (CVM) type.
  • -
  • Inside the CVMs, the correct node images are running. The node images are identified through the measurements obtained in the previous step.
  • -
  • The unique ID of the cluster matches the one from your constellation-state.yaml file or passed in via --cluster-id.
  • -
-

Once the above properties are verified, you know that you are talking to the right Constellation cluster and it's in a good and trustworthy shape.

-

Custom arguments

-

The verify command also allows you to verify any Constellation deployment that you have network access to. For this you need the following:

-
    -
  • The IP address of a running Constellation cluster's VerificationService. The VerificationService is exposed via a NodePort service using the external IP address of your cluster. Run kubectl get nodes -o wide and look for EXTERNAL-IP.
  • -
  • The cluster's clusterID. See cluster identity for more details.
  • -
  • A constellation-conf.yaml file with the expected measurements of the cluster in your working directory.
  • -
-

For example:

-
constellation verify -e 192.0.2.1 --cluster-id Q29uc3RlbGxhdGlvbkRvY3VtZW50YXRpb25TZWNyZXQ=
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/404.html b/pr-preview/pr-4027/404.html deleted file mode 100644 index dd8ebff69..000000000 --- a/pr-preview/pr-4027/404.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Constellation - - - - - - - -
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/_redirects b/pr-preview/pr-4027/_redirects deleted file mode 100644 index 32cfa8c84..000000000 --- a/pr-preview/pr-4027/_redirects +++ /dev/null @@ -1 +0,0 @@ -/constellation/* /:splat 200! diff --git a/pr-preview/pr-4027/architecture/attestation/index.html b/pr-preview/pr-4027/architecture/attestation/index.html deleted file mode 100644 index 072d4d5c5..000000000 --- a/pr-preview/pr-4027/architecture/attestation/index.html +++ /dev/null @@ -1,229 +0,0 @@ - - - - - -Attestation | Constellation - - - - - - - -
Skip to main content
Version: 2.24

Attestation

-

This page explains Constellation's attestation process and highlights the cornerstones of its trust model.

-

Terms

-

The following lists terms and concepts that help to understand the attestation concept of Constellation.

-

Trusted Platform Module (TPM)

-

A TPM chip is a dedicated tamper-resistant crypto-processor. -It can securely store artifacts such as passwords, certificates, encryption keys, or runtime measurements (more on this below). -When a TPM is implemented in software, it's typically called a virtual TPM (vTPM).

-

Runtime measurement

-

A runtime measurement is a cryptographic hash of the memory pages of a so called runtime component. Runtime components of interest typically include a system's bootloader or OS kernel.

-

Platform Configuration Register (PCR)

-

A Platform Configuration Register (PCR) is a memory location in the TPM that has some unique properties. -To store a new value in a PCR, the existing value is extended with a new value as follows:

-
PCR[N] = HASHalg( PCR[N] || ArgumentOfExtend )
-

The PCRs are typically used to store runtime measurements. -The new value of a PCR is always an extension of the existing value. -Thus, storing the measurements of multiple components into the same PCR irreversibly links them together.

-

Measured boot

-

Measured boot builds on the concept of chained runtime measurements. -Each component in the boot chain loads and measures the next component into the PCR before executing it. -By comparing the resulting PCR values against trusted reference values, the integrity of the entire boot chain and thereby the running system can be ensured.

-

Remote attestation (RA)

-

Remote attestation is the process of verifying certain properties of an application or platform, such as integrity and confidentiality, from a remote location. -In the case of a measured boot, the goal is to obtain a signed attestation statement on the PCR values of the boot measurements. -The statement can then be verified and compared to a set of trusted reference values. -This way, the integrity of the platform can be ensured before sharing secrets with it.

-

Confidential virtual machine (CVM)

-

Confidential computing (CC) is the protection of data in-use with hardware-based trusted execution environments (TEEs). -With CVMs, TEEs encapsulate entire virtual machines and isolate them against the hypervisor, other VMs, and direct memory access. -After loading the initial VM image into encrypted memory, the hypervisor calls for a secure processor to measure these initial memory pages. -The secure processor locks these pages and generates an attestation report on the initial page measurements. -CVM memory pages are encrypted with a key that resides inside the secure processor, which makes sure only the guest VM can access them. -The attestation report is signed by the secure processor and can be verified using remote attestation via the certificate authority of the hardware vendor. -Such an attestation statement guarantees the confidentiality and integrity of a CVM.

-

Attested TLS (aTLS)

-

In a CC environment, attested TLS (aTLS) can be used to establish secure connections between two parties using the remote attestation features of the CC components.

-

aTLS modifies the TLS handshake by embedding an attestation statement into the TLS certificate. -Instead of relying on a certificate authority, aTLS uses this attestation statement to establish trust in the certificate.

-

The protocol can be used by clients to verify a server certificate, by a server to verify a client certificate, or for mutual verification (mutual aTLS).

-

Overview

-

The challenge for Constellation is to lift a CVM's attestation statement to the Kubernetes software layer and make it end-to-end verifiable. -From there, Constellation needs to expand the attestation from a single CVM to the entire cluster.

-

The JoinService and VerificationService are where all runs together. -Internally, the JoinService uses remote attestation to securely join CVM nodes to the cluster. -Externally, the VerificationService provides an attestation statement for the cluster's CVMs and configuration.

-

The following explains the details of both steps.

-

Node attestation

-

The idea is that Constellation nodes should have verifiable integrity from the CVM hardware measurement up to the Kubernetes software layer. -The solution is a verifiable boot chain and an integrity-protected runtime environment.

-

Constellation uses measured boot within CVMs, measuring each component in the boot process before executing it. -Outside of CC, this is usually implemented via TPMs. -CVM technologies differ in how they implement runtime measurements, but the general concepts are similar to those of a TPM. -For simplicity, TPM terminology like PCR is used in the following.

-

When a Constellation node image boots inside a CVM, measured boot is used for all stages and components of the boot chain. -This process goes up to the root filesystem. -The root filesystem is mounted read-only with integrity protection. -For the details on the image and boot stages see the image architecture documentation. -Any changes to the image will inevitably also change the corresponding PCR values. -To create a node attestation statement, the Constellation image obtains a CVM attestation statement from the hardware. -This includes the runtime measurements and thereby binds the measured boot results to the CVM hardware measurement.

-

In addition to the image measurements, Constellation extends a PCR during the initialization phase that irrevocably marks the node as initialized. -The measurement is created using the clusterID, tying all future attestation statements to this ID. -Thereby, an attestation statement is unique for every cluster and a node can be identified unambiguously as being initialized.

-

To verify an attestation, the hardware's signature and a statement are verified first to establish trust in the contained runtime measurements. -If successful, the measurements are verified against the trusted values of the particular Constellation release version. -Finally, the measurement of the clusterID can be compared by calculating it with the master secret.

-

Runtime measurements

-

Constellation uses runtime measurements to implement the measured boot approach. -As stated above, the underlying hardware technology and guest firmware differ in their implementations of runtime measurements. -The following gives a detailed description of the available measurements in the different cloud environments.

-

The runtime measurements consist of two types of values:

-
    -
  • -

    Measurements produced by the cloud infrastructure and firmware of the CVM: -These are measurements of closed-source firmware and other values controlled by the cloud provider. -While not being reproducible for the user, some of them can be compared against previously observed values. -Others may change frequently and aren't suitable for verification. -The signed image measurements include measurements that are known, previously observed values.

    -
  • -
  • -

    Measurements produced by the Constellation bootloader and boot chain: -The Constellation Bootloader takes over from the CVM firmware and measures the rest of the boot chain. -The Constellation Bootstrapper is the first user mode component that runs in a Constellation image. -It extends PCR registers with the IDs of the cluster marking a node as initialized.

    -
  • -
-

Constellation allows to specify in the config which measurements should be enforced during the attestation process. -Enforcing non-reproducible measurements controlled by the cloud provider means that changes in these values require manual updates to the cluster's config. -By default, Constellation only enforces measurements that are stable values produced by the infrastructure or by Constellation directly.

-

Constellation uses the vTPM (NitroTPM) feature of the AWS Nitro System on AWS for runtime measurements.

The vTPM adheres to the TPM 2.0 specification. -The VMs are attested by obtaining signed PCR values over the VM's boot configuration from the TPM and comparing them to a known, good state (measured boot).

The following table lists all PCR values of the vTPM and the measured components. -It also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable. -The latter means that the value can be generated offline and compared to the one in the vTPM.

PCRComponentsMeasured byReproducible and verifiable
0FirmwareAWSNo
1FirmwareAWSNo
2FirmwareAWSNo
3FirmwareAWSNo
4Constellation Bootloader, Kernel, initramfs, Kernel command lineAWS, Constellation BootloaderYes
5FirmwareAWSNo
6FirmwareAWSNo
7Secure Boot PolicyAWS, Constellation BootloaderNo
8---
9initramfs, Kernel command lineLinux KernelYes
10User spaceLinux IMANo1
11Unified Kernel Image componentsConstellation BootloaderYes
12Reserved(User space, Constellation Bootloader)Yes
13Reserved(Constellation Bootloader)Yes
14Secure Boot StateConstellation BootloaderNo
15ClusterIDConstellation BootstrapperYes
16–23Unused--
-

CVM verification

-

To verify the integrity of the received attestation statement, a chain of trust from the CVM technology to the interface providing the statement has to be established. -For verification of the CVM technology, Constellation may expose additional options in its config file.

-

On AWS, AMD SEV-SNP is used to provide runtime encryption to the VMs. -An SEV-SNP attestation report is used to establish trust in the VM. -You may customize certain parameters for verification of the attestation statement using the Constellation config file.

    -
  • -

    TCB versions

    -

    You can set the minimum version numbers of components in the SEV-SNP TCB. -Use the latest versions to enforce that only machines with the most recent firmware updates are allowed to join the cluster. -Alternatively, you can set a lower minimum version to allow slightly out-of-date machines to still be able to join the cluster.

    -
  • -
  • -

    AMD Root Key Certificate

    -

    This certificate is the root of trust for verifying the SEV-SNP certificate chain.

    -
  • -
  • -

    AMD Signing Key Certificate

    -

    This is the intermediate certificate for verifying the SEV-SNP report's signature. -If it's not specified, the CLI fetches it from the AMD key distribution server.

    -
  • -
-

Cluster attestation

-

Cluster-facing, Constellation's JoinService verifies each node joining the cluster given the configured ground truth runtime measurements. -User-facing, the VerificationService provides an interface to verify a node using remote attestation. -By verifying the first node during the initialization and configuring the ground truth measurements that are subsequently enforced by the JoinService, the whole cluster is verified in a transitive way.

-

Cluster-facing attestation

-

The JoinService is provided with the runtime measurements of the whitelisted Constellation image version as the ground truth. -During the initialization and the cluster bootstrapping, each node connects to the JoinService using aTLS. -During the handshake, the node transmits an attestation statement including its runtime measurements. -The JoinService verifies that statement and compares the measurements against the ground truth. -For details of the initialization process check the microservice descriptions.

-

After the initialization, every node updates its runtime measurements with the clusterID value, marking it irreversibly as initialized. -When an initialized node tries to join another cluster, its measurements inevitably mismatch the measurements of an uninitialized node and it will be declined.

-

User-facing attestation

-

The VerificationService provides an endpoint for obtaining its hardware-based remote attestation statement, which includes the runtime measurements. -A user can verify this statement and compare the measurements against the configured ground truth and, thus, verify the identity and integrity of all Constellation components and the cluster configuration. Subsequently, the user knows that the entire cluster is in the expected state and is trustworthy.

-

Putting it all together

-

This section puts the aforementioned concepts together and illustrate how trust into a Constellation cluster is established and maintained.

-

CLI and node images

-

It all starts with the CLI executable. The CLI is signed by Edgeless Systems. To ensure non-repudiability for CLI releases, Edgeless Systems publishes corresponding signatures to the public ledger of the sigstore project. There's a step-by-step guide on how to verify CLI signatures based on sigstore.

-

The CLI contains the latest runtime measurements of the Constellation node image for all supported cloud platforms. In case a different version of the node image is to be used, the corresponding runtime measurements can be fetched using the CLI's fetch-measurements command. This command downloads the runtime measurements and the corresponding signature from cdn.confidential.cloud. See for example the following files corresponding to node image v2.16.3:

- -

The CLI contains the long-term public key of Edgeless Systems to verify the signature of downloaded runtime measurements.

-

Cluster creation

-

When a cluster is created, the CLI automatically verifies the runtime measurements of the first node using remote attestation. Based on this, the CLI and the first node set up a temporary TLS connection. This aTLS connection is used for two things:

-
    -
  1. The CLI sends the master secret of the to-be-created cluster to the CLI. The master secret is generated by the first node.
  2. -
  3. The first node sends a kubeconfig file with Kubernetes credentials to the CLI.
  4. -
-

After this, the aTLS connection is closed and the first node bootstraps the Kubernetes cluster. All subsequent interactions between the CLI and the cluster go via the Kubernetes API server running inside the cluster. The CLI (and other tools like kubectl) use the credentials referenced by the kubeconfig file to authenticate themselves towards the Kubernetes API server and to establish a mTLS connection.

-

The CLI connects to the Kubernetes API to write the runtime measurements for the applicable node image to etcd. The JoinService uses these runtime measurements to verify all nodes that join the cluster subsequently.

-

Chain of trust

-

In summary, there's a chain of trust based on cryptographic signatures that goes from the user to the cluster via the CLI. This is illustrated in the following diagram.

- -

Upgrades

-

Whenever a cluster is upgraded to a new version of the node image, the CLI sends the corresponding runtime measurements via the Kubernetes API server. The new runtime measurements are stored in etcd within the cluster and replace any previous runtime measurements. The new runtime measurements are then used automatically by the JoinService for the verification of new nodes.

-

References

- -

Footnotes

-
    -
  1. -

    Linux IMA produces runtime measurements of user-space binaries. -However, these measurements aren't deterministic and thus, PCR[10] can't be compared to a constant value. -Instead, a policy engine must be used to verify the TPM event log against a policy. 2 3 4

    -
  2. -
-
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/architecture/encrypted-storage/index.html b/pr-preview/pr-4027/architecture/encrypted-storage/index.html deleted file mode 100644 index 905bbc00f..000000000 --- a/pr-preview/pr-4027/architecture/encrypted-storage/index.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - -Encrypted persistent storage | Constellation - - - - - - - -
Skip to main content
Version: 2.24

Encrypted persistent storage

-

Confidential VMs provide runtime memory encryption to protect data in use. -In the context of Kubernetes, this is sufficient for the confidentiality and integrity of stateless services. -Consider a front-end web server, for example, that keeps all connection information cached in main memory. -No sensitive data is ever written to an insecure medium. -However, many real-world applications need some form of state or data-lake service that's connected to a persistent storage device and requires encryption at rest. -As described in Use persistent storage, cloud service providers (CSPs) use the container storage interface (CSI) to make their storage solutions available to Kubernetes workloads. -These CSI storage solutions often support some sort of encryption. -For example, Google Cloud encrypts data at rest by default, without any action required by the customer.

-

Cloud provider-managed encryption

-

CSP-managed storage solutions encrypt the data in the cloud backend before writing it physically to disk. -In the context of confidential computing and Constellation, the CSP and its managed services aren't trusted. -Hence, cloud provider-managed encryption protects your data from offline hardware access to physical storage devices. -It doesn't protect it from anyone with infrastructure-level access to the storage backend or a malicious insider in the cloud platform. -Even with "bring your own key" or similar concepts, the CSP performs the encryption process with access to the keys and plaintext data.

-

In the security model of Constellation, securing persistent storage and thereby data at rest requires that all cryptographic operations are performed inside a trusted execution environment. -Consequently, using CSP-managed encryption of persistent storage usually isn't an option.

-

Constellation-managed encryption

-

Constellation provides CSI drivers for storage solutions in all major clouds with built-in encryption support. -Block storage provisioned by the CSP is mapped using the dm-crypt, and optionally the dm-integrity, kernel modules, before it's formatted and accessed by the Kubernetes workloads. -All cryptographic operations happen inside the trusted environment of the confidential Constellation node.

-

Note that for integrity-protected disks, volume expansion isn't supported.

-

By default the driver uses data encryption keys (DEKs) issued by the Constellation KeyService. -The DEKs are in turn derived from the Constellation's key encryption key (KEK), which is directly derived from the master secret. -This is the recommended mode of operation, and also requires the least amount of setup by the cluster administrator.

-

Alternatively, the driver can be configured to use a key management system to store and access KEKs and DEKs.

-

Refer to keys and cryptography for more details on key management in Constellation.

-

Once deployed and configured, the CSI driver ensures transparent encryption and integrity of all persistent volumes provisioned via its storage class. -Data at rest is secured without any additional actions required by the developer.

-

Cryptographic algorithms

-

This section gives an overview of the libraries, cryptographic algorithms, and their configurations, used in Constellation's CSI drivers.

-

dm-crypt

-

To interact with the dm-crypt kernel module, Constellation uses libcryptsetup. -New devices are formatted as LUKS2 partitions with a sector size of 4096 bytes. -The used key derivation function is Argon2id with the recommended parameters for memory-constrained environments of 3 iterations and 64 MiB of memory, utilizing 4 parallel threads. -For encryption Constellation uses AES in XTS-Plain64. The key size is 512 bit.

-

dm-integrity

-

To interact with the dm-integrity kernel module, Constellation uses libcryptsetup. -When enabled, the used data integrity algorithm is HMAC with SHA256 as the hash function. -The tag size is 32 Bytes.

-

Encrypted S3 object storage

-

Constellation comes with a service that you can use to transparently retrofit client-side encryption to existing applications that use S3 (AWS or compatible) for storage. -To learn more, check out the s3proxy documentation.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/architecture/images/index.html b/pr-preview/pr-4027/architecture/images/index.html deleted file mode 100644 index fb0402c9a..000000000 --- a/pr-preview/pr-4027/architecture/images/index.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - -Constellation images | Constellation - - - - - - - -
Skip to main content
Version: 2.24

Constellation images

-

Constellation uses a minimal version of Fedora as the operating system running inside confidential VMs. This Linux distribution is optimized for containers and designed to be stateless. -The Constellation images provide measured boot and an immutable filesystem.

-

Measured boot

- -

Measured boot uses a Trusted Platform Module (TPM) to measure every part of the boot process. This allows for verification of the integrity of a running system at any point in time. To ensure correct measurements of every stage, each stage is responsible to measure the next stage before transitioning.

-

Firmware

-

With confidential VMs, the firmware is the root of trust and is measured automatically at boot. After initialization, the firmware will load and measure the bootloader before executing it.

-

Bootloader

-

The bootloader is the first modifiable part of the boot chain. The bootloader is tasked with loading the kernel, initramfs and setting the kernel command line. The Constellation bootloader measures these components before starting the kernel.

-

initramfs

-

The initramfs is a small filesystem loaded to prepare the actual root filesystem. The Constellation initramfs maps the block device containing the root filesystem with dm-verity. The initramfs then mounts the root filesystem from the mapped block device.

-

dm-verity provides integrity checking using a cryptographic hash tree. When a block is read, its integrity is checked by verifying the tree against a trusted root hash. The initramfs reads this root hash from the previously measured kernel command line. Thus, if any block of the root filesystem's device is modified on disk, trying to read the modified block will result in a kernel panic at runtime.

-

After mounting the root filesystem, the initramfs will switch over and start the init process of the integrity-protected root filesystem.

-

State disk

-

In addition to the read-only root filesystem, each Constellation node has a disk for storing state data. -This disk is mounted readable and writable by the initramfs and contains data that should persist across reboots. -Such data can contain sensitive information and, therefore, must be stored securely. -To that end, the state disk is protected by authenticated encryption. -See the section on keys and encryption for more information on the cryptographic primitives in use.

-

Kubernetes components

-

During initialization, the Bootstrapper downloads and verifies the Kubernetes components as configured by the user. -They're stored on the state partition and can be updated once new releases need to be installed.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/architecture/keys/index.html b/pr-preview/pr-4027/architecture/keys/index.html deleted file mode 100644 index 2dc8131a0..000000000 --- a/pr-preview/pr-4027/architecture/keys/index.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - -Key management and cryptographic primitives | Constellation - - - - - - - -
Skip to main content
Version: 2.24

Key management and cryptographic primitives

-

Constellation protects and isolates your cluster and workloads. -To that end, cryptography is the foundation that ensures the confidentiality and integrity of all components. -Evaluating the security and compliance of Constellation requires a precise understanding of the cryptographic primitives and keys used. -The following gives an overview of the architecture and explains the technical details.

-

Confidential VMs

-

Confidential VM (CVM) technology comes with hardware and software components for memory encryption, isolation, and remote attestation. -For details on the implementations and cryptographic soundness, refer to the hardware vendors' documentation and advisories.

-

Master secret

-

The master secret is the cryptographic material used for deriving the clusterID and the key encryption key (KEK) for storage encryption. -It's generated during the bootstrapping of a Constellation cluster. -It can either be managed by Constellation or an external key management system. -In case of recovery, the master secret allows to decrypt the state and recover a Constellation cluster.

-

Cluster identity

-

The identity of a Constellation cluster is represented by cryptographic measurements:

-

The base measurements represent the identity of a valid, uninitialized Constellation node. -They depend on the node image, but are otherwise the same for every Constellation cluster. -On node boot, they're determined using the CVM's attestation mechanism and measured boot up to the read-only root filesystem.

-

The clusterID represents the identity of a single initialized Constellation cluster. -It's derived from the master secret and a cryptographically random salt and unique for every Constellation cluster. -The Bootstrapper measures the clusterID into its own PCR before executing any code not measured as part of the base measurements. -See Node attestation for details.

-

The remote attestation statement of a Constellation cluster combines the base measurements and the clusterID for a verifiable, unspoofable, unique identity.

-

Network encryption

-

Constellation encrypts all cluster network communication using the container network interface (CNI). -See network encryption for more details.

-

The Cilium agent running on each node establishes a secure WireGuard tunnel between it and all other known nodes in the cluster. -Each node creates its own Curve25519 encryption key pair and distributes its public key via Kubernetes. -A node uses another node's public key to decrypt and encrypt traffic from and to Cilium-managed endpoints running on that node. -Connections are always encrypted peer-to-peer using ChaCha20 with Poly1305. -WireGuard implements forward secrecy with key rotation every 2 minutes.

-

Storage encryption

-

Constellation supports transparent encryption of persistent storage. -The Linux kernel's device mapper-based encryption features are used to encrypt the data on the block storage level. -Currently, the following primitives are used for block storage encryption:

- -

Adding primitives for integrity protection in the CVM attacker model are under active development and will be available in a future version of Constellation. -See encrypted storage for more details.

-

As a cluster administrator, when creating a cluster, you can use the Constellation installation program to select one of the following methods for key management:

-
    -
  • Constellation-managed key management
  • -
  • User-managed key management
  • -
-

Constellation-managed key management

-

Key material and key derivation

-

During the creation of a Constellation cluster, the cluster's master secret is used to derive a KEK. -This means creating two clusters with the same master secret will yield the same KEK. -Any data encryption key (DEK) is derived from the KEK via HKDF. -Note that the master secret is recommended to be unique for every cluster and shouldn't be reused (except in case of recovering a cluster).

-

State and storage

-

The KEK is derived from the master secret during the initialization. -Subsequently, all other key material is derived from the KEK. -Given the same KEK, any DEK can be derived deterministically from a given identifier. -Hence, there is no need to store DEKs. They can be derived on demand. -After the KEK was derived, it's stored in memory only and never leaves the CVM context.

-

Availability

-

Constellation-managed key management has the same availability as the underlying Kubernetes cluster. -Therefore, the KEK is stored in the distributed Kubernetes etcd storage to allow for unexpected but non-fatal (control-plane) node failure. -The etcd storage is backed by the encrypted and integrity protected state disk of the nodes.

-

Recovery

-

Constellation clusters can be recovered in the event of a disaster, even when all node machines have been stopped and need to be rebooted. -For details on the process see the recovery workflow.

-

User-managed key management

-

User-managed key management is under active development and will be available soon. -In scenarios where constellation-managed key management isn't an option, this mode allows you to keep full control of your keys. -For example, compliance requirements may force you to keep your KEKs in an on-prem key management system (KMS).

-

During the creation of a Constellation cluster, you specify a KEK present in a remote KMS. -This follows the common scheme of "bring your own key" (BYOK). -Constellation will support several KMSs for managing the storage and access of your KEK. -Initially, it will support the following KMSs:

- -

Storing the keys in Cloud KMS of AWS, Azure, or GCP binds the key usage to the particular cloud identity access management (IAM). -In the future, Constellation will support remote attestation-based access policies for Cloud KMS once available. -Note that using a Cloud KMS limits the isolation and protection to the guarantees of the particular offering.

-

KMIP support allows you to use your KMIP-compatible on-prem KMS and keep full control over your keys. -This follows the common scheme of "hold your own key" (HYOK).

-

The KEK is used to encrypt per-data "data encryption keys" (DEKs). -DEKs are generated to encrypt your data before storing it on persistent storage. -After being encrypted by the KEK, the DEKs are stored on dedicated cloud storage for persistence. -Currently, Constellation supports the following cloud storage options:

- -

The DEKs are only present in plaintext form in the encrypted main memory of the CVMs. -Similarly, the cryptographic operations for encrypting data before writing it to persistent storage are performed in the context of the CVMs.

-

Recovery and migration

-

In the case of a disaster, the KEK can be used to decrypt the DEKs locally and subsequently use them to decrypt and retrieve the data. -In case of migration, configuring the same KEK will provide seamless migration of data. -Thus, only the DEK storage needs to be transferred to the new cluster alongside the encrypted data for seamless migration.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/architecture/microservices/index.html b/pr-preview/pr-4027/architecture/microservices/index.html deleted file mode 100644 index 325a3ba90..000000000 --- a/pr-preview/pr-4027/architecture/microservices/index.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - -Microservices | Constellation - - - - - - - -
Skip to main content
Version: 2.24

Microservices

-

Constellation takes care of bootstrapping and initializing a Confidential Kubernetes cluster. -During the lifetime of the cluster, it handles day 2 operations such as key management, remote attestation, and updates. -These features are provided by several microservices:

- -

The relations between microservices are shown in the following diagram:

- -

Bootstrapper

-

The Bootstrapper is the first microservice launched after booting a Constellation node image. -It sets up that machine as a Kubernetes node and integrates that node into the Kubernetes cluster. -To this end, the Bootstrapper first downloads and verifies the Kubernetes components at the configured versions. -The Bootstrapper tries to find an existing cluster and if successful, communicates with the JoinService to join the node. -Otherwise, it waits for an initialization request to create a new Kubernetes cluster.

-

JoinService

-

The JoinService runs as DaemonSet on each control-plane node. -New nodes (at cluster start, or later through autoscaling) send a request to the service over attested TLS (aTLS). -The JoinService verifies the new node's certificate and attestation statement. -If attestation is successful, the new node is supplied with an encryption key from the KeyService for its state disk, and a Kubernetes bootstrap token.

- -

VerificationService

-

The VerificationService runs as DaemonSet on each node. -It provides user-facing functionality for remote attestation during the cluster's lifetime via an endpoint for verifying the cluster. -Read more about the hardware-based attestation feature of Constellation and how to verify a cluster on the client side.

-

KeyService

-

The KeyService runs as DaemonSet on each control-plane node. -It implements the key management for the storage encryption keys in Constellation. These keys are used for the state disk of each node and the transparently encrypted storage for Kubernetes. -Depending on wether the constellation-managed or user-managed mode is used, the KeyService holds the key encryption key (KEK) directly or calls an external key management service (KMS) for key derivation respectively.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/architecture/networking/index.html b/pr-preview/pr-4027/architecture/networking/index.html deleted file mode 100644 index 204b14d36..000000000 --- a/pr-preview/pr-4027/architecture/networking/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -Network encryption | Constellation - - - - - - - -
Skip to main content
Version: 2.24

Network encryption

-

Constellation encrypts all pod communication using the container network interface (CNI). -To that end, Constellation deploys, configures, and operates the Cilium CNI plugin. -Cilium provides transparent encryption for all cluster traffic using either IPSec or WireGuard. -Currently, Constellation only supports WireGuard as the encryption engine. -You can read more about the cryptographic soundness of WireGuard in their white paper.

-

Cilium is actively working on implementing a feature called host-to-host encryption mode for WireGuard. -With host-to-host, all traffic between nodes will be tunneled via WireGuard (host-to-host, host-to-pod, pod-to-host, pod-to-pod). -Until the host-to-host feature is released, Constellation enables pod-to-pod encryption. -This mode encrypts all traffic between Kubernetes pods using WireGuard tunnels.

-

When using Cilium in the default setup but with encryption enabled, there is a known issue -that can cause pod-to-pod traffic to be unencrypted. -To mitigate this issue, Constellation adds a strict mode to Cilium's pod-to-pod encryption. -This mode changes the default behavior of traffic that's destined for an unknown endpoint to not be send out in plaintext, but instead being dropped. -The strict mode distinguishes between traffic that's send to a pod from traffic that's destined for a cluster-external endpoint by considering the pod's CIDR range.

-

Traffic originating from hosts isn't encrypted yet. -This mainly includes health checks from Kubernetes API server. -Also, traffic proxied over the API server via e.g. kubectl port-forward isn't encrypted.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/architecture/observability/index.html b/pr-preview/pr-4027/architecture/observability/index.html deleted file mode 100644 index 3f4f46302..000000000 --- a/pr-preview/pr-4027/architecture/observability/index.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - -Observability | Constellation - - - - - - - -
Skip to main content
Version: 2.24

Observability

-

In Kubernetes, observability is the ability to gain insight into the behavior and performance of applications. -It helps identify and resolve issues more effectively, ensuring stability and performance of Kubernetes workloads, reducing downtime and outages, and improving efficiency. -The "three pillars of observability" are logs, metrics, and traces.

-

In the context of Confidential Computing, observability is a delicate subject and needs to be applied such that it doesn't leak any sensitive information. -The following gives an overview of where and how you can apply standard observability tools in Constellation.

-

Cloud resource monitoring

-

While inaccessible, Constellation's nodes are still visible as black box VMs to the hypervisor. -Resource consumption, such as memory and CPU utilization, can be monitored from the outside and observed via the cloud platforms directly. -Similarly, other resources, such as storage and network and their respective metrics, are visible via the cloud platform.

-

Metrics

-

Metrics are numeric representations of data measured over intervals of time. They're essential for understanding system health and gaining insights using telemetry signals.

-

By default, Constellation exposes the metrics for Kubernetes system components inside the cluster. -Similarly, the etcd metrics endpoints are exposed inside the cluster. -These metrics endpoints can be disabled.

-

You can collect these cluster-internal metrics via tools such as Prometheus or the Elastic Stack.

-

Constellation's CNI Cilium also supports metrics via Prometheus endpoints. -However, in Constellation, they're disabled by default and must be enabled first.

-

Logs

-

Logs represent discrete events that usually describe what's happening with your service. -The payload is an actual message emitted from your system along with a metadata section containing a timestamp, labels, and tracking identifiers.

-

System logs

-

Detailed system-level logs are accessible via /var/log and journald on the nodes directly. -They can be collected from there, for example, via Filebeat and Logstash, which are tools of the Elastic Stack.

-

In case of an error during the initialization, the CLI automatically collects the Bootstrapper logs and returns these as a file for troubleshooting. Here is an example of such an event:

-
Cluster initialization failed. This error is not recoverable.
Terminate your cluster and try again.
Fetched bootstrapper logs are stored in "constellation-cluster.log"
-

Kubernetes logs

-

Constellation supports the Kubernetes logging architecture. -By default, logs are written to the nodes' encrypted state disks. -These include the Pod and container logs and the system component logs.

-

Constellation services run as Pods inside the kube-system namespace and use the standard container logging mechanism. -The same applies for the Cilium Pods.

-

You can collect logs from within the cluster via tools such as Fluentd, Loki, or the Elastic Stack.

-

Traces

-

Modern systems are implemented as interconnected complex and distributed microservices. Understanding request flows and system communications is challenging, mainly because all systems in a chain need to be modified to propagate tracing information. Distributed tracing is a new approach to increasing observability and understanding performance bottlenecks. A trace represents consecutive events that reflect an end-to-end request path in a distributed system.

-

Constellation supports traces for Kubernetes system components. -By default, they're disabled and need to be enabled first.

-

Similarly, Cilium can be enabled to export traces.

-

You can collect these traces via tools such as Jaeger or Zipkin.

-

Integrations

-

Platforms and SaaS solutions such as Datadog, logz.io, Dynatrace, or New Relic facilitate the observability challenge for Kubernetes and provide all-in-one SaaS solutions. -They install agents into the cluster that collect metrics, logs, and tracing information and upload them into the data lake of the platform. -Technically, the agent-based approach is compatible with Constellation, and attaching these platforms is straightforward. -However, you need to evaluate if the exported data might violate Constellation's compliance and privacy guarantees by uploading them to a third-party platform.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/architecture/orchestration/index.html b/pr-preview/pr-4027/architecture/orchestration/index.html deleted file mode 100644 index da7540323..000000000 --- a/pr-preview/pr-4027/architecture/orchestration/index.html +++ /dev/null @@ -1,80 +0,0 @@ - - - - - -Orchestrating Constellation clusters | Constellation - - - - - - - -
Skip to main content
Version: 2.24

Orchestrating Constellation clusters

-

You can use the CLI to create a cluster on the supported cloud platforms. -The CLI provisions the resources in your cloud environment and initiates the initialization of your cluster. -It uses a set of parameters and an optional configuration file to manage your cluster installation. -The CLI is also used for updating your cluster.

-

Workspaces

-

Each Constellation cluster has an associated workspace. -The workspace is where data such as the Constellation state and config files are stored. -Each workspace is associated with a single cluster and configuration. -The CLI stores state in the local filesystem making the current directory the active workspace. -Multiple clusters require multiple workspaces, hence, multiple directories. -Note that every operation on a cluster always has to be performed from the directory associated with its workspace.

-

You may copy files from the workspace to other locations, -but you shouldn't move or delete them while the cluster is still being used. -The Constellation CLI takes care of managing the workspace. -Only when a cluster was terminated, and you are sure the files aren't needed anymore, should you remove a workspace.

-

Cluster creation process

-

To allow for fine-grained configuration of your cluster and cloud environment, Constellation supports an extensive configuration file with strong defaults. Generating the configuration file is typically the first thing you do in the workspace.

-

Altogether, the following files are generated during the creation of a Constellation cluster and stored in the current workspace:

-
    -
  • a configuration file
  • -
  • a state file
  • -
  • a Base64-encoded master secret
  • -
  • Terraform artifacts, stored in subdirectories
  • -
  • a Kubernetes kubeconfig file.
  • -
-

After the initialization of your cluster, the CLI will provide you with a Kubernetes kubeconfig file. -This file grants you access to your Kubernetes cluster and configures the kubectl tool. -In addition, the cluster's identifier is returned and stored in the state file.

-

Creation process details

-
    -
  1. The CLI apply command first creates the confidential VM (CVM) resources in your cloud environment and configures the network
  2. -
  3. Each CVM boots the Constellation node image and measures every component in the boot chain
  4. -
  5. The first microservice launched in each node is the Bootstrapper
  6. -
  7. The Bootstrapper waits until it either receives an initialization request or discovers an initialized cluster
  8. -
  9. The CLI then connects to the Bootstrapper of a selected node, sends the configuration, and initiates the initialization of the cluster
  10. -
  11. The Bootstrapper of that node initializes the Kubernetes cluster and deploys the other Constellation microservices including the JoinService
  12. -
  13. Subsequently, the Bootstrappers of the other nodes discover the initialized cluster and send join requests to the JoinService
  14. -
  15. As part of the join request each node includes an attestation statement of its boot measurements as authentication
  16. -
  17. The JoinService verifies the attestation statements and joins the nodes to the Kubernetes cluster
  18. -
  19. This process is repeated for every node joining the cluster later (e.g., through autoscaling)
  20. -
-

Post-installation configuration

-

Post-installation the CLI provides a configuration for accessing the cluster using the Kubernetes API. -The kubeconfig file provides the credentials and configuration for connecting and authenticating to the API server. -Once configured, orchestrate the Kubernetes cluster via kubectl.

-

After the initialization, the CLI will present you with a couple of tokens:

-
    -
  • The master secret (stored in the constellation-mastersecret.json file by default)
  • -
  • The clusterID of your cluster in Base64 encoding
  • -
-

You can read more about these values and their meaning in the guide on cluster identity.

-

The master secret must be kept secret and can be used to recover your cluster. -Instead of managing this secret manually, you can use your key management solution of choice with Constellation.

-

The clusterID uniquely identifies a cluster and can be used to verify your cluster.

-

Upgrades

-

Constellation images and microservices may need to be upgraded to new versions during the lifetime of a cluster. -Constellation implements a rolling update mechanism ensuring no downtime of the control or data plane. -You can upgrade a Constellation cluster with a single operation by using the CLI. -For step-by-step instructions on how to do this, refer to Upgrade your cluster.

-

Attestation of upgrades

-

With every new image, corresponding measurements are released. -During an update procedure, the CLI provides new measurements to the JoinService securely. -New measurements for an updated image are automatically pulled and verified by the CLI following the supply chain security concept of Constellation. -The attestation section describes in detail how these measurements are then used by the JoinService for the attestation of nodes.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/architecture/overview/index.html b/pr-preview/pr-4027/architecture/overview/index.html deleted file mode 100644 index 440c81c08..000000000 --- a/pr-preview/pr-4027/architecture/overview/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - -Overview | Constellation - - - - - - - -
Skip to main content
Version: 2.24

Overview

-

Constellation is a cloud-based confidential orchestration platform. -The foundation of Constellation is Kubernetes and therefore shares the same technology stack and architecture principles. -To learn more about Constellation and Kubernetes, see product overview.

-

About orchestration and updates

-

As a cluster administrator, you can use the Constellation CLI to install and deploy a cluster. -Updates are provided in accordance with the support policy.

-

About microservices and attestation

-

Constellation manages the nodes and network in your cluster. All nodes are bootstrapped by the Bootstrapper. They're verified and authenticated by the JoinService before being added to the cluster and the network. Finally, the entire cluster can be verified via the VerificationService using remote attestation.

-

About node images and verified boot

-

Constellation comes with operating system images for Kubernetes control-plane and worker nodes. -They're highly optimized for running containerized workloads and specifically prepared for running inside confidential VMs. -You can learn more about the images and how verified boot ensures their integrity during boot and beyond.

-

About key management and cryptographic primitives

-

Encryption of data at-rest, in-transit, and in-use is the fundamental building block for confidential computing and Constellation. Learn more about the keys and cryptographic primitives used in Constellation, encrypted persistent storage, and network encryption.

-

About observability

-

Observability in Kubernetes refers to the capability to troubleshoot issues using telemetry signals such as logs, metrics, and traces. -In the realm of Confidential Computing, it's crucial that observability aligns with confidentiality, necessitating careful implementation. -Learn more about the observability capabilities in Constellation.

- - \ No newline at end of file diff --git a/pr-preview/pr-4027/architecture/versions/index.html b/pr-preview/pr-4027/architecture/versions/index.html deleted file mode 100644 index f6beb0543..000000000 --- a/pr-preview/pr-4027/architecture/versions/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - -Versions and support policy | Constellation - - - - - - - -
Skip to main content
Version: 2.24

Versions and support policy

-

All components of Constellation use a three-digit version number of the form v<MAJOR>.<MINOR>.<PATCH>. -The components are released in lock step, usually on the first Tuesday of every month. This release primarily introduces new features, but may also include security or performance improvements. The MINOR version will be incremented as part of this release.

-

Additional PATCH releases may be created on demand, to fix security issues or bugs before the next MINOR release window.

-

New releases are published on GitHub.

-

Kubernetes support policy

-

Constellation is aligned to the version support policy of Kubernetes, and therefore usually supports the most recent three minor versions. -When a new minor version of Kubernetes is released, support is added to the next Constellation release, and that version then supports four Kubernetes versions. -Subsequent Constellation releases drop support for the oldest (and deprecated) Kubernetes version.

-

The following Kubernetes versions are currently supported:

-
    -
  • v1.30.14
  • -
  • v1.31.12
  • -
  • v1.32.8
  • -
- - \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/check-sbom.cast b/pr-preview/pr-4027/assets/check-sbom.cast deleted file mode 100644 index cc846f776..000000000 --- a/pr-preview/pr-4027/assets/check-sbom.cast +++ /dev/null @@ -1,991 +0,0 @@ -{"version": 2, "width": 199, "height": 20, "timestamp": 1703674651, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}} -[0.003646, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[0.004175, "o", "#"] -[0.136015, "o", " "] -[0.18609, "o", "S"] -[0.236253, "o", "t"] -[0.307376, "o", "e"] -[0.357476, "o", "p"] -[0.407556, "o", " "] -[0.527658, "o", "1"] -[0.577704, "o", ":"] -[0.627909, "o", " "] -[0.678042, "o", "I"] -[0.785138, "o", "n"] -[0.835217, "o", "s"] -[0.917326, "o", "t"] -[0.967415, "o", "a"] -[1.01753, "o", "l"] -[1.18565, "o", "l"] -[1.235784, "o", " "] -[1.324879, "o", "S"] -[1.374955, "o", "L"] -[1.499051, "o", "S"] -[1.549163, "o", "A"] -[1.599267, "o", " "] -[1.705415, "o", "v"] -[1.755487, "o", "e"] -[1.805614, "o", "r"] -[1.855715, "o", "i"] -[1.905798, "o", "f"] -[1.955904, "o", "i"] -[2.006058, "o", "e"] -[2.107178, "o", "r\r\n\u001b[?2004l\r"] -[2.107287, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[3.107803, "o", "c"] -[3.157819, "o", "u"] -[3.207896, "o", "r"] -[3.258013, "o", "l"] -[3.308122, "o", " "] -[3.358213, "o", "-"] -[3.494326, "o", "s"] -[3.551422, "o", "L"] -[3.616539, "o", "O"] -[3.66665, "o", " "] -[3.732749, "o", "h"] -[3.78292, "o", "t"] -[3.869985, "o", "t"] -[3.920077, "o", "p"] -[3.970174, "o", "s"] -[4.020279, "o", ":"] -[4.07039, "o", "/"] -[4.176518, "o", "/"] -[4.226636, "o", "g"] -[4.27675, "o", "i"] -[4.356833, "o", "t"] -[4.457963, "o", "h"] -[4.508026, "o", "u"] -[4.564136, "o", "b"] -[4.614194, "o", "."] -[4.696297, "o", "c"] -[4.870439, "o", "o"] -[4.920538, "o", "m"] -[4.970605, "o", "/"] -[5.020765, "o", "s"] -[5.143868, "o", "l"] -[5.193961, "o", "s"] -[5.435081, "o", "a"] -[5.485189, "o", "-"] -[5.543212, "o", "f"] -[5.615385, "o", "r"] -[5.665492, "o", "a"] -[5.715578, "o", "m"] -[5.765676, "o", "e"] -[5.848808, "o", "w"] -[5.898913, "o", "o"] -[6.057058, "o", "r"] -[6.107124, "o", "k"] -[6.157206, "o", "/"] -[6.207317, "o", "s"] -[6.257429, "o", "l"] -[6.312547, "o", "s"] -[6.362627, "o", "a"] -[6.412767, "o", "-"] -[6.572853, "o", "v"] -[6.622963, "o", "e"] -[6.810128, "o", "r"] -[6.897207, "o", "i"] -[6.947302, "o", "f"] -[6.997406, "o", "i"] -[7.047498, "o", "e"] -[7.097607, "o", "r"] -[7.147711, "o", "/"] -[7.197809, "o", "r"] -[7.247939, "o", "e"] -[7.369049, "o", "l"] -[7.419142, "o", "e"] -[7.469249, "o", "a"] -[7.524363, "o", "s"] -[7.57443, "o", "e"] -[7.675544, "o", "s"] -[7.725661, "o", "/"] -[7.775764, "o", "l"] -[7.825871, "o", "a"] -[7.878951, "o", "t"] -[7.954065, "o", "e"] -[8.006063, "o", "s"] -[8.056225, "o", "t"] -[8.106326, "o", "/"] -[8.156447, "o", "d"] -[8.209553, "o", "o"] -[8.259659, "o", "w"] -[8.309772, "o", "n"] -[8.378873, "o", "l"] -[8.428974, "o", "o"] -[8.509057, "o", "a"] -[8.559148, "o", "d"] -[8.609259, "o", "/"] -[8.659361, "o", "s"] -[8.709457, "o", "l"] -[8.759577, "o", "s"] -[8.873687, "o", "a"] -[8.923784, "o", "-"] -[8.998909, "o", "v"] -[9.049011, "o", "e"] -[9.099123, "o", "r"] -[9.149226, "o", "i"] -[9.199315, "o", "f"] -[9.261418, "o", "i"] -[9.311538, "o", "e"] -[9.361627, "o", "r"] -[9.411721, "o", "-"] -[9.461827, "o", "l"] -[9.511909, "o", "i"] -[9.561995, "o", "n"] -[9.63615, "o", "u"] -[9.686234, "o", "x"] -[9.736357, "o", "-"] -[9.786471, "o", "a"] -[9.870594, "o", "m"] -[9.920695, "o", "d"] -[10.005794, "o", "6"] -[10.05591, "o", "4\r\n\u001b[?2004l\r"] -[10.698194, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[10.698422, "o", "s"] -[10.748578, "o", "u"] -[10.838679, "o", "d"] -[10.929795, "o", "o"] -[10.979865, "o", " "] -[11.029973, "o", "i"] -[11.080037, "o", "n"] -[11.184193, "o", "s"] -[11.333311, "o", "t"] -[11.383376, "o", "a"] -[11.433501, "o", "l"] -[11.483603, "o", "l"] -[11.533693, "o", " "] -[11.583813, "o", "s"] -[11.648921, "o", "l"] -[11.699005, "o", "s"] -[11.786082, "o", "a"] -[11.836227, "o", "-"] -[11.891313, "o", "v"] -[11.941407, "o", "e"] -[12.136563, "o", "r"] -[12.308691, "o", "i"] -[12.358745, "o", "f"] -[12.40883, "o", "i"] -[12.491954, "o", "e"] -[12.542021, "o", "r"] -[12.592149, "o", "-"] -[12.642226, "o", "l"] -[12.692354, "o", "i"] -[12.742446, "o", "n"] -[12.792553, "o", "u"] -[12.842698, "o", "x"] -[12.892761, "o", "-"] -[12.94289, "o", "a"] -[12.992959, "o", "m"] -[13.043064, "o", "d"] -[13.093196, "o", "6"] -[13.143304, "o", "4"] -[13.193394, "o", " "] -[13.243513, "o", "/"] -[13.293596, "o", "u"] -[13.371722, "o", "s"] -[13.421829, "o", "r"] -[13.471913, "o", "/"] -[13.522018, "o", "l"] -[13.572136, "o", "o"] -[13.622208, "o", "c"] -[13.782337, "o", "a"] -[13.856446, "o", "l"] -[13.906541, "o", "/"] -[13.956629, "o", "b"] -[14.006756, "o", "i"] -[14.064865, "o", "n"] -[14.114996, "o", "/"] -[14.165093, "o", "s"] -[14.215206, "o", "l"] -[14.265311, "o", "s"] -[14.330415, "o", "a"] -[14.380486, "o", "-"] -[14.532627, "o", "v"] -[14.832776, "o", "e"] -[14.957839, "o", "r"] -[15.00794, "o", "i"] -[15.058029, "o", "f"] -[15.108138, "o", "i"] -[15.158246, "o", "e"] -[15.20835, "o", "r\r\n\u001b[?2004l\r"] -[15.233551, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[16.234026, "o", "#"] -[16.284076, "o", " "] -[16.334203, "o", "S"] -[16.384295, "o", "t"] -[16.434388, "o", "e"] -[16.51851, "o", "p"] -[16.568597, "o", " "] -[16.673728, "o", "2"] -[16.723817, "o", ":"] -[16.786873, "o", " "] -[16.920009, "o", "D"] -[16.976137, "o", "o"] -[17.026203, "o", "w"] -[17.079303, "o", "n"] -[17.129405, "o", "l"] -[17.206457, "o", "o"] -[17.256599, "o", "a"] -[17.306703, "o", "d"] -[17.356818, "o", " "] -[17.406942, "o", "C"] -[17.457031, "o", "o"] -[17.507127, "o", "n"] -[17.557239, "o", "s"] -[17.607313, "o", "t"] -[17.657453, "o", "e"] -[17.725546, "o", "l"] -[17.77564, "o", "l"] -[17.825738, "o", "a"] -[17.875811, "o", "t"] -[17.925937, "o", "i"] -[17.993053, "o", "o"] -[18.043216, "o", "n"] -[18.093297, "o", " "] -[18.164393, "o", "S"] -[18.322549, "o", "B"] -[18.399612, "o", "O"] -[18.449686, "o", "M"] -[18.499808, "o", " "] -[18.553929, "o", "a"] -[18.604017, "o", "n"] -[18.654099, "o", "d"] -[18.704209, "o", " "] -[18.874334, "o", "p"] -[18.924416, "o", "r"] -[18.9745, "o", "o"] -[19.024648, "o", "v"] -[19.074721, "o", "e"] -[19.19279, "o", "n"] -[19.242929, "o", "a"] -[19.299029, "o", "n"] -[19.349129, "o", "c"] -[19.399267, "o", "e\r\n\u001b[?2004l\r"] -[19.399369, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[20.399761, "o", "c"] -[20.449853, "o", "u"] -[20.515967, "o", "r"] -[20.567067, "o", "l"] -[20.617169, "o", " "] -[20.690326, "o", "-"] -[20.799426, "o", "s"] -[20.858519, "o", "L"] -[20.908641, "o", "O"] -[20.958734, "o", " "] -[21.008841, "o", "h"] -[21.079945, "o", "t"] -[21.130034, "o", "t"] -[21.327195, "o", "p"] -[21.377232, "o", "s"] -[21.427366, "o", ":"] -[21.477465, "o", "/"] -[21.691607, "o", "/"] -[21.741667, "o", "g"] -[21.791786, "o", "i"] -[21.841887, "o", "t"] -[21.913003, "o", "h"] -[21.963089, "o", "u"] -[22.013206, "o", "b"] -[22.063282, "o", "."] -[22.178436, "o", "c"] -[22.228483, "o", "o"] -[22.278612, "o", "m"] -[22.328722, "o", "/"] -[22.37881, "o", "e"] -[22.428906, "o", "d"] -[22.479023, "o", "g"] -[22.529112, "o", "e"] -[22.579226, "o", "l"] -[22.629373, "o", "e"] -[22.67946, "o", "s"] -[22.729553, "o", "s"] -[22.779644, "o", "s"] -[22.860791, "o", "y"] -[22.910863, "o", "s"] -[22.960972, "o", "/"] -[23.048098, "o", "c"] -[23.098182, "o", "o"] -[23.280314, "o", "n"] -[23.362459, "o", "s"] -[23.432532, "o", "t"] -[23.482634, "o", "e"] -[23.53276, "o", "l"] -[23.582816, "o", "l"] -[23.632932, "o", "a"] -[23.683034, "o", "t"] -[23.782135, "o", "i"] -[23.832245, "o", "o"] -[23.882367, "o", "n"] -[23.932454, "o", "/"] -[23.982542, "o", "r"] -[24.032664, "o", "e"] -[24.082759, "o", "l"] -[24.13289, "o", "e"] -[24.182973, "o", "a"] -[24.233055, "o", "s"] -[24.283188, "o", "e"] -[24.333273, "o", "s"] -[24.383414, "o", "/"] -[24.439524, "o", "l"] -[24.552574, "o", "a"] -[24.602663, "o", "t"] -[24.671789, "o", "e"] -[24.721869, "o", "s"] -[24.818959, "o", "t"] -[24.869038, "o", "/"] -[24.983177, "o", "d"] -[25.04024, "o", "o"] -[25.090339, "o", "w"] -[25.141452, "o", "n"] -[25.191591, "o", "l"] -[25.319654, "o", "o"] -[25.42976, "o", "a"] -[25.479847, "o", "d"] -[25.529955, "o", "/"] -[25.580113, "o", "c"] -[25.630194, "o", "o"] -[25.680301, "o", "n"] -[25.851459, "o", "s"] -[25.923535, "o", "t"] -[25.973643, "o", "e"] -[26.023731, "o", "l"] -[26.139862, "o", "l"] -[26.255982, "o", "a"] -[26.30608, "o", "t"] -[26.356198, "o", "i"] -[26.406295, "o", "o"] -[26.485361, "o", "n"] -[26.535497, "o", "."] -[26.58558, "o", "s"] -[26.635716, "o", "p"] -[26.686784, "o", "d"] -[26.736886, "o", "x"] -[26.786998, "o", "."] -[26.852126, "o", "s"] -[26.902199, "o", "b"] -[26.952273, "o", "o"] -[27.002437, "o", "m\r\n\u001b[?2004l\r"] -[27.810738, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[27.811023, "o", "c"] -[27.861134, "o", "u"] -[27.944264, "o", "r"] -[27.995355, "o", "l"] -[28.04542, "o", " "] -[28.10558, "o", "-"] -[28.178674, "o", "s"] -[28.241807, "o", "L"] -[28.291899, "o", "O"] -[28.341988, "o", " "] -[28.392118, "o", "h"] -[28.44221, "o", "t"] -[28.534325, "o", "t"] -[28.584472, "o", "p"] -[28.641552, "o", "s"] -[28.691652, "o", ":"] -[28.741748, "o", "/"] -[28.791851, "o", "/"] -[28.841956, "o", "g"] -[28.892067, "o", "i"] -[28.947183, "o", "t"] -[29.050199, "o", "h"] -[29.100342, "o", "u"] -[29.223496, "o", "b"] -[29.273578, "o", "."] -[29.333666, "o", "c"] -[29.454774, "o", "o"] -[29.531893, "o", "m"] -[29.581901, "o", "/"] -[29.632077, "o", "e"] -[29.682187, "o", "d"] -[29.732276, "o", "g"] -[29.782377, "o", "e"] -[29.855454, "o", "l"] -[29.909573, "o", "e"] -[29.977692, "o", "s"] -[30.027803, "o", "s"] -[30.077895, "o", "s"] -[30.128002, "o", "y"] -[30.231162, "o", "s"] -[30.281229, "o", "/"] -[30.359303, "o", "c"] -[30.409383, "o", "o"] -[30.459506, "o", "n"] -[30.509603, "o", "s"] -[30.64375, "o", "t"] -[30.693798, "o", "e"] -[30.74391, "o", "l"] -[30.826028, "o", "l"] -[31.04817, "o", "a"] -[31.100227, "o", "t"] -[31.150363, "o", "i"] -[31.200473, "o", "o"] -[31.285574, "o", "n"] -[31.335675, "o", "/"] -[31.393786, "o", "r"] -[31.443861, "o", "e"] -[31.493993, "o", "l"] -[31.544086, "o", "e"] -[31.672217, "o", "a"] -[31.722318, "o", "s"] -[31.776413, "o", "e"] -[31.916535, "o", "s"] -[31.966612, "o", "/"] -[32.016742, "o", "l"] -[32.066905, "o", "a"] -[32.117018, "o", "t"] -[32.1721, "o", "e"] -[32.253216, "o", "s"] -[32.303282, "o", "t"] -[32.353422, "o", "/"] -[32.403516, "o", "d"] -[32.453599, "o", "o"] -[32.531729, "o", "w"] -[32.58178, "o", "n"] -[32.631909, "o", "l"] -[32.696025, "o", "o"] -[32.746104, "o", "a"] -[32.799206, "o", "d"] -[32.849295, "o", "/"] -[32.899406, "o", "c"] -[32.94949, "o", "o"] -[33.025626, "o", "n"] -[33.082733, "o", "s"] -[33.196865, "o", "t"] -[33.349977, "o", "e"] -[33.400083, "o", "l"] -[33.45019, "o", "l"] -[33.500303, "o", "a"] -[33.595398, "o", "t"] -[33.702507, "o", "i"] -[33.752616, "o", "o"] -[33.802708, "o", "n"] -[33.852808, "o", "."] -[33.951986, "o", "i"] -[34.002024, "o", "n"] -[34.052131, "o", "t"] -[34.102271, "o", "o"] -[34.152344, "o", "t"] -[34.202443, "o", "o"] -[34.252573, "o", "."] -[34.302659, "o", "j"] -[34.352774, "o", "s"] -[34.402878, "o", "o"] -[34.45299, "o", "n"] -[34.521051, "o", "l\r\n\u001b[?2004l\r"] -[34.999674, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[34.999921, "o", "#"] -[35.07111, "o", " "] -[35.121224, "o", "S"] -[35.30639, "o", "t"] -[35.356464, "o", "e"] -[35.406582, "o", "p"] -[35.456686, "o", " "] -[35.550776, "o", "3"] -[35.600866, "o", ":"] -[35.664, "o", " "] -[35.714099, "o", "C"] -[35.842202, "o", "h"] -[35.963349, "o", "e"] -[36.013392, "o", "c"] -[36.087525, "o", "k"] -[36.137616, "o", " "] -[36.223759, "o", "i"] -[36.311862, "o", "n"] -[36.361979, "o", "t"] -[36.412056, "o", "e"] -[36.462179, "o", "g"] -[36.545292, "o", "r"] -[36.595367, "o", "i"] -[36.645489, "o", "t"] -[36.727592, "o", "y"] -[36.777696, "o", " "] -[36.840784, "o", "o"] -[36.890915, "o", "f"] -[36.941006, "o", " "] -[37.011094, "o", "S"] -[37.061218, "o", "B"] -[37.111305, "o", "O"] -[37.161442, "o", "M\r\n\u001b[?2004l\r"] -[37.161549, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[38.16197, "o", "s"] -[38.212065, "o", "l"] -[38.262153, "o", "s"] -[38.312241, "o", "a"] -[38.36235, "o", "-"] -[38.533512, "o", "v"] -[38.583586, "o", "e"] -[38.63967, "o", "r"] -[38.689767, "o", "i"] -[38.739884, "o", "f"] -[38.790009, "o", "i"] -[38.840082, "o", "e"] -[38.917208, "o", "r"] -[38.96731, "o", " "] -[39.033401, "o", "v"] -[39.083493, "o", "e"] -[39.133626, "o", "r"] -[39.183739, "o", "i"] -[39.316862, "o", "f"] -[39.36696, "o", "y"] -[39.417005, "o", "-"] -[39.467151, "o", "a"] -[39.598223, "o", "r"] -[39.712365, "o", "t"] -[39.765432, "o", "i"] -[39.850551, "o", "f"] -[39.917674, "o", "a"] -[39.967765, "o", "c"] -[40.017871, "o", "t"] -[40.067973, "o", " "] -[40.118088, "o", "c"] -[40.231202, "o", "o"] -[40.311328, "o", "n"] -[40.361424, "o", "s"] -[40.411486, "o", "t"] -[40.481621, "o", "e"] -[40.531701, "o", "l"] -[40.581823, "o", "l"] -[40.631854, "o", "a"] -[40.681997, "o", "t"] -[40.732109, "o", "i"] -[40.782152, "o", "o"] -[40.832292, "o", "n"] -[40.882385, "o", "."] -[40.932444, "o", "s"] -[40.982563, "o", "p"] -[41.043694, "o", "d"] -[41.122782, "o", "x"] -[41.172873, "o", "."] -[41.22296, "o", "s"] -[41.280085, "o", "b"] -[41.330194, "o", "o"] -[41.380275, "o", "m"] -[41.430391, "o", " "] -[41.480492, "o", "-"] -[41.555589, "o", "-"] -[41.60566, "o", "p"] -[41.707785, "o", "r"] -[41.772886, "o", "o"] -[41.822955, "o", "v"] -[41.873085, "o", "e"] -[42.045138, "o", "n"] -[42.095282, "o", "a"] -[42.145394, "o", "n"] -[42.195495, "o", "c"] -[42.245563, "o", "e"] -[42.295691, "o", "-"] -[42.345777, "o", "p"] -[42.43086, "o", "a"] -[42.481006, "o", "t"] -[42.565107, "o", "h"] -[42.615202, "o", " "] -[42.665313, "o", "c"] -[42.715427, "o", "o"] -[42.765516, "o", "n"] -[42.820598, "o", "s"] -[42.870703, "o", "t"] -[43.003889, "o", "e"] -[43.053936, "o", "l"] -[43.104067, "o", "l"] -[43.15416, "o", "a"] -[43.20426, "o", "t"] -[43.315365, "o", "i"] -[43.365457, "o", "o"] -[43.415555, "o", "n"] -[43.465711, "o", "."] -[43.515792, "o", "i"] -[43.565941, "o", "n"] -[43.619986, "o", "t"] -[43.687106, "o", "o"] -[43.818197, "o", "t"] -[43.868326, "o", "o"] -[43.918419, "o", "."] -[43.968547, "o", "j"] -[44.018653, "o", "s"] -[44.099767, "o", "o"] -[44.149868, "o", "n"] -[44.199982, "o", "l"] -[44.250081, "o", " "] -[44.3642, "o", "-"] -[44.414207, "o", "-"] -[44.464374, "o", "s"] -[44.514497, "o", "o"] -[44.564611, "o", "u"] -[44.614674, "o", "r"] -[44.664811, "o", "c"] -[44.766905, "o", "e"] -[44.81698, "o", "-"] -[44.961093, "o", "u"] -[45.011194, "o", "r"] -[45.084322, "o", "i"] -[45.134363, "o", " "] -[45.184526, "o", "g"] -[45.234609, "o", "i"] -[45.284745, "o", "t"] -[45.334806, "o", "h"] -[45.384882, "o", "u"] -[45.435013, "o", "b"] -[45.485144, "o", "."] -[45.596248, "o", "c"] -[45.678352, "o", "o"] -[45.728428, "o", "m"] -[45.778523, "o", "/"] -[45.828654, "o", "e"] -[45.878738, "o", "d"] -[45.928873, "o", "g"] -[46.025961, "o", "e"] -[46.076052, "o", "l"] -[46.126164, "o", "e"] -[46.176273, "o", "s"] -[46.226335, "o", "s"] -[46.276508, "o", "s"] -[46.37963, "o", "y"] -[46.42971, "o", "s"] -[46.479802, "o", "/"] -[46.560926, "o", "c"] -[46.610965, "o", "o"] -[46.661106, "o", "n"] -[46.711196, "o", "s"] -[46.761322, "o", "t"] -[46.865416, "o", "e"] -[46.923504, "o", "l"] -[46.973615, "o", "l"] -[47.089723, "o", "a"] -[47.139819, "o", "t"] -[47.189891, "o", "i"] -[47.239992, "o", "o"] -[47.290139, "o", "n\r\n\u001b[?2004l\r"] -[47.982375, "o", "Verified signature against tlog entry index 57885093 at URL: https://rekor.sigstore.dev/api/v1/log/entries/24296fb24b8ad77a78f50198d0b0a4554049eec73d59a7e5e1f895c4ad5b3d202c62132aea18c4c1\r\n"] -[47.997219, "o", "Verified build using builder \"https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v1.9.0\" at commit 1d05f438ffa564d2e4ac3b071dbaf322e6d954ab\r\n"] -[47.997275, "o", "Verifying artifact constellation.spdx.sbom: PASSED\r\n\r\nPASSED: Verified SLSA provenance\r\n"] -[47.998419, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[47.998603, "o", "#"] -[48.088785, "o", " "] -[48.138885, "o", "S"] -[48.217918, "o", "t"] -[48.268062, "o", "e"] -[48.373203, "o", "p"] -[48.423265, "o", " "] -[48.47337, "o", "4"] -[48.523446, "o", ":"] -[48.584558, "o", " "] -[48.680705, "o", "I"] -[48.841802, "o", "n"] -[48.891906, "o", "s"] -[49.01802, "o", "t"] -[49.068149, "o", "a"] -[49.118278, "o", "l"] -[49.168333, "o", "l"] -[49.218431, "o", " "] -[49.268515, "o", "g"] -[49.31859, "o", "r"] -[49.368692, "o", "y"] -[49.49377, "o", "p"] -[49.543849, "o", "e"] -[49.593916, "o", " "] -[49.644038, "o", "("] -[49.694077, "o", "s"] -[49.744164, "o", "e"] -[49.794225, "o", "c"] -[49.844337, "o", "u"] -[49.92449, "o", "r"] -[49.974575, "o", "i"] -[50.024666, "o", "t"] -[50.074775, "o", "y"] -[50.12483, "o", " "] -[50.316965, "o", "s"] -[50.391113, "o", "c"] -[50.441153, "o", "a"] -[50.529288, "o", "n"] -[50.579374, "o", "n"] -[50.681516, "o", "e"] -[50.731593, "o", "r"] -[50.781733, "o", ")\r\n\u001b[?2004l\r"] -[50.781863, "o", "\u001b[?2004h"] -[50.781919, "o", "\u001b[38;2;139;4;221m$\u001b[0m "] -[51.782348, "o", "c"] -[51.881391, "o", "u"] -[51.955455, "o", "r"] -[52.018593, "o", "l"] -[52.068698, "o", " "] -[52.118772, "o", "-"] -[52.184813, "o", "s"] -[52.234919, "o", "L"] -[52.351046, "o", "O"] -[52.401144, "o", " "] -[52.600202, "o", "h"] -[52.650277, "o", "t"] -[52.700358, "o", "t"] -[52.750397, "o", "p"] -[52.800498, "o", "s"] -[52.850627, "o", ":"] -[52.946683, "o", "/"] -[52.99673, "o", "/"] -[53.046779, "o", "g"] -[53.096882, "o", "i"] -[53.147016, "o", "t"] -[53.197052, "o", "h"] -[53.24714, "o", "u"] -[53.297253, "o", "b"] -[53.347321, "o", "."] -[53.403409, "o", "c"] -[53.490509, "o", "o"] -[53.54056, "o", "m"] -[53.590619, "o", "/"] -[53.640708, "o", "a"] -[53.75379, "o", "n"] -[53.881871, "o", "c"] -[54.181998, "o", "h"] -[54.232015, "o", "o"] -[54.28308, "o", "r"] -[54.333173, "o", "e"] -[54.383301, "o", "/"] -[54.433389, "o", "g"] -[54.545535, "o", "r"] -[54.600652, "o", "y"] -[54.650734, "o", "p"] -[54.701875, "o", "e"] -[54.752016, "o", "/"] -[54.802149, "o", "r"] -[54.85225, "o", "e"] -[54.942348, "o", "l"] -[55.070445, "o", "e"] -[55.120565, "o", "a"] -[55.170705, "o", "s"] -[55.220803, "o", "e"] -[55.319939, "o", "s"] -[55.369999, "o", "/"] -[55.420126, "o", "d"] -[55.47017, "o", "o"] -[55.558311, "o", "w"] -[55.608407, "o", "n"] -[55.671523, "o", "l"] -[55.724627, "o", "o"] -[55.774695, "o", "a"] -[55.82481, "o", "d"] -[55.874899, "o", "/"] -[55.925068, "o", "v"] -[56.088184, "o", "0"] -[56.138275, "o", "."] -[56.198386, "o", "5"] -[56.248474, "o", "6"] -[56.298599, "o", "."] -[56.357724, "o", "0"] -[56.407848, "o", "/"] -[56.457923, "o", "g"] -[56.508035, "o", "r"] -[56.573121, "o", "y"] -[56.632192, "o", "p"] -[56.733328, "o", "e"] -[56.78341, "o", "_"] -[56.833519, "o", "0"] -[56.88364, "o", "."] -[56.933719, "o", "5"] -[57.03282, "o", "6"] -[57.082922, "o", "."] -[57.174059, "o", "0"] -[57.224126, "o", "_"] -[57.418282, "o", "l"] -[57.468348, "o", "i"] -[57.540451, "o", "n"] -[57.623562, "o", "u"] -[57.742662, "o", "x"] -[57.792774, "o", "_"] -[57.842853, "o", "a"] -[57.892949, "o", "m"] -[57.943065, "o", "d"] -[58.022208, "o", "6"] -[58.094259, "o", "4"] -[58.144368, "o", "."] -[58.194447, "o", "t"] -[58.244557, "o", "a"] -[58.294605, "o", "r"] -[58.344782, "o", "."] -[58.404852, "o", "g"] -[58.462042, "o", "z\r\n\u001b[?2004l\r"] -[59.482722, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[59.48292, "o", "t"] -[59.573075, "o", "a"] -[59.623201, "o", "r"] -[59.673286, "o", " "] -[59.733388, "o", "-"] -[59.783498, "o", "x"] -[59.833591, "o", "v"] -[59.88373, "o", "z"] -[59.933798, "o", "f"] -[59.983907, "o", " "] -[60.033995, "o", "g"] -[60.248148, "o", "r"] -[60.298228, "o", "y"] -[60.348332, "o", "p"] -[60.398418, "o", "e"] -[60.448526, "o", "_"] -[60.498587, "o", "0"] -[60.548763, "o", "."] -[60.599833, "o", "5"] -[60.649973, "o", "6"] -[60.700099, "o", "."] -[60.836203, "o", "0"] -[60.886285, "o", "_"] -[60.936398, "o", "l"] -[61.093519, "o", "i"] -[61.143601, "o", "n"] -[61.231707, "o", "u"] -[61.281818, "o", "x"] -[61.331909, "o", "_"] -[61.382013, "o", "a"] -[61.432112, "o", "m"] -[61.540237, "o", "d"] -[61.590317, "o", "6"] -[61.640442, "o", "4"] -[61.690531, "o", "."] -[61.782631, "o", "t"] -[61.832735, "o", "a"] -[61.993902, "o", "r"] -[62.044033, "o", "."] -[62.11714, "o", "g"] -[62.216257, "o", "z\r\n\u001b[?2004l\r"] -[62.218486, "o", "CHANGELOG.md\r\n"] -[62.218573, "o", "LICENSE\r\n"] -[62.218636, "o", "README.md\r\n"] -[62.218898, "o", "grype\r\n"] -[62.583512, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[62.583761, "o", "s"] -[62.633879, "o", "u"] -[62.684024, "o", "d"] -[62.786132, "o", "o"] -[62.836247, "o", " "] -[62.886333, "o", "i"] -[63.086489, "o", "n"] -[63.136564, "o", "s"] -[63.227678, "o", "t"] -[63.277776, "o", "a"] -[63.327871, "o", "l"] -[63.377976, "o", "l"] -[63.428082, "o", " "] -[63.523207, "o", "g"] -[63.573292, "o", "r"] -[63.623386, "o", "y"] -[63.680486, "o", "p"] -[63.730568, "o", "e"] -[63.780681, "o", " "] -[63.992838, "o", "/"] -[64.059976, "o", "u"] -[64.122052, "o", "s"] -[64.17215, "o", "r"] -[64.222254, "o", "/"] -[64.272401, "o", "l"] -[64.441502, "o", "o"] -[64.496554, "o", "c"] -[64.546644, "o", "a"] -[64.616771, "o", "l"] -[64.666882, "o", "/"] -[64.73901, "o", "b"] -[64.789087, "o", "i"] -[64.855211, "o", "n"] -[64.905325, "o", "/"] -[65.076452, "o", "g"] -[65.126538, "o", "r"] -[65.176681, "o", "y"] -[65.325805, "o", "p"] -[65.375926, "o", "e\r\n\u001b[?2004l\r"] -[65.39875, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[66.399189, "o", "g"] -[66.44936, "o", "r"] -[66.499442, "o", "y"] -[66.549537, "o", "p"] -[66.599637, "o", "e"] -[66.649755, "o", " "] -[66.700867, "o", "-"] -[66.750972, "o", "-"] -[66.866108, "o", "h"] -[66.9482, "o", "e"] -[66.998294, "o", "l"] -[67.107435, "o", "p\r\n\u001b[?2004l\r"] -[67.133287, "o", "A vulnerability scanner for container images, filesystems, and SBOMs.\r\n\r\nSupports the following image sources:\r\n grype yourrepo/yourimage:tag defaults to using images from a Docker daemon\r\n grype path/to/yourproject a Docker tar, OCI tar, OCI directory, SIF container, or generic filesystem directory\r\n grype attestation.json --key cosign.pub extract and scan SBOM from attestation file\r\n\r\nYou can also explicitly specify the scheme to use:\r\n grype podman:yourrepo/yourimage:tag explicitly use the Podman daemon\r\n grype docker:yourrepo/yourimage:tag explicitly use the Docker daemon\r\n grype docker-archive:path/to/yourimage.tar use a tarball from disk for archives created from \"docker save\"\r\n grype oci-archive:path/to/yourimage.tar use a tarball from disk for OCI archives (from Podman or otherwise)\r\n grype oci-dir:path/to/yourimage read directly from a path on disk for OCI layout directories (from Skopeo or otherwise)\r\n grype"] -[67.13335, "o", " singularity:path/to/yourimage.sif read directly from a Singularity Image Format (SIF) container on disk\r\n grype dir:path/to/yourproject read directly from a path on disk (any directory)\r\n grype sbom:path/to/syft.json read Syft JSON from path on disk\r\n grype registry:yourrepo/yourimage:tag pull image directly from a registry (no container runtime required)\r\n grype att:attestation.json --key cosign.pub explicitly use the input as an attestation\r\n grype purl:path/to/purl/file read a newline separated file of purls from a path on disk\r\n\r\nYou can also pipe in Syft JSON directly:\r\n\tsyft yourimage:tag -o json | grype\r\n\r\n"] -[67.134367, "o", "Usage:\r\n grype [IMAGE] [flags]\r\n grype [command]\r\n\r\nAvailable Commands:\r\n completion Generate a shell completion for Grype (listing local docker images)\r\n db vulnerability database operations\r\n help Help about any command\r\n version show the version\r\n\r\nFlags:\r\n --add-cpes-if-none generate CPEs for packages with no CPE data\r\n --by-cve orient results by CVE instead of the original vulnerability ID when possible\r\n -c, --config string application config file\r\n --distro string distro to match against in the format: :\r\n --exclude stringArray exclude paths from being scanned using a glob expression\r\n -f, --fail-on string set the return code to 1 if a vulnerability is found with a severity >= the given severity, options=[negligible low medium high critical]\r\n --file string file to write the report output to (default is STDOUT)\r\n -h, --help help for grype\r\n --key string "] -[67.134512, "o", " File path to a public key to validate attestation\r\n --only-fixed ignore matches for vulnerabilities that are not fixed\r\n --only-notfixed ignore matches for vulnerabilities that are fixed\r\n -o, --output string report output formatter, formats=[json table cyclonedx cyclonedx-json sarif template], deprecated formats=[embedded-cyclonedx-vex-json embedded-cyclonedx-vex-xml]\r\n --platform string an optional platform specifier for container image sources (e.g. 'linux/arm64', 'linux/arm64/v8', 'arm64', 'linux')\r\n -q, --quiet suppress all logging output\r\n -s, --scope string selection of layers to analyze, options=[Squashed AllLayers] (default \"Squashed\")\r\n --show-suppressed show suppressed/ignored vulnerabilities in the output (only supported with table output format)\r\n -t, --template string specify the path to a Go template file (requires 'template' output to be selected)\r\n -v, --verbose count increase verbo"] -[67.13459, "o", "sity (-v = info, -vv = debug)\r\n\r\nUse \"grype [command] --help\" for more information about a command.\r\n"] -[67.135666, "o", "\u001b[?2004h"] -[67.135682, "o", "\u001b[38;2;139;4;221m$\u001b[0m "] -[68.136095, "o", "#"] -[68.238218, "o", " "] -[68.288378, "o", "S"] -[68.338457, "o", "t"] -[68.388622, "o", "e"] -[68.576751, "o", "p"] -[68.62676, "o", " "] -[68.771975, "o", "5"] -[68.822001, "o", ":"] -[68.872118, "o", " "] -[68.934225, "o", "C"] -[68.984343, "o", "h"] -[69.052468, "o", "e"] -[69.119589, "o", "c"] -[69.169675, "o", "k"] -[69.219783, "o", " "] -[69.284903, "o", "f"] -[69.33499, "o", "o"] -[69.607177, "o", "r"] -[69.657213, "o", " "] -[69.707329, "o", "v"] -[69.757433, "o", "u"] -[69.89558, "o", "l"] -[69.945665, "o", "n"] -[69.995771, "o", "e"] -[70.045863, "o", "r"] -[70.197003, "o", "a"] -[70.247062, "o", "b"] -[70.378228, "o", "i"] -[70.428335, "o", "l"] -[70.478431, "o", "i"] -[70.528523, "o", "t"] -[70.597668, "o", "i"] -[70.720806, "o", "e"] -[70.770913, "o", "s\r\n\u001b[?2004l\r"] -[70.771054, "o", "\u001b[?2004h"] -[70.771103, "o", "\u001b[38;2;139;4;221m$\u001b[0m "] -[71.771528, "o", "g"] -[71.882659, "o", "r"] -[71.932765, "o", "y"] -[71.999894, "o", "p"] -[72.049983, "o", "e"] -[72.100078, "o", " "] -[72.150204, "o", "c"] -[72.405363, "o", "o"] -[72.538448, "o", "n"] -[72.702565, "o", "s"] -[72.752703, "o", "t"] -[72.8378, "o", "e"] -[72.896879, "o", "l"] -[72.946963, "o", "l"] -[72.997074, "o", "a"] -[73.047183, "o", "t"] -[73.097283, "o", "i"] -[73.242451, "o", "o"] -[73.405569, "o", "n"] -[73.455655, "o", "."] -[73.505736, "o", "s"] -[73.555888, "o", "p"] -[73.605983, "o", "d"] -[73.679102, "o", "x"] -[73.729262, "o", "."] -[73.790379, "o", "s"] -[73.846481, "o", "b"] -[73.896578, "o", "o"] -[73.946706, "o", "m"] -[73.996848, "o", " "] -[74.046866, "o", "-"] -[74.096937, "o", "o"] -[74.14701, "o", " "] -[74.197095, "o", "t"] -[74.247171, "o", "a"] -[74.299252, "o", "b"] -[74.370336, "o", "l"] -[74.601468, "o", "e"] -[74.651494, "o", " "] -[74.709569, "o", "-"] -[74.773696, "o", "q\r\n\u001b[?2004l\r"] -[84.703424, "o", "No vulnerabilities found\r\n"] -[84.706167, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] diff --git a/pr-preview/pr-4027/assets/configure-cluster.cast b/pr-preview/pr-4027/assets/configure-cluster.cast deleted file mode 100644 index 9e1144436..000000000 --- a/pr-preview/pr-4027/assets/configure-cluster.cast +++ /dev/null @@ -1,287 +0,0 @@ -{"version": 2, "width": 199, "height": 20, "timestamp": 1703674736, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}} -[0.004032, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[0.0047, "o", "#"] -[0.136425, "o", " "] -[0.18652, "o", "S"] -[0.236646, "o", "t"] -[0.307751, "o", "e"] -[0.357879, "o", "p"] -[0.407924, "o", " "] -[0.528109, "o", "1"] -[0.578222, "o", ":"] -[0.628331, "o", " "] -[0.678432, "o", "C"] -[0.785541, "o", "r"] -[0.835629, "o", "e"] -[0.917737, "o", "a"] -[0.967837, "o", "t"] -[1.017913, "o", "e"] -[1.068028, "o", " "] -[1.143165, "o", "a"] -[1.193321, "o", " "] -[1.24335, "o", "c"] -[1.367532, "o", "o"] -[1.417521, "o", "n"] -[1.478682, "o", "f"] -[1.584787, "o", "i"] -[1.634917, "o", "g"] -[1.68502, "o", "u"] -[1.735123, "o", "r"] -[1.785259, "o", "a"] -[1.835365, "o", "t"] -[1.885473, "o", "i"] -[1.986584, "o", "o"] -[2.036683, "o", "n"] -[2.086792, "o", " "] -[2.136903, "o", "f"] -[2.186955, "o", "i"] -[2.237061, "o", "l"] -[2.287153, "o", "e"] -[2.337246, "o", " "] -[2.394374, "o", "f"] -[2.459474, "o", "o"] -[2.509565, "o", "r"] -[2.559701, "o", " "] -[2.609766, "o", "C"] -[2.696897, "o", "o"] -[2.746999, "o", "n"] -[2.797107, "o", "s"] -[2.855202, "o", "t"] -[2.905286, "o", "e"] -[3.01141, "o", "l"] -[3.061575, "o", "l"] -[3.111629, "o", "a"] -[3.191802, "o", "t"] -[3.292869, "o", "i"] -[3.342912, "o", "o"] -[3.399061, "o", "n\r\n\u001b[?2004l\r"] -[3.399191, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[4.399632, "o", "c"] -[4.481744, "o", "o"] -[4.655888, "o", "n"] -[4.705977, "o", "s"] -[4.823081, "o", "t"] -[4.873147, "o", "e"] -[4.9963, "o", "l"] -[5.046371, "o", "l"] -[5.287489, "o", "a"] -[5.393609, "o", "t"] -[5.451736, "o", "i"] -[5.523853, "o", "o"] -[5.573935, "o", "n"] -[5.624052, "o", " "] -[5.674145, "o", "c"] -[5.757261, "o", "o"] -[5.807352, "o", "n"] -[5.965528, "o", "f"] -[6.015715, "o", "i"] -[6.065677, "o", "g"] -[6.115839, "o", " "] -[6.165908, "o", "g"] -[6.22102, "o", "e"] -[6.271112, "o", "n"] -[6.321249, "o", "e"] -[6.481384, "o", "r"] -[6.531481, "o", "a"] -[6.718632, "o", "t"] -[6.80562, "o", "e"] -[6.855783, "o", " "] -[6.905964, "o", "g"] -[6.956034, "o", "c"] -[7.006121, "o", "p\r\n\u001b[?2004l\r"] -[7.035317, "o", "Config file written to constellation-conf.yaml\r\nPlease fill in your CSP-specific configuration before proceeding.\r\n"] -[7.035572, "o", "State file written to constellation-state.yaml\r\nFor more information refer to the documentation:\r\n\thttps://docs.edgeless.systems/constellation/getting-started/first-steps\r\n"] -[7.038178, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[8.038633, "o", "#"] -[8.088712, "o", " "] -[8.138817, "o", "S"] -[8.259909, "o", "t"] -[8.31, "o", "e"] -[8.360132, "o", "p"] -[8.410205, "o", " "] -[8.460368, "o", "2"] -[8.510439, "o", ":"] -[8.560548, "o", " "] -[8.610654, "o", "C"] -[8.660765, "o", "r"] -[8.713833, "o", "e"] -[8.788945, "o", "a"] -[8.84102, "o", "t"] -[8.891088, "o", "e"] -[8.941238, "o", " "] -[8.991346, "o", "y"] -[9.044459, "o", "o"] -[9.094568, "o", "u"] -[9.144646, "o", "r"] -[9.194761, "o", " "] -[9.244875, "o", "c"] -[9.324972, "o", "l"] -[9.375092, "o", "u"] -[9.536214, "o", "s"] -[9.586296, "o", "t"] -[9.6364, "o", "e"] -[9.686521, "o", "r"] -[9.736603, "o", "'"] -[9.786759, "o", "s"] -[9.836852, "o", " "] -[9.886958, "o", "I"] -[9.937051, "o", "A"] -[9.987165, "o", "M"] -[10.037293, "o", " "] -[10.099391, "o", "c"] -[10.149491, "o", "o"] -[10.199613, "o", "n"] -[10.249678, "o", "f"] -[10.299784, "o", "i"] -[10.349852, "o", "g"] -[10.399952, "o", "u"] -[10.474072, "o", "r"] -[10.524166, "o", "a"] -[10.605278, "o", "t"] -[10.655383, "o", "i"] -[10.739508, "o", "o"] -[10.789624, "o", "n\r\n\u001b[?2004l\r"] -[10.789745, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[11.790173, "o", "c"] -[11.840254, "o", "o"] -[11.890331, "o", "n"] -[11.940431, "o", "s"] -[12.030563, "o", "t"] -[12.121623, "o", "e"] -[12.171772, "o", "l"] -[12.221873, "o", "l"] -[12.27199, "o", "a"] -[12.376097, "o", "t"] -[12.525194, "o", "i"] -[12.575311, "o", "o"] -[12.62537, "o", "n"] -[12.675493, "o", " "] -[12.72561, "o", "i"] -[12.775709, "o", "a"] -[12.840809, "o", "m"] -[12.890909, "o", " "] -[12.978004, "o", "c"] -[13.028105, "o", "r"] -[13.083183, "o", "e"] -[13.133317, "o", "a"] -[13.328475, "o", "t"] -[13.500571, "o", "e"] -[13.550589, "o", " "] -[13.600733, "o", "g"] -[13.683842, "o", "c"] -[13.733945, "o", "p"] -[13.784006, "o", " "] -[13.83407, "o", "-"] -[13.884212, "o", "-"] -[13.934298, "o", "u"] -[13.984399, "o", "p"] -[14.034493, "o", "d"] -[14.084615, "o", "a"] -[14.134706, "o", "t"] -[14.184824, "o", "e"] -[14.234934, "o", "-"] -[14.285033, "o", "c"] -[14.335095, "o", "o"] -[14.406208, "o", "n"] -[14.456318, "o", "f"] -[14.506333, "o", "i"] -[14.58452, "o", "g"] -[14.634566, "o", " "] -[14.696712, "o", "-"] -[14.746804, "o", "-"] -[14.796923, "o", "p"] -[14.846966, "o", "r"] -[15.007094, "o", "o"] -[15.081205, "o", "j"] -[15.145334, "o", "e"] -[15.195449, "o", "c"] -[15.245547, "o", "t"] -[15.303651, "o", "I"] -[15.353709, "o", "D"] -[15.403816, "o", " "] -[15.453927, "o", "c"] -[15.504006, "o", "o"] -[15.569101, "o", "n"] -[15.684325, "o", "s"] -[15.836396, "o", "t"] -[16.136569, "o", "e"] -[16.261635, "o", "l"] -[16.311702, "o", "l"] -[16.361785, "o", "a"] -[16.411903, "o", "t"] -[16.462006, "o", "i"] -[16.512109, "o", "o"] -[16.562191, "o", "n"] -[16.612327, "o", "-"] -[16.662437, "o", "3"] -[16.712526, "o", "3"] -[16.762669, "o", "1"] -[16.846792, "o", "6"] -[16.928893, "o", "1"] -[17.033982, "o", "3"] -[17.084126, "o", " "] -[17.147145, "o", "-"] -[17.280363, "o", "-"] -[17.336469, "o", "s"] -[17.386543, "o", "e"] -[17.439609, "o", "r"] -[17.489728, "o", "v"] -[17.566833, "o", "i"] -[17.61694, "o", "c"] -[17.667028, "o", "e"] -[17.717124, "o", "A"] -[17.767239, "o", "c"] -[17.817365, "o", "c"] -[17.867472, "o", "o"] -[17.917573, "o", "u"] -[17.967659, "o", "n"] -[18.017751, "o", "t"] -[18.085884, "o", "I"] -[18.135969, "o", "D"] -[18.18609, "o", " "] -[18.236186, "o", "c"] -[18.286291, "o", "o"] -[18.353396, "o", "n"] -[18.403499, "o", "s"] -[18.453618, "o", "t"] -[18.524736, "o", "e"] -[18.682906, "o", "l"] -[18.759976, "o", "l"] -[18.810088, "o", "a"] -[18.860234, "o", "t"] -[18.91433, "o", "i"] -[18.964426, "o", "o"] -[19.014564, "o", "n"] -[19.064793, "o", "-"] -[19.23487, "o", "d"] -[19.284893, "o", "e"] -[19.335003, "o", "m"] -[19.385139, "o", "o"] -[19.435222, "o", " "] -[19.553365, "o", "-"] -[19.603414, "o", "-"] -[19.659537, "o", "z"] -[19.709637, "o", "o"] -[19.759731, "o", "n"] -[19.833864, "o", "e"] -[19.883996, "o", " "] -[19.950136, "o", "e"] -[20.001271, "o", "u"] -[20.103368, "o", "r"] -[20.176485, "o", "o"] -[20.285563, "o", "p"] -[20.344673, "o", "e"] -[20.394801, "o", "-"] -[20.444906, "o", "w"] -[20.495018, "o", "e"] -[20.566087, "o", "s"] -[20.616229, "o", "t"] -[20.813354, "o", "3"] -[20.863452, "o", "-"] -[20.929523, "o", "b\r\n\u001b[?2004l\r"] -[20.959012, "o", "The following IAM configuration will be created:\r\n\r\nProject ID:\t\tconstellation-331613\r\nService Account ID:\tconstellation-demo\r\nRegion:\t\t\teurope-west3\r\nZone:\t\t\teurope-west3-b\r\n\r\nDo you want to create the configuration? [y/n]: "] -[21.959455, "o", "y\r\n"] -[21.960106, "o", "The configuration file \"constellation-conf.yaml\" will be automatically updated with the IAM values and zone/region information.\r\n"] -[53.669359, "o", "\r\n"] -[53.670722, "o", "Your IAM configuration was created and filled into constellation-conf.yaml successfully.\r\n"] -[53.672522, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] diff --git a/pr-preview/pr-4027/assets/create-cluster.cast b/pr-preview/pr-4027/assets/create-cluster.cast deleted file mode 100644 index 3c9f00a95..000000000 --- a/pr-preview/pr-4027/assets/create-cluster.cast +++ /dev/null @@ -1,240 +0,0 @@ -{"version": 2, "width": 199, "height": 20, "timestamp": 1703674791, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}} -[0.003932, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[0.004442, "o", "#"] -[0.13627, "o", " "] -[0.186407, "o", "S"] -[0.236501, "o", "t"] -[0.307613, "o", "e"] -[0.357752, "o", "p"] -[0.407798, "o", " "] -[0.527922, "o", "1"] -[0.578048, "o", ":"] -[0.628181, "o", " "] -[0.678254, "o", "C"] -[0.785391, "o", "r"] -[0.835465, "o", "e"] -[0.917608, "o", "a"] -[0.967677, "o", "t"] -[1.017778, "o", "e"] -[1.037903, "o", " "] -[1.067903, "o", "t"] -[1.087903, "o", "h"] -[1.097903, "o", "e"] -[1.127903, "o", " "] -[1.143014, "o", "C"] -[1.232114, "o", "o"] -[1.282227, "o", "n"] -[1.406303, "o", "s"] -[1.456428, "o", "t"] -[1.517561, "o", "e"] -[1.62366, "o", "l"] -[1.6738, "o", "l"] -[1.723877, "o", "a"] -[1.77399, "o", "t"] -[1.824095, "o", "i"] -[1.87418, "o", "o"] -[1.924301, "o", "n"] -[1.97442, "o", " "] -[2.024526, "o", "c"] -[2.07459, "o", "l"] -[2.1247, "o", "u"] -[2.17482, "o", "s"] -[2.224927, "o", "t"] -[2.275007, "o", "e"] -[2.41116, "o", "r\r\n\u001b[?2004l\r"] -[2.411311, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[3.411738, "o", "c"] -[3.476772, "o", "o"] -[3.526845, "o", "n"] -[3.592982, "o", "s"] -[3.643096, "o", "t"] -[3.730205, "o", "e"] -[3.780291, "o", "l"] -[3.830406, "o", "l"] -[3.88851, "o", "a"] -[3.938607, "o", "t"] -[4.044725, "o", "i"] -[4.094826, "o", "o"] -[4.144943, "o", "n"] -[4.195041, "o", " "] -[4.296156, "o", "a"] -[4.346307, "o", "p"] -[4.402382, "o", "p"] -[4.520462, "o", "l"] -[4.602605, "o", "y\r\n\u001b[?2004l\r"] -[4.63371, "o", "Using community license.\r\n"] -[6.514164, "o", "For details, see https://docs.edgeless.systems/constellation/overview/license\r\n"] -[13.901035, "o", "The following Constellation cluster will be created:\r\n 3 control-plane nodes of type n2d-standard-4 will be created.\r\n 1 worker node of type n2d-standard-4 will be created.\r\nDo you want to create this cluster? [y/n]: "] -[13.901255, "o", "y\r\n"] -[180.722532, "o", "Cloud infrastructure created successfully.\r\n"] -[180.727688, "o", "Your Constellation master secret was successfully written to \"constellation-mastersecret.json\"\r\n"] -[618.109354, "o", "Your Constellation cluster was successfully initialized.\r\n\r\nConstellation cluster identifier 9eb7de42a641b8356176bb39e03d29a1dc7d1dab142cd1c39283cf329b53fe1f\r\nKubernetes configuration constellation-admin.conf\r\n\r\nYou can now connect to your cluster by executing:\r\n\texport KUBECONFIG=\"/constellation/constellation-admin.conf\"\r\n\r\n"] -[618.112273, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[618.112452, "o", "#"] -[618.162615, "o", " "] -[618.27972, "o", "W"] -[618.329771, "o", "a"] -[618.452971, "o", "i"] -[618.503067, "o", "t"] -[618.553173, "o", " "] -[618.659285, "o", "f"] -[618.717399, "o", "o"] -[618.789486, "o", "r"] -[618.839562, "o", " "] -[618.889693, "o", "c"] -[618.939774, "o", "l"] -[619.022877, "o", "u"] -[619.072989, "o", "s"] -[619.231143, "o", "t"] -[619.281216, "o", "e"] -[619.331289, "o", "r"] -[619.381425, "o", " "] -[619.431537, "o", "t"] -[619.486631, "o", "o"] -[619.536746, "o", " "] -[619.586851, "o", "f"] -[619.746988, "o", "i"] -[619.797078, "o", "n"] -[619.984209, "o", "i"] -[620.071254, "o", "s"] -[620.121392, "o", "h"] -[620.171525, "o", " "] -[620.221608, "o", "b"] -[620.271693, "o", "o"] -[620.321798, "o", "o"] -[620.371899, "o", "t"] -[620.422017, "o", "s"] -[620.543136, "o", "t"] -[620.593202, "o", "r"] -[620.643302, "o", "a"] -[620.6984, "o", "p"] -[620.748497, "o", "p"] -[620.849635, "o", "i"] -[620.89974, "o", "n"] -[620.949856, "o", "g"] -[620.999931, "o", "."] -[621.053046, "o", "."] -[621.128139, "o", ".\r\n\u001b[?2004l\r"] -[621.128243, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[622.128706, "o", "s"] -[622.178801, "o", "l"] -[622.245878, "o", "e"] -[622.295996, "o", "e"] -[622.34909, "o", "p"] -[622.399213, "o", " "] -[622.449322, "o", "3"] -[622.518402, "o", "0"] -[622.568555, "o", "0\r\n\u001b[?2004l\r"] -[922.569816, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[922.570091, "o", "#"] -[922.620252, "o", " "] -[922.781381, "o", "S"] -[922.831473, "o", "t"] -[922.881535, "o", "e"] -[922.931669, "o", "p"] -[922.981802, "o", " "] -[923.031901, "o", "2"] -[923.081984, "o", ":"] -[923.132097, "o", " "] -[923.182194, "o", "C"] -[923.232299, "o", "o"] -[923.282392, "o", "n"] -[923.344508, "o", "n"] -[923.394605, "o", "e"] -[923.444718, "o", "c"] -[923.494807, "o", "t"] -[923.544924, "o", " "] -[923.594999, "o", "t"] -[923.645113, "o", "o"] -[923.695213, "o", " "] -[923.745331, "o", "C"] -[923.826438, "o", "o"] -[923.876552, "o", "n"] -[923.960705, "o", "s"] -[924.010765, "o", "t"] -[924.095864, "o", "e"] -[924.145985, "o", "l"] -[924.1961, "o", "l"] -[924.246204, "o", "a"] -[924.33634, "o", "t"] -[924.427441, "o", "i"] -[924.477518, "o", "o"] -[924.527621, "o", "n\r\n\u001b[?2004l\r"] -[924.527698, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[925.528137, "o", "e"] -[925.632219, "o", "x"] -[925.781333, "o", "p"] -[925.831428, "o", "o"] -[925.881544, "o", "r"] -[925.931644, "o", "t"] -[925.981765, "o", " "] -[926.031898, "o", "K"] -[926.097042, "o", "U"] -[926.147111, "o", "B"] -[926.23429, "o", "E"] -[926.284331, "o", "C"] -[926.339442, "o", "O"] -[926.389539, "o", "N"] -[926.584675, "o", "F"] -[926.756799, "o", "I"] -[926.806872, "o", "G"] -[926.856936, "o", "="] -[926.907083, "o", "/"] -[926.957183, "o", "c"] -[927.014283, "o", "o"] -[927.06438, "o", "n"] -[927.114506, "o", "s"] -[927.164609, "o", "t"] -[927.214722, "o", "e"] -[927.26483, "o", "l"] -[927.31494, "o", "l"] -[927.36502, "o", "a"] -[927.415112, "o", "t"] -[927.465239, "o", "i"] -[927.515332, "o", "o"] -[927.565458, "o", "n"] -[927.615551, "o", "/"] -[927.665689, "o", "c"] -[927.715762, "o", "o"] -[927.793871, "o", "n"] -[927.84395, "o", "s"] -[927.906071, "o", "t"] -[927.956178, "o", "e"] -[928.006281, "o", "l"] -[928.056398, "o", "l"] -[928.216517, "o", "a"] -[928.290615, "o", "t"] -[928.354726, "o", "i"] -[928.404809, "o", "o"] -[928.454909, "o", "n"] -[928.505005, "o", "-"] -[928.555124, "o", "a"] -[928.605221, "o", "d"] -[928.655301, "o", "m"] -[928.705434, "o", "i"] -[928.770572, "o", "n"] -[928.820661, "o", "."] -[928.972754, "o", "c"] -[929.272921, "o", "o"] -[929.398058, "o", "n"] -[929.448135, "o", "f\r\n\u001b[?2004l\r"] -[929.448274, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[930.448699, "o", "k"] -[930.498765, "o", "u"] -[930.548887, "o", "b"] -[930.598986, "o", "e"] -[930.649151, "o", "c"] -[930.699174, "o", "t"] -[930.74929, "o", "l"] -[930.799366, "o", " "] -[930.849512, "o", "g"] -[930.933616, "o", "e"] -[931.015733, "o", "t"] -[931.065804, "o", " "] -[931.211941, "o", "n"] -[931.275028, "o", "o"] -[931.408148, "o", "d"] -[931.464248, "o", "e"] -[931.514347, "o", "s\r\n\u001b[?2004l\r"] -[932.37047, "o", "NAME STATUS ROLES AGE VERSION\r\nconstell-1088351e-control-plane-caac834e-dvf9 Ready control-plane 3m13s v1.27.8\r\nconstell-1088351e-control-plane-caac834e-rjq7 Ready control-plane 8m36s v1.27.8\r\nconstell-1088351e-control-plane-caac834e-w6fk Ready control-plane 4m26s v1.27.8\r\nconstell-1088351e-worker-5f94f70a-bf9d Ready 4m46s v1.27.8\r\n"] -[932.372893, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] diff --git a/pr-preview/pr-4027/assets/css/styles.9ca3c5b3.css b/pr-preview/pr-4027/assets/css/styles.9ca3c5b3.css deleted file mode 100644 index e556a2584..000000000 --- a/pr-preview/pr-4027/assets/css/styles.9ca3c5b3.css +++ /dev/null @@ -1 +0,0 @@ -@import url(https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap);.col,.container{padding:0 var(--ifm-spacing-horizontal);width:100%}.markdown>h2,.markdown>h3,.markdown>h4,.markdown>h5,.markdown>h6{margin-bottom:calc(var(--ifm-heading-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown li,body{word-wrap:break-word}body,ol ol,ol ul,ul ol,ul ul{margin:0}pre,table{overflow:auto}blockquote,pre{margin:0 0 var(--ifm-spacing-vertical)}.breadcrumbs__link,.button{transition-timing-function:var(--ifm-transition-timing-default)}.button,.hash-link{-webkit-user-select:none}.button,code{vertical-align:middle}.button--outline.button--active,.button--outline:active,.button--outline:hover,:root{--ifm-button-color:var(--ifm-font-color-base-inverse)}.menu__link:hover,a{transition:color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.navbar--dark,:root{--ifm-navbar-link-hover-color:var(--ifm-color-primary)}.menu,.navbar-sidebar{overflow-x:hidden}:root,html[data-theme=dark]{--ifm-color-emphasis-500:var(--ifm-color-gray-500)}.toggleButton_gllP,html{-webkit-tap-highlight-color:transparent}:root,body.dark,body[data-theme=dark]{--aa-icon-color-rgb:119,119,163;--aa-scrollbar-thumb-background-color-rgb:var(--aa-background-color-rgb)}:root{--ifm-color-scheme:light;--ifm-dark-value:10%;--ifm-darker-value:15%;--ifm-darkest-value:30%;--ifm-light-value:15%;--ifm-lighter-value:30%;--ifm-lightest-value:50%;--ifm-contrast-background-value:90%;--ifm-contrast-foreground-value:70%;--ifm-contrast-background-dark-value:70%;--ifm-contrast-foreground-dark-value:90%;--ifm-color-primary:#3578e5;--ifm-color-secondary:#ebedf0;--ifm-color-success:#00a400;--ifm-color-info:#54c7ec;--ifm-color-warning:#ffba00;--ifm-color-danger:#fa383e;--ifm-color-primary-dark:#306cce;--ifm-color-primary-darker:#2d66c3;--ifm-color-primary-darkest:#2554a0;--ifm-color-primary-light:#538ce9;--ifm-color-primary-lighter:#72a1ed;--ifm-color-primary-lightest:#9abcf2;--ifm-color-primary-contrast-background:#ebf2fc;--ifm-color-primary-contrast-foreground:#102445;--ifm-color-secondary-dark:#d4d5d8;--ifm-color-secondary-darker:#c8c9cc;--ifm-color-secondary-darkest:#a4a6a8;--ifm-color-secondary-light:#eef0f2;--ifm-color-secondary-lighter:#f1f2f5;--ifm-color-secondary-lightest:#f5f6f8;--ifm-color-secondary-contrast-background:#fdfdfe;--ifm-color-secondary-contrast-foreground:#474748;--ifm-color-success-dark:#009400;--ifm-color-success-darker:#008b00;--ifm-color-success-darkest:#007300;--ifm-color-success-light:#26b226;--ifm-color-success-lighter:#4dbf4d;--ifm-color-success-lightest:#80d280;--ifm-color-success-contrast-background:#e6f6e6;--ifm-color-success-contrast-foreground:#003100;--ifm-color-info-dark:#4cb3d4;--ifm-color-info-darker:#47a9c9;--ifm-color-info-darkest:#3b8ba5;--ifm-color-info-light:#6ecfef;--ifm-color-info-lighter:#87d8f2;--ifm-color-info-lightest:#aae3f6;--ifm-color-info-contrast-background:#eef9fd;--ifm-color-info-contrast-foreground:#193c47;--ifm-color-warning-dark:#e6a700;--ifm-color-warning-darker:#d99e00;--ifm-color-warning-darkest:#b38200;--ifm-color-warning-light:#ffc426;--ifm-color-warning-lighter:#ffcf4d;--ifm-color-warning-lightest:#ffdd80;--ifm-color-warning-contrast-background:#fff8e6;--ifm-color-warning-contrast-foreground:#4d3800;--ifm-color-danger-dark:#e13238;--ifm-color-danger-darker:#d53035;--ifm-color-danger-darkest:#af272b;--ifm-color-danger-light:#fb565b;--ifm-color-danger-lighter:#fb7478;--ifm-color-danger-lightest:#fd9c9f;--ifm-color-danger-contrast-background:#ffebec;--ifm-color-danger-contrast-foreground:#4b1113;--ifm-color-white:#fff;--ifm-color-black:#000;--ifm-color-gray-0:var(--ifm-color-white);--ifm-color-gray-100:#f5f6f7;--ifm-color-gray-200:#ebedf0;--ifm-color-gray-300:#dadde1;--ifm-color-gray-400:#ccd0d5;--ifm-color-gray-500:#bec3c9;--ifm-color-gray-600:#8d949e;--ifm-color-gray-700:#606770;--ifm-color-gray-800:#444950;--ifm-color-gray-900:#1c1e21;--ifm-color-gray-1000:var(--ifm-color-black);--ifm-color-emphasis-0:var(--ifm-color-gray-0);--ifm-color-emphasis-100:var(--ifm-color-gray-100);--ifm-color-emphasis-200:var(--ifm-color-gray-200);--ifm-color-emphasis-300:var(--ifm-color-gray-300);--ifm-color-emphasis-400:var(--ifm-color-gray-400);--ifm-color-emphasis-600:var(--ifm-color-gray-600);--ifm-color-emphasis-700:var(--ifm-color-gray-700);--ifm-color-emphasis-800:var(--ifm-color-gray-800);--ifm-color-emphasis-900:var(--ifm-color-gray-900);--ifm-color-emphasis-1000:var(--ifm-color-gray-1000);--ifm-color-content:var(--ifm-color-emphasis-900);--ifm-color-content-inverse:var(--ifm-color-emphasis-0);--ifm-color-content-secondary:#525860;--ifm-background-color:#0000;--ifm-background-surface-color:var(--ifm-color-content-inverse);--ifm-global-border-width:1px;--ifm-global-radius:0.4rem;--ifm-hover-overlay:#0000000d;--ifm-font-color-base:var(--ifm-color-content);--ifm-font-color-base-inverse:var(--ifm-color-content-inverse);--ifm-font-color-secondary:var(--ifm-color-content-secondary);--ifm-font-family-base:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--ifm-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--ifm-font-size-base:100%;--ifm-font-weight-light:300;--ifm-font-weight-normal:400;--ifm-font-weight-semibold:500;--ifm-font-weight-bold:700;--ifm-font-weight-base:var(--ifm-font-weight-normal);--ifm-line-height-base:1.65;--ifm-global-spacing:1rem;--ifm-spacing-vertical:var(--ifm-global-spacing);--ifm-spacing-horizontal:var(--ifm-global-spacing);--ifm-transition-fast:200ms;--ifm-transition-slow:400ms;--ifm-transition-timing-default:cubic-bezier(0.08,0.52,0.52,1);--ifm-global-shadow-lw:0 1px 2px 0 #0000001a;--ifm-global-shadow-md:0 5px 40px #0003;--ifm-global-shadow-tl:0 12px 28px 0 #0003,0 2px 4px 0 #0000001a;--ifm-z-index-dropdown:100;--ifm-z-index-fixed:200;--ifm-z-index-overlay:400;--ifm-container-width:1140px;--ifm-container-width-xl:1320px;--ifm-code-background:#f6f7f8;--ifm-code-border-radius:var(--ifm-global-radius);--ifm-code-font-size:90%;--ifm-code-padding-horizontal:0.1rem;--ifm-code-padding-vertical:0.1rem;--ifm-pre-background:var(--ifm-code-background);--ifm-pre-border-radius:var(--ifm-code-border-radius);--ifm-pre-color:inherit;--ifm-pre-line-height:1.45;--ifm-pre-padding:1rem;--ifm-heading-color:inherit;--ifm-heading-margin-top:0;--ifm-heading-margin-bottom:var(--ifm-spacing-vertical);--ifm-heading-font-family:var(--ifm-font-family-base);--ifm-heading-font-weight:var(--ifm-font-weight-bold);--ifm-heading-line-height:1.25;--ifm-h1-font-size:2rem;--ifm-h2-font-size:1.5rem;--ifm-h3-font-size:1.25rem;--ifm-h4-font-size:1rem;--ifm-h5-font-size:0.875rem;--ifm-h6-font-size:0.85rem;--ifm-image-alignment-padding:1.25rem;--ifm-leading-desktop:1.25;--ifm-leading:calc(var(--ifm-leading-desktop)*1rem);--ifm-list-left-padding:2rem;--ifm-list-margin:1rem;--ifm-list-item-margin:0.25rem;--ifm-list-paragraph-margin:1rem;--ifm-table-cell-padding:0.75rem;--ifm-table-background:#0000;--ifm-table-stripe-background:#00000008;--ifm-table-border-width:1px;--ifm-table-border-color:var(--ifm-color-emphasis-300);--ifm-table-head-background:inherit;--ifm-table-head-color:inherit;--ifm-table-head-font-weight:var(--ifm-font-weight-bold);--ifm-table-cell-color:inherit;--ifm-link-color:var(--ifm-color-primary);--ifm-link-decoration:none;--ifm-link-hover-color:var(--ifm-link-color);--ifm-link-hover-decoration:underline;--ifm-paragraph-margin-bottom:var(--ifm-leading);--ifm-blockquote-font-size:var(--ifm-font-size-base);--ifm-blockquote-border-left-width:2px;--ifm-blockquote-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-blockquote-padding-vertical:0;--ifm-blockquote-shadow:none;--ifm-blockquote-color:var(--ifm-color-emphasis-800);--ifm-blockquote-border-color:var(--ifm-color-emphasis-300);--ifm-hr-background-color:var(--ifm-color-emphasis-500);--ifm-hr-height:1px;--ifm-hr-margin-vertical:1.5rem;--ifm-scrollbar-size:7px;--ifm-scrollbar-track-background-color:#f1f1f1;--ifm-scrollbar-thumb-background-color:silver;--ifm-scrollbar-thumb-hover-background-color:#a7a7a7;--ifm-alert-background-color:inherit;--ifm-alert-border-color:inherit;--ifm-alert-border-radius:var(--ifm-global-radius);--ifm-alert-border-width:0px;--ifm-alert-border-left-width:5px;--ifm-alert-color:var(--ifm-font-color-base);--ifm-alert-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-alert-padding-vertical:var(--ifm-spacing-vertical);--ifm-alert-shadow:var(--ifm-global-shadow-lw);--ifm-avatar-intro-margin:1rem;--ifm-avatar-intro-alignment:inherit;--ifm-avatar-photo-size:3rem;--ifm-badge-background-color:inherit;--ifm-badge-border-color:inherit;--ifm-badge-border-radius:var(--ifm-global-radius);--ifm-badge-border-width:var(--ifm-global-border-width);--ifm-badge-color:var(--ifm-color-white);--ifm-badge-padding-horizontal:calc(var(--ifm-spacing-horizontal)*0.5);--ifm-badge-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-breadcrumb-border-radius:1.5rem;--ifm-breadcrumb-spacing:0.5rem;--ifm-breadcrumb-color-active:var(--ifm-color-primary);--ifm-breadcrumb-item-background-active:var(--ifm-hover-overlay);--ifm-breadcrumb-padding-horizontal:0.8rem;--ifm-breadcrumb-padding-vertical:0.4rem;--ifm-breadcrumb-size-multiplier:1;--ifm-breadcrumb-separator:url('data:image/svg+xml;utf8,');--ifm-breadcrumb-separator-filter:none;--ifm-breadcrumb-separator-size:0.5rem;--ifm-breadcrumb-separator-size-multiplier:1.25;--ifm-button-background-color:inherit;--ifm-button-border-color:var(--ifm-button-background-color);--ifm-button-border-width:var(--ifm-global-border-width);--ifm-button-font-weight:var(--ifm-font-weight-bold);--ifm-button-padding-horizontal:1.5rem;--ifm-button-padding-vertical:0.375rem;--ifm-button-size-multiplier:1;--ifm-button-transition-duration:var(--ifm-transition-fast);--ifm-button-border-radius:calc(var(--ifm-global-radius)*var(--ifm-button-size-multiplier));--ifm-button-group-spacing:2px;--ifm-card-background-color:var(--ifm-background-surface-color);--ifm-card-border-radius:calc(var(--ifm-global-radius)*2);--ifm-card-horizontal-spacing:var(--ifm-global-spacing);--ifm-card-vertical-spacing:var(--ifm-global-spacing);--ifm-toc-border-color:var(--ifm-color-emphasis-300);--ifm-toc-link-color:var(--ifm-color-content-secondary);--ifm-toc-padding-vertical:0.5rem;--ifm-toc-padding-horizontal:0.5rem;--ifm-dropdown-background-color:var(--ifm-background-surface-color);--ifm-dropdown-font-weight:var(--ifm-font-weight-semibold);--ifm-dropdown-link-color:var(--ifm-font-color-base);--ifm-dropdown-hover-background-color:var(--ifm-hover-overlay);--ifm-footer-background-color:var(--ifm-color-emphasis-100);--ifm-footer-color:inherit;--ifm-footer-link-color:var(--ifm-color-emphasis-700);--ifm-footer-link-hover-color:var(--ifm-color-primary);--ifm-footer-link-horizontal-spacing:0.5rem;--ifm-footer-padding-horizontal:calc(var(--ifm-spacing-horizontal)*2);--ifm-footer-padding-vertical:calc(var(--ifm-spacing-vertical)*2);--ifm-footer-title-color:inherit;--ifm-footer-logo-max-width:min(30rem,90vw);--ifm-hero-background-color:var(--ifm-background-surface-color);--ifm-hero-text-color:var(--ifm-color-emphasis-800);--ifm-menu-color:var(--ifm-color-emphasis-700);--ifm-menu-color-active:var(--ifm-color-primary);--ifm-menu-color-background-active:var(--ifm-hover-overlay);--ifm-menu-color-background-hover:var(--ifm-hover-overlay);--ifm-menu-link-padding-horizontal:0.75rem;--ifm-menu-link-padding-vertical:0.375rem;--ifm-menu-link-sublist-icon:url('data:image/svg+xml;utf8,');--ifm-menu-link-sublist-icon-filter:none;--ifm-navbar-background-color:var(--ifm-background-surface-color);--ifm-navbar-height:3.75rem;--ifm-navbar-item-padding-horizontal:0.75rem;--ifm-navbar-item-padding-vertical:0.25rem;--ifm-navbar-link-color:var(--ifm-font-color-base);--ifm-navbar-link-active-color:var(--ifm-link-color);--ifm-navbar-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-navbar-padding-vertical:calc(var(--ifm-spacing-vertical)*0.5);--ifm-navbar-shadow:var(--ifm-global-shadow-lw);--ifm-navbar-search-input-background-color:var(--ifm-color-emphasis-200);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-800);--ifm-navbar-search-input-placeholder-color:var(--ifm-color-emphasis-500);--ifm-navbar-search-input-icon:url('data:image/svg+xml;utf8,');--ifm-navbar-sidebar-width:83vw;--ifm-pagination-border-radius:var(--ifm-global-radius);--ifm-pagination-color-active:var(--ifm-color-primary);--ifm-pagination-font-size:1rem;--ifm-pagination-item-active-background:var(--ifm-hover-overlay);--ifm-pagination-page-spacing:0.2em;--ifm-pagination-padding-horizontal:calc(var(--ifm-spacing-horizontal)*1);--ifm-pagination-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-pagination-nav-border-radius:var(--ifm-global-radius);--ifm-pagination-nav-color-hover:var(--ifm-color-primary);--ifm-pills-color-active:var(--ifm-color-primary);--ifm-pills-color-background-active:var(--ifm-hover-overlay);--ifm-pills-spacing:0.125rem;--ifm-tabs-color:var(--ifm-font-color-secondary);--ifm-tabs-color-active:var(--ifm-color-primary);--ifm-tabs-color-active-border:var(--ifm-tabs-color-active);--ifm-tabs-padding-horizontal:1rem;--ifm-tabs-padding-vertical:1rem;--docusaurus-progress-bar-color:var(--ifm-color-primary);--ifm-color-primary:#8b04dd;--ifm-color-primary-dark:#58089e;--ifm-color-primary-darker:#330663;--ifm-color-primary-darkest:#1c033c;--ifm-color-primary-light:#8b04dd;--ifm-color-primary-lighter:#b873f4;--ifm-color-primary-lightest:#e3d2ff;--ifm-font-family-base:"Inter",sans-serif;--ifm-code-font-size:95%;--docusaurus-highlighted-code-line-bg:#0000001a;--docusaurus-tag-list-border:var(--ifm-color-emphasis-300);--docusaurus-announcement-bar-height:auto;--docusaurus-collapse-button-bg:#0000;--docusaurus-collapse-button-bg-hover:#0000001a;--doc-sidebar-width:300px;--doc-sidebar-hidden-width:30px;--aa-search-input-height:44px;--aa-input-icon-size:20px;--aa-base-unit:16;--aa-spacing-factor:1;--aa-spacing:calc(var(--aa-base-unit)*var(--aa-spacing-factor)*1px);--aa-spacing-half:calc(var(--aa-spacing)/2);--aa-panel-max-height:650px;--aa-base-z-index:9999;--aa-font-size:calc(var(--aa-base-unit)*1px);--aa-font-family:inherit;--aa-font-weight-medium:500;--aa-font-weight-semibold:600;--aa-font-weight-bold:700;--aa-icon-size:20px;--aa-icon-stroke-width:1.6;--aa-icon-color-alpha:1;--aa-action-icon-size:20px;--aa-text-color-rgb:38,38,39;--aa-text-color-alpha:1;--aa-primary-color-rgb:62,52,211;--aa-primary-color-alpha:0.2;--aa-muted-color-rgb:128,126,163;--aa-muted-color-alpha:0.6;--aa-panel-border-color-rgb:128,126,163;--aa-panel-border-color-alpha:0.3;--aa-input-border-color-rgb:128,126,163;--aa-input-border-color-alpha:0.8;--aa-background-color-rgb:255,255,255;--aa-background-color-alpha:1;--aa-input-background-color-rgb:255,255,255;--aa-input-background-color-alpha:1;--aa-selected-color-rgb:179,173,214;--aa-selected-color-alpha:0.205;--aa-description-highlight-background-color-rgb:245,223,77;--aa-description-highlight-background-color-alpha:0.5;--aa-detached-media-query:(max-width:680px);--aa-detached-modal-media-query:(min-width:680px);--aa-detached-modal-max-width:680px;--aa-detached-modal-max-height:500px;--aa-overlay-color-rgb:115,114,129;--aa-overlay-color-alpha:0.4;--aa-panel-shadow:0 0 0 1px #23263b1a,0 6px 16px -4px #23263b26;--aa-scrollbar-width:13px;--aa-scrollbar-track-background-color-rgb:234,234,234;--aa-scrollbar-track-background-color-alpha:1;--aa-scrollbar-thumb-background-color-alpha:1;--aa-search-input-height:36px}.badge--danger,.badge--info,.badge--primary,.badge--secondary,.badge--success,.badge--warning{--ifm-badge-border-color:var(--ifm-badge-background-color)}.button--link,.button--outline{--ifm-button-background-color:#0000}*,.aa-Autocomplete *,.aa-DetachedFormContainer *,.aa-Panel *,pre.ap-terminal .ap-line .cp-259a,pre.ap-terminal .ap-line .cp-259e{box-sizing:border-box}html{background-color:var(--ifm-background-color);color:var(--ifm-font-color-base);color-scheme:var(--ifm-color-scheme);font:var(--ifm-font-size-base)/var(--ifm-line-height-base) var(--ifm-font-family-base);-webkit-font-smoothing:antialiased;text-rendering:optimizelegibility;-webkit-text-size-adjust:100%;text-size-adjust:100%}iframe{border:0;color-scheme:auto}.container{margin:0 auto;max-width:var(--ifm-container-width)}.container--fluid{max-width:inherit}.row{display:flex;flex-wrap:wrap;margin:0 calc(var(--ifm-spacing-horizontal)*-1)}.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none,.tabItem_LNqP{margin-top:0!important}.row--no-gutters{margin-left:0;margin-right:0}.margin-horiz--none,.margin-right--none{margin-right:0!important}.row--no-gutters>.col{padding-left:0;padding-right:0}.row--align-top{align-items:flex-start}.row--align-bottom{align-items:flex-end}.menuExternalLink_NmtK,.row--align-center{align-items:center}.row--align-stretch{align-items:stretch}.row--align-baseline{align-items:baseline}.col{--ifm-col-width:100%;flex:1 0;margin-left:0;max-width:var(--ifm-col-width)}.padding-bottom--none,.padding-vert--none{padding-bottom:0!important}.padding-top--none,.padding-vert--none{padding-top:0!important}.padding-horiz--none,.padding-left--none{padding-left:0!important}.padding-horiz--none,.padding-right--none{padding-right:0!important}.col[class*=col--]{flex:0 0 var(--ifm-col-width)}.col--1{--ifm-col-width:8.33333%}.col--offset-1{margin-left:8.33333%}.col--2{--ifm-col-width:16.66667%}.col--offset-2{margin-left:16.66667%}.col--3{--ifm-col-width:25%}.col--offset-3{margin-left:25%}.col--4{--ifm-col-width:33.33333%}.col--offset-4{margin-left:33.33333%}.col--5{--ifm-col-width:41.66667%}.col--offset-5{margin-left:41.66667%}.col--6{--ifm-col-width:50%}.col--offset-6{margin-left:50%}.col--7{--ifm-col-width:58.33333%}.col--offset-7{margin-left:58.33333%}.col--8{--ifm-col-width:66.66667%}.col--offset-8{margin-left:66.66667%}.col--9{--ifm-col-width:75%}.col--offset-9{margin-left:75%}.col--10{--ifm-col-width:83.33333%}.col--offset-10{margin-left:83.33333%}.col--11{--ifm-col-width:91.66667%}.col--offset-11{margin-left:91.66667%}.col--12{--ifm-col-width:100%}.col--offset-12{margin-left:100%}.margin-horiz--none,.margin-left--none{margin-left:0!important}.margin--none{margin:0!important}.margin-bottom--xs,.margin-vert--xs{margin-bottom:.25rem!important}.margin-top--xs,.margin-vert--xs{margin-top:.25rem!important}.margin-horiz--xs,.margin-left--xs{margin-left:.25rem!important}.margin-horiz--xs,.margin-right--xs{margin-right:.25rem!important}.margin--xs{margin:.25rem!important}.margin-bottom--sm,.margin-vert--sm{margin-bottom:.5rem!important}.margin-top--sm,.margin-vert--sm{margin-top:.5rem!important}.margin-horiz--sm,.margin-left--sm{margin-left:.5rem!important}.margin-horiz--sm,.margin-right--sm{margin-right:.5rem!important}.margin--sm{margin:.5rem!important}.margin-bottom--md,.margin-vert--md{margin-bottom:1rem!important}.margin-top--md,.margin-vert--md{margin-top:1rem!important}.margin-horiz--md,.margin-left--md{margin-left:1rem!important}.margin-horiz--md,.margin-right--md{margin-right:1rem!important}.margin--md{margin:1rem!important}.margin-bottom--lg,.margin-vert--lg{margin-bottom:2rem!important}.margin-top--lg,.margin-vert--lg{margin-top:2rem!important}.margin-horiz--lg,.margin-left--lg{margin-left:2rem!important}.margin-horiz--lg,.margin-right--lg{margin-right:2rem!important}.margin--lg{margin:2rem!important}.margin-bottom--xl,.margin-vert--xl{margin-bottom:5rem!important}.margin-top--xl,.margin-vert--xl{margin-top:5rem!important}.margin-horiz--xl,.margin-left--xl{margin-left:5rem!important}.margin-horiz--xl,.margin-right--xl{margin-right:5rem!important}.margin--xl{margin:5rem!important}.padding--none{padding:0!important}.padding-bottom--xs,.padding-vert--xs{padding-bottom:.25rem!important}.padding-top--xs,.padding-vert--xs{padding-top:.25rem!important}.padding-horiz--xs,.padding-left--xs{padding-left:.25rem!important}.padding-horiz--xs,.padding-right--xs{padding-right:.25rem!important}.padding--xs{padding:.25rem!important}.padding-bottom--sm,.padding-vert--sm{padding-bottom:.5rem!important}.padding-top--sm,.padding-vert--sm{padding-top:.5rem!important}.padding-horiz--sm,.padding-left--sm{padding-left:.5rem!important}.padding-horiz--sm,.padding-right--sm{padding-right:.5rem!important}.padding--sm{padding:.5rem!important}.padding-bottom--md,.padding-vert--md{padding-bottom:1rem!important}.padding-top--md,.padding-vert--md{padding-top:1rem!important}.padding-horiz--md,.padding-left--md{padding-left:1rem!important}.padding-horiz--md,.padding-right--md{padding-right:1rem!important}.padding--md{padding:1rem!important}.padding-bottom--lg,.padding-vert--lg{padding-bottom:2rem!important}.padding-top--lg,.padding-vert--lg{padding-top:2rem!important}.padding-horiz--lg,.padding-left--lg{padding-left:2rem!important}.padding-horiz--lg,.padding-right--lg{padding-right:2rem!important}.padding--lg{padding:2rem!important}.padding-bottom--xl,.padding-vert--xl{padding-bottom:5rem!important}.padding-top--xl,.padding-vert--xl{padding-top:5rem!important}.padding-horiz--xl,.padding-left--xl{padding-left:5rem!important}.padding-horiz--xl,.padding-right--xl{padding-right:5rem!important}.padding--xl{padding:5rem!important}code{background-color:var(--ifm-code-background);border:.1rem solid #0000001a;border-radius:var(--ifm-code-border-radius);font-family:var(--ifm-font-family-monospace);font-size:var(--ifm-code-font-size);padding:var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal)}a code{color:inherit}pre{background-color:var(--ifm-pre-background);border-radius:var(--ifm-pre-border-radius);color:var(--ifm-pre-color);font:var(--ifm-code-font-size)/var(--ifm-pre-line-height) var(--ifm-font-family-monospace);padding:var(--ifm-pre-padding)}pre code{background-color:initial;border:none;font-size:100%;line-height:inherit;padding:0}kbd{background-color:var(--ifm-color-emphasis-0);border:1px solid var(--ifm-color-emphasis-400);border-radius:.2rem;box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-400);color:var(--ifm-color-emphasis-800);font:80% var(--ifm-font-family-monospace);padding:.15rem .3rem}h1,h2,h3,h4,h5,h6{color:var(--ifm-heading-color);font-family:var(--ifm-heading-font-family);font-weight:var(--ifm-heading-font-weight);line-height:var(--ifm-heading-line-height);margin:var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0}h1{font-size:var(--ifm-h1-font-size)}h2{font-size:var(--ifm-h2-font-size)}h3{font-size:var(--ifm-h3-font-size)}h4{font-size:var(--ifm-h4-font-size)}h5{font-size:var(--ifm-h5-font-size)}h6{font-size:var(--ifm-h6-font-size)}.container_lyt7,.container_lyt7>svg,img{max-width:100%}img[align=right]{padding-left:var(--image-alignment-padding)}img[align=left]{padding-right:var(--image-alignment-padding)}.markdown{--ifm-h1-vertical-rhythm-top:3;--ifm-h2-vertical-rhythm-top:2;--ifm-h3-vertical-rhythm-top:1.5;--ifm-heading-vertical-rhythm-top:1.25;--ifm-h1-vertical-rhythm-bottom:1.25;--ifm-heading-vertical-rhythm-bottom:1}.markdown:after,.markdown:before{content:"";display:table}.markdown:after{clear:both}.markdown h1:first-child{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-h1-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown>h2{--ifm-h2-font-size:2rem;margin-top:calc(var(--ifm-h2-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h3{--ifm-h3-font-size:1.5rem;margin-top:calc(var(--ifm-h3-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h4,.markdown>h5,.markdown>h6{margin-top:calc(var(--ifm-heading-vertical-rhythm-top)*var(--ifm-leading))}.markdown>p,.markdown>pre,.markdown>ul,.tabList__CuJ{margin-bottom:var(--ifm-leading)}.markdown li>p{margin-top:var(--ifm-list-paragraph-margin)}.markdown li+li{margin-top:var(--ifm-list-item-margin)}ol,ul{margin:0 0 var(--ifm-list-margin);padding-left:var(--ifm-list-left-padding)}ol ol,ul ol{list-style-type:lower-roman}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}table{border-collapse:collapse;display:block;margin-bottom:var(--ifm-spacing-vertical)}table thead tr{border-bottom:2px solid var(--ifm-table-border-color)}table thead,table tr:nth-child(2n){background-color:var(--ifm-table-stripe-background)}table tr{background-color:var(--ifm-table-background);border-top:var(--ifm-table-border-width) solid var(--ifm-table-border-color)}table td,table th{border:var(--ifm-table-border-width) solid var(--ifm-table-border-color);padding:var(--ifm-table-cell-padding)}table th{background-color:var(--ifm-table-head-background);color:var(--ifm-table-head-color);font-weight:var(--ifm-table-head-font-weight)}table td{color:var(--ifm-table-cell-color)}strong{font-weight:var(--ifm-font-weight-bold)}a{color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}a:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button:hover,.text--no-decoration,.text--no-decoration:hover,a:not([href]){-webkit-text-decoration:none;text-decoration:none}p{margin:0 0 var(--ifm-paragraph-margin-bottom)}blockquote{border-left:var(--ifm-blockquote-border-left-width) solid var(--ifm-blockquote-border-color);box-shadow:var(--ifm-blockquote-shadow);color:var(--ifm-blockquote-color);font-size:var(--ifm-blockquote-font-size);padding:var(--ifm-blockquote-padding-vertical) var(--ifm-blockquote-padding-horizontal)}.docItemContainer_Djhp article>:first-child,.docItemContainer_Djhp header+*,.footer__item,blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}hr{background-color:var(--ifm-hr-background-color);border:0;height:var(--ifm-hr-height);margin:var(--ifm-hr-margin-vertical) 0}.shadow--lw{box-shadow:var(--ifm-global-shadow-lw)!important}.shadow--md{box-shadow:var(--ifm-global-shadow-md)!important}.shadow--tl{box-shadow:var(--ifm-global-shadow-tl)!important}.text--primary,.wordWrapButtonEnabled_uzNF .wordWrapButtonIcon_b1P5{color:var(--ifm-color-primary)}.text--secondary{color:var(--ifm-color-secondary)}.text--success{color:var(--ifm-color-success)}.text--info{color:var(--ifm-color-info)}.text--warning{color:var(--ifm-color-warning)}.text--danger{color:var(--ifm-color-danger)}.text--center{text-align:center}.text--left{text-align:left}.text--justify{text-align:justify}.text--right{text-align:right}.text--capitalize{text-transform:capitalize}.text--lowercase{text-transform:lowercase}.admonitionHeading_Gvgb,.alert__heading,.text--uppercase{text-transform:uppercase}.text--light{font-weight:var(--ifm-font-weight-light)}.text--normal{font-weight:var(--ifm-font-weight-normal)}.text--semibold{font-weight:var(--ifm-font-weight-semibold)}.text--bold{font-weight:var(--ifm-font-weight-bold)}.text--italic,pre.ap-terminal .ap-italic{font-style:italic}.text--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text--break{word-wrap:break-word!important;word-break:break-word!important}.clean-btn{background:none;border:none;color:inherit;cursor:pointer;font-family:inherit;padding:0}.alert,.alert .close{color:var(--ifm-alert-foreground-color)}.clean-list{list-style:none;padding-left:0}.alert--primary{--ifm-alert-background-color:var(--ifm-color-primary-contrast-background);--ifm-alert-background-color-highlight:#3578e526;--ifm-alert-foreground-color:var(--ifm-color-primary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-primary-dark)}.alert--secondary{--ifm-alert-background-color:var(--ifm-color-secondary-contrast-background);--ifm-alert-background-color-highlight:#ebedf026;--ifm-alert-foreground-color:var(--ifm-color-secondary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-secondary-dark)}.alert--success{--ifm-alert-background-color:var(--ifm-color-success-contrast-background);--ifm-alert-background-color-highlight:#00a40026;--ifm-alert-foreground-color:var(--ifm-color-success-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-success-dark)}.alert--info{--ifm-alert-background-color:var(--ifm-color-info-contrast-background);--ifm-alert-background-color-highlight:#54c7ec26;--ifm-alert-foreground-color:var(--ifm-color-info-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-info-dark)}.alert--warning{--ifm-alert-background-color:var(--ifm-color-warning-contrast-background);--ifm-alert-background-color-highlight:#ffba0026;--ifm-alert-foreground-color:var(--ifm-color-warning-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-warning-dark)}.alert--danger{--ifm-alert-background-color:var(--ifm-color-danger-contrast-background);--ifm-alert-background-color-highlight:#fa383e26;--ifm-alert-foreground-color:var(--ifm-color-danger-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-danger-dark)}.alert{--ifm-code-background:var(--ifm-alert-background-color-highlight);--ifm-link-color:var(--ifm-alert-foreground-color);--ifm-link-hover-color:var(--ifm-alert-foreground-color);--ifm-link-decoration:underline;--ifm-tabs-color:var(--ifm-alert-foreground-color);--ifm-tabs-color-active:var(--ifm-alert-foreground-color);--ifm-tabs-color-active-border:var(--ifm-alert-border-color);background-color:var(--ifm-alert-background-color);border:var(--ifm-alert-border-width) solid var(--ifm-alert-border-color);border-left-width:var(--ifm-alert-border-left-width);border-radius:var(--ifm-alert-border-radius);box-shadow:var(--ifm-alert-shadow);padding:var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal)}.alert__heading{align-items:center;display:flex;font:700 var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.5rem}.alert__icon{display:inline-flex;margin-right:.4em}.alert__icon svg{fill:var(--ifm-alert-foreground-color);stroke:var(--ifm-alert-foreground-color);stroke-width:0}.alert .close{margin:calc(var(--ifm-alert-padding-vertical)*-1) calc(var(--ifm-alert-padding-horizontal)*-1) 0 0;opacity:.75}.alert .close:focus,.alert .close:hover{opacity:1}.alert a{text-decoration-color:var(--ifm-alert-border-color)}.alert a:hover{text-decoration-thickness:2px}.avatar{column-gap:var(--ifm-avatar-intro-margin);display:flex}.avatar__photo{border-radius:50%;display:block;height:var(--ifm-avatar-photo-size);overflow:hidden;width:var(--ifm-avatar-photo-size)}.avatar__photo--sm{--ifm-avatar-photo-size:2rem}.avatar__photo--lg{--ifm-avatar-photo-size:4rem}.avatar__photo--xl{--ifm-avatar-photo-size:6rem}.avatar__intro{display:flex;flex:1 1;flex-direction:column;justify-content:center;text-align:var(--ifm-avatar-intro-alignment)}.badge,.breadcrumbs__item,.breadcrumbs__link,.button,.dropdown>.navbar__link:after{display:inline-block}.avatar__name{font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base)}.avatar__subtitle{margin-top:.25rem}.avatar--vertical{--ifm-avatar-intro-alignment:center;--ifm-avatar-intro-margin:0.5rem;align-items:center;flex-direction:column}.badge{background-color:var(--ifm-badge-background-color);border:var(--ifm-badge-border-width) solid var(--ifm-badge-border-color);border-radius:var(--ifm-badge-border-radius);color:var(--ifm-badge-color);font-size:75%;font-weight:var(--ifm-font-weight-bold);line-height:1;padding:var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal)}.badge--primary{--ifm-badge-background-color:var(--ifm-color-primary)}.badge--secondary{--ifm-badge-background-color:var(--ifm-color-secondary);color:var(--ifm-color-black)}.breadcrumbs__link,.button.button--secondary.button--outline:not(.button--active):not(:hover){color:var(--ifm-font-color-base)}.badge--success{--ifm-badge-background-color:var(--ifm-color-success)}.badge--info{--ifm-badge-background-color:var(--ifm-color-info)}.badge--warning{--ifm-badge-background-color:var(--ifm-color-warning)}.badge--danger{--ifm-badge-background-color:var(--ifm-color-danger)}.breadcrumbs{margin-bottom:0;padding-left:0}.breadcrumbs__item:not(:last-child):after{background:var(--ifm-breadcrumb-separator) center;content:" ";display:inline-block;filter:var(--ifm-breadcrumb-separator-filter);height:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier));margin:0 var(--ifm-breadcrumb-spacing);opacity:.5;width:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier))}.breadcrumbs__item--active .breadcrumbs__link{background:var(--ifm-breadcrumb-item-background-active);color:var(--ifm-breadcrumb-color-active)}.breadcrumbs__link{border-radius:var(--ifm-breadcrumb-border-radius);font-size:calc(1rem*var(--ifm-breadcrumb-size-multiplier));padding:calc(var(--ifm-breadcrumb-padding-vertical)*var(--ifm-breadcrumb-size-multiplier)) calc(var(--ifm-breadcrumb-padding-horizontal)*var(--ifm-breadcrumb-size-multiplier));transition-duration:var(--ifm-transition-fast);transition-property:background,color}.breadcrumbs__link:any-link:hover,.breadcrumbs__link:link:hover,.breadcrumbs__link:visited:hover,area[href].breadcrumbs__link:hover{background:var(--ifm-breadcrumb-item-background-active);-webkit-text-decoration:none;text-decoration:none}.breadcrumbs--sm{--ifm-breadcrumb-size-multiplier:0.8}.breadcrumbs--lg{--ifm-breadcrumb-size-multiplier:1.2}.button{background-color:var(--ifm-button-background-color);border:var(--ifm-button-border-width) solid var(--ifm-button-border-color);border-radius:var(--ifm-button-border-radius);cursor:pointer;font-size:calc(.875rem*var(--ifm-button-size-multiplier));font-weight:var(--ifm-button-font-weight);line-height:1.5;padding:calc(var(--ifm-button-padding-vertical)*var(--ifm-button-size-multiplier)) calc(var(--ifm-button-padding-horizontal)*var(--ifm-button-size-multiplier));text-align:center;transition-duration:var(--ifm-button-transition-duration);transition-property:color,background,border-color;user-select:none;white-space:nowrap}.button,.button:hover{color:var(--ifm-button-color)}.button--outline{--ifm-button-color:var(--ifm-button-border-color)}.button--outline:hover{--ifm-button-background-color:var(--ifm-button-border-color)}.button--link{--ifm-button-border-color:#0000;color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}.button--link.button--active,.button--link:active,.button--link:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.aa-ItemLink,.aa-SourceFooterSeeAll,.dropdown__link--active,.dropdown__link:hover,.menu__link:hover,.navbar__brand:hover,.navbar__link--active,.navbar__link:hover,.pagination-nav__link:hover,.pagination__link:hover,.tag_zVej:hover,div.ap-wrapper .title-bar a:hover{-webkit-text-decoration:none;text-decoration:none}.button.disabled,.button:disabled,.button[disabled]{opacity:.65;pointer-events:none}.button--sm{--ifm-button-size-multiplier:0.8}.button--lg{--ifm-button-size-multiplier:1.35}.button--block{display:block;width:100%}.button.button--secondary{color:var(--ifm-color-gray-900)}:where(.button--primary){--ifm-button-background-color:var(--ifm-color-primary);--ifm-button-border-color:var(--ifm-color-primary)}:where(.button--primary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-primary-dark);--ifm-button-border-color:var(--ifm-color-primary-dark)}.button--primary.button--active,.button--primary:active{--ifm-button-background-color:var(--ifm-color-primary-darker);--ifm-button-border-color:var(--ifm-color-primary-darker)}:where(.button--secondary){--ifm-button-background-color:var(--ifm-color-secondary);--ifm-button-border-color:var(--ifm-color-secondary)}:where(.button--secondary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-secondary-dark);--ifm-button-border-color:var(--ifm-color-secondary-dark)}.button--secondary.button--active,.button--secondary:active{--ifm-button-background-color:var(--ifm-color-secondary-darker);--ifm-button-border-color:var(--ifm-color-secondary-darker)}:where(.button--success){--ifm-button-background-color:var(--ifm-color-success);--ifm-button-border-color:var(--ifm-color-success)}:where(.button--success):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-success-dark);--ifm-button-border-color:var(--ifm-color-success-dark)}.button--success.button--active,.button--success:active{--ifm-button-background-color:var(--ifm-color-success-darker);--ifm-button-border-color:var(--ifm-color-success-darker)}:where(.button--info){--ifm-button-background-color:var(--ifm-color-info);--ifm-button-border-color:var(--ifm-color-info)}:where(.button--info):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-info-dark);--ifm-button-border-color:var(--ifm-color-info-dark)}.button--info.button--active,.button--info:active{--ifm-button-background-color:var(--ifm-color-info-darker);--ifm-button-border-color:var(--ifm-color-info-darker)}:where(.button--warning){--ifm-button-background-color:var(--ifm-color-warning);--ifm-button-border-color:var(--ifm-color-warning)}:where(.button--warning):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-warning-dark);--ifm-button-border-color:var(--ifm-color-warning-dark)}.button--warning.button--active,.button--warning:active{--ifm-button-background-color:var(--ifm-color-warning-darker);--ifm-button-border-color:var(--ifm-color-warning-darker)}:where(.button--danger){--ifm-button-background-color:var(--ifm-color-danger);--ifm-button-border-color:var(--ifm-color-danger)}:where(.button--danger):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-danger-dark);--ifm-button-border-color:var(--ifm-color-danger-dark)}.button--danger.button--active,.button--danger:active{--ifm-button-background-color:var(--ifm-color-danger-darker);--ifm-button-border-color:var(--ifm-color-danger-darker)}.button-group{display:inline-flex;gap:var(--ifm-button-group-spacing)}.button-group>.button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.button-group>.button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.button-group--block{display:flex;justify-content:stretch}.button-group--block>.button{flex-grow:1}.card{background-color:var(--ifm-card-background-color);border-radius:var(--ifm-card-border-radius);box-shadow:var(--ifm-global-shadow-lw);display:flex;flex-direction:column;overflow:hidden}.card--full-height{height:100%}.card__image{padding-top:var(--ifm-card-vertical-spacing)}.card__image:first-child{padding-top:0}.card__body,.card__footer,.card__header{padding:var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing)}.card__body:not(:last-child),.card__footer:not(:last-child),.card__header:not(:last-child){padding-bottom:0}.card__body>:last-child,.card__footer>:last-child,.card__header>:last-child{margin-bottom:0}.card__footer{margin-top:auto}.table-of-contents{font-size:.8rem;margin-bottom:0;padding:var(--ifm-toc-padding-vertical) 0}.table-of-contents,.table-of-contents ul{list-style:none;padding-left:var(--ifm-toc-padding-horizontal)}.table-of-contents li{margin:var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal)}.table-of-contents__left-border{border-left:1px solid var(--ifm-toc-border-color)}.table-of-contents__link{color:var(--ifm-toc-link-color);display:block}.table-of-contents__link--active,.table-of-contents__link--active code,.table-of-contents__link:hover,.table-of-contents__link:hover code{color:var(--ifm-color-primary);-webkit-text-decoration:none;text-decoration:none}.content_knG7 a,div.ap-wrapper .title-bar a,pre.ap-terminal .ap-underline{-webkit-text-decoration:underline;text-decoration:underline}.close{color:var(--ifm-color-black);float:right;font-size:1.5rem;font-weight:var(--ifm-font-weight-bold);line-height:1;opacity:.5;padding:1rem;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.close:hover{opacity:.7}.close:focus,.theme-code-block-highlighted-line .codeLineNumber_Tfdd:before{opacity:.8}.dropdown{display:inline-flex;font-weight:var(--ifm-dropdown-font-weight);position:relative;vertical-align:top}.dropdown--hoverable:hover .dropdown__menu,.dropdown--show .dropdown__menu{opacity:1;pointer-events:all;transform:translateY(-1px);visibility:visible}#nprogress,.dropdown__menu,.navbar__item.dropdown .navbar__link:not([href]){pointer-events:none}.dropdown--right .dropdown__menu{left:inherit;right:0}.dropdown--nocaret .navbar__link:after{content:none!important}.dropdown__menu{background-color:var(--ifm-dropdown-background-color);border-radius:var(--ifm-global-radius);box-shadow:var(--ifm-global-shadow-md);left:0;list-style:none;max-height:80vh;min-width:10rem;opacity:0;overflow-y:auto;padding:.5rem;position:absolute;top:calc(100% - var(--ifm-navbar-item-padding-vertical) + .3rem);transform:translateY(-.625rem);transition-duration:var(--ifm-transition-fast);transition-property:opacity,transform,visibility;transition-timing-function:var(--ifm-transition-timing-default);visibility:hidden;z-index:var(--ifm-z-index-dropdown)}.menu__caret,.menu__link,.menu__list-item-collapsible{border-radius:.25rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.dropdown__link{border-radius:.25rem;color:var(--ifm-dropdown-link-color);display:block;font-size:.875rem;margin-top:.2rem;padding:.25rem .5rem;white-space:nowrap}.dropdown__link--active,.dropdown__link:hover{background-color:var(--ifm-dropdown-hover-background-color);color:var(--ifm-dropdown-link-color)}.dropdown__link--active,.dropdown__link--active:hover{--ifm-dropdown-link-color:var(--ifm-link-color)}.dropdown>.navbar__link:after{border-color:currentcolor #0000;border-style:solid;border-width:.4em .4em 0;content:"";margin-left:.3em;position:relative;top:2px;transform:translateY(-50%)}.footer{background-color:var(--ifm-footer-background-color);color:var(--ifm-footer-color);padding:var(--ifm-footer-padding-vertical) var(--ifm-footer-padding-horizontal)}.footer__links{margin-bottom:1rem}.footer__link-item{color:var(--ifm-footer-link-color);line-height:2}.footer__link-item:hover{color:var(--ifm-footer-link-hover-color)}.footer__link-separator{margin:0 var(--ifm-footer-link-horizontal-spacing)}.footer__logo{margin-top:1rem;max-width:var(--ifm-footer-logo-max-width)}.footer__title{color:var(--ifm-footer-title-color);font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base);margin-bottom:var(--ifm-heading-margin-bottom)}.menu,.navbar__link{font-weight:var(--ifm-font-weight-semibold)}.admonitionContent_BuS1>:last-child,.cardContainer_fWXF :last-child,.collapsibleContent_i85q p:last-child,.details_lb9f>summary>p:last-child,.footer__items,.tabItem_Ymn6>:last-child{margin-bottom:0}.codeBlockStandalone_MEMb,[type=checkbox]{padding:0}.hero{align-items:center;background-color:var(--ifm-hero-background-color);color:var(--ifm-hero-text-color);display:flex;padding:4rem 2rem}.hero--primary{--ifm-hero-background-color:var(--ifm-color-primary);--ifm-hero-text-color:var(--ifm-font-color-base-inverse)}.hero--dark{--ifm-hero-background-color:#303846;--ifm-hero-text-color:var(--ifm-color-white)}.hero__title{font-size:3rem}.hero__subtitle{font-size:1.5rem}.menu__list{list-style:none;margin:0;padding-left:0}.menu__caret,.menu__link{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu__list .menu__list{flex:0 0 100%;margin-top:.25rem;padding-left:var(--ifm-menu-link-padding-horizontal)}.menu__list-item:not(:first-child){margin-top:.25rem}.menu__list-item--collapsed .menu__list{height:0;overflow:hidden}.details_lb9f[data-collapsed=false].isBrowser_bmU9>summary:before,.details_lb9f[open]:not(.isBrowser_bmU9)>summary:before,.menu__list-item--collapsed .menu__caret:before,.menu__list-item--collapsed .menu__link--sublist:after{transform:rotate(90deg)}.menu__list-item-collapsible{display:flex;flex-wrap:wrap;position:relative}.menu__caret:hover,.menu__link:hover,.menu__list-item-collapsible--active,.menu__list-item-collapsible:hover{background:var(--ifm-menu-color-background-hover)}.menu__list-item-collapsible .menu__link--active,.menu__list-item-collapsible .menu__link:hover{background:none!important}.menu__caret,.menu__link{align-items:center;display:flex}.navbar-sidebar,.navbar-sidebar__backdrop{bottom:0;opacity:0;transition-duration:var(--ifm-transition-fast);transition-timing-function:ease-in-out;top:0;left:0;visibility:hidden}.menu__link{color:var(--ifm-menu-color);flex:1;line-height:1.25}.menu__link:hover{color:var(--ifm-menu-color)}.menu__caret:before,.menu__link--sublist-caret:after{height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem;filter:var(--ifm-menu-link-sublist-icon-filter);content:""}.menu__link--sublist-caret:after{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem;margin-left:auto;min-width:1.25rem}.menu__link--active,.menu__link--active:hover{color:var(--ifm-menu-color-active)}.navbar__brand,.navbar__link{color:var(--ifm-navbar-link-color)}.menu__link--active:not(.menu__link--sublist){background-color:var(--ifm-menu-color-background-active)}.menu__caret:before{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem}.navbar--dark,html[data-theme=dark]{--ifm-menu-link-sublist-icon-filter:invert(100%) sepia(94%) saturate(17%) hue-rotate(223deg) brightness(104%) contrast(98%)}.navbar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-navbar-shadow);height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar,.navbar>.container,.navbar>.container-fluid,div.ap-control-bar span.ap-timer:hover .ap-time-remaining{display:flex}.navbar--fixed-top{position:sticky;top:0;z-index:var(--ifm-z-index-fixed)}.navbar__inner{display:flex;flex-wrap:wrap;justify-content:space-between;width:100%}.navbar__brand{align-items:center;display:flex;margin-right:1rem;min-width:0}.navbar__brand:hover{color:var(--ifm-navbar-link-hover-color)}.announcementBarContent_xLdY,.navbar__title{flex:1 1 auto}.navbar__toggle{display:none;margin-right:.5rem}.navbar__logo{flex:0 0 auto;height:2rem;margin-right:.5rem}.ap-player .ap-overlay-start .ap-play-button div,.docCardListItem_W1sv>*,.navbar__logo img,body,html{height:100%}.navbar__items{align-items:center;display:flex;flex:1;min-width:0}.navbar__items--center{flex:0 0 auto}.navbar__items--center .navbar__brand{margin:0}.navbar__items--center+.navbar__items--right{flex:1}.navbar__items--right{flex:0 0 auto;justify-content:flex-end}.navbar__item{display:inline-block;padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.navbar__link--active,.navbar__link:hover{color:var(--ifm-navbar-link-hover-color)}.navbar--dark,.navbar--primary{--ifm-menu-color:var(--ifm-color-gray-300);--ifm-navbar-link-color:var(--ifm-color-gray-100);--ifm-navbar-search-input-background-color:#ffffff1a;--ifm-navbar-search-input-placeholder-color:#ffffff80;color:var(--ifm-color-white)}.navbar--dark{--ifm-navbar-background-color:#242526;--ifm-menu-color-background-active:#ffffff0d;--ifm-navbar-search-input-color:var(--ifm-color-white)}.navbar--primary{--ifm-navbar-background-color:var(--ifm-color-primary);--ifm-navbar-link-hover-color:var(--ifm-color-white);--ifm-menu-color-active:var(--ifm-color-white);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-500)}.navbar__search-input{appearance:none;background:var(--ifm-navbar-search-input-background-color) var(--ifm-navbar-search-input-icon) no-repeat .75rem center/1rem 1rem;border:none;border-radius:2rem;color:var(--ifm-navbar-search-input-color);cursor:text;display:inline-block;font-size:1rem;height:2rem;padding:0 .5rem 0 2.25rem;width:12.5rem}.navbar__search-input::placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar-sidebar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-global-shadow-md);position:fixed;transform:translate3d(-100%,0,0);transition-property:opacity,visibility,transform;width:var(--ifm-navbar-sidebar-width)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar__items{transform:translateZ(0)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar--show .navbar-sidebar__backdrop{opacity:1;visibility:visible}.navbar-sidebar__backdrop{background-color:#0009;position:fixed;right:0;transition-property:opacity,visibility}.navbar-sidebar__brand{align-items:center;box-shadow:var(--ifm-navbar-shadow);display:flex;flex:1;height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar-sidebar__items{display:flex;height:calc(100% - var(--ifm-navbar-height));transition:transform var(--ifm-transition-fast) ease-in-out}.navbar-sidebar__items--show-secondary{transform:translate3d(calc((var(--ifm-navbar-sidebar-width))*-1),0,0)}.navbar-sidebar__item{flex-shrink:0;padding:.5rem;width:calc(var(--ifm-navbar-sidebar-width))}.navbar-sidebar__back{background:var(--ifm-menu-color-background-active);font-size:15px;font-weight:var(--ifm-button-font-weight);margin:0 0 .2rem -.5rem;padding:.6rem 1.5rem;position:relative;text-align:left;top:-.5rem;width:calc(100% + 1rem)}.navbar-sidebar__close{display:flex;margin-left:auto}.pagination{column-gap:var(--ifm-pagination-page-spacing);display:flex;font-size:var(--ifm-pagination-font-size);padding-left:0}.pagination--sm{--ifm-pagination-font-size:0.8rem;--ifm-pagination-padding-horizontal:0.8rem;--ifm-pagination-padding-vertical:0.2rem}.pagination--lg{--ifm-pagination-font-size:1.2rem;--ifm-pagination-padding-horizontal:1.2rem;--ifm-pagination-padding-vertical:0.3rem}.pagination__item{display:inline-flex}.pagination__item>span{padding:var(--ifm-pagination-padding-vertical)}.pagination__item--active .pagination__link{color:var(--ifm-pagination-color-active)}.pagination__item--active .pagination__link,.pagination__item:not(.pagination__item--active):hover .pagination__link{background:var(--ifm-pagination-item-active-background)}.pagination__item--disabled,.pagination__item[disabled]{opacity:.25;pointer-events:none}.pagination__link{border-radius:var(--ifm-pagination-border-radius);color:var(--ifm-font-color-base);display:inline-block;padding:var(--ifm-pagination-padding-vertical) var(--ifm-pagination-padding-horizontal);transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav{display:grid;grid-gap:var(--ifm-spacing-horizontal);gap:var(--ifm-spacing-horizontal);grid-template-columns:repeat(2,1fr)}.pagination-nav__link{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);display:block;height:100%;line-height:var(--ifm-heading-line-height);padding:var(--ifm-global-spacing);transition:border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav__link:hover{border-color:var(--ifm-pagination-nav-color-hover)}.pagination-nav__link--next{grid-column:2/3;text-align:right}.pagination-nav__label{font-size:var(--ifm-h4-font-size);font-weight:var(--ifm-heading-font-weight);word-break:break-word}.pagination-nav__link--prev .pagination-nav__label:before{content:"« "}.pagination-nav__link--next .pagination-nav__label:after{content:" »"}.pagination-nav__sublabel{color:var(--ifm-color-content-secondary);font-size:var(--ifm-h5-font-size);font-weight:var(--ifm-font-weight-semibold);margin-bottom:.25rem}.pills__item,.tabs{font-weight:var(--ifm-font-weight-bold)}.pills{display:flex;gap:var(--ifm-pills-spacing);padding-left:0}.pills__item{border-radius:.5rem;cursor:pointer;display:inline-block;padding:.25rem 1rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs,:not(.containsTaskList_mC6p>li)>.containsTaskList_mC6p{padding-left:0}.pills__item--active{color:var(--ifm-pills-color-active)}.pills__item--active,.pills__item:not(.pills__item--active):hover{background:var(--ifm-pills-color-background-active)}.pills--block{justify-content:stretch}.pills--block .pills__item{flex-grow:1;text-align:center}.tabs{color:var(--ifm-tabs-color);display:flex;margin-bottom:0;overflow-x:auto}.tabs__item{border-bottom:3px solid #0000;border-radius:var(--ifm-global-radius);cursor:pointer;display:inline-flex;padding:var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal);transition:background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs__item--active{border-bottom-color:var(--ifm-tabs-color-active-border);border-bottom-left-radius:0;border-bottom-right-radius:0;color:var(--ifm-tabs-color-active)}.tabs__item:hover{background-color:var(--ifm-hover-overlay)}.tabs--block{justify-content:stretch}.tabs--block .tabs__item{flex-grow:1;justify-content:center}html[data-theme=dark]{--ifm-color-scheme:dark;--ifm-color-emphasis-0:var(--ifm-color-gray-1000);--ifm-color-emphasis-100:var(--ifm-color-gray-900);--ifm-color-emphasis-200:var(--ifm-color-gray-800);--ifm-color-emphasis-300:var(--ifm-color-gray-700);--ifm-color-emphasis-400:var(--ifm-color-gray-600);--ifm-color-emphasis-600:var(--ifm-color-gray-400);--ifm-color-emphasis-700:var(--ifm-color-gray-300);--ifm-color-emphasis-800:var(--ifm-color-gray-200);--ifm-color-emphasis-900:var(--ifm-color-gray-100);--ifm-color-emphasis-1000:var(--ifm-color-gray-0);--ifm-background-color:#1b1b1d;--ifm-background-surface-color:#242526;--ifm-hover-overlay:#ffffff0d;--ifm-color-content:#e3e3e3;--ifm-color-content-secondary:#fff;--ifm-breadcrumb-separator-filter:invert(64%) sepia(11%) saturate(0%) hue-rotate(149deg) brightness(99%) contrast(95%);--ifm-code-background:#ffffff1a;--ifm-scrollbar-track-background-color:#444;--ifm-scrollbar-thumb-background-color:#686868;--ifm-scrollbar-thumb-hover-background-color:#7a7a7a;--ifm-table-stripe-background:#ffffff12;--ifm-toc-border-color:var(--ifm-color-emphasis-200);--ifm-color-primary-contrast-background:#102445;--ifm-color-primary-contrast-foreground:#ebf2fc;--ifm-color-secondary-contrast-background:#474748;--ifm-color-secondary-contrast-foreground:#fdfdfe;--ifm-color-success-contrast-background:#003100;--ifm-color-success-contrast-foreground:#e6f6e6;--ifm-color-info-contrast-background:#193c47;--ifm-color-info-contrast-foreground:#eef9fd;--ifm-color-warning-contrast-background:#4d3800;--ifm-color-warning-contrast-foreground:#fff8e6;--ifm-color-danger-contrast-background:#4b1113;--ifm-color-danger-contrast-foreground:#ffebec}#nprogress .bar{background:var(--docusaurus-progress-bar-color);height:2px;left:0;position:fixed;top:0;width:100%;z-index:1031}#nprogress .peg{box-shadow:0 0 10px var(--docusaurus-progress-bar-color),0 0 5px var(--docusaurus-progress-bar-color);height:100%;opacity:1;position:absolute;right:0;transform:rotate(3deg) translateY(-4px);width:100px}[data-theme=dark]{--ifm-color-primary:#90ff99;--ifm-color-primary-dark:#5bc95b;--ifm-color-primary-darker:#238723;--ifm-color-primary-darkest:#124c12;--ifm-color-primary-light:#90ff99;--ifm-color-primary-lighter:#d2ffd3;--ifm-color-primary-lightest:#d2ffd3;--docusaurus-highlighted-code-line-bg:#0000004d}.header-github-link:hover{opacity:.6}.header-github-link:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") no-repeat;content:"";display:flex;height:24px;width:24px}html[data-theme=dark] .header-github-link:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") no-repeat}.tabs-container{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);padding:var(--ifm-global-spacing)}.tabs{border-bottom:1px solid var(--ifm-color-emphasis-300)}.footer--dark{--ifm-footer-background-color:#303846;--ifm-footer-color:var(--ifm-footer-link-color);--ifm-footer-link-color:var(--ifm-color-secondary);--ifm-footer-title-color:var(--ifm-color-white);background-color:#000}.asciinema-theme-edgeless .asciinema-terminal{background-color:#000;border-color:#000;color:#fff}.asciinema-theme-edgeless .fg-bg{color:#000}.asciinema-theme-edgeless .bg-fg{background-color:#fff}.tag_zVej{border:1px solid var(--docusaurus-tag-list-border);transition:border var(--ifm-transition-fast)}.tag_zVej:hover{--docusaurus-tag-list-border:var(--ifm-link-color)}.tagRegular_sFm0{border-radius:var(--ifm-global-radius);font-size:90%;padding:.2rem .5rem .3rem}.tagWithCount_h2kH{align-items:center;border-left:0;display:flex;padding:0 .5rem 0 1rem;position:relative}.tagWithCount_h2kH:after,.tagWithCount_h2kH:before{border:1px solid var(--docusaurus-tag-list-border);content:"";position:absolute;top:50%;transition:inherit}.tagWithCount_h2kH:before{border-bottom:0;border-right:0;height:1.18rem;right:100%;transform:translate(50%,-50%) rotate(-45deg);width:1.18rem}.tagWithCount_h2kH:after{border-radius:50%;height:.5rem;left:0;transform:translateY(-50%);width:.5rem}.tagWithCount_h2kH span{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.7rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.tags_jXut,div.ap-control-bar .ap-fullscreen-button svg.ap-icon-fullscreen-on{display:inline}.tag_QGVx{display:inline-block;margin:0 .4rem .5rem 0}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}.lastUpdated_JAkA{font-size:smaller;font-style:italic;margin-top:.2rem}.tocCollapsibleButton_TO0P{align-items:center;display:flex;font-size:inherit;justify-content:space-between;padding:.4rem .8rem;width:100%}.tocCollapsibleButton_TO0P:after{background:var(--ifm-menu-link-sublist-icon) 50% 50%/2rem 2rem no-repeat;content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast);width:1.25rem}.tocCollapsibleButtonExpanded_MG3E:after,.tocCollapsibleExpanded_sAul{transform:none}.tocCollapsible_ETCw{background-color:var(--ifm-menu-color-background-active);border-radius:var(--ifm-global-radius);margin:1rem 0}.tocCollapsibleContent_vkbj>ul{border-left:none;border-top:1px solid var(--ifm-color-emphasis-300);font-size:15px;padding:.2rem 0}.tocCollapsibleContent_vkbj ul li{margin:.4rem .8rem}.tocCollapsibleContent_vkbj a{display:block}.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem);overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.backToTopButton_sjWU{background-color:var(--ifm-color-emphasis-200);border-radius:50%;bottom:1.3rem;box-shadow:var(--ifm-global-shadow-lw);height:3rem;opacity:0;position:fixed;right:1.3rem;transform:scale(0);transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default);visibility:hidden;width:3rem;z-index:calc(var(--ifm-z-index-fixed) - 1)}.backToTopButton_sjWU:after{background-color:var(--ifm-color-emphasis-1000);content:" ";display:inline-block;height:100%;-webkit-mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;width:100%}.backToTopButtonShow_xfvO{opacity:1;transform:scale(1);visibility:visible}body:not(.navigation-with-keyboard) :not(input):focus{outline:0}#__docusaurus-base-url-issue-banner-container,.docSidebarContainer_YfHR,.sidebarLogo_isFc,.themedComponent_mlkZ,.toggleIcon_g3eP,html[data-announcement-bar-initially-dismissed=true] .announcementBar_mb4j{display:none}.skipToContent_fXgn{background-color:var(--ifm-background-surface-color);color:var(--ifm-color-emphasis-900);left:100%;padding:calc(var(--ifm-global-spacing)/2) var(--ifm-global-spacing);position:fixed;top:1rem;z-index:calc(var(--ifm-z-index-fixed) + 1)}.skipToContent_fXgn:focus{box-shadow:var(--ifm-global-shadow-md);left:1rem}.closeButton_CVFx{line-height:0;padding:0}.content_knG7{font-size:85%;padding:5px 0;text-align:center}.content_knG7 a{color:inherit}.announcementBar_mb4j{align-items:center;background-color:var(--ifm-color-white);border-bottom:1px solid var(--ifm-color-emphasis-100);color:var(--ifm-color-black);display:flex;height:var(--docusaurus-announcement-bar-height)}.buttonGroup_M5ko button,.codeBlockContainer_Ckt0{background:var(--prism-background-color);color:var(--prism-color)}.announcementBarPlaceholder_vyr4{flex:0 0 10px}.announcementBarClose_gvF7{align-self:stretch;flex:0 0 30px}.toggle_vylO{height:2rem;width:2rem}.toggleButton_gllP{align-items:center;border-radius:50%;display:flex;height:100%;justify-content:center;transition:background var(--ifm-transition-fast);width:100%}.toggleButton_gllP:hover{background:var(--ifm-color-emphasis-200)}[data-theme-choice=dark] .darkToggleIcon_wfgR,[data-theme-choice=light] .lightToggleIcon_pyhR,[data-theme-choice=system] .systemToggleIcon_QzmC,[data-theme=dark] .themedComponent--dark_xIcU,[data-theme=light] .themedComponent--light_NVdE,html:not([data-theme]) .themedComponent--light_NVdE{display:initial}.toggleButtonDisabled_aARS{cursor:not-allowed}.darkNavbarColorModeToggle_X3D1:hover{background:var(--ifm-color-gray-800)}[data-theme=dark]:root{--docusaurus-collapse-button-bg:#ffffff0d;--docusaurus-collapse-button-bg-hover:#ffffff1a}.collapseSidebarButton_PEFL{display:none;margin:0}.categoryLinkLabel_W154,.linkLabel_WmDU{display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical}.iconExternalLink_nPIU{margin-left:.3rem}.linkLabel_WmDU{line-clamp:2;-webkit-line-clamp:2}.categoryLink_byQd{overflow:hidden}.menu__link--sublist-caret:after{margin-left:var(--ifm-menu-link-padding-vertical)}.categoryLinkLabel_W154{flex:1;line-clamp:2;-webkit-line-clamp:2}.docMainContainer_TBSr,.docRoot_UBD9{display:flex;width:100%}.docsWrapper_hBAB{display:flex;flex:1 0 auto}.anchorTargetStickyNavbar_Vzrq{scroll-margin-top:calc(var(--ifm-navbar-height) + .5rem)}.anchorTargetHideOnScrollNavbar_vjPI{scroll-margin-top:.5rem}.hash-link{opacity:0;padding-left:.5rem;transition:opacity var(--ifm-transition-fast);user-select:none}.hash-link:before{content:"#"}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link,div.ap-wrapper.ap-hud .ap-control-bar{opacity:1}.cardContainer_fWXF{--ifm-link-color:var(--ifm-color-emphasis-800);--ifm-link-hover-color:var(--ifm-color-emphasis-700);--ifm-link-hover-decoration:none;border:1px solid var(--ifm-color-emphasis-200);box-shadow:0 1.5px 3px 0 #00000026;transition:all var(--ifm-transition-fast) ease;transition-property:border,box-shadow}.cardContainer_fWXF:hover{border-color:var(--ifm-color-primary);box-shadow:0 3px 6px 0 #0003}.cardTitle_rnsV{font-size:1.2rem}.cardDescription_PWke{font-size:.8rem}.docCardListItem_W1sv{margin-bottom:2rem}.codeBlockContainer_Ckt0{border-radius:var(--ifm-code-border-radius);box-shadow:var(--ifm-global-shadow-lw);margin-bottom:var(--ifm-leading)}.codeBlock_bY9V{--ifm-pre-background:var(--prism-background-color);margin:0;padding:0}.codeBlockLines_e6Vv{float:left;font:inherit;min-width:100%;padding:var(--ifm-pre-padding)}.codeBlockLinesWithNumbering_o6Pm{display:table;padding:var(--ifm-pre-padding) 0}:where(:root){--docusaurus-highlighted-code-line-bg:#484d5b}:where([data-theme=dark]){--docusaurus-highlighted-code-line-bg:#646464}.theme-code-block-highlighted-line{background-color:var(--docusaurus-highlighted-code-line-bg);display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.codeLine_lJS_{counter-increment:line-count;display:table-row}.codeLineNumber_Tfdd{background:var(--ifm-pre-background);display:table-cell;left:0;overflow-wrap:normal;padding:0 var(--ifm-pre-padding);position:sticky;text-align:right;width:1%}.codeLineNumber_Tfdd:before{content:counter(line-count);opacity:.4}.codeLineContent_feaV{padding-right:var(--ifm-pre-padding)}.theme-code-block:hover .copyButtonCopied_Vdqa{opacity:1!important}.copyButtonIcons_IEyt{height:1.125rem;position:relative;width:1.125rem}.copyButtonIcon_TrPX,.copyButtonSuccessIcon_cVMy{fill:currentColor;height:inherit;left:0;opacity:inherit;position:absolute;top:0;transition:all var(--ifm-transition-fast) ease;width:inherit}.copyButtonSuccessIcon_cVMy{color:#00d600;left:50%;opacity:0;top:50%;transform:translate(-50%,-50%) scale(.33)}.copyButtonCopied_Vdqa .copyButtonIcon_TrPX{opacity:0;transform:scale(.33)}.copyButtonCopied_Vdqa .copyButtonSuccessIcon_cVMy{opacity:1;transform:translate(-50%,-50%) scale(1);transition-delay:75ms}.wordWrapButtonIcon_b1P5{height:1.2rem;width:1.2rem}.buttonGroup_M5ko{column-gap:.2rem;display:flex;position:absolute;right:calc(var(--ifm-pre-padding)/2);top:calc(var(--ifm-pre-padding)/2)}.buttonGroup_M5ko button{align-items:center;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-global-radius);display:flex;line-height:0;opacity:0;padding:.4rem;transition:opacity var(--ifm-transition-fast) ease-in-out}.buttonGroup_M5ko button:focus-visible,.buttonGroup_M5ko button:hover{opacity:1!important}.theme-code-block:hover .buttonGroup_M5ko button{opacity:.4}.codeBlockContent_QJqH{border-radius:inherit;direction:ltr;position:relative}.codeBlockTitle_OeMC{border-bottom:1px solid var(--ifm-color-emphasis-300);border-top-left-radius:inherit;border-top-right-radius:inherit;font-size:var(--ifm-code-font-size);font-weight:500;padding:.75rem var(--ifm-pre-padding)}.codeBlockTitle_OeMC+.codeBlockContent_QJqH .codeBlock_a8dz{border-top-left-radius:0;border-top-right-radius:0}.details_lb9f{--docusaurus-details-summary-arrow-size:0.38rem;--docusaurus-details-transition:transform 200ms ease;--docusaurus-details-decoration-color:grey}.details_lb9f>summary{cursor:pointer;list-style:none;padding-left:1rem;position:relative}.details_lb9f>summary::-webkit-details-marker{display:none}.details_lb9f>summary:before{border-color:#0000 #0000 #0000 var(--docusaurus-details-decoration-color);border-style:solid;border-width:var(--docusaurus-details-summary-arrow-size);content:"";left:0;position:absolute;top:.45rem;transform:rotate(0);transform-origin:calc(var(--docusaurus-details-summary-arrow-size)/2) 50%;transition:var(--docusaurus-details-transition)}.collapsibleContent_i85q{border-top:1px solid var(--docusaurus-details-decoration-color);margin-top:1rem;padding-top:1rem}.details_b_Ee{--docusaurus-details-decoration-color:var(--ifm-alert-border-color);--docusaurus-details-transition:transform var(--ifm-transition-fast) ease;border:1px solid var(--ifm-alert-border-color);margin:0 0 var(--ifm-spacing-vertical)}.containsTaskList_mC6p{list-style:none}.img_ev3q{height:auto}.admonition_xJq3{margin-bottom:1em}.admonitionHeading_Gvgb{font:var(--ifm-heading-font-weight) var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family)}.admonitionHeading_Gvgb:not(:last-child){margin-bottom:.3rem}.admonitionHeading_Gvgb code{text-transform:none}.admonitionIcon_Rf37{display:inline-block;margin-right:.4em;vertical-align:middle}.admonitionIcon_Rf37 svg{display:inline-block;fill:var(--ifm-alert-foreground-color);height:1.6em;width:1.6em}.ap-player .ap-overlay-start,.dropdownNavbarItemMobile_J0Sd,div.ap-control-bar.ap-seekable .ap-progressbar .ap-bar{cursor:pointer}.iconLanguage_nlXk{margin-right:5px;vertical-align:text-bottom}body.dark,body[data-theme=dark]{--aa-text-color-rgb:183,192,199;--aa-primary-color-rgb:146,138,255;--aa-muted-color-rgb:146,138,255;--aa-input-background-color-rgb:0,3,9;--aa-background-color-rgb:21,24,42;--aa-selected-color-rgb:146,138,255;--aa-selected-color-alpha:0.25;--aa-description-highlight-background-color-rgb:0 255 255;--aa-description-highlight-background-color-alpha:0.25;--aa-panel-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--aa-scrollbar-track-background-color-rgb:44,46,64;--aa-muted-color-alpha:1}.aa-Autocomplete,.aa-DetachedFormContainer,.aa-Panel{color:#262627;color:rgba(var(--aa-text-color-rgb),var(--aa-text-color-alpha));font-family:inherit;font-family:var(--aa-font-family);font-size:16px;font-size:var(--aa-font-size);font-weight:400;line-height:1em;margin:0;padding:0;text-align:left}.aa-Form{align-items:center;background-color:#fff;background-color:rgba(var(--aa-input-background-color-rgb),var(--aa-input-background-color-alpha));border:1px solid #807ea3cc;border:1px solid rgba(var(--aa-input-border-color-rgb),var(--aa-input-border-color-alpha));border-radius:3px;display:flex;line-height:1em;margin:0;position:relative;width:100%}.aa-ClearButton,.aa-Input,.aa-SubmitButton{border:0;background:none}.aa-Form:focus-within{border-color:#3e34d3;border-color:rgba(var(--aa-primary-color-rgb),1);box-shadow:0 0 0 2px #3e34d333,inset 0 0 0 2px #3e34d333;box-shadow:rgba(var(--aa-primary-color-rgb),var(--aa-primary-color-alpha)) 0 0 0 2px,inset rgba(var(--aa-primary-color-rgb),var(--aa-primary-color-alpha)) 0 0 0 2px;outline:currentColor}.aa-InputWrapperPrefix{align-items:center;display:flex;flex-shrink:0;height:44px;height:var(--aa-search-input-height);order:1}.aa-Label,.aa-LoadingIndicator{cursor:auto;flex-shrink:0;height:100%;padding:0;text-align:left}.aa-Label svg,.aa-LoadingIndicator svg{color:#3e34d3;color:rgba(var(--aa-primary-color-rgb),1);height:auto;max-height:20px;max-height:var(--aa-input-icon-size);stroke-width:1.6;stroke-width:var(--aa-icon-stroke-width);width:20px;width:var(--aa-input-icon-size)}.aa-LoadingIndicator,.aa-SubmitButton{height:100%;padding-left:11px;padding-left:calc(var(--aa-spacing)*.75 - 1px);padding-right:8px;padding-right:var(--aa-spacing-half);width:47px;width:calc(var(--aa-spacing)*1.75 + var(--aa-icon-size) - 1px)}.aa-SubmitButton{appearance:none;margin:0}.aa-LoadingIndicator{align-items:center;display:flex;justify-content:center}.aa-ClearButton[hidden],.aa-ItemContent:empty,.aa-LoadingIndicator[hidden],.aa-Source:empty,.aa-SourceHeader:empty{display:none}.aa-InputWrapper{order:3;position:relative;width:100%}.aa-Input{appearance:none;color:#262627;color:rgba(var(--aa-text-color-rgb),var(--aa-text-color-alpha));font:inherit;height:44px;height:var(--aa-search-input-height);padding:0;width:100%}.aa-Input::placeholder{color:#807ea399;color:rgba(var(--aa-muted-color-rgb),var(--aa-muted-color-alpha));opacity:1}.aa-Input:focus{border-color:none;box-shadow:none;outline:0}.aa-Input::-webkit-search-cancel-button,.aa-Input::-webkit-search-decoration,.aa-Input::-webkit-search-results-button,.aa-Input::-webkit-search-results-decoration{appearance:none}.aa-InputWrapperSuffix{align-items:center;display:flex;height:44px;height:var(--aa-search-input-height);order:4}.aa-ClearButton{align-items:center;color:#807ea399;color:rgba(var(--aa-muted-color-rgb),var(--aa-muted-color-alpha));cursor:pointer;display:flex;height:100%;margin:0;padding:0 12.83328px;padding:0 calc(var(--aa-spacing)*.83333 - .5px)}.aa-Item,.aa-ItemIcon{align-items:center;border-radius:3px}.aa-ClearButton:focus,.aa-ClearButton:hover,.aa-ItemActionButton:focus svg,.aa-ItemActionButton:hover svg{color:#262627;color:rgba(var(--aa-text-color-rgb),var(--aa-text-color-alpha))}.aa-ClearButton svg{stroke-width:1.6;stroke-width:var(--aa-icon-stroke-width);width:20px;width:var(--aa-icon-size)}.aa-Panel{background-color:#fff;background-color:rgba(var(--aa-background-color-rgb),var(--aa-background-color-alpha));border-radius:4px;border-radius:calc(var(--aa-spacing)/4);box-shadow:0 0 0 1px #23263b1a,0 6px 16px -4px #23263b26;box-shadow:var(--aa-panel-shadow);margin:8px 0 0;overflow:hidden;position:absolute;transition:opacity .2s ease-in,filter .2s ease-in}.aa-Panel button{appearance:none;background:none;border:0;margin:0;padding:0}.aa-PanelLayout{height:100%;margin:0;max-height:650px;max-height:var(--aa-panel-max-height);overflow-y:auto;padding:0;position:relative;text-align:left}.aa-PanelLayoutColumns--twoGolden{display:grid;grid-template-columns:39.2% auto;overflow:hidden;padding:0}.aa-PanelLayoutColumns--two{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));overflow:hidden;padding:0}.aa-PanelLayoutColumns--three{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));overflow:hidden;padding:0}.aa-Panel--stalled .aa-Source{filter:grayscale(1);opacity:.8}.aa-Panel--scrollable{margin:0;max-height:650px;max-height:var(--aa-panel-max-height);overflow-x:hidden;overflow-y:auto;padding:8px;padding:var(--aa-spacing-half);scrollbar-color:#fff #eaeaea;scrollbar-color:rgba(var(--aa-scrollbar-thumb-background-color-rgb),var(--aa-scrollbar-thumb-background-color-alpha)) rgba(var(--aa-scrollbar-track-background-color-rgb),var(--aa-scrollbar-track-background-color-alpha));scrollbar-width:thin}.aa-Panel--scrollable::-webkit-scrollbar{width:13px;width:var(--aa-scrollbar-width)}.aa-Panel--scrollable::-webkit-scrollbar-track{background-color:#eaeaea;background-color:rgba(var(--aa-scrollbar-track-background-color-rgb),var(--aa-scrollbar-track-background-color-alpha))}.aa-Panel--scrollable::-webkit-scrollbar-thumb{background-color:#fff;background-color:rgba(var(--aa-scrollbar-thumb-background-color-rgb),var(--aa-scrollbar-thumb-background-color-alpha));border:3px solid #eaeaea;border:3px solid rgba(var(--aa-scrollbar-track-background-color-rgb),var(--aa-scrollbar-track-background-color-alpha));border-radius:9999px;border-right-width:2px}.aa-Source{margin:0;padding:0;position:relative;width:100%}.aa-SourceNoResults{font-size:1em;margin:0;padding:16px;padding:var(--aa-spacing)}.aa-List{list-style:none;margin:0}.aa-List,.aa-SourceHeader{padding:0;position:relative}.aa-SourceHeader{margin:8px .5em 8px 0;margin:var(--aa-spacing-half) .5em var(--aa-spacing-half) 0}.aa-SourceHeaderTitle{background:#fff;background:rgba(var(--aa-background-color-rgb),var(--aa-background-color-alpha));color:#3e34d3;color:rgba(var(--aa-primary-color-rgb),1);display:inline-block;font-size:.8em;font-weight:600;font-weight:var(--aa-font-weight-semibold);margin:0;padding:0 8px 0 0;padding:0 var(--aa-spacing-half) 0 0;position:relative;z-index:9999;z-index:var(--aa-base-z-index)}.aa-SourceHeaderLine{border-bottom:1px solid #3e34d3;border-bottom:1px solid rgba(var(--aa-primary-color-rgb),1);display:block;height:2px;left:0;margin:0;opacity:.3;padding:0;position:absolute;right:0;top:8px;top:var(--aa-spacing-half);z-index:9998;z-index:calc(var(--aa-base-z-index) - 1)}.aa-SourceFooterSeeAll{background:linear-gradient(180deg,#fff,#807ea324);background:linear-gradient(180deg,rgba(var(--aa-background-color-rgb),var(--aa-background-color-alpha)),#807ea324);border:1px solid #807ea399;border:1px solid rgba(var(--aa-muted-color-rgb),var(--aa-muted-color-alpha));border-radius:5px;box-shadow:inset 0 0 2px #fff,0 2px 2px -1px #4c455826;color:inherit;font-size:.95em;font-weight:500;font-weight:var(--aa-font-weight-medium);padding:.475em 1em .6em}.aa-SourceFooterSeeAll:focus,.aa-SourceFooterSeeAll:hover{border:1px solid #3e34d3;border:1px solid rgba(var(--aa-primary-color-rgb),1);color:#3e34d3;color:rgba(var(--aa-primary-color-rgb),1)}.aa-Item{cursor:pointer;display:grid;min-height:40px;min-height:calc(var(--aa-spacing)*2.5);padding:4px;padding:calc(var(--aa-spacing-half)/2)}.aa-Item[aria-selected=true]{background-color:rgba(179,173,214,.205);background-color:rgba(var(--aa-selected-color-rgb),var(--aa-selected-color-alpha))}.aa-Item[aria-selected=true] .aa-ActiveOnly,.aa-Item[aria-selected=true] .aa-ItemActionButton,.ap-tooltip-container:hover span.ap-tooltip{visibility:visible}.aa-ItemIcon{background:#fff;background:rgba(var(--aa-background-color-rgb),var(--aa-background-color-alpha));box-shadow:inset 0 0 0 1px #807ea34d;box-shadow:inset 0 0 0 1px rgba(var(--aa-panel-border-color-rgb),var(--aa-panel-border-color-alpha));color:#7777a3;color:rgba(var(--aa-icon-color-rgb),var(--aa-icon-color-alpha));display:flex;flex-shrink:0;font-size:.7em;height:28px;height:calc(var(--aa-icon-size) + var(--aa-spacing-half));justify-content:center;overflow:hidden;stroke-width:1.6;stroke-width:var(--aa-icon-stroke-width);text-align:center;width:28px;width:calc(var(--aa-icon-size) + var(--aa-spacing-half))}.aa-ItemIcon img{height:auto;max-height:20px;max-height:calc(var(--aa-icon-size) + var(--aa-spacing-half) - 8px);max-width:20px;max-width:calc(var(--aa-icon-size) + var(--aa-spacing-half) - 8px);width:auto}.aa-ItemIcon svg{height:20px;height:var(--aa-icon-size);width:20px;width:var(--aa-icon-size)}.aa-ItemIcon--alignTop{align-self:flex-start}.aa-ItemIcon--noBorder{background:none;box-shadow:none}.aa-ItemIcon--picture{height:96px;width:96px}.aa-ItemIcon--picture img{max-height:100%;max-width:100%;padding:8px;padding:var(--aa-spacing-half)}.aa-ItemContent{align-items:center;cursor:pointer;display:grid;gap:8px;grid-gap:8px;grid-gap:var(--aa-spacing-half);gap:var(--aa-spacing-half);grid-auto-flow:column;line-height:1.25em;overflow:hidden}.aa-ItemContent mark{background:none;color:#262627;color:rgba(var(--aa-text-color-rgb),var(--aa-text-color-alpha));font-style:normal;font-weight:700;font-weight:var(--aa-font-weight-bold)}.aa-ItemContent--dual{display:flex;flex-direction:column;justify-content:space-between;text-align:left}.aa-ItemContent--dual .aa-ItemContentSubtitle,.aa-ItemContent--dual .aa-ItemContentTitle{display:block}.aa-ItemContent--indented{padding-left:36px;padding-left:calc(var(--aa-icon-size) + var(--aa-spacing))}.aa-ItemContentBody{display:grid;gap:4px;grid-gap:4px;grid-gap:calc(var(--aa-spacing-half)/2);gap:calc(var(--aa-spacing-half)/2)}.aa-ItemContentTitle{display:inline-block;margin:0 .5em 0 0;max-width:100%;overflow:hidden;padding:0;text-overflow:ellipsis;white-space:nowrap}.aa-ItemContentSubtitle{font-size:.92em}.aa-ItemContentSubtitleIcon:before{border-color:#807ea3a3;border-color:rgba(var(--aa-muted-color-rgb),.64);border-style:solid;content:"";display:inline-block;left:1px;position:relative;top:-3px}.aa-PanelFooter:after,.aa-PanelHeader:after{position:absolute;pointer-events:none;left:0;content:"";right:0}.aa-ItemContentSubtitle--inline .aa-ItemContentSubtitleIcon:before{border-width:0 0 1.5px;margin-left:8px;margin-left:var(--aa-spacing-half);margin-right:4px;margin-right:calc(var(--aa-spacing-half)/2);width:10px;width:calc(var(--aa-spacing-half) + 2px)}.aa-ItemContentSubtitle--standalone{align-items:center;color:#262627;color:rgba(var(--aa-text-color-rgb),var(--aa-text-color-alpha));display:grid;gap:8px;grid-gap:8px;grid-gap:var(--aa-spacing-half);gap:var(--aa-spacing-half);grid-auto-flow:column;justify-content:start}.aa-DetachedContainer--modal .aa-PanelLayout:empty,.aa-DetachedSearchButtonPlaceholder[hidden],.aa-ItemContentDash,.aa-ItemContentDescription:empty,.navbarSearchContainer_Bca1:empty,div.ap-control-bar .ap-fullscreen-button svg.ap-icon-fullscreen-off,div.ap-control-bar span.ap-timer .ap-time-remaining,div.ap-control-bar span.ap-timer:hover .ap-time-elapsed{display:none}.aa-ItemContentSubtitle--standalone .aa-ItemContentSubtitleIcon:before{border-radius:0 0 0 3px;border-width:0 0 1.5px 1.5px;height:8px;height:var(--aa-spacing-half);width:8px;width:var(--aa-spacing-half)}.aa-ItemContentSubtitleCategory{color:#807ea3;color:rgba(var(--aa-muted-color-rgb),1);font-weight:500}.aa-ItemContentDescription{color:#262627;color:rgba(var(--aa-text-color-rgb),var(--aa-text-color-alpha));font-size:.85em;max-width:100%;overflow-x:hidden;text-overflow:ellipsis}.aa-ItemContentDescription mark{background:#f5df4d80;background:rgba(var(--aa-description-highlight-background-color-rgb),var(--aa-description-highlight-background-color-alpha));color:#262627;color:rgba(var(--aa-text-color-rgb),var(--aa-text-color-alpha));font-style:normal;font-weight:500;font-weight:var(--aa-font-weight-medium)}div.ap-wrapper div.ap-player,pre.ap-terminal{background-color:var(--term-color-background);box-sizing:initial;overflow:hidden}.aa-ItemContentDash{color:#807ea399;color:rgba(var(--aa-muted-color-rgb),var(--aa-muted-color-alpha));opacity:.4}.aa-ItemContentTag{background-color:#3e34d333;background-color:rgba(var(--aa-primary-color-rgb),var(--aa-primary-color-alpha));border-radius:3px;margin:0 .4em 0 0;padding:.08em .3em}.aa-ItemLink,.aa-ItemWrapper{align-items:center;color:inherit;display:grid;gap:4px;grid-gap:4px;grid-gap:calc(var(--aa-spacing-half)/2);gap:calc(var(--aa-spacing-half)/2);grid-auto-flow:column;justify-content:space-between;width:100%}.aa-ItemLink{color:inherit}.aa-ItemActions{display:grid;grid-auto-flow:column;height:100%;justify-self:end;margin:0 -5.33333px;margin:0 calc(var(--aa-spacing)/-3);padding:0 2px 0 0}.aa-ItemActionButton{align-items:center;background:none;border:0;color:#807ea399;color:rgba(var(--aa-muted-color-rgb),var(--aa-muted-color-alpha));cursor:pointer;display:flex;flex-shrink:0;padding:0}.aa-ItemActionButton svg{color:#807ea399;color:rgba(var(--aa-muted-color-rgb),var(--aa-muted-color-alpha));margin:5.33333px;margin:calc(var(--aa-spacing)/3);stroke-width:1.6;stroke-width:var(--aa-icon-stroke-width);width:20px;width:var(--aa-action-icon-size)}.aa-ActiveOnly{visibility:hidden}.aa-PanelHeader{align-items:center;background:#3e34d3;background:rgba(var(--aa-primary-color-rgb),1);color:#fff;display:grid;height:var(--aa-modal-header-height);margin:0;padding:8px 16px;padding:var(--aa-spacing-half) var(--aa-spacing);position:relative}.aa-PanelHeader:after{background-image:linear-gradient(#fff,#fff0);background-image:linear-gradient(rgba(var(--aa-background-color-rgb),1),rgba(var(--aa-background-color-rgb),0));bottom:-8px;bottom:calc(var(--aa-spacing-half)*-1);height:8px;height:var(--aa-spacing-half)}.aa-PanelFooter,.aa-PanelHeader:after{z-index:9999;z-index:var(--aa-base-z-index)}.aa-PanelFooter{background-color:#fff;background-color:rgba(var(--aa-background-color-rgb),var(--aa-background-color-alpha));box-shadow:inset 0 1px 0 #807ea34d;box-shadow:inset 0 1px 0 rgba(var(--aa-panel-border-color-rgb),var(--aa-panel-border-color-alpha));display:flex;justify-content:space-between;margin:0;padding:16px;padding:var(--aa-spacing);position:relative}.aa-PanelFooter:after{background-image:linear-gradient(#fff0,#807ea399);background-image:linear-gradient(rgba(var(--aa-background-color-rgb),0),rgba(var(--aa-muted-color-rgb),var(--aa-muted-color-alpha)));height:16px;height:var(--aa-spacing);opacity:.12;top:-16px;top:calc(var(--aa-spacing)*-1);z-index:9998;z-index:calc(var(--aa-base-z-index) - 1)}.aa-DetachedContainer{background:#fff;background:rgba(var(--aa-background-color-rgb),var(--aa-background-color-alpha));bottom:0;box-shadow:0 0 0 1px #23263b1a,0 6px 16px -4px #23263b26;box-shadow:var(--aa-panel-shadow);display:flex;flex-direction:column;left:0;margin:0;overflow:hidden;padding:0;position:fixed;right:0;top:0;z-index:9999;z-index:var(--aa-base-z-index)}.aa-DetachedContainer:after{height:32px}.aa-DetachedContainer .aa-SourceHeader{margin:8px 0 8px 2px;margin:var(--aa-spacing-half) 0 var(--aa-spacing-half) 2px}.aa-DetachedContainer .aa-Panel{background-color:#fff;background-color:rgba(var(--aa-background-color-rgb),var(--aa-background-color-alpha));border-radius:0;box-shadow:none;flex-grow:1;margin:0;padding:0;position:relative}.aa-DetachedContainer .aa-PanelLayout{bottom:0;box-shadow:none;left:0;margin:0;max-height:none;overflow-y:auto;position:absolute;right:0;top:0;width:100%}.aa-DetachedFormContainer{border-bottom:1px solid #807ea34d;border-bottom:1px solid rgba(var(--aa-panel-border-color-rgb),var(--aa-panel-border-color-alpha));display:flex;flex-direction:row;justify-content:space-between;margin:0;padding:8px;padding:var(--aa-spacing-half)}.aa-DetachedCancelButton{background:none;border:0;border-radius:3px;color:#262627;color:rgba(var(--aa-text-color-rgb),var(--aa-text-color-alpha));cursor:pointer;font:inherit;margin:0 0 0 8px;margin:0 0 0 var(--aa-spacing-half);padding:0 8px;padding:0 var(--aa-spacing-half)}.aa-DetachedCancelButton:focus,.aa-DetachedCancelButton:hover{box-shadow:inset 0 0 0 1px #807ea34d;box-shadow:inset 0 0 0 1px rgba(var(--aa-panel-border-color-rgb),var(--aa-panel-border-color-alpha))}.aa-DetachedContainer--modal{border-radius:6px;bottom:inherit;height:auto;margin:0 auto;max-width:680px;max-width:var(--aa-detached-modal-max-width);position:absolute;top:3%}.aa-DetachedContainer--modal .aa-PanelLayout{max-height:500px;max-height:var(--aa-detached-modal-max-height);padding-bottom:8px;padding-bottom:var(--aa-spacing-half);position:static}.aa-DetachedSearchButton{align-items:center;background-color:#fff;background-color:rgba(var(--aa-input-background-color-rgb),var(--aa-input-background-color-alpha));border:1px solid #807ea3cc;border:1px solid rgba(var(--aa-input-border-color-rgb),var(--aa-input-border-color-alpha));border-radius:3px;color:#807ea399;color:rgba(var(--aa-muted-color-rgb),var(--aa-muted-color-alpha));cursor:pointer;display:flex;font:inherit;font-family:inherit;font-family:var(--aa-font-family);font-size:16px;font-size:var(--aa-font-size);height:44px;height:var(--aa-search-input-height);margin:0;padding:0 5.5px;padding:0 calc(var(--aa-search-input-height)/8);position:relative;text-align:left;width:100%}.aa-DetachedSearchButton:focus{border-color:#3e34d3;border-color:rgba(var(--aa-primary-color-rgb),1);box-shadow:0 0 0 3px #3e34d333,inset 0 0 0 2px #3e34d333;box-shadow:rgba(var(--aa-primary-color-rgb),var(--aa-primary-color-alpha)) 0 0 0 3px,inset rgba(var(--aa-primary-color-rgb),var(--aa-primary-color-alpha)) 0 0 0 2px;outline:currentColor}.aa-DetachedSearchButtonIcon{align-items:center;color:#3e34d3;color:rgba(var(--aa-primary-color-rgb),1);cursor:auto;display:flex;flex-shrink:0;height:100%;justify-content:center;width:36px;width:calc(var(--aa-icon-size) + var(--aa-spacing))}.aa-DetachedSearchButtonQuery{color:#262627;color:rgba(var(--aa-text-color-rgb),1);line-height:1.25em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.aa-Detached{height:100vh;overflow:hidden}.aa-DetachedOverlay{background-color:#73728166;background-color:rgba(var(--aa-overlay-color-rgb),var(--aa-overlay-color-alpha));height:100vh;left:0;margin:0;padding:0;position:fixed;right:0;top:0;z-index:9998;z-index:calc(var(--aa-base-z-index) - 1)}.aa-GradientBottom,.aa-GradientTop{height:8px;height:var(--aa-spacing-half);left:0;pointer-events:none;position:absolute;right:0;z-index:9999;z-index:var(--aa-base-z-index)}.aa-GradientTop{background-image:linear-gradient(#fff,#fff0);background-image:linear-gradient(rgba(var(--aa-background-color-rgb),1),rgba(var(--aa-background-color-rgb),0));top:0}.aa-GradientBottom{background-image:linear-gradient(#fff0,#fff);background-image:linear-gradient(rgba(var(--aa-background-color-rgb),0),rgba(var(--aa-background-color-rgb),1));border-bottom-left-radius:4px;border-bottom-left-radius:calc(var(--aa-spacing)/4);border-bottom-right-radius:4px;border-bottom-right-radius:calc(var(--aa-spacing)/4);bottom:0}.navbarHideable_m1mJ{transition:transform var(--ifm-transition-fast) ease}.navbarHidden_jGov{transform:translate3d(0,calc(-100% - 2px),0)}.errorBoundaryError_a6uf{color:red;white-space:pre-wrap}.errorBoundaryFallback_VBag{color:red;padding:.55rem}.navbar__items--right>:last-child{padding-right:0}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.mainWrapper_z2l0{display:flex;flex:1 0 auto;flex-direction:column}.docusaurus-mt-lg{margin-top:3rem}#__docusaurus{display:flex;flex-direction:column;min-height:100%}div.ap-wrapper{display:flex;height:100%;justify-content:center;outline:0}div.ap-wrapper .title-bar{background-color:#000c;box-sizing:initial;color:#fff;display:none;font-family:sans-serif;font-size:20px;left:0;line-height:1em;padding:15px;position:absolute;right:0;top:-78px;transition:top .15s linear}div.ap-wrapper .title-bar img{height:48px;margin-right:16px;vertical-align:middle}div.ap-wrapper .title-bar a{color:#fff}div.ap-wrapper:fullscreen{align-items:center;background-color:#000;width:100%}div.ap-wrapper:fullscreen .title-bar{display:initial}div.ap-wrapper:fullscreen.hud .title-bar{top:0}div.ap-wrapper div.ap-player{border-radius:4px;display:inline-block;font-size:15px;max-width:100%;padding:0;position:relative;text-align:left}pre.ap-terminal .ap-line span,pre.ap-terminal.ap-cursor-on .ap-line .ap-cursor.ap-inverse{background-color:var(--bg);color:var(--fg)}.ap-player{--term-color-foreground:#fff;--term-color-background:#000;--term-color-0:var(--term-color-foreground);--term-color-1:var(--term-color-foreground);--term-color-2:var(--term-color-foreground);--term-color-3:var(--term-color-foreground);--term-color-4:var(--term-color-foreground);--term-color-5:var(--term-color-foreground);--term-color-6:var(--term-color-foreground);--term-color-7:var(--term-color-foreground);--term-color-8:var(--term-color-0);--term-color-9:var(--term-color-1);--term-color-10:var(--term-color-2);--term-color-11:var(--term-color-3);--term-color-12:var(--term-color-4);--term-color-13:var(--term-color-5);--term-color-14:var(--term-color-6);--term-color-15:var(--term-color-7)}.ap-player .fg-0{--fg:var(--term-color-0)}.ap-player .bg-0{--bg:var(--term-color-0)}.ap-player .fg-1{--fg:var(--term-color-1)}.ap-player .bg-1{--bg:var(--term-color-1)}.ap-player .fg-2{--fg:var(--term-color-2)}.ap-player .bg-2{--bg:var(--term-color-2)}.ap-player .fg-3{--fg:var(--term-color-3)}.ap-player .bg-3{--bg:var(--term-color-3)}.ap-player .fg-4{--fg:var(--term-color-4)}.ap-player .bg-4{--bg:var(--term-color-4)}.ap-player .fg-5{--fg:var(--term-color-5)}.ap-player .bg-5{--bg:var(--term-color-5)}.ap-player .fg-6{--fg:var(--term-color-6)}.ap-player .bg-6{--bg:var(--term-color-6)}.ap-player .fg-7{--fg:var(--term-color-7)}.ap-player .bg-7{--bg:var(--term-color-7)}.ap-player .fg-8{--fg:var(--term-color-8)}.ap-player .bg-8{--bg:var(--term-color-8)}.ap-player .fg-9{--fg:var(--term-color-9)}.ap-player .bg-9{--bg:var(--term-color-9)}.ap-player .fg-10{--fg:var(--term-color-10)}.ap-player .bg-10{--bg:var(--term-color-10)}.ap-player .fg-11{--fg:var(--term-color-11)}.ap-player .bg-11{--bg:var(--term-color-11)}.ap-player .fg-12{--fg:var(--term-color-12)}.ap-player .bg-12{--bg:var(--term-color-12)}.ap-player .fg-13{--fg:var(--term-color-13)}.ap-player .bg-13{--bg:var(--term-color-13)}.ap-player .fg-14{--fg:var(--term-color-14)}.ap-player .bg-14{--bg:var(--term-color-14)}.ap-player .fg-15{--fg:var(--term-color-15)}.ap-player .bg-15{--bg:var(--term-color-15)}.ap-player .fg-10,.ap-player .fg-11,.ap-player .fg-12,.ap-player .fg-13,.ap-player .fg-14,.ap-player .fg-15,.ap-player .fg-8,.ap-player .fg-9,pre.ap-terminal .ap-bright{font-weight:700}pre.ap-terminal{display:block;margin:0;padding:0;white-space:pre;word-wrap:normal;border-color:var(--term-color-background);border-radius:0;border-style:solid;border-width:.75em;color:var(--term-color-foreground);cursor:text;font-family:Consolas,Menlo,Bitstream Vera Sans Mono,monospace,Powerline Symbols;font-feature-settings:none;font-variant-ligatures:none;line-height:var(--term-line-height);outline:0;word-break:normal}pre.ap-terminal .ap-line{letter-spacing:normal;overflow:hidden;display:block;height:var(--term-line-height);position:relative;width:100%}pre.ap-terminal .ap-line span{display:inline-block;height:100%;padding:0;left:calc(100%*var(--offset)/var(--term-cols));position:absolute}pre.ap-terminal .ap-line .ap-inverse{background-color:var(--fg);color:var(--bg)}pre.ap-terminal .ap-line .cp-2580,pre.ap-terminal .ap-line .cp-259b,pre.ap-terminal .ap-line .cp-259c{border-top:calc(var(--term-line-height)*.5) solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-2581{border-bottom:calc(var(--term-line-height)*.125) solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-2582{border-bottom:calc(var(--term-line-height)*.25) solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-2583{border-bottom:calc(var(--term-line-height)*.375) solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-2584{border-bottom:calc(var(--term-line-height)*.5) solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-2585{border-bottom:calc(var(--term-line-height)*.625) solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-2586{border-bottom:calc(var(--term-line-height)*.75) solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-2587{border-bottom:calc(var(--term-line-height)*.875) solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-2588{background-color:var(--fg)}pre.ap-terminal .ap-line .cp-2589{border-left:.875ch solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-258a{border-left:.75ch solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-258b{border-left:.625ch solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-258c{border-left:.5ch solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-258d{border-left:.375ch solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-258e{border-left:.25ch solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-258f{border-left:.125ch solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-2590{border-right:.5ch solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-2591{background-color:color-mix(in srgb,var(--fg) 25%,var(--bg))}pre.ap-terminal .ap-line .cp-2592{background-color:color-mix(in srgb,var(--fg) 50%,var(--bg))}pre.ap-terminal .ap-line .cp-2593{background-color:color-mix(in srgb,var(--fg) 75%,var(--bg))}pre.ap-terminal .ap-line .cp-2594{border-top:calc(var(--term-line-height)*.125) solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-2595{border-right:.125ch solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-2596,pre.ap-terminal .ap-line .cp-2598{border-right:.5ch solid var(--bg)}pre.ap-terminal .ap-line .cp-2596,pre.ap-terminal .ap-line .cp-2597{background-color:var(--fg);border-top:calc(var(--term-line-height)*.5) solid var(--bg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-2597{border-left:.5ch solid var(--bg)}pre.ap-terminal .ap-line .cp-2598{background-color:var(--fg);border-bottom:calc(var(--term-line-height)*.5) solid var(--bg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-259c,pre.ap-terminal .ap-line .cp-259f{border-right:.5ch solid var(--fg)}pre.ap-terminal .ap-line .cp-2599{border-bottom:calc(var(--term-line-height)*.5) solid var(--fg);border-left:.5ch solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-259a:after,pre.ap-terminal .ap-line .cp-259a:before,pre.ap-terminal .ap-line .cp-259e:after,pre.ap-terminal .ap-line .cp-259e:before{background-color:var(--fg);content:"";height:calc(var(--term-line-height)*.5);position:absolute;width:.5ch}pre.ap-terminal .ap-line .cp-259a:before{left:0;top:0}pre.ap-terminal .ap-line .cp-259a:after{bottom:0;right:0}pre.ap-terminal .ap-line .cp-259b{border-left:.5ch solid var(--fg)}pre.ap-terminal .ap-line .cp-259d{background-color:var(--fg);border-bottom:calc(var(--term-line-height)*.5) solid var(--bg);border-left:.5ch solid var(--bg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-259e:before{right:0;top:0}pre.ap-terminal .ap-line .cp-259e:after{bottom:0;left:0}pre.ap-terminal .ap-line .cp-259f{border-bottom:calc(var(--term-line-height)*.5) solid var(--fg);box-sizing:border-box}pre.ap-terminal .ap-line .cp-e0b0{border-left:1ch solid var(--fg)}pre.ap-terminal .ap-line .cp-e0b0,pre.ap-terminal .ap-line .cp-e0b2{border-bottom:calc(var(--term-line-height)*.5) solid #0000;border-top:calc(var(--term-line-height)*.5) solid #0000;box-sizing:border-box}pre.ap-terminal .ap-line .cp-e0b2{border-right:1ch solid var(--fg)}pre.ap-terminal.ap-cursor-on .ap-line .ap-cursor{background-color:var(--fg);border-radius:.05em;color:var(--bg)}pre.ap-terminal:not(.ap-blink) .ap-line .ap-blink{border-color:#0000;color:#0000}pre.ap-terminal .ap-faint{opacity:.5}pre.ap-terminal .ap-strikethrough{-webkit-text-decoration:line-through;text-decoration:line-through}.ap-line span{--fg:var(--term-color-foreground);--bg:var(--term-color-background)}div.ap-player div.ap-control-bar{align-items:stretch;border-top:2px solid color-mix(in oklab,var(--term-color-background) 80%,var(--term-color-foreground));bottom:0;box-sizing:initial;color:var(--term-color-foreground);display:flex;height:32px;justify-content:space-between;left:0;line-height:1;opacity:0;position:absolute;transition:opacity .15s linear;-webkit-user-select:none;user-select:none;width:100%;z-index:30}div.ap-player div.ap-control-bar *{box-sizing:inherit}div.ap-control-bar svg.ap-icon path{fill:var(--term-color-foreground)}div.ap-control-bar span.ap-button{cursor:pointer;display:flex;flex:0 0 auto}div.ap-control-bar span.ap-playback-button{height:12px;margin:0 0 0 2px;padding:10px;width:12px}div.ap-control-bar span.ap-playback-button svg{height:12px;width:12px}div.ap-control-bar span.ap-timer{cursor:default;display:flex;flex:0 0 auto;font-size:13px;height:100%;line-height:100%;margin:0 10px;min-width:50px;text-align:center}div.ap-control-bar span.ap-timer span{font-family:Consolas,Menlo,Bitstream Vera Sans Mono,monospace;font-size:inherit;font-weight:600;margin:auto}div.ap-control-bar .ap-progressbar{display:block;flex:1 1 auto;height:100%;padding:0 10px}div.ap-control-bar .ap-progressbar .ap-bar{cursor:default;display:block;font-size:0;height:100%;position:relative}div.ap-control-bar .ap-progressbar .ap-bar .ap-gutter{display:block;height:3px;left:0;position:absolute;right:0;top:15px}div.ap-control-bar .ap-progressbar .ap-bar .ap-gutter-empty{background-color:color-mix(in oklab,var(--term-color-foreground) 20%,var(--term-color-background))}.ap-player .ap-overlay-help>div div kbd,.ap-tooltip-container span.ap-tooltip,div.ap-control-bar .ap-progressbar .ap-bar .ap-gutter-full,span.ap-marker-container span.ap-marker.ap-marker-past{background-color:var(--term-color-foreground)}div.ap-control-bar .ap-progressbar .ap-bar .ap-gutter-full{border-radius:3px;transform-origin:left center;width:100%}div.ap-control-bar .ap-fullscreen-button{height:14px;margin:0 2px 0 4px;padding:9px;width:14px}div.ap-control-bar .ap-fullscreen-button svg{height:14px;width:14px}div.ap-control-bar .ap-fullscreen-button .ap-tooltip,div.ap-control-bar .ap-kbd-button .ap-tooltip{left:auto;right:5px;transform:none}div.ap-control-bar .ap-kbd-button{height:14px;margin:0 0 0 4px;padding:9px}div.ap-control-bar .ap-kbd-button svg{height:14px;width:26px}div.ap-control-bar .ap-speaker-button{margin:0 0 0 4px;padding:6px 9px;position:relative;width:19px}div.ap-control-bar .ap-speaker-button svg{width:19px}div.ap-control-bar .ap-speaker-button .ap-tooltip{left:-50%;transform:none}div.ap-wrapper:fullscreen .ap-fullscreen-button svg.ap-icon-fullscreen-on{display:none}div.ap-wrapper:fullscreen .ap-fullscreen-button svg.ap-icon-fullscreen-off{display:inline}span.ap-progressbar span.ap-marker-container{bottom:0;display:block;margin-left:-10px;position:absolute;top:0;width:21px}span.ap-marker-container span.ap-marker{background-color:color-mix(in oklab,var(--term-color-foreground) 33%,var(--term-color-background));border-radius:50%;bottom:12px;display:block;left:7px;position:absolute;right:7px;top:13px;transition:top .1s,bottom .1s,left .1s,right .1s,background-color .1s}.ap-player .ap-overlay-help>div div,.ap-player .ap-overlay-info{background-color:var(--term-color-background)}span.ap-marker-container span.ap-marker:hover,span.ap-marker-container:hover span.ap-marker{background-color:var(--term-color-foreground);bottom:10px;left:5px;right:5px;top:11px}.ap-tooltip-container span.ap-tooltip{border-radius:4px;bottom:100%;color:var(--term-color-background);font-family:Consolas,Menlo,Bitstream Vera Sans Mono,monospace;font-size:13px;font-weight:700;left:50%;line-height:2em;padding:0 .5em;position:absolute;text-align:center;transform:translateX(-50%);visibility:hidden;white-space:nowrap;z-index:1}.ap-player .ap-overlay-help>div,.ap-player .ap-overlay-info span{color:var(--term-color-foreground);font-family:Consolas,Menlo,Bitstream Vera Sans Mono,monospace,Powerline Symbols;font-feature-settings:none;font-variant-ligatures:none}.ap-player .ap-overlay{align-items:center;background-position:50%;background-repeat:no-repeat;bottom:0;display:flex;justify-content:center;left:0;position:absolute;right:0;top:0;z-index:10}.ap-player .ap-overlay-start .ap-play-button{bottom:0;color:#fff;font-size:0;height:80px;left:0;margin:auto;max-height:66%;position:absolute;right:0;text-align:center;top:0}.ap-player .ap-overlay-start .ap-play-button div span{display:block;height:100%}.ap-player .ap-overlay-start .ap-play-button div span svg{display:inline-block;height:100%}.ap-player .ap-overlay-start .ap-play-button svg{filter:drop-shadow(0 0 5px rgba(0,0,0,.4))}.ap-player .ap-overlay-loading .ap-loader{animation:1s linear infinite a;border-color:#ffffff4d #ffffff80 #ffffffb3 #fff;border-radius:50%;border-style:solid;border-width:10px;box-sizing:border-box;display:inline-block;height:48px;position:relative;width:48px}@supports (color:color-mix(in lch,red,blue)){.ap-player .ap-overlay-loading .ap-loader{border-color:color-mix(in srgb,var(--term-color-foreground) 30%,var(--term-color-background)) color-mix(in srgb,var(--term-color-foreground) 50%,var(--term-color-background)) color-mix(in srgb,var(--term-color-foreground) 70%,var(--term-color-background)) color-mix(in srgb,var(--term-color-foreground) 100%,var(--term-color-background))}}.ap-player .ap-overlay-info span{font-size:2em}.ap-player .ap-overlay-help>div .ap-line,.ap-player .ap-overlay-info span .ap-line{letter-spacing:normal;overflow:hidden}.ap-player .ap-overlay-help>div .ap-line span,.ap-player .ap-overlay-info span .ap-line span{display:inline-block;height:100%;padding:0}.ap-player .ap-overlay-help{background-color:#000c;container-type:inline-size}.ap-player .ap-overlay-help>div{box-sizing:border-box;font-size:18px;margin-bottom:32px;max-height:85%;max-width:85%}.ap-player .ap-overlay-help>div div{border:1px solid color-mix(in oklab,var(--term-color-background) 90%,var(--term-color-foreground));border-radius:6px;font-size:calc(min(1.9cqw, 18px));padding:calc(min(4cqw,40px))}.ap-player .ap-overlay-help>div div p{font-weight:700;margin:0 0 2em}.ap-player .ap-overlay-help>div div ul{list-style:none;padding:0}.ap-player .ap-overlay-help>div div ul li{margin:0 0 .75em}.ap-player .ap-overlay-help>div div kbd{border:none;border-radius:.2em;color:var(--term-color-background);font-family:inherit;font-size:.85em;margin:0;padding:.2em .5em}.ap-player .ap-overlay-error span{font-size:8em}.ap-player .slide-enter-active{transition:opacity .2s}.ap-player .slide-enter-active.ap-was-playing{transition:top .2s ease-out,opacity .2s}.ap-player .slide-exit-active{transition:top .2s ease-in,opacity .2s}.ap-player .slide-enter,.ap-player .slide-exit-to{opacity:0;top:-50%}.ap-player .slide-enter-to,.ap-player .slide-exit{top:0}.ap-player .slide-enter,.ap-player .slide-enter-to,.ap-player .slide-exit,.ap-player .slide-exit-to{bottom:auto;height:100%}@keyframes a{0%{transform:rotate(0)}to{transform:rotate(1turn)}}.ap-terminal .fg-16{--fg:#000}.ap-terminal .bg-16{--bg:#000}.ap-terminal .fg-17{--fg:#00005f}.ap-terminal .bg-17{--bg:#00005f}.ap-terminal .fg-18{--fg:#000087}.ap-terminal .bg-18{--bg:#000087}.ap-terminal .fg-19{--fg:#0000af}.ap-terminal .bg-19{--bg:#0000af}.ap-terminal .fg-20{--fg:#0000d7}.ap-terminal .bg-20{--bg:#0000d7}.ap-terminal .fg-21{--fg:#00f}.ap-terminal .bg-21{--bg:#00f}.ap-terminal .fg-22{--fg:#005f00}.ap-terminal .bg-22{--bg:#005f00}.ap-terminal .fg-23{--fg:#005f5f}.ap-terminal .bg-23{--bg:#005f5f}.ap-terminal .fg-24{--fg:#005f87}.ap-terminal .bg-24{--bg:#005f87}.ap-terminal .fg-25{--fg:#005faf}.ap-terminal .bg-25{--bg:#005faf}.ap-terminal .fg-26{--fg:#005fd7}.ap-terminal .bg-26{--bg:#005fd7}.ap-terminal .fg-27{--fg:#005fff}.ap-terminal .bg-27{--bg:#005fff}.ap-terminal .fg-28{--fg:#008700}.ap-terminal .bg-28{--bg:#008700}.ap-terminal .fg-29{--fg:#00875f}.ap-terminal .bg-29{--bg:#00875f}.ap-terminal .fg-30{--fg:#008787}.ap-terminal .bg-30{--bg:#008787}.ap-terminal .fg-31{--fg:#0087af}.ap-terminal .bg-31{--bg:#0087af}.ap-terminal .fg-32{--fg:#0087d7}.ap-terminal .bg-32{--bg:#0087d7}.ap-terminal .fg-33{--fg:#0087ff}.ap-terminal .bg-33{--bg:#0087ff}.ap-terminal .fg-34{--fg:#00af00}.ap-terminal .bg-34{--bg:#00af00}.ap-terminal .fg-35{--fg:#00af5f}.ap-terminal .bg-35{--bg:#00af5f}.ap-terminal .fg-36{--fg:#00af87}.ap-terminal .bg-36{--bg:#00af87}.ap-terminal .fg-37{--fg:#00afaf}.ap-terminal .bg-37{--bg:#00afaf}.ap-terminal .fg-38{--fg:#00afd7}.ap-terminal .bg-38{--bg:#00afd7}.ap-terminal .fg-39{--fg:#00afff}.ap-terminal .bg-39{--bg:#00afff}.ap-terminal .fg-40{--fg:#00d700}.ap-terminal .bg-40{--bg:#00d700}.ap-terminal .fg-41{--fg:#00d75f}.ap-terminal .bg-41{--bg:#00d75f}.ap-terminal .fg-42{--fg:#00d787}.ap-terminal .bg-42{--bg:#00d787}.ap-terminal .fg-43{--fg:#00d7af}.ap-terminal .bg-43{--bg:#00d7af}.ap-terminal .fg-44{--fg:#00d7d7}.ap-terminal .bg-44{--bg:#00d7d7}.ap-terminal .fg-45{--fg:#00d7ff}.ap-terminal .bg-45{--bg:#00d7ff}.ap-terminal .fg-46{--fg:#0f0}.ap-terminal .bg-46{--bg:#0f0}.ap-terminal .fg-47{--fg:#00ff5f}.ap-terminal .bg-47{--bg:#00ff5f}.ap-terminal .fg-48{--fg:#00ff87}.ap-terminal .bg-48{--bg:#00ff87}.ap-terminal .fg-49{--fg:#00ffaf}.ap-terminal .bg-49{--bg:#00ffaf}.ap-terminal .fg-50{--fg:#00ffd7}.ap-terminal .bg-50{--bg:#00ffd7}.ap-terminal .fg-51{--fg:#0ff}.ap-terminal .bg-51{--bg:#0ff}.ap-terminal .fg-52{--fg:#5f0000}.ap-terminal .bg-52{--bg:#5f0000}.ap-terminal .fg-53{--fg:#5f005f}.ap-terminal .bg-53{--bg:#5f005f}.ap-terminal .fg-54{--fg:#5f0087}.ap-terminal .bg-54{--bg:#5f0087}.ap-terminal .fg-55{--fg:#5f00af}.ap-terminal .bg-55{--bg:#5f00af}.ap-terminal .fg-56{--fg:#5f00d7}.ap-terminal .bg-56{--bg:#5f00d7}.ap-terminal .fg-57{--fg:#5f00ff}.ap-terminal .bg-57{--bg:#5f00ff}.ap-terminal .fg-58{--fg:#5f5f00}.ap-terminal .bg-58{--bg:#5f5f00}.ap-terminal .fg-59{--fg:#5f5f5f}.ap-terminal .bg-59{--bg:#5f5f5f}.ap-terminal .fg-60{--fg:#5f5f87}.ap-terminal .bg-60{--bg:#5f5f87}.ap-terminal .fg-61{--fg:#5f5faf}.ap-terminal .bg-61{--bg:#5f5faf}.ap-terminal .fg-62{--fg:#5f5fd7}.ap-terminal .bg-62{--bg:#5f5fd7}.ap-terminal .fg-63{--fg:#5f5fff}.ap-terminal .bg-63{--bg:#5f5fff}.ap-terminal .fg-64{--fg:#5f8700}.ap-terminal .bg-64{--bg:#5f8700}.ap-terminal .fg-65{--fg:#5f875f}.ap-terminal .bg-65{--bg:#5f875f}.ap-terminal .fg-66{--fg:#5f8787}.ap-terminal .bg-66{--bg:#5f8787}.ap-terminal .fg-67{--fg:#5f87af}.ap-terminal .bg-67{--bg:#5f87af}.ap-terminal .fg-68{--fg:#5f87d7}.ap-terminal .bg-68{--bg:#5f87d7}.ap-terminal .fg-69{--fg:#5f87ff}.ap-terminal .bg-69{--bg:#5f87ff}.ap-terminal .fg-70{--fg:#5faf00}.ap-terminal .bg-70{--bg:#5faf00}.ap-terminal .fg-71{--fg:#5faf5f}.ap-terminal .bg-71{--bg:#5faf5f}.ap-terminal .fg-72{--fg:#5faf87}.ap-terminal .bg-72{--bg:#5faf87}.ap-terminal .fg-73{--fg:#5fafaf}.ap-terminal .bg-73{--bg:#5fafaf}.ap-terminal .fg-74{--fg:#5fafd7}.ap-terminal .bg-74{--bg:#5fafd7}.ap-terminal .fg-75{--fg:#5fafff}.ap-terminal .bg-75{--bg:#5fafff}.ap-terminal .fg-76{--fg:#5fd700}.ap-terminal .bg-76{--bg:#5fd700}.ap-terminal .fg-77{--fg:#5fd75f}.ap-terminal .bg-77{--bg:#5fd75f}.ap-terminal .fg-78{--fg:#5fd787}.ap-terminal .bg-78{--bg:#5fd787}.ap-terminal .fg-79{--fg:#5fd7af}.ap-terminal .bg-79{--bg:#5fd7af}.ap-terminal .fg-80{--fg:#5fd7d7}.ap-terminal .bg-80{--bg:#5fd7d7}.ap-terminal .fg-81{--fg:#5fd7ff}.ap-terminal .bg-81{--bg:#5fd7ff}.ap-terminal .fg-82{--fg:#5fff00}.ap-terminal .bg-82{--bg:#5fff00}.ap-terminal .fg-83{--fg:#5fff5f}.ap-terminal .bg-83{--bg:#5fff5f}.ap-terminal .fg-84{--fg:#5fff87}.ap-terminal .bg-84{--bg:#5fff87}.ap-terminal .fg-85{--fg:#5fffaf}.ap-terminal .bg-85{--bg:#5fffaf}.ap-terminal .fg-86{--fg:#5fffd7}.ap-terminal .bg-86{--bg:#5fffd7}.ap-terminal .fg-87{--fg:#5fffff}.ap-terminal .bg-87{--bg:#5fffff}.ap-terminal .fg-88{--fg:#870000}.ap-terminal .bg-88{--bg:#870000}.ap-terminal .fg-89{--fg:#87005f}.ap-terminal .bg-89{--bg:#87005f}.ap-terminal .fg-90{--fg:#870087}.ap-terminal .bg-90{--bg:#870087}.ap-terminal .fg-91{--fg:#8700af}.ap-terminal .bg-91{--bg:#8700af}.ap-terminal .fg-92{--fg:#8700d7}.ap-terminal .bg-92{--bg:#8700d7}.ap-terminal .fg-93{--fg:#8700ff}.ap-terminal .bg-93{--bg:#8700ff}.ap-terminal .fg-94{--fg:#875f00}.ap-terminal .bg-94{--bg:#875f00}.ap-terminal .fg-95{--fg:#875f5f}.ap-terminal .bg-95{--bg:#875f5f}.ap-terminal .fg-96{--fg:#875f87}.ap-terminal .bg-96{--bg:#875f87}.ap-terminal .fg-97{--fg:#875faf}.ap-terminal .bg-97{--bg:#875faf}.ap-terminal .fg-98{--fg:#875fd7}.ap-terminal .bg-98{--bg:#875fd7}.ap-terminal .fg-99{--fg:#875fff}.ap-terminal .bg-99{--bg:#875fff}.ap-terminal .fg-100{--fg:#878700}.ap-terminal .bg-100{--bg:#878700}.ap-terminal .fg-101{--fg:#87875f}.ap-terminal .bg-101{--bg:#87875f}.ap-terminal .fg-102{--fg:#878787}.ap-terminal .bg-102{--bg:#878787}.ap-terminal .fg-103{--fg:#8787af}.ap-terminal .bg-103{--bg:#8787af}.ap-terminal .fg-104{--fg:#8787d7}.ap-terminal .bg-104{--bg:#8787d7}.ap-terminal .fg-105{--fg:#8787ff}.ap-terminal .bg-105{--bg:#8787ff}.ap-terminal .fg-106{--fg:#87af00}.ap-terminal .bg-106{--bg:#87af00}.ap-terminal .fg-107{--fg:#87af5f}.ap-terminal .bg-107{--bg:#87af5f}.ap-terminal .fg-108{--fg:#87af87}.ap-terminal .bg-108{--bg:#87af87}.ap-terminal .fg-109{--fg:#87afaf}.ap-terminal .bg-109{--bg:#87afaf}.ap-terminal .fg-110{--fg:#87afd7}.ap-terminal .bg-110{--bg:#87afd7}.ap-terminal .fg-111{--fg:#87afff}.ap-terminal .bg-111{--bg:#87afff}.ap-terminal .fg-112{--fg:#87d700}.ap-terminal .bg-112{--bg:#87d700}.ap-terminal .fg-113{--fg:#87d75f}.ap-terminal .bg-113{--bg:#87d75f}.ap-terminal .fg-114{--fg:#87d787}.ap-terminal .bg-114{--bg:#87d787}.ap-terminal .fg-115{--fg:#87d7af}.ap-terminal .bg-115{--bg:#87d7af}.ap-terminal .fg-116{--fg:#87d7d7}.ap-terminal .bg-116{--bg:#87d7d7}.ap-terminal .fg-117{--fg:#87d7ff}.ap-terminal .bg-117{--bg:#87d7ff}.ap-terminal .fg-118{--fg:#87ff00}.ap-terminal .bg-118{--bg:#87ff00}.ap-terminal .fg-119{--fg:#87ff5f}.ap-terminal .bg-119{--bg:#87ff5f}.ap-terminal .fg-120{--fg:#87ff87}.ap-terminal .bg-120{--bg:#87ff87}.ap-terminal .fg-121{--fg:#87ffaf}.ap-terminal .bg-121{--bg:#87ffaf}.ap-terminal .fg-122{--fg:#87ffd7}.ap-terminal .bg-122{--bg:#87ffd7}.ap-terminal .fg-123{--fg:#87ffff}.ap-terminal .bg-123{--bg:#87ffff}.ap-terminal .fg-124{--fg:#af0000}.ap-terminal .bg-124{--bg:#af0000}.ap-terminal .fg-125{--fg:#af005f}.ap-terminal .bg-125{--bg:#af005f}.ap-terminal .fg-126{--fg:#af0087}.ap-terminal .bg-126{--bg:#af0087}.ap-terminal .fg-127{--fg:#af00af}.ap-terminal .bg-127{--bg:#af00af}.ap-terminal .fg-128{--fg:#af00d7}.ap-terminal .bg-128{--bg:#af00d7}.ap-terminal .fg-129{--fg:#af00ff}.ap-terminal .bg-129{--bg:#af00ff}.ap-terminal .fg-130{--fg:#af5f00}.ap-terminal .bg-130{--bg:#af5f00}.ap-terminal .fg-131{--fg:#af5f5f}.ap-terminal .bg-131{--bg:#af5f5f}.ap-terminal .fg-132{--fg:#af5f87}.ap-terminal .bg-132{--bg:#af5f87}.ap-terminal .fg-133{--fg:#af5faf}.ap-terminal .bg-133{--bg:#af5faf}.ap-terminal .fg-134{--fg:#af5fd7}.ap-terminal .bg-134{--bg:#af5fd7}.ap-terminal .fg-135{--fg:#af5fff}.ap-terminal .bg-135{--bg:#af5fff}.ap-terminal .fg-136{--fg:#af8700}.ap-terminal .bg-136{--bg:#af8700}.ap-terminal .fg-137{--fg:#af875f}.ap-terminal .bg-137{--bg:#af875f}.ap-terminal .fg-138{--fg:#af8787}.ap-terminal .bg-138{--bg:#af8787}.ap-terminal .fg-139{--fg:#af87af}.ap-terminal .bg-139{--bg:#af87af}.ap-terminal .fg-140{--fg:#af87d7}.ap-terminal .bg-140{--bg:#af87d7}.ap-terminal .fg-141{--fg:#af87ff}.ap-terminal .bg-141{--bg:#af87ff}.ap-terminal .fg-142{--fg:#afaf00}.ap-terminal .bg-142{--bg:#afaf00}.ap-terminal .fg-143{--fg:#afaf5f}.ap-terminal .bg-143{--bg:#afaf5f}.ap-terminal .fg-144{--fg:#afaf87}.ap-terminal .bg-144{--bg:#afaf87}.ap-terminal .fg-145{--fg:#afafaf}.ap-terminal .bg-145{--bg:#afafaf}.ap-terminal .fg-146{--fg:#afafd7}.ap-terminal .bg-146{--bg:#afafd7}.ap-terminal .fg-147{--fg:#afafff}.ap-terminal .bg-147{--bg:#afafff}.ap-terminal .fg-148{--fg:#afd700}.ap-terminal .bg-148{--bg:#afd700}.ap-terminal .fg-149{--fg:#afd75f}.ap-terminal .bg-149{--bg:#afd75f}.ap-terminal .fg-150{--fg:#afd787}.ap-terminal .bg-150{--bg:#afd787}.ap-terminal .fg-151{--fg:#afd7af}.ap-terminal .bg-151{--bg:#afd7af}.ap-terminal .fg-152{--fg:#afd7d7}.ap-terminal .bg-152{--bg:#afd7d7}.ap-terminal .fg-153{--fg:#afd7ff}.ap-terminal .bg-153{--bg:#afd7ff}.ap-terminal .fg-154{--fg:#afff00}.ap-terminal .bg-154{--bg:#afff00}.ap-terminal .fg-155{--fg:#afff5f}.ap-terminal .bg-155{--bg:#afff5f}.ap-terminal .fg-156{--fg:#afff87}.ap-terminal .bg-156{--bg:#afff87}.ap-terminal .fg-157{--fg:#afffaf}.ap-terminal .bg-157{--bg:#afffaf}.ap-terminal .fg-158{--fg:#afffd7}.ap-terminal .bg-158{--bg:#afffd7}.ap-terminal .fg-159{--fg:#afffff}.ap-terminal .bg-159{--bg:#afffff}.ap-terminal .fg-160{--fg:#d70000}.ap-terminal .bg-160{--bg:#d70000}.ap-terminal .fg-161{--fg:#d7005f}.ap-terminal .bg-161{--bg:#d7005f}.ap-terminal .fg-162{--fg:#d70087}.ap-terminal .bg-162{--bg:#d70087}.ap-terminal .fg-163{--fg:#d700af}.ap-terminal .bg-163{--bg:#d700af}.ap-terminal .fg-164{--fg:#d700d7}.ap-terminal .bg-164{--bg:#d700d7}.ap-terminal .fg-165{--fg:#d700ff}.ap-terminal .bg-165{--bg:#d700ff}.ap-terminal .fg-166{--fg:#d75f00}.ap-terminal .bg-166{--bg:#d75f00}.ap-terminal .fg-167{--fg:#d75f5f}.ap-terminal .bg-167{--bg:#d75f5f}.ap-terminal .fg-168{--fg:#d75f87}.ap-terminal .bg-168{--bg:#d75f87}.ap-terminal .fg-169{--fg:#d75faf}.ap-terminal .bg-169{--bg:#d75faf}.ap-terminal .fg-170{--fg:#d75fd7}.ap-terminal .bg-170{--bg:#d75fd7}.ap-terminal .fg-171{--fg:#d75fff}.ap-terminal .bg-171{--bg:#d75fff}.ap-terminal .fg-172{--fg:#d78700}.ap-terminal .bg-172{--bg:#d78700}.ap-terminal .fg-173{--fg:#d7875f}.ap-terminal .bg-173{--bg:#d7875f}.ap-terminal .fg-174{--fg:#d78787}.ap-terminal .bg-174{--bg:#d78787}.ap-terminal .fg-175{--fg:#d787af}.ap-terminal .bg-175{--bg:#d787af}.ap-terminal .fg-176{--fg:#d787d7}.ap-terminal .bg-176{--bg:#d787d7}.ap-terminal .fg-177{--fg:#d787ff}.ap-terminal .bg-177{--bg:#d787ff}.ap-terminal .fg-178{--fg:#d7af00}.ap-terminal .bg-178{--bg:#d7af00}.ap-terminal .fg-179{--fg:#d7af5f}.ap-terminal .bg-179{--bg:#d7af5f}.ap-terminal .fg-180{--fg:#d7af87}.ap-terminal .bg-180{--bg:#d7af87}.ap-terminal .fg-181{--fg:#d7afaf}.ap-terminal .bg-181{--bg:#d7afaf}.ap-terminal .fg-182{--fg:#d7afd7}.ap-terminal .bg-182{--bg:#d7afd7}.ap-terminal .fg-183{--fg:#d7afff}.ap-terminal .bg-183{--bg:#d7afff}.ap-terminal .fg-184{--fg:#d7d700}.ap-terminal .bg-184{--bg:#d7d700}.ap-terminal .fg-185{--fg:#d7d75f}.ap-terminal .bg-185{--bg:#d7d75f}.ap-terminal .fg-186{--fg:#d7d787}.ap-terminal .bg-186{--bg:#d7d787}.ap-terminal .fg-187{--fg:#d7d7af}.ap-terminal .bg-187{--bg:#d7d7af}.ap-terminal .fg-188{--fg:#d7d7d7}.ap-terminal .bg-188{--bg:#d7d7d7}.ap-terminal .fg-189{--fg:#d7d7ff}.ap-terminal .bg-189{--bg:#d7d7ff}.ap-terminal .fg-190{--fg:#d7ff00}.ap-terminal .bg-190{--bg:#d7ff00}.ap-terminal .fg-191{--fg:#d7ff5f}.ap-terminal .bg-191{--bg:#d7ff5f}.ap-terminal .fg-192{--fg:#d7ff87}.ap-terminal .bg-192{--bg:#d7ff87}.ap-terminal .fg-193{--fg:#d7ffaf}.ap-terminal .bg-193{--bg:#d7ffaf}.ap-terminal .fg-194{--fg:#d7ffd7}.ap-terminal .bg-194{--bg:#d7ffd7}.ap-terminal .fg-195{--fg:#d7ffff}.ap-terminal .bg-195{--bg:#d7ffff}.ap-terminal .fg-196{--fg:red}.ap-terminal .bg-196{--bg:red}.ap-terminal .fg-197{--fg:#ff005f}.ap-terminal .bg-197{--bg:#ff005f}.ap-terminal .fg-198{--fg:#ff0087}.ap-terminal .bg-198{--bg:#ff0087}.ap-terminal .fg-199{--fg:#ff00af}.ap-terminal .bg-199{--bg:#ff00af}.ap-terminal .fg-200{--fg:#ff00d7}.ap-terminal .bg-200{--bg:#ff00d7}.ap-terminal .fg-201{--fg:#f0f}.ap-terminal .bg-201{--bg:#f0f}.ap-terminal .fg-202{--fg:#ff5f00}.ap-terminal .bg-202{--bg:#ff5f00}.ap-terminal .fg-203{--fg:#ff5f5f}.ap-terminal .bg-203{--bg:#ff5f5f}.ap-terminal .fg-204{--fg:#ff5f87}.ap-terminal .bg-204{--bg:#ff5f87}.ap-terminal .fg-205{--fg:#ff5faf}.ap-terminal .bg-205{--bg:#ff5faf}.ap-terminal .fg-206{--fg:#ff5fd7}.ap-terminal .bg-206{--bg:#ff5fd7}.ap-terminal .fg-207{--fg:#ff5fff}.ap-terminal .bg-207{--bg:#ff5fff}.ap-terminal .fg-208{--fg:#ff8700}.ap-terminal .bg-208{--bg:#ff8700}.ap-terminal .fg-209{--fg:#ff875f}.ap-terminal .bg-209{--bg:#ff875f}.ap-terminal .fg-210{--fg:#ff8787}.ap-terminal .bg-210{--bg:#ff8787}.ap-terminal .fg-211{--fg:#ff87af}.ap-terminal .bg-211{--bg:#ff87af}.ap-terminal .fg-212{--fg:#ff87d7}.ap-terminal .bg-212{--bg:#ff87d7}.ap-terminal .fg-213{--fg:#ff87ff}.ap-terminal .bg-213{--bg:#ff87ff}.ap-terminal .fg-214{--fg:#ffaf00}.ap-terminal .bg-214{--bg:#ffaf00}.ap-terminal .fg-215{--fg:#ffaf5f}.ap-terminal .bg-215{--bg:#ffaf5f}.ap-terminal .fg-216{--fg:#ffaf87}.ap-terminal .bg-216{--bg:#ffaf87}.ap-terminal .fg-217{--fg:#ffafaf}.ap-terminal .bg-217{--bg:#ffafaf}.ap-terminal .fg-218{--fg:#ffafd7}.ap-terminal .bg-218{--bg:#ffafd7}.ap-terminal .fg-219{--fg:#ffafff}.ap-terminal .bg-219{--bg:#ffafff}.ap-terminal .fg-220{--fg:gold}.ap-terminal .bg-220{--bg:gold}.ap-terminal .fg-221{--fg:#ffd75f}.ap-terminal .bg-221{--bg:#ffd75f}.ap-terminal .fg-222{--fg:#ffd787}.ap-terminal .bg-222{--bg:#ffd787}.ap-terminal .fg-223{--fg:#ffd7af}.ap-terminal .bg-223{--bg:#ffd7af}.ap-terminal .fg-224{--fg:#ffd7d7}.ap-terminal .bg-224{--bg:#ffd7d7}.ap-terminal .fg-225{--fg:#ffd7ff}.ap-terminal .bg-225{--bg:#ffd7ff}.ap-terminal .fg-226{--fg:#ff0}.ap-terminal .bg-226{--bg:#ff0}.ap-terminal .fg-227{--fg:#ffff5f}.ap-terminal .bg-227{--bg:#ffff5f}.ap-terminal .fg-228{--fg:#ffff87}.ap-terminal .bg-228{--bg:#ffff87}.ap-terminal .fg-229{--fg:#ffffaf}.ap-terminal .bg-229{--bg:#ffffaf}.ap-terminal .fg-230{--fg:#ffffd7}.ap-terminal .bg-230{--bg:#ffffd7}.ap-terminal .fg-231{--fg:#fff}.ap-terminal .bg-231{--bg:#fff}.ap-terminal .fg-232{--fg:#080808}.ap-terminal .bg-232{--bg:#080808}.ap-terminal .fg-233{--fg:#121212}.ap-terminal .bg-233{--bg:#121212}.ap-terminal .fg-234{--fg:#1c1c1c}.ap-terminal .bg-234{--bg:#1c1c1c}.ap-terminal .fg-235{--fg:#262626}.ap-terminal .bg-235{--bg:#262626}.ap-terminal .fg-236{--fg:#303030}.ap-terminal .bg-236{--bg:#303030}.ap-terminal .fg-237{--fg:#3a3a3a}.ap-terminal .bg-237{--bg:#3a3a3a}.ap-terminal .fg-238{--fg:#444}.ap-terminal .bg-238{--bg:#444}.ap-terminal .fg-239{--fg:#4e4e4e}.ap-terminal .bg-239{--bg:#4e4e4e}.ap-terminal .fg-240{--fg:#585858}.ap-terminal .bg-240{--bg:#585858}.ap-terminal .fg-241{--fg:#626262}.ap-terminal .bg-241{--bg:#626262}.ap-terminal .fg-242{--fg:#6c6c6c}.ap-terminal .bg-242{--bg:#6c6c6c}.ap-terminal .fg-243{--fg:#767676}.ap-terminal .bg-243{--bg:#767676}.ap-terminal .fg-244{--fg:grey}.ap-terminal .bg-244{--bg:grey}.ap-terminal .fg-245{--fg:#8a8a8a}.ap-terminal .bg-245{--bg:#8a8a8a}.ap-terminal .fg-246{--fg:#949494}.ap-terminal .bg-246{--bg:#949494}.ap-terminal .fg-247{--fg:#9e9e9e}.ap-terminal .bg-247{--bg:#9e9e9e}.ap-terminal .fg-248{--fg:#a8a8a8}.ap-terminal .bg-248{--bg:#a8a8a8}.ap-terminal .fg-249{--fg:#b2b2b2}.ap-terminal .bg-249{--bg:#b2b2b2}.ap-terminal .fg-250{--fg:#bcbcbc}.ap-terminal .bg-250{--bg:#bcbcbc}.ap-terminal .fg-251{--fg:#c6c6c6}.ap-terminal .bg-251{--bg:#c6c6c6}.ap-terminal .fg-252{--fg:#d0d0d0}.ap-terminal .bg-252{--bg:#d0d0d0}.ap-terminal .fg-253{--fg:#dadada}.ap-terminal .bg-253{--bg:#dadada}.ap-terminal .fg-254{--fg:#e4e4e4}.ap-terminal .bg-254{--bg:#e4e4e4}.ap-terminal .fg-255{--fg:#eee}.ap-terminal .bg-255{--bg:#eee}.asciinema-player-theme-asciinema{--term-color-foreground:#ccc;--term-color-background:#121314;--term-color-0:#000;--term-color-1:#dd3c69;--term-color-2:#4ebf22;--term-color-3:#ddaf3c;--term-color-4:#26b0d7;--term-color-5:#b954e1;--term-color-6:#54e1b9;--term-color-7:#d9d9d9;--term-color-8:#4d4d4d;--term-color-9:#dd3c69;--term-color-10:#4ebf22;--term-color-11:#ddaf3c;--term-color-12:#26b0d7;--term-color-13:#b954e1;--term-color-14:#54e1b9;--term-color-15:#fff}.asciinema-player-theme-dracula{--term-color-foreground:#f8f8f2;--term-color-background:#282a36;--term-color-0:#21222c;--term-color-1:#f55;--term-color-2:#50fa7b;--term-color-3:#f1fa8c;--term-color-4:#bd93f9;--term-color-5:#ff79c6;--term-color-6:#8be9fd;--term-color-7:#f8f8f2;--term-color-8:#6272a4;--term-color-9:#ff6e6e;--term-color-10:#69ff94;--term-color-11:#ffffa5;--term-color-12:#d6acff;--term-color-13:#ff92df;--term-color-14:#a4ffff;--term-color-15:#fff}.asciinema-player-theme-monokai{--term-color-foreground:#f8f8f2;--term-color-background:#272822;--term-color-0:#272822;--term-color-1:#f92672;--term-color-2:#a6e22e;--term-color-3:#f4bf75;--term-color-4:#66d9ef;--term-color-5:#ae81ff;--term-color-6:#a1efe4;--term-color-7:#f8f8f2;--term-color-8:#75715e;--term-color-15:#f9f8f5}.asciinema-player-theme-nord{--term-color-foreground:#eceff4;--term-color-background:#2e3440;--term-color-0:#3b4252;--term-color-1:#bf616a;--term-color-2:#a3be8c;--term-color-3:#ebcb8b;--term-color-4:#81a1c1;--term-color-5:#b48ead;--term-color-6:#88c0d0;--term-color-7:#eceff4}.asciinema-player-theme-seti{--term-color-foreground:#cacecd;--term-color-background:#111213;--term-color-0:#323232;--term-color-1:#c22832;--term-color-2:#8ec43d;--term-color-3:#e0c64f;--term-color-4:#43a5d5;--term-color-5:#8b57b5;--term-color-6:#8ec43d;--term-color-7:#eee;--term-color-15:#fff}.asciinema-player-theme-solarized-dark,.asciinema-player-theme-solarized-light{--term-color-0:#073642;--term-color-1:#dc322f;--term-color-2:#859900;--term-color-3:#b58900;--term-color-4:#268bd2;--term-color-5:#d33682;--term-color-6:#2aa198;--term-color-7:#eee8d5;--term-color-8:#002b36;--term-color-9:#cb4b16;--term-color-10:#586e75;--term-color-12:#839496;--term-color-13:#6c71c4;--term-color-14:#93a1a1;--term-color-15:#fdf6e3}.asciinema-player-theme-solarized-dark{--term-color-foreground:#839496;--term-color-background:#002b36;--term-color-11:#657b83}.asciinema-player-theme-solarized-light{--term-color-foreground:#657b83;--term-color-background:#fdf6e3;--term-color-11:#657c83}.asciinema-player-theme-solarized-light .ap-overlay-start .ap-play-button svg .ap-play-btn-fill{fill:var(--term-color-1)}.asciinema-player-theme-solarized-light .ap-overlay-start .ap-play-button svg .ap-play-btn-stroke{stroke:var(--term-color-1)}.asciinema-player-theme-tango{--term-color-foreground:#ccc;--term-color-background:#121314;--term-color-0:#000;--term-color-1:#c00;--term-color-2:#4e9a06;--term-color-3:#c4a000;--term-color-4:#3465a4;--term-color-5:#75507b;--term-color-6:#06989a;--term-color-7:#d3d7cf;--term-color-8:#555753;--term-color-9:#ef2929;--term-color-10:#8ae234;--term-color-11:#fce94f;--term-color-12:#729fcf;--term-color-13:#ad7fa8;--term-color-14:#34e2e2;--term-color-15:#eeeeec}.asciinema-player-theme-gruvbox-dark{--term-color-foreground:#fbf1c7;--term-color-background:#282828;--term-color-0:#282828;--term-color-1:#cc241d;--term-color-2:#98971a;--term-color-3:#d79921;--term-color-4:#458588;--term-color-5:#b16286;--term-color-6:#689d6a;--term-color-7:#a89984;--term-color-8:#7c6f65;--term-color-9:#fb4934;--term-color-10:#b8bb26;--term-color-11:#fabd2f;--term-color-12:#83a598;--term-color-13:#d3869b;--term-color-14:#8ec07c;--term-color-15:#fbf1c7}.breadcrumbHomeIcon_YNFT{height:1.1rem;position:relative;top:1px;vertical-align:top;width:1.1rem}.breadcrumbsContainer_Z_bl{--ifm-breadcrumb-size-multiplier:0.8;margin-bottom:.8rem}.title_kItE{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-leading)*1.25)}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_TmdG{background-color:var(--docusaurus-collapse-button-bg)}.lastUpdated_JAkA{text-align:right}.tocMobile_ITEo{display:none}:root{--docusaurus-announcement-bar-height:30px}.announcementBarClose_gvF7,.announcementBarPlaceholder_vyr4{flex-basis:50px}.collapseSidebarButton_PEFL{border:1px solid var(--ifm-toc-border-color);border-radius:0;bottom:0;display:block!important;height:40px;position:sticky}.collapseSidebarButtonIcon_kv0_{margin-top:4px;transform:rotate(180deg)}.expandButtonIcon_i1dp,[dir=rtl] .collapseSidebarButtonIcon_kv0_{transform:rotate(0)}.collapseSidebarButton_PEFL:focus,.collapseSidebarButton_PEFL:hover,.expandButton_TmdG:focus,.expandButton_TmdG:hover{background-color:var(--docusaurus-collapse-button-bg-hover)}.menuHtmlItem_M9Kj{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu_SIkG{flex-grow:1;padding:.5rem}@supports (scrollbar-gutter:stable){.menu_SIkG{padding:.5rem 0 .5rem .5rem;scrollbar-gutter:stable}}.menuWithAnnouncementBar_GW3s{margin-bottom:var(--docusaurus-announcement-bar-height)}.sidebar_njMd{display:flex;flex-direction:column;height:100%;padding-top:var(--ifm-navbar-height);width:var(--doc-sidebar-width)}.sidebarWithHideableNavbar_wUlq{padding-top:0}.sidebarHidden_VK0M{opacity:0;visibility:hidden}.sidebarLogo_isFc{align-items:center;color:inherit!important;display:flex!important;margin:0 var(--ifm-navbar-padding-horizontal);max-height:var(--ifm-navbar-height);min-height:var(--ifm-navbar-height);-webkit-text-decoration:none!important;text-decoration:none!important}.sidebarLogo_isFc img{height:2rem;margin-right:.5rem}.expandButton_TmdG{align-items:center;display:flex;height:100%;justify-content:center;position:absolute;right:0;top:0;transition:background-color var(--ifm-transition-fast) ease;width:100%}[dir=rtl] .expandButtonIcon_i1dp{transform:rotate(180deg)}.docSidebarContainer_YfHR{border-right:1px solid var(--ifm-toc-border-color);clip-path:inset(0);display:block;margin-top:calc(var(--ifm-navbar-height)*-1);transition:width var(--ifm-transition-fast) ease;width:var(--doc-sidebar-width);will-change:width}.docSidebarContainerHidden_DPk8{cursor:pointer;width:var(--doc-sidebar-hidden-width)}.sidebarViewport_aRkj{height:100%;max-height:100vh;position:sticky;top:0}.docMainContainer_TBSr{flex-grow:1;max-width:calc(100% - var(--doc-sidebar-width))}.docMainContainerEnhanced_lQrH{max-width:calc(100% - var(--doc-sidebar-hidden-width))}.docItemWrapperEnhanced_JWYK{max-width:calc(var(--ifm-container-width) + var(--doc-sidebar-width))!important}.navbarSearchContainer_Bca1{padding:0 var(--ifm-navbar-item-padding-horizontal)}.docItemCol_VOVn,.generatedIndexPage_vN6x{max-width:75%!important}}@media (min-width:1440px){.container{max-width:var(--ifm-container-width-xl)}}@media (max-width:996px){.col{--ifm-col-width:100%;flex-basis:var(--ifm-col-width);margin-left:0}.footer{--ifm-footer-padding-horizontal:0}.colorModeToggle_DEke,.footer__link-separator,.navbar__item,.tableOfContents_bqdL{display:none}.footer__col{margin-bottom:calc(var(--ifm-spacing-vertical)*3)}.footer__link-item{display:block;width:max-content}.hero{padding-left:0;padding-right:0}.navbar>.container,.navbar>.container-fluid{padding:0}.navbar__toggle{display:inherit}.navbar__search-input{width:9rem}.pills--block,.tabs--block{flex-direction:column}.docItemContainer_F8PC{padding:0 .3rem}.navbarSearchContainer_Bca1{position:absolute;right:var(--ifm-navbar-padding-horizontal)}}@media (max-width:576px){.markdown h1:first-child{--ifm-h1-font-size:2rem}.markdown>h2{--ifm-h2-font-size:1.5rem}.markdown>h3{--ifm-h3-font-size:1.25rem}}@media (hover:hover){.backToTopButton_sjWU:hover{background-color:var(--ifm-color-emphasis-300)}.aa-TouchOnly{display:none}}@media (hover:none) and (pointer:coarse){:root{--aa-spacing-factor:1.2;--aa-action-icon-size:22px}.aa-LoadingIndicator,.aa-SubmitButton{padding-left:3px;padding-left:calc(var(--aa-spacing-half)/ 2 - 1px);width:39px;width:calc(var(--aa-icon-size) + var(--aa-spacing)*1.25 - 1px)}.aa-ClearButton{padding:0 10.16672px;padding:0 calc(var(--aa-spacing)*.66667 - .5px)}.aa-ItemActionButton:focus svg,.aa-ItemActionButton:hover svg{color:inherit}.aa-DesktopOnly{display:none}}@media (pointer:fine){.thin-scrollbar{scrollbar-width:thin}.thin-scrollbar::-webkit-scrollbar{height:var(--ifm-scrollbar-size);width:var(--ifm-scrollbar-size)}.thin-scrollbar::-webkit-scrollbar-track{background:var(--ifm-scrollbar-track-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb{background:var(--ifm-scrollbar-thumb-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--ifm-scrollbar-thumb-hover-background-color)}}@media (prefers-reduced-motion:reduce){:root{--ifm-transition-fast:0ms;--ifm-transition-slow:0ms}}@media screen and (prefers-reduced-motion){.aa-Panel{transition:none}}@media print{.announcementBar_mb4j,.footer,.menu,.navbar,.noPrint_WFHX,.pagination-nav,.table-of-contents,.tocMobile_ITEo{display:none}.tabs{page-break-inside:avoid}.codeBlockLines_e6Vv{white-space:pre-wrap}} \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/images/benchmark_fio_azure_bw-9294313529fb8cc2c0230b3b581faddb.png b/pr-preview/pr-4027/assets/images/benchmark_fio_azure_bw-9294313529fb8cc2c0230b3b581faddb.png deleted file mode 100644 index a82ebe2d0511dc0a54f663e23c25dc275edaa15c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30975 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�awQ>N&Uf?MYaB0>911Z$XQDz2h_WnZ`HC#RNE z!^--ER8y`idG#DJ^S*`AQZ)A?B2TZ|+U9cym9>-1W^uOW7)R$)K(^14rJp}O1A@Q{ zrD^>B&i3~9ZwxdFrH58lL-w19_n8aC@{_8<#c;ask%ydW%RddczL*aLqkmYN)lE0BH1lmwgU=85$AaQkE| z$SA!pvu{qynrTubh)%=0x;k&Y^)UO=M~e#%SZ((lWO%{q7xTG2qf>|%t@mm~3CN3^ zB;*8ARS=rkK2EE0e&mQyn6ScOm$F^=^?VT&0`)6)?tZ`SpR&h}CF@FdK|>%7xxfiU zx5%czMh3VW2Z$hyW>-x#Aym}S^GjXH)v>N=xpAZIluKVZBI9qG{dRv4lav6lq#;*& zJE5OSoklEO$qBIcmXjfQ;lZ_;sps*hk_p!0mCbP>Q7K(j3Qx&-mLWjRC1eVu8h+zk zgZHp3-edegsM#yW8p;yYBy5|tp7!>c4w~&DSGKS1X}gxuCpY@tcH^hx3qCUN!^4So z?GFP~x3WJzytc*eJMau)MpDwF(lonTEnJuREW26S`p$-zQk+tF9zF6OpItsBhB{*z z?QPYRo+D@ClT1tMUhQXPzZFTzns2`zK69c;0XYg0(_9V(H_;M$4~?EsytW(_KoWp# z@t^?#7qfr*G#4*qBsS`-B}M%=gOG4FRcVtKr&Q)3PRV9QL2RtaK{s<=!FKN7Z=;9l zX->H9b`ZpGFaCGo?JMr35xAw5R&ULgGSc1Y(e68OOQCn2#utg za)wNd_o&;{JHoSw33ThbI|FvL-R)PN;W5NKg{r|22tSQPGc>+a*51m$t+;1T;iL2z zq^+9MCO}T9&0Mpbbq*8n*5=I5xXC)GO0Y8qU!hWnAK)8%KXQT!%Cf|(fs68<&3e|# z^ZAZ@*aDUsvn_?2_M<*w{91**85E)G@70ePN7BSCmMOQGabyl|9@%dJV=my!%^~JS zmRX18${kV#puUvvWjLO|^X0nv0VMXc(1Q8Z$ie@dotLr`j8no=EmIAwyLI|n|IjZ^ zzKRH*%eHNF?-Nglh{%W;-s*IpYp3x#M>B3EZ-SY=g&=9A%^!YYKQ--4?Nz(joabN9 z&n_bS400Dfz{t&$k%?V+QoJZLVDy!YPx0mnEs3o5*AYWn&FeII`v5mBz<&x38|JOx|aQ$U5bqOUiL;=5ol9X+z3G8-vhVV*gk&# z1U?59UF0}`A61SBVG4&ZJa}-I(`iL;3cKJk^a@48$xyK3+BbLW`V@eoy|u8Qw&}&- z&o7ZL5L|a+wsPvFgkAP8^8-z@)NKMC9A2t%obtcO8>`RH=M@&Z0X4?}1)X!x(tz9G|N6yzoOpFvTL73im?9OqLZVg3 z@6NqZ_ZuafRZ`(tXnC0gHwn3t(!~!uRBX)(Z}LaB0gV%|~fZl?QN@Yvb!b6~j$m8;wv(vZV&0mlS7;Zx- zm*TA1E_9!Yej>Wc=K4A%5K2Ib@qEkVN`#-F(U1IsFuS0dScV zKA@LX(bFloizcx~b@r&M1GP|A4;{4vRy|JyT5VV|@xK~ooxJ+*|3@YNZ$h`er&n&p Wd&#xuzHQJ)b^FlcgN%ubHvR|v6RGR~ diff --git a/pr-preview/pr-4027/assets/images/benchmark_fio_azure_iops-a85caab4031a29df58a3e7175a62b792.png b/pr-preview/pr-4027/assets/images/benchmark_fio_azure_iops-a85caab4031a29df58a3e7175a62b792.png deleted file mode 100644 index 1723257a812a773fea286d512d38ed9186a9a46e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29702 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 diff --git a/pr-preview/pr-4027/assets/images/benchmark_fio_gcp_bw-f8739bb79b0e47f896217bcacba14cdf.png b/pr-preview/pr-4027/assets/images/benchmark_fio_gcp_bw-f8739bb79b0e47f896217bcacba14cdf.png deleted file mode 100644 index 4f0ecc94bb43d5f9534300605a74aca374da4c3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30401 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 diff --git a/pr-preview/pr-4027/assets/images/benchmark_net_p2p_azure-fbad5555553d559281f605939f5e26c8.png b/pr-preview/pr-4027/assets/images/benchmark_net_p2p_azure-fbad5555553d559281f605939f5e26c8.png deleted file mode 100644 index 9130349c764286e66108a54ffa77a2079807a57b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36902 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 RMnD*58gDV~*w6Df{tphRb0+`* diff --git a/pr-preview/pr-4027/assets/images/benchmark_net_p2p_gcp-8ce759468868272c67b53f5db2a3cf88.png b/pr-preview/pr-4027/assets/images/benchmark_net_p2p_gcp-8ce759468868272c67b53f5db2a3cf88.png deleted file mode 100644 index a41557e96c15e5407beadc5011a3f3fa6aaaa71d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36961 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 w{l|Gl!_|L&u}A+)itsPO`I2 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 Z{Ipv;Zm&N^7q&v795sIAG0R!&{{`ycGXVeq diff --git a/pr-preview/pr-4027/assets/images/benchmark_net_p2svc_gcp-4ae5b9b8d4317ad9d3005c4243d78367.png b/pr-preview/pr-4027/assets/images/benchmark_net_p2svc_gcp-4ae5b9b8d4317ad9d3005c4243d78367.png deleted file mode 100644 index 55916a1de91094b18b3d47c50fc5f5900adfe9a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38395 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
    xlH_*x9qK zS$~ntnP}6tZGC%td!(Ih6)y`5H^7E=)7EYnA0O`kBd*raG}SV%H^tUsFRx^J*%4r;nl*pU89;oQP4Qrzuyd!1<+yR_n1Q!iwI?Yl$$8c+#R03$oEm(= zJIGxAkcT-r?Oa`5vCH@NOA4JCNb$6H@7^1?Zq)~S{^=bYA8)L<@%V9jV`F1;E31vy zua7u<_;A*gh(+>^7>eD%Sw*%)7lHtBs88paN|p|3*0A1m56ZJ`-jP zB0Jy~?@TcwVVG4$XHm?yzbE#n-qn@eoTg8g&kKz<`Vy$zk%uTIH;g*R{9P#_wA za(PI=G0JWoeQ z?1KNR}c6XB2X3 z^k83Z70LZXKh+P(5(`Htc-!mf=$KEKFlE)nIAib1uCeFO_h)2(_L@9fI0tg0GA@>O&t zu~0SXK`CzmtM1B!_PA6U|(a?(bisK1*dNzb3tp^|Wc*_!T`U*}uGhahF+;b3mWbA4_P;UhJ$VU&No? ztzLFt!q1mKLw*1AZ)ZtlkUwD!I)vi=BY#R2zm)v_FaO7WX>Eh`FQ% - diff --git a/pr-preview/pr-4027/assets/images/concept-d3a09a16a8e7ca14a7bdf274ea7bce40.svg b/pr-preview/pr-4027/assets/images/concept-d3a09a16a8e7ca14a7bdf274ea7bce40.svg deleted file mode 100644 index 2286ff308..000000000 --- a/pr-preview/pr-4027/assets/images/concept-d3a09a16a8e7ca14a7bdf274ea7bce40.svg +++ /dev/null @@ -1,201 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pr-preview/pr-4027/assets/images/concept-managed-33482ac199f949182872dc32d69bd3bc.svg b/pr-preview/pr-4027/assets/images/concept-managed-33482ac199f949182872dc32d69bd3bc.svg deleted file mode 100644 index 5645a608f..000000000 --- a/pr-preview/pr-4027/assets/images/concept-managed-33482ac199f949182872dc32d69bd3bc.svg +++ /dev/null @@ -1,591 +0,0 @@ - - diff --git a/pr-preview/pr-4027/assets/images/example-emojivoto-55d31a6fd0c07e8e44b2b51d55dac60d.jpg b/pr-preview/pr-4027/assets/images/example-emojivoto-55d31a6fd0c07e8e44b2b51d55dac60d.jpg deleted file mode 100644 index 4be0d5b26dc70a6fb99a5105c234e6d7ab51a213..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141236 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 K-*lqjT diff --git a/pr-preview/pr-4027/assets/images/max_latency-ae0fad7be416fae0d31ab35bb8284234.png b/pr-preview/pr-4027/assets/images/max_latency-ae0fad7be416fae0d31ab35bb8284234.png deleted file mode 100644 index 696250181be9911f1ee02affe3bfbbe5012e703d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21327 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 VZqJAB#@`TUPAZ?sk~8rCe*osmgx diff --git a/pr-preview/pr-4027/assets/images/p99_latency-fd60c7ae80666133370f9b8e47404994.png b/pr-preview/pr-4027/assets/images/p99_latency-fd60c7ae80666133370f9b8e47404994.png deleted file mode 100644 index 0190118b22f8ea7dbfc862067b06a47bd6ce0d42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24062 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 fzhzeZch178eTiYWYbMif0YhC`N2%(mP2~Rqh diff --git a/pr-preview/pr-4027/assets/images/tcb-424516bbf9d20afe12576bc1305ebc29.svg b/pr-preview/pr-4027/assets/images/tcb-424516bbf9d20afe12576bc1305ebc29.svg deleted file mode 100644 index e5bcb5b95..000000000 --- a/pr-preview/pr-4027/assets/images/tcb-424516bbf9d20afe12576bc1305ebc29.svg +++ /dev/null @@ -1,535 +0,0 @@ - - diff --git a/pr-preview/pr-4027/assets/js/01f9c0c3.252afaac.js b/pr-preview/pr-4027/assets/js/01f9c0c3.252afaac.js deleted file mode 100644 index a28031eae..000000000 --- a/pr-preview/pr-4027/assets/js/01f9c0c3.252afaac.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8806],{28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>r});var s=t(96540);const a={},o=s.createContext(a);function i(e){const n=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),s.createElement(o.Provider,{value:n},e.children)}},55730:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"getting-started/examples/horizontal-scaling","title":"Horizontal Pod Autoscaling","description":"This example demonstrates Constellation\'s autoscaling capabilities. It\'s based on the Kubernetes HorizontalPodAutoscaler Walkthrough. During the following steps, Constellation will spawn new VMs on demand, verify them, add them to the cluster, and delete them again when the load has settled down.","source":"@site/versioned_docs/version-2.24/getting-started/examples/horizontal-scaling.md","sourceDirName":"getting-started/examples","slug":"/getting-started/examples/horizontal-scaling","permalink":"/constellation/pr-preview/pr-4027/getting-started/examples/horizontal-scaling","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/getting-started/examples/horizontal-scaling.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Online Boutique","permalink":"/constellation/pr-preview/pr-4027/getting-started/examples/online-boutique"},"next":{"title":"Filestash with s3proxy","permalink":"/constellation/pr-preview/pr-4027/getting-started/examples/filestash-s3proxy"}}');var a=t(74848),o=t(28453);const i={},r="Horizontal Pod Autoscaling",l={},c=[{value:"Requirements",id:"requirements",level:2},{value:"Setup",id:"setup",level:2},{value:"Monitoring",id:"monitoring",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"horizontal-pod-autoscaling",children:"Horizontal Pod Autoscaling"})}),"\n",(0,a.jsxs)(n.p,{children:["This example demonstrates Constellation's autoscaling capabilities. It's based on the Kubernetes ",(0,a.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/",children:"HorizontalPodAutoscaler Walkthrough"}),". During the following steps, Constellation will spawn new VMs on demand, verify them, add them to the cluster, and delete them again when the load has settled down."]}),"\n",(0,a.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,a.jsxs)(n.p,{children:["The cluster needs to be initialized with Kubernetes 1.23 or later. In addition, ",(0,a.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/scale",children:"autoscaling must be enabled"})," to enable Constellation to assign new nodes dynamically."]}),"\n",(0,a.jsxs)(n.p,{children:["Just for this example specifically, the cluster should have as few worker nodes in the beginning as possible. Start with a small cluster with only ",(0,a.jsx)(n.em,{children:"one"})," low-powered node for the control-plane node and ",(0,a.jsx)(n.em,{children:"one"})," low-powered worker node."]}),"\n",(0,a.jsx)(n.admonition,{type:"info",children:(0,a.jsxs)(n.p,{children:["We tested the example using instances of types ",(0,a.jsx)(n.code,{children:"Standard_DC4as_v5"})," on Azure and ",(0,a.jsx)(n.code,{children:"n2d-standard-4"})," on GCP."]})}),"\n",(0,a.jsx)(n.h2,{id:"setup",children:"Setup"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Install the Kubernetes Metrics Server:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Deploy the HPA example server that's supposed to be scaled under load."}),"\n",(0,a.jsx)(n.p,{children:"This manifest is similar to the one from the Kubernetes HPA walkthrough, but with increased CPU limits and requests to facilitate the triggering of node scaling events."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cat <{r.d(n,{R:()=>d,x:()=>l});var i=r(96540);const s={},o=i.createContext(s);function d(e){const n=i.useContext(o);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),i.createElement(o.Provider,{value:n},e.children)}},47410:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>d,metadata:()=>i,toc:()=>t});const i=JSON.parse('{"id":"reference/migration","title":"Migrations","description":"This document describes breaking changes and migrations between Constellation releases.","source":"@site/docs/reference/migration.md","sourceDirName":"reference","slug":"/reference/migration","permalink":"/constellation/pr-preview/pr-4027/next/reference/migration","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/reference/migration.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"CLI","permalink":"/constellation/pr-preview/pr-4027/next/reference/cli"},"next":{"title":"Terraform usage","permalink":"/constellation/pr-preview/pr-4027/next/reference/terraform"}}');var s=r(74848),o=r(28453);const d={},l="Migrations",c={},t=[{value:"Migrations to v2.23.0",id:"migrations-to-v2230",level:2},{value:"GCP",id:"gcp",level:3},{value:"Migrations to v2.19.1",id:"migrations-to-v2191",level:2},{value:"Azure",id:"azure",level:3},{value:"Migrating from CLI versions before 2.21.1",id:"migrating-from-cli-versions-before-2211",level:2},{value:"AWS",id:"aws",level:3},{value:"Migrating from CLI versions before 2.19.0",id:"migrating-from-cli-versions-before-2190",level:2},{value:"Azure",id:"azure-1",level:3},{value:"Migrating from CLI versions before 2.18.0",id:"migrating-from-cli-versions-before-2180",level:2},{value:"Migrating from CLI versions before 2.10",id:"migrating-from-cli-versions-before-210",level:2},{value:"Migrating from CLI versions before 2.9",id:"migrating-from-cli-versions-before-29",level:2},{value:"Migrating from CLI versions before 2.8",id:"migrating-from-cli-versions-before-28",level:2},{value:"Migrating from CLI versions before 2.3",id:"migrating-from-cli-versions-before-23",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components},{Details:r}=n;return r||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"migrations",children:"Migrations"})}),"\n",(0,s.jsxs)(n.p,{children:["This document describes breaking changes and migrations between Constellation releases.\nUse ",(0,s.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/reference/cli#constellation-config-migrate",children:(0,s.jsx)(n.code,{children:"constellation config migrate"})})," to automatically update an old config file to a new format."]}),"\n",(0,s.jsx)(n.h2,{id:"migrations-to-v2230",children:"Migrations to v2.23.0"}),"\n",(0,s.jsx)(n.h3,{id:"gcp",children:"GCP"}),"\n",(0,s.jsxs)(n.p,{children:["GCP will require the additional permission ",(0,s.jsx)(n.code,{children:"compute.forwardingRules.list"}),". Please update your IAM roles using ",(0,s.jsx)(n.code,{children:"constellation iam upgrade apply"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"migrations-to-v2191",children:"Migrations to v2.19.1"}),"\n",(0,s.jsx)(n.h3,{id:"azure",children:"Azure"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"During the upgrade, security rules are migrated and the old ones need to be cleaned up manually by the user. The below script shows how to delete them through the Azure CLI:"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'#!/usr/bin/env bash\nname="" # the name provided in the config\nuid="" # the cluster id can be retrieved via `yq \'.infrastructure.uid\' constellation-state.yaml`\nresource_group="" # the RG can be retrieved via `yq \'.provider.azure.resourceGroup\' constellation-conf.yaml`\n\nrules=(\n "kubernetes"\n "bootstrapper"\n "verify"\n "recovery"\n "join"\n "debugd"\n "konnectivity"\n)\n\nfor rule in "${rules[@]}"; do\n echo "Deleting rule: ${rule}"\n az network nsg rule delete \\\n --resource-group "${resource_group}" \\\n --nsg-name "${name}-${uid}" \\\n --name "${rule}"\ndone\n\necho "All specified rules have been deleted."\n'})}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-2211",children:"Migrating from CLI versions before 2.21.1"}),"\n",(0,s.jsx)(n.h3,{id:"aws",children:"AWS"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["AWS clusters that use ",(0,s.jsx)(n.code,{children:"LoadBalancer"})," resources require more IAM permissions. Please upgrade your IAM roles using ",(0,s.jsx)(n.code,{children:"constellation iam upgrade apply"}),". This will show necessary changes and apply them, if desired."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-2190",children:"Migrating from CLI versions before 2.19.0"}),"\n",(0,s.jsx)(n.h3,{id:"azure-1",children:"Azure"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["To allow seamless upgrades on Azure when Kubernetes services of type ",(0,s.jsx)(n.code,{children:"LoadBalancer"})," are deployed, the target\nload balancer in which the ",(0,s.jsx)(n.code,{children:"cloud-controller-manager"})," creates load balancing rules was changed. Instead of using the load balancer\ncreated and maintained by the CLI's Terraform code, the ",(0,s.jsx)(n.code,{children:"cloud-controller-manager"})," now creates its own load balancer in Azure.\nIf your Constellation has services of type ",(0,s.jsx)(n.code,{children:"LoadBalancer"}),", please remove them before the upgrade and re-apply them\nafterward."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-2180",children:"Migrating from CLI versions before 2.18.0"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"provider.azure.appClientID"})," and ",(0,s.jsx)(n.code,{children:"provider.azure.appClientSecret"})," fields are no longer supported and should be removed."]}),"\n",(0,s.jsxs)(n.li,{children:["To keep using an existing UAMI, add the ",(0,s.jsx)(n.code,{children:"Owner"})," permission with the scope of your ",(0,s.jsx)(n.code,{children:"resourceGroup"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["Otherwise, simply ",(0,s.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/config#creating-an-iam-configuration",children:"create new Constellation IAM credentials"})," and use the created UAMI."]}),"\n",(0,s.jsxs)(n.li,{children:["To migrate the authentication for an existing cluster on Azure to an UAMI with the necessary permissions:","\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Remove the ",(0,s.jsx)(n.code,{children:"aadClientId"})," and ",(0,s.jsx)(n.code,{children:"aadClientSecret"})," from the azureconfig secret."]}),"\n",(0,s.jsxs)(n.li,{children:["Set ",(0,s.jsx)(n.code,{children:"useManagedIdentityExtension"})," to ",(0,s.jsx)(n.code,{children:"true"})," and use the ",(0,s.jsx)(n.code,{children:"userAssignedIdentity"})," from the Constellation config for the value of ",(0,s.jsx)(n.code,{children:"userAssignedIdentityID"}),"."]}),"\n",(0,s.jsx)(n.li,{children:"Restart the CSI driver, cloud controller manager, cluster autoscaler, and Constellation operator pods."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-210",children:"Migrating from CLI versions before 2.10"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["AWS cluster upgrades require additional IAM permissions for the newly introduced ",(0,s.jsx)(n.code,{children:"aws-load-balancer-controller"}),". Please upgrade your IAM roles using ",(0,s.jsx)(n.code,{children:"iam upgrade apply"}),". This will show necessary changes and apply them, if desired."]}),"\n",(0,s.jsxs)(n.li,{children:["The global ",(0,s.jsx)(n.code,{children:"nodeGroups"})," field was added."]}),"\n",(0,s.jsxs)(n.li,{children:["The fields ",(0,s.jsx)(n.code,{children:"instanceType"}),", ",(0,s.jsx)(n.code,{children:"stateDiskSizeGB"}),", and ",(0,s.jsx)(n.code,{children:"stateDiskType"})," for each cloud provider are now part of the configuration of individual node groups."]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"constellation create"})," command no longer uses the flags ",(0,s.jsx)(n.code,{children:"--control-plane-count"})," and ",(0,s.jsx)(n.code,{children:"--worker-count"}),". Instead, the initial node count is configured per node group in the ",(0,s.jsx)(n.code,{children:"nodeGroups"})," field."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-29",children:"Migrating from CLI versions before 2.9"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"provider.azure.appClientID"})," and ",(0,s.jsx)(n.code,{children:"provider.azure.clientSecretValue"})," fields were removed to enforce migration to managed identity authentication"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-28",children:"Migrating from CLI versions before 2.8"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"measurements"})," field for each cloud service provider was replaced with a global ",(0,s.jsx)(n.code,{children:"attestation"})," field."]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"confidentialVM"}),", ",(0,s.jsx)(n.code,{children:"idKeyDigest"}),", and ",(0,s.jsx)(n.code,{children:"enforceIdKeyDigest"})," fields for the Azure cloud service provider were removed in favor of using the global ",(0,s.jsx)(n.code,{children:"attestation"})," field."]}),"\n",(0,s.jsxs)(n.li,{children:["The optional global field ",(0,s.jsx)(n.code,{children:"attestationVariant"})," was replaced by the now required ",(0,s.jsx)(n.code,{children:"attestation"})," field."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-23",children:"Migrating from CLI versions before 2.3"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"sshUsers"})," field was deprecated in v2.2 and has been removed from the configuration in v2.3.\nAs an alternative for SSH, check the workflow section ",(0,s.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/troubleshooting#node-shell-access",children:"Connect to nodes"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"image"})," field for each cloud service provider has been replaced with a global ",(0,s.jsx)(n.code,{children:"image"})," field. Use the following mapping to migrate your configuration:"]}),"\n",(0,s.jsxs)(r,{children:[(0,s.jsx)("summary",{children:"Show all"}),(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"CSP"}),(0,s.jsx)(n.th,{children:"old image"}),(0,s.jsx)(n.th,{children:"new image"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-06b8cbf4837a0a57c"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-02e96dc04a9e438cd"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-028ead928a9034b2f"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-032ac10dd8d8266e3"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-032e0d57cc4395088"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-053c3e49e19b96bdd"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-0e27ebcefc38f648b"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-098cd37f66523b7c3"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-04a87d302e2509aad"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.2"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.2"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.1"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.1"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.1.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.1.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.1.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.1.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.0.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.0.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.0.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.0.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"GCP"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"projects/constellation-images/global/images/constellation-v2-2-2"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"GCP"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"projects/constellation-images/global/images/constellation-v2-2-1"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"GCP"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"projects/constellation-images/global/images/constellation-v2-2-0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"GCP"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"projects/constellation-images/global/images/constellation-v2-1-0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.1.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"GCP"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"projects/constellation-images/global/images/constellation-v2-0-0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.0.0"})})]})]})]})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"enforcedMeasurements"})," field has been removed and merged with the ",(0,s.jsx)(n.code,{children:"measurements"})," field."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["To migrate your config containing a new image (",(0,s.jsx)(n.code,{children:"v2.3"})," or greater), remove the old ",(0,s.jsx)(n.code,{children:"measurements"})," and ",(0,s.jsx)(n.code,{children:"enforcedMeasurements"})," entries from your config and run ",(0,s.jsx)(n.code,{children:"constellation fetch-measurements"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["To migrate your config containing an image older than ",(0,s.jsx)(n.code,{children:"v2.3"}),", remove the ",(0,s.jsx)(n.code,{children:"enforcedMeasurements"})," entry and replace the entries in ",(0,s.jsx)(n.code,{children:"measurements"})," as shown in the example below:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-diff",children:"measurements:\n- 0: DzXCFGCNk8em5ornNZtKi+Wg6Z7qkQfs5CfE3qTkOc8=\n+ 0:\n+ expected: DzXCFGCNk8em5ornNZtKi+Wg6Z7qkQfs5CfE3qTkOc8=\n+ warnOnly: true\n- 8: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\n+ 8:\n+ expected: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\n+ warnOnly: false\n-enforcedMeasurements:\n- - 8\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/039005a9.e980c3d6.js b/pr-preview/pr-4027/assets/js/039005a9.e980c3d6.js deleted file mode 100644 index b16fcb787..000000000 --- a/pr-preview/pr-4027/assets/js/039005a9.e980c3d6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6996],{74333:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Basics","slug":"/category/basics","permalink":"/constellation/pr-preview/pr-4027/category/basics","sidebar":"docs","navigation":{"previous":{"title":"Introduction","permalink":"/constellation/pr-preview/pr-4027/"},"next":{"title":"Confidential Kubernetes","permalink":"/constellation/pr-preview/pr-4027/overview/confidential-kubernetes"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/0428ff27.9f4bd7a8.js b/pr-preview/pr-4027/assets/js/0428ff27.9f4bd7a8.js deleted file mode 100644 index b3497d30e..000000000 --- a/pr-preview/pr-4027/assets/js/0428ff27.9f4bd7a8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5116],{21581:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"architecture/observability","title":"Observability","description":"In Kubernetes, observability is the ability to gain insight into the behavior and performance of applications.","source":"@site/versioned_docs/version-2.22/architecture/observability.md","sourceDirName":"architecture","slug":"/architecture/observability","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/observability","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/architecture/observability.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Networking","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/networking"},"next":{"title":"Reference","permalink":"/constellation/pr-preview/pr-4027/2.22/category/reference"}}');var n=s(74848),r=s(28453);const a={},o="Observability",l={},c=[{value:"Cloud resource monitoring",id:"cloud-resource-monitoring",level:2},{value:"Metrics",id:"metrics",level:2},{value:"Logs",id:"logs",level:2},{value:"System logs",id:"system-logs",level:3},{value:"Kubernetes logs",id:"kubernetes-logs",level:3},{value:"Traces",id:"traces",level:2},{value:"Integrations",id:"integrations",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"observability",children:"Observability"})}),"\n",(0,n.jsx)(t.p,{children:'In Kubernetes, observability is the ability to gain insight into the behavior and performance of applications.\nIt helps identify and resolve issues more effectively, ensuring stability and performance of Kubernetes workloads, reducing downtime and outages, and improving efficiency.\nThe "three pillars of observability" are logs, metrics, and traces.'}),"\n",(0,n.jsx)(t.p,{children:"In the context of Confidential Computing, observability is a delicate subject and needs to be applied such that it doesn't leak any sensitive information.\nThe following gives an overview of where and how you can apply standard observability tools in Constellation."}),"\n",(0,n.jsx)(t.h2,{id:"cloud-resource-monitoring",children:"Cloud resource monitoring"}),"\n",(0,n.jsx)(t.p,{children:"While inaccessible, Constellation's nodes are still visible as black box VMs to the hypervisor.\nResource consumption, such as memory and CPU utilization, can be monitored from the outside and observed via the cloud platforms directly.\nSimilarly, other resources, such as storage and network and their respective metrics, are visible via the cloud platform."}),"\n",(0,n.jsx)(t.h2,{id:"metrics",children:"Metrics"}),"\n",(0,n.jsx)(t.p,{children:"Metrics are numeric representations of data measured over intervals of time. They're essential for understanding system health and gaining insights using telemetry signals."}),"\n",(0,n.jsxs)(t.p,{children:["By default, Constellation exposes the ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/system-metrics/",children:"metrics for Kubernetes system components"})," inside the cluster.\nSimilarly, the ",(0,n.jsx)(t.a,{href:"https://etcd.io/docs/v3.5/metrics/",children:"etcd metrics"})," endpoints are exposed inside the cluster.\nThese ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/system-metrics/#disabling-metrics",children:"metrics endpoints can be disabled"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["You can collect these cluster-internal metrics via tools such as ",(0,n.jsx)(t.a,{href:"https://prometheus.io/",children:"Prometheus"})," or the ",(0,n.jsx)(t.a,{href:"https://www.elastic.co/de/elastic-stack/",children:"Elastic Stack"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["Constellation's CNI Cilium also supports ",(0,n.jsx)(t.a,{href:"https://docs.cilium.io/en/latest/observability/metrics/",children:"metrics via Prometheus endpoints"}),".\nHowever, in Constellation, they're disabled by default and must be enabled first."]}),"\n",(0,n.jsx)(t.h2,{id:"logs",children:"Logs"}),"\n",(0,n.jsx)(t.p,{children:"Logs represent discrete events that usually describe what's happening with your service.\nThe payload is an actual message emitted from your system along with a metadata section containing a timestamp, labels, and tracking identifiers."}),"\n",(0,n.jsx)(t.h3,{id:"system-logs",children:"System logs"}),"\n",(0,n.jsxs)(t.p,{children:["Detailed system-level logs are accessible via ",(0,n.jsx)(t.code,{children:"/var/log"})," and ",(0,n.jsx)(t.a,{href:"https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html",children:"journald"})," on the nodes directly.\nThey can be collected from there, for example, via ",(0,n.jsx)(t.a,{href:"https://www.elastic.co/guide/en/beats/filebeat/current/logstash-output.html",children:"Filebeat and Logstash"}),", which are tools of the ",(0,n.jsx)(t.a,{href:"https://www.elastic.co/de/elastic-stack/",children:"Elastic Stack"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["In case of an error during the initialization, the CLI automatically collects the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#bootstrapper",children:"Bootstrapper"})," logs and returns these as a file for ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting",children:"troubleshooting"}),". Here is an example of such an event:"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell-session",children:'Cluster initialization failed. This error is not recoverable.\nTerminate your cluster and try again.\nFetched bootstrapper logs are stored in "constellation-cluster.log"\n'})}),"\n",(0,n.jsx)(t.h3,{id:"kubernetes-logs",children:"Kubernetes logs"}),"\n",(0,n.jsxs)(t.p,{children:["Constellation supports the ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/logging/",children:"Kubernetes logging architecture"}),".\nBy default, logs are written to the nodes' encrypted state disks.\nThese include the Pod and container logs and the ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/logging/#system-component-logs",children:"system component logs"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices",children:"Constellation services"})," run as Pods inside the ",(0,n.jsx)(t.code,{children:"kube-system"})," namespace and use the standard container logging mechanism.\nThe same applies for the ",(0,n.jsx)(t.a,{href:"https://docs.cilium.io/en/latest/operations/troubleshooting/#logs",children:"Cilium Pods"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["You can collect logs from within the cluster via tools such as ",(0,n.jsx)(t.a,{href:"https://github.com/fluent/fluentd",children:"Fluentd"}),", ",(0,n.jsx)(t.a,{href:"https://github.com/grafana/loki",children:"Loki"}),", or the ",(0,n.jsx)(t.a,{href:"https://www.elastic.co/de/elastic-stack/",children:"Elastic Stack"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"traces",children:"Traces"}),"\n",(0,n.jsx)(t.p,{children:"Modern systems are implemented as interconnected complex and distributed microservices. Understanding request flows and system communications is challenging, mainly because all systems in a chain need to be modified to propagate tracing information. Distributed tracing is a new approach to increasing observability and understanding performance bottlenecks. A trace represents consecutive events that reflect an end-to-end request path in a distributed system."}),"\n",(0,n.jsxs)(t.p,{children:["Constellation supports ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/system-traces/",children:"traces for Kubernetes system components"}),".\nBy default, they're disabled and need to be enabled first."]}),"\n",(0,n.jsxs)(t.p,{children:["Similarly, Cilium can be enabled to ",(0,n.jsx)(t.a,{href:"https://cilium.io/use-cases/metrics-export/",children:"export traces"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["You can collect these traces via tools such as ",(0,n.jsx)(t.a,{href:"https://www.jaegertracing.io/",children:"Jaeger"})," or ",(0,n.jsx)(t.a,{href:"https://zipkin.io/",children:"Zipkin"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"integrations",children:"Integrations"}),"\n",(0,n.jsx)(t.p,{children:"Platforms and SaaS solutions such as Datadog, logz.io, Dynatrace, or New Relic facilitate the observability challenge for Kubernetes and provide all-in-one SaaS solutions.\nThey install agents into the cluster that collect metrics, logs, and tracing information and upload them into the data lake of the platform.\nTechnically, the agent-based approach is compatible with Constellation, and attaching these platforms is straightforward.\nHowever, you need to evaluate if the exported data might violate Constellation's compliance and privacy guarantees by uploading them to a third-party platform."})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>o});var i=s(96540);const n={},r=i.createContext(n);function a(e){const t=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/061c4c8e.6d11960a.js b/pr-preview/pr-4027/assets/js/061c4c8e.6d11960a.js deleted file mode 100644 index 2dabfbf21..000000000 --- a/pr-preview/pr-4027/assets/js/061c4c8e.6d11960a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9727],{28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>a});var o=r(96540);const s={},n=o.createContext(s);function i(e){const t=o.useContext(n);return o.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(n.Provider,{value:t},e.children)}},44225:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"overview/product","title":"Product features","description":"Constellation is a Kubernetes engine that aims to provide the best possible data security in combination with enterprise-grade scalability and reliability features---and a smooth user experience.","source":"@site/versioned_docs/version-2.22/overview/product.md","sourceDirName":"overview","slug":"/overview/product","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/product","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/overview/product.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Security benefits","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/security-benefits"},"next":{"title":"Feature status of clouds","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/clouds"}}');var s=r(74848),n=r(28453);const i={},a="Product features",l={},c=[];function u(e){const t={a:"a",h1:"h1",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,n.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"product-features",children:"Product features"})}),"\n",(0,s.jsx)(t.p,{children:"Constellation is a Kubernetes engine that aims to provide the best possible data security in combination with enterprise-grade scalability and reliability features---and a smooth user experience."}),"\n",(0,s.jsxs)(t.p,{children:["From a security perspective, Constellation implements the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/overview/confidential-kubernetes",children:"Confidential Kubernetes"})," concept and corresponding security features, which shield your entire cluster from the underlying infrastructure."]}),"\n",(0,s.jsx)(t.p,{children:"From an operational perspective, Constellation provides the following key features:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Native support for different clouds"}),": Constellation works on Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), and STACKIT. Support for OpenStack-based environments is coming with a future release. Constellation securely interfaces with the cloud infrastructure to provide ",(0,s.jsx)(t.a,{href:"https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler",children:"cluster autoscaling"}),", ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/storage/dynamic-provisioning/",children:"dynamic persistent volumes"}),", and ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer",children:"service load balancing"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"High availability"}),": Constellation uses a ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/",children:"multi-master architecture"})," with a ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/ha-topology/#stacked-etcd-topology",children:"stacked etcd topology"})," to ensure high availability."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Integrated Day-2 operations"}),": Constellation lets you securely ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade",children:"upgrade"})," your cluster to a new release. It also lets you securely ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/recovery",children:"recover"})," a failed cluster. Both with a single command."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Support for Terraform"}),": Constellation includes a ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/terraform-provider",children:"Terraform provider"})," that lets you manage the full lifecycle of your cluster via Terraform."]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/073bbd6a.de1348f1.js b/pr-preview/pr-4027/assets/js/073bbd6a.de1348f1.js deleted file mode 100644 index 9e33b07a1..000000000 --- a/pr-preview/pr-4027/assets/js/073bbd6a.de1348f1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5514],{28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>r});var t=s(96540);const l={},i=t.createContext(l);function o(e){const n=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:o(e.components),t.createElement(i.Provider,{value:n},e.children)}},94145:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"getting-started/first-steps-local","title":"First steps with a local cluster","description":"A local cluster lets you deploy and test Constellation without a cloud subscription.","source":"@site/versioned_docs/version-2.23/getting-started/first-steps-local.md","sourceDirName":"getting-started","slug":"/getting-started/first-steps-local","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps-local","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/getting-started/first-steps-local.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"First steps (cloud)","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps"},"next":{"title":"Cloud Marketplaces","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/marketplaces"}}');var l=s(74848),i=s(28453);const o={},r="First steps with a local cluster",a={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Software installation on Ubuntu",id:"software-installation-on-ubuntu",level:3},{value:"Create a cluster",id:"create-a-cluster",level:2},{value:"Connect to the cluster",id:"connect-to-the-cluster",level:2},{value:"Deploy a sample application",id:"deploy-a-sample-application",level:2},{value:"Terminate your cluster",id:"terminate-your-cluster",level:2},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"VMs have no internet access / CLI remains in "Initializing cluster" state",id:"vms-have-no-internet-access--cli-remains-in-initializing-cluster-state",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components},{TabItem:s,Tabs:t}=n;return s||h("TabItem",!0),t||h("Tabs",!0),(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"first-steps-with-a-local-cluster",children:"First steps with a local cluster"})}),"\n",(0,l.jsx)(n.p,{children:"A local cluster lets you deploy and test Constellation without a cloud subscription.\nYou have two options:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Use MiniConstellation to automatically deploy a two-node cluster."}),"\n",(0,l.jsx)(n.li,{children:"For more fine-grained control, create the cluster using the QEMU provider."}),"\n"]}),"\n",(0,l.jsxs)(n.p,{children:["Both options use virtualization to create a local cluster with control-plane nodes and worker nodes. They ",(0,l.jsx)(n.strong,{children:"don't"})," require hardware with Confidential VM (CVM) support. For attestation, they currently use a software-based vTPM provided by KVM/QEMU."]}),"\n",(0,l.jsx)(n.p,{children:"You need an x64 machine with a Linux OS.\nYou can use a VM, but it needs nested virtualization."}),"\n",(0,l.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Machine requirements:","\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"An x86-64 CPU with at least 4 cores (6 cores are recommended)"}),"\n",(0,l.jsx)(n.li,{children:"At least 4 GB RAM (6 GB are recommended)"}),"\n",(0,l.jsx)(n.li,{children:"20 GB of free disk space"}),"\n",(0,l.jsx)(n.li,{children:"Hardware virtualization enabled in the BIOS/UEFI (often referred to as Intel VT-x or AMD-V/SVM) / nested-virtualization support when using a VM"}),"\n"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["Software requirements:","\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Linux OS with ",(0,l.jsx)(n.a,{href:"https://www.linux-kvm.org/page/Main_Page",children:"KVM kernel module"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Recommended: Ubuntu 22.04 LTS"}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://docs.docker.com/engine/install/",children:"Docker"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://gitlab.gnome.org/GNOME/libxslt/-/wikis/home",children:"xsltproc"})}),"\n",(0,l.jsxs)(n.li,{children:["(Optional) ",(0,l.jsx)(n.a,{href:"https://www.libvirt.org/manpages/virsh.html",children:"virsh"})," to observe and access your nodes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"software-installation-on-ubuntu",children:"Software installation on Ubuntu"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:'# install Docker\ncurl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg\necho "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null\nsudo apt update\nsudo apt install docker-ce\n# install other dependencies\nsudo apt install xsltproc\nsudo snap install kubectl --classic\n# install Constellation CLI\ncurl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-amd64\nsudo install constellation-linux-amd64 /usr/local/bin/constellation\n# do not drop forwarded packages\nsudo iptables -P FORWARD ACCEPT\n'})}),"\n",(0,l.jsx)(n.h2,{id:"create-a-cluster",children:"Create a cluster"}),"\n",(0,l.jsxs)(t,{groupId:"csp",children:[(0,l.jsxs)(s,{value:"mini",label:"MiniConstellation",children:[(0,l.jsxs)(n.p,{children:["With the ",(0,l.jsx)(n.code,{children:"constellation mini"})," command, you can deploy and test Constellation locally. This mode is called MiniConstellation. Conceptually, MiniConstellation is similar to ",(0,l.jsx)(n.a,{href:"https://microk8s.io/",children:"MicroK8s"}),", ",(0,l.jsx)(n.a,{href:"https://k3s.io/",children:"K3s"}),", and ",(0,l.jsx)(n.a,{href:"https://minikube.sigs.k8s.io/docs/",children:"minikube"}),"."]}),(0,l.jsx)(n.admonition,{type:"caution",children:(0,l.jsxs)(n.p,{children:["MiniConstellation has specific soft- and hardware requirements such as a Linux OS running on an x86-64 CPU. Pay attention to all ",(0,l.jsx)(n.a,{href:"#prerequisites",children:"prerequisites"})," when setting up."]})}),(0,l.jsx)(n.admonition,{type:"note",children:(0,l.jsx)(n.p,{children:"Since MiniConstellation runs on your local system, cloud features such as load balancing,\nattaching persistent storage, or autoscaling aren't available."})}),(0,l.jsx)(n.p,{children:"The following creates your MiniConstellation cluster (may take up to 10 minutes to complete):"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation mini up\n"})}),(0,l.jsxs)(n.p,{children:["This will configure your current directory as the ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/orchestration#workspaces",children:"workspace"})," for this cluster.\nAll ",(0,l.jsx)(n.code,{children:"constellation"})," commands concerning this cluster need to be issued from this directory."]})]}),(0,l.jsxs)(s,{value:"qemu",label:"QEMU",children:[(0,l.jsxs)(n.p,{children:["With the QEMU provider, you can create a local Constellation cluster as if it were in the cloud. The provider uses ",(0,l.jsx)(n.a,{href:"https://www.qemu.org/",children:"QEMU"})," to create multiple VMs for the cluster nodes, which interact with each other."]}),(0,l.jsx)(n.admonition,{type:"caution",children:(0,l.jsxs)(n.p,{children:["Constellation on QEMU has specific soft- and hardware requirements such as a Linux OS running on an x86-64 CPU. Pay attention to all ",(0,l.jsx)(n.a,{href:"#prerequisites",children:"prerequisites"})," when setting up."]})}),(0,l.jsx)(n.admonition,{type:"note",children:(0,l.jsx)(n.p,{children:"Since Constellation on QEMU runs on your local system, cloud features such as load balancing,\nattaching persistent storage, or autoscaling aren't available."})}),(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"To set up your local cluster, you need to create a configuration file for Constellation first."}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation config generate qemu\n"})}),(0,l.jsxs)(n.p,{children:["This creates a ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/config",children:"configuration file"})," for QEMU called ",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"}),". After that, your current folder also becomes your ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/orchestration#workspaces",children:"workspace"}),". All ",(0,l.jsx)(n.code,{children:"constellation"})," commands for your cluster need to be executed from this directory."]}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["Now you can create your cluster and its nodes. ",(0,l.jsx)(n.code,{children:"constellation apply"})," uses the options set in ",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"}),"."]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation apply -y\n"})}),(0,l.jsx)(n.p,{children:"The Output should look like the following:"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:'$ constellation apply -y\nChecking for infrastructure changes\nThe following Constellation cluster will be created:\n 3 control-plane nodes of type 2-vCPUs will be created.\n 1 worker node of type 2-vCPUs will be created.\nCreating\nCloud infrastructure created successfully.\nYour Constellation master secret was successfully written to ./constellation-mastersecret.json\nConnecting\nInitializing cluster\nInstalling Kubernetes components\nYour Constellation cluster was successfully initialized.\n\nConstellation cluster identifier g6iMP5wRU1b7mpOz2WEISlIYSfdAhB0oNaOg6XEwKFY=\nKubernetes configuration constellation-admin.conf\n\nYou can now connect to your cluster by executing:\n export KUBECONFIG="$PWD/constellation-admin.conf"\n'})}),(0,l.jsxs)(n.p,{children:["The cluster's identifier will be different in your output.\nKeep ",(0,l.jsx)(n.code,{children:"constellation-mastersecret.json"})," somewhere safe.\nThis will allow you to ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/recovery",children:"recover your cluster"})," in case of a disaster."]}),(0,l.jsx)(n.admonition,{type:"info",children:(0,l.jsxs)(n.p,{children:["Depending on your setup, ",(0,l.jsx)(n.code,{children:"constellation apply"})," may take 10+ minutes to complete."]})}),(0,l.jsxs)(n.ol,{start:"3",children:["\n",(0,l.jsx)(n.li,{children:"Configure kubectl"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:'export KUBECONFIG="$PWD/constellation-admin.conf"\n'})})]})]}),"\n",(0,l.jsx)(n.h2,{id:"connect-to-the-cluster",children:"Connect to the cluster"}),"\n",(0,l.jsx)(n.p,{children:"Your cluster initially consists of a single control-plane node:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"$ kubectl get nodes\nNAME STATUS ROLES AGE VERSION\ncontrol-plane-0 Ready control-plane 66s v1.24.6\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Additional nodes will request to join the cluster shortly. Before each additional node is allowed to join the cluster, its state is verified using remote attestation by the ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#joinservice",children:"JoinService"}),".\nIf verification passes successfully, the new node receives keys and certificates to join the cluster."]}),"\n",(0,l.jsx)(n.p,{children:"You can follow this process by viewing the logs of the JoinService:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:'$ kubectl logs -n kube-system daemonsets/join-service -f\n{"level":"INFO","ts":"2022-10-14T09:32:20Z","caller":"cmd/main.go:48","msg":"Constellation Node Join Service","version":"2.1.0","cloudProvider":"qemu"}\n{"level":"INFO","ts":"2022-10-14T09:32:20Z","logger":"validator","caller":"watcher/validator.go:96","msg":"Updating expected measurements"}\n...\n'})}),"\n",(0,l.jsx)(n.p,{children:"Once all nodes have joined your cluster, it may take a couple of minutes for all resources to become available.\nYou can check on the state of your cluster by running the following:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"$ kubectl get nodes\nNAME STATUS ROLES AGE VERSION\ncontrol-plane-0 Ready control-plane 2m59s v1.24.6\nworker-0 Ready 32s v1.24.6\n"})}),"\n",(0,l.jsx)(n.h2,{id:"deploy-a-sample-application",children:"Deploy a sample application"}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["Deploy the ",(0,l.jsx)(n.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"emojivoto app"})]}),"\n"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment\n"})}),"\n",(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsx)(n.li,{children:"Expose the frontend service locally"}),"\n"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments\nkubectl -n emojivoto port-forward svc/web-svc 8080:80 &\ncurl http://localhost:8080\nkill %1\n"})}),"\n",(0,l.jsx)(n.h2,{id:"terminate-your-cluster",children:"Terminate your cluster"}),"\n",(0,l.jsxs)(t,{groupId:"csp",children:[(0,l.jsxs)(s,{value:"mini",label:"MiniConstellation",children:[(0,l.jsx)(n.p,{children:"Once you are done, you can clean up the created resources using the following command:"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation mini down\n"})}),(0,l.jsxs)(n.p,{children:["This will destroy your cluster and clean up your workspace.\nThe VM image and cluster configuration file (",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"}),") will be kept and may be reused to create new clusters."]})]}),(0,l.jsxs)(s,{value:"qemu",label:"QEMU",children:[(0,l.jsx)(n.p,{children:"Once you are done, you can clean up the created resources using the following command:"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation terminate\n"})}),(0,l.jsx)(n.p,{children:"This should give the following output:"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"$ constellation terminate\nYou are about to terminate a Constellation cluster.\nAll of its associated resources will be DESTROYED.\nThis action is irreversible and ALL DATA WILL BE LOST.\nDo you want to continue? [y/n]:\n"})}),(0,l.jsxs)(n.p,{children:["Confirm with ",(0,l.jsx)(n.code,{children:"y"})," to terminate the cluster:"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"Terminating ...\nYour Constellation cluster was terminated successfully.\n"})}),(0,l.jsxs)(n.p,{children:["This will destroy your cluster and clean up your workspace.\nThe VM image and cluster configuration file (",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"}),") will be kept and may be reused to create new clusters."]})]})]}),"\n",(0,l.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,l.jsxs)(n.p,{children:["Make sure to use the ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/releases/latest",children:"latest release"})," and check out the ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"known issues"}),"."]}),"\n",(0,l.jsx)(n.h3,{id:"vms-have-no-internet-access--cli-remains-in-initializing-cluster-state",children:'VMs have no internet access / CLI remains in "Initializing cluster" state'}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:"iptables"})," rules may prevent your VMs from accessing the internet.\nMake sure your rules aren't dropping forwarded packages."]}),"\n",(0,l.jsx)(n.p,{children:"List your rules:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo iptables -S\n"})}),"\n",(0,l.jsx)(n.p,{children:"The output may look similar to the following:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"-P INPUT ACCEPT\n-P FORWARD DROP\n-P OUTPUT ACCEPT\n-N DOCKER\n-N DOCKER-ISOLATION-STAGE-1\n-N DOCKER-ISOLATION-STAGE-2\n-N DOCKER-USER\n"})}),"\n",(0,l.jsxs)(n.p,{children:["If your ",(0,l.jsx)(n.code,{children:"FORWARD"})," chain is set to ",(0,l.jsx)(n.code,{children:"DROP"}),", you need to update your rules:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo iptables -P FORWARD ACCEPT\n"})})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}function h(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/074359f8.c3c68ee5.js b/pr-preview/pr-4027/assets/js/074359f8.c3c68ee5.js deleted file mode 100644 index 647286111..000000000 --- a/pr-preview/pr-4027/assets/js/074359f8.c3c68ee5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8295],{19101:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>m,frontMatter:()=>a,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"overview/performance/performance","title":"Performance analysis of Constellation","description":"This section provides a comprehensive examination of the performance characteristics of Constellation.","source":"@site/versioned_docs/version-2.23/overview/performance/performance.md","sourceDirName":"overview/performance","slug":"/overview/performance/","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/performance/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/overview/performance/performance.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Feature status of clouds","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/clouds"},"next":{"title":"Compute benchmarks","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/performance/compute"}}');var t=o(74848),i=o(28453);const a={},s="Performance analysis of Constellation",c={},l=[{value:"Runtime encryption",id:"runtime-encryption",level:2},{value:"I/O performance benchmarks",id:"io-performance-benchmarks",level:2},{value:"Application benchmarking",id:"application-benchmarking",level:2}];function p(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"performance-analysis-of-constellation",children:"Performance analysis of Constellation"})}),"\n",(0,t.jsx)(n.p,{children:"This section provides a comprehensive examination of the performance characteristics of Constellation."}),"\n",(0,t.jsx)(n.h2,{id:"runtime-encryption",children:"Runtime encryption"}),"\n",(0,t.jsxs)(n.p,{children:["Runtime encryption affects compute performance. ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/overview/performance/compute",children:"Benchmarks by Azure and Google"})," show that the performance degradation of Confidential VMs (CVMs) is small, ranging from 2% to 8% for compute-intensive workloads."]}),"\n",(0,t.jsx)(n.h2,{id:"io-performance-benchmarks",children:"I/O performance benchmarks"}),"\n",(0,t.jsxs)(n.p,{children:["We evaluated the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/overview/performance/io",children:"I/O performance"})," of Constellation, utilizing a collection of synthetic benchmarks targeting networking and storage.\nWe further compared this performance to native managed Kubernetes offerings from various cloud providers, to better understand how Constellation stands in relation to standard practices."]}),"\n",(0,t.jsx)(n.h2,{id:"application-benchmarking",children:"Application benchmarking"}),"\n",(0,t.jsxs)(n.p,{children:["To gauge Constellation's applicability to well-known applications, we performed a ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/overview/performance/application",children:"benchmark of HashiCorp Vault"})," running on Constellation.\nThe results were then compared to deployments on the managed Kubernetes offerings from different cloud providers, providing a tangible perspective on Constellation's performance in actual deployment scenarios."]})]})}function m(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>a,x:()=>s});var r=o(96540);const t={},i=r.createContext(t);function a(e){const n=r.useContext(i);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/0a66f7ff.c540accf.js b/pr-preview/pr-4027/assets/js/0a66f7ff.c540accf.js deleted file mode 100644 index 8818bd945..000000000 --- a/pr-preview/pr-4027/assets/js/0a66f7ff.c540accf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7335],{20672:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>a});const i=JSON.parse('{"id":"workflows/config","title":"Configure your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","source":"@site/versioned_docs/version-2.22/workflows/config.md","sourceDirName":"workflows","slug":"/workflows/config","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/config","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/workflows/config.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Verify the CLI","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli"},"next":{"title":"Create your cluster","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/create"}}');var t=s(74848),r=s(28453);const o={},l="Configure your cluster",c={},a=[{value:"Creating the configuration file",id:"creating-the-configuration-file",level:2},{value:"Choosing a VM type",id:"choosing-a-vm-type",level:2},{value:"Creating additional node groups",id:"creating-additional-node-groups",level:2},{value:"Choosing a Kubernetes version",id:"choosing-a-kubernetes-version",level:2},{value:"Creating an IAM configuration",id:"creating-an-iam-configuration",level:2},{value:"Deleting an IAM configuration",id:"deleting-an-iam-configuration",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components},{AsciinemaWidget:s,Details:i,TabItem:o,Tabs:l}=n;return s||u("AsciinemaWidget",!0),i||u("Details",!0),o||u("TabItem",!0),l||u("Tabs",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"configure-your-cluster",children:"Configure your cluster"})}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsx)(n.p,{children:"This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details."})}),"\n",(0,t.jsx)(s,{src:"/constellation/assets/configure-cluster.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.p,{children:"Before you can create your cluster, you need to configure the identity and access management (IAM) for your cloud service provider (CSP) and choose machine types for the nodes."}),"\n",(0,t.jsx)(n.h2,{id:"creating-the-configuration-file",children:"Creating the configuration file"}),"\n",(0,t.jsx)(n.p,{children:"You can generate a configuration file for your CSP by using the following CLI command:"}),"\n",(0,t.jsxs)(l,{groupId:"csp",children:[(0,t.jsx)(o,{value:"aws",label:"AWS",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation config generate aws\n"})})}),(0,t.jsx)(o,{value:"azure",label:"Azure",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation config generate azure\n"})})}),(0,t.jsx)(o,{value:"gcp",label:"GCP",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation config generate gcp\n"})})}),(0,t.jsx)(o,{value:"stackit",label:"STACKIT",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation config generate stackit\n"})})})]}),"\n",(0,t.jsxs)(n.p,{children:["This creates the file ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," in the current directory."]}),"\n",(0,t.jsx)(n.h2,{id:"choosing-a-vm-type",children:"Choosing a VM type"}),"\n",(0,t.jsx)(n.p,{children:"Constellation supports the following VM types:"}),"\n",(0,t.jsxs)(l,{groupId:"csp",children:[(0,t.jsxs)(o,{value:"aws",label:"AWS",children:[(0,t.jsxs)(n.p,{children:["By default, Constellation uses ",(0,t.jsx)(n.code,{children:"m6a.xlarge"})," VMs (4 vCPUs, 16 GB RAM) to create your cluster.\nOptionally, you can switch to a different VM type by modifying ",(0,t.jsx)(n.code,{children:"instanceType"})," in the configuration file.\nIf you are using the default attestation variant ",(0,t.jsx)(n.code,{children:"awsSEVSNP"}),", you can use the instance types described in ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/snp-requirements.html",children:"AWS's AMD SEV-SNP docs"}),".\nPlease mind the region restrictions mentioned in the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps#create-a-cluster",children:"Getting started"})," section."]}),(0,t.jsxs)(n.p,{children:["If you are using the attestation variant ",(0,t.jsx)(n.code,{children:"awsNitroTPM"}),", you can choose any of the ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enable-nitrotpm-prerequisites.html",children:"nitroTPM-enabled instance types"}),"."]}),(0,t.jsxs)(n.p,{children:["The Constellation CLI can also print the supported instance types with: ",(0,t.jsx)(n.code,{children:"constellation config instance-types"}),"."]})]}),(0,t.jsxs)(o,{value:"azure",label:"Azure",children:[(0,t.jsxs)(n.p,{children:["By default, Constellation uses ",(0,t.jsx)(n.code,{children:"Standard_DC4as_v5"})," CVMs (4 vCPUs, 16 GB RAM) to create your cluster. Optionally, you can switch to a different VM type by modifying ",(0,t.jsx)(n.code,{children:"instanceType"})," in the configuration file. For CVMs, any VM type with a minimum of 4 vCPUs from the ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/dcasv5-dcadsv5-series",children:"DCasv5 & DCadsv5"})," or ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/ecasv5-ecadsv5-series",children:"ECasv5 & ECadsv5"})," families is supported."]}),(0,t.jsxs)(n.p,{children:["You can also run ",(0,t.jsx)(n.code,{children:"constellation config instance-types"})," to get the list of all supported options."]})]}),(0,t.jsx)(o,{value:"gcp",label:"GCP",children:(0,t.jsxs)(n.p,{children:["By default, Constellation uses ",(0,t.jsx)(n.code,{children:"n2d-standard-4"})," VMs (4 vCPUs, 16 GB RAM) to create your cluster. Optionally, you can switch to a different VM type by modifying ",(0,t.jsx)(n.code,{children:"instanceType"})," in the configuration file. Supported are all machines with a minimum of 4 vCPUs from the ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/compute-optimized-machines#c2d_machine_types",children:"C2D"})," or ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/general-purpose-machines#n2d_machines",children:"N2D"})," family. You can run ",(0,t.jsx)(n.code,{children:"constellation config instance-types"})," to get the list of all supported options."]})}),(0,t.jsxs)(o,{value:"stackit",label:"STACKIT",children:[(0,t.jsxs)(n.p,{children:["By default, Constellation uses ",(0,t.jsx)(n.code,{children:"m1a.4cd"})," VMs (4 vCPUs, 30 GB RAM) to create your cluster.\nOptionally, you can switch to a different VM type by modifying ",(0,t.jsx)(n.code,{children:"instanceType"})," in the configuration file."]}),(0,t.jsx)(n.p,{children:"The following instance types are known to be supported:"}),(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"name"}),(0,t.jsx)(n.th,{children:"vCPUs"}),(0,t.jsx)(n.th,{children:"GB RAM"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"m1a.4cd"}),(0,t.jsx)(n.td,{children:"4"}),(0,t.jsx)(n.td,{children:"30"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"m1a.8cd"}),(0,t.jsx)(n.td,{children:"8"}),(0,t.jsx)(n.td,{children:"60"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"m1a.16cd"}),(0,t.jsx)(n.td,{children:"16"}),(0,t.jsx)(n.td,{children:"120"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"m1a.30cd"}),(0,t.jsx)(n.td,{children:"30"}),(0,t.jsx)(n.td,{children:"230"})]})]})]}),(0,t.jsxs)(n.p,{children:["You can choose any of the SEV-enabled instance types. You can find a list of all supported instance types in the ",(0,t.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/virtual-machine-flavors-75137231.html",children:"STACKIT documentation"}),"."]}),(0,t.jsxs)(n.p,{children:["The Constellation CLI can also print the supported instance types with: ",(0,t.jsx)(n.code,{children:"constellation config instance-types"}),"."]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Fill the desired VM type into the ",(0,t.jsx)(n.code,{children:"instanceType"})," fields in the ",(0,t.jsx)(n.code,{children:"constellation-conf.yml"})," file."]}),"\n",(0,t.jsx)(n.h2,{id:"creating-additional-node-groups",children:"Creating additional node groups"}),"\n",(0,t.jsxs)(n.p,{children:["By default, Constellation creates the node groups ",(0,t.jsx)(n.code,{children:"control_plane_default"})," and ",(0,t.jsx)(n.code,{children:"worker_default"})," for control-plane nodes and workers, respectively.\nIf you require additional control-plane or worker groups with different instance types, zone placements, or disk sizes, you can add additional node groups to the ",(0,t.jsx)(n.code,{children:"constellation-conf.yml"})," file.\nEach node group can be scaled individually."]}),"\n",(0,t.jsx)(n.p,{children:"Consider the following example for AWS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"nodeGroups:\n control_plane_default:\n role: control-plane\n instanceType: c6a.xlarge\n stateDiskSizeGB: 30\n stateDiskType: gp3\n zone: eu-west-1c\n initialCount: 3\n worker_default:\n role: worker\n instanceType: c6a.xlarge\n stateDiskSizeGB: 30\n stateDiskType: gp3\n zone: eu-west-1c\n initialCount: 2\n high_cpu:\n role: worker\n instanceType: c6a.24xlarge\n stateDiskSizeGB: 128\n stateDiskType: gp3\n zone: eu-west-1c\n initialCount: 1\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This configuration creates an additional node group ",(0,t.jsx)(n.code,{children:"high_cpu"})," with a larger instance type and disk."]}),"\n",(0,t.jsxs)(n.p,{children:["You can use the field ",(0,t.jsx)(n.code,{children:"zone"})," to specify what availability zone nodes of the group are placed in.\nOn Azure, this field is empty by default and nodes are automatically spread across availability zones.\nSTACKIT currently offers SEV-enabled CPUs in the ",(0,t.jsx)(n.code,{children:"eu01-1"}),", ",(0,t.jsx)(n.code,{children:"eu01-2"}),", and ",(0,t.jsx)(n.code,{children:"eu01-3"})," zones.\nConsult the documentation of your cloud provider for more information:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://aws.amazon.com/about-aws/global-infrastructure/regions_az/",children:"AWS"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/explore/global-infrastructure/availability-zones",children:"Azure"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones",children:"GCP"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/regions-and-availability-zones-75137212.html",children:"STACKIT"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"choosing-a-kubernetes-version",children:"Choosing a Kubernetes version"}),"\n",(0,t.jsxs)(n.p,{children:["To learn which Kubernetes versions can be installed with your current CLI, you can run ",(0,t.jsx)(n.code,{children:"constellation config kubernetes-versions"}),".\nSee also Constellation's ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/versions#kubernetes-support-policy",children:"Kubernetes support policy"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"creating-an-iam-configuration",children:"Creating an IAM configuration"}),"\n",(0,t.jsxs)(n.p,{children:["You can create an IAM configuration for your cluster automatically using the ",(0,t.jsx)(n.code,{children:"constellation iam create"})," command.\nIf you already have a Constellation configuration file, you can add the ",(0,t.jsx)(n.code,{children:"--update-config"})," flag to the command. This writes the needed IAM fields into your configuration. Furthermore, the flag updates the zone/region of the configuration if it hasn't been set yet."]}),"\n",(0,t.jsxs)(l,{groupId:"csp",children:[(0,t.jsxs)(o,{value:"aws",label:"AWS",children:[(0,t.jsxs)(n.p,{children:["You must be authenticated with the ",(0,t.jsx)(n.a,{href:"https://aws.amazon.com/en/cli/",children:"AWS CLI"})," in the shell session with a user that has the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/install#set-up-cloud-credentials",children:"required permissions for IAM creation"}),"."]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation iam create aws --zone=us-east-2a --prefix=constellTest\n"})}),(0,t.jsxs)(n.p,{children:["This command creates IAM configuration for the AWS zone ",(0,t.jsx)(n.code,{children:"us-east-2a"})," using the prefix ",(0,t.jsx)(n.code,{children:"constellTest"})," for all named resources being created."]}),(0,t.jsx)(n.p,{children:"Constellation OS images are currently replicated to the following regions:"}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-central-1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-west-1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-west-3"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"us-east-2"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"ap-south-1"})}),"\n"]}),(0,t.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+AWS+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),(0,t.jsxs)(n.p,{children:["You can find a list of all ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions",children:"regions in AWS's documentation"}),"."]}),(0,t.jsxs)(n.p,{children:["Paste the output into the corresponding fields of the ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," file."]})]}),(0,t.jsxs)(o,{value:"azure",label:"Azure",children:[(0,t.jsxs)(n.p,{children:["You must be authenticated with the ",(0,t.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/cli/azure/install-azure-cli",children:"Azure CLI"})," in the shell session with a user that has the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/install#set-up-cloud-credentials",children:"required permissions for IAM creation"}),"."]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation iam create azure --subscriptionID 00000000-0000-0000-0000-000000000000 --region=westus --resourceGroup=constellTest --servicePrincipal=spTest\n"})}),(0,t.jsxs)(n.p,{children:["This command creates IAM configuration on the Azure region ",(0,t.jsx)(n.code,{children:"westus"})," creating a new resource group ",(0,t.jsx)(n.code,{children:"constellTest"})," and a new service principal ",(0,t.jsx)(n.code,{children:"spTest"}),"."]}),(0,t.jsx)(n.p,{children:"CVMs are available in several Azure regions. Constellation OS images are currently replicated to the following:"}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"germanywestcentral"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"westus"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eastus"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"northeurope"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"westeurope"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"southeastasia"})}),"\n"]}),(0,t.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+Azure+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),(0,t.jsxs)(n.p,{children:["You can find a list of all ",(0,t.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/global-infrastructure/services/?products=virtual-machines®ions=all",children:"regions in Azure's documentation"}),"."]}),(0,t.jsxs)(n.p,{children:["Paste the output into the corresponding fields of the ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," file."]})]}),(0,t.jsxs)(o,{value:"gcp",label:"GCP",children:[(0,t.jsxs)(n.p,{children:["You must be authenticated with the ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/sdk/gcloud",children:"GCP CLI"})," in the shell session with a user that has the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/install#set-up-cloud-credentials",children:"required permissions for IAM creation"}),"."]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation iam create gcp --projectID=yourproject-12345 --zone=europe-west3-a --prefix=constell-test\n"})}),(0,t.jsxs)(n.p,{children:["This command creates IAM configuration in the GCP project ",(0,t.jsx)(n.code,{children:"yourproject-12345"})," on the GCP zone ",(0,t.jsx)(n.code,{children:"europe-west3-a"})," creating a new service account ",(0,t.jsx)(n.code,{children:"constell-test"}),"."]}),(0,t.jsxs)(n.p,{children:["Note that only regions offering CVMs of the ",(0,t.jsx)(n.code,{children:"C2D"})," or ",(0,t.jsx)(n.code,{children:"N2D"})," series are supported. You can find a ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones#available",children:"list of all regions in Google's documentation"}),", which you can filter by machine type ",(0,t.jsx)(n.code,{children:"N2D"}),"."]}),(0,t.jsxs)(n.p,{children:["Paste the output into the corresponding fields of the ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," file."]})]}),(0,t.jsx)(o,{value:"stackit",label:"STACKIT",children:(0,t.jsxs)(n.p,{children:["STACKIT requires manual creation and configuration of service accounts. Look at the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps",children:"first steps"})," for more information."]})})]}),"\n",(0,t.jsxs)(i,{children:[(0,t.jsx)("summary",{children:"Alternatively, you can manually create the IAM configuration on your CSP."}),(0,t.jsx)(n.p,{children:"The following describes the configuration fields and how you obtain the required information or create the required resources."}),(0,t.jsxs)(l,{groupId:"csp",children:[(0,t.jsx)(o,{value:"aws",label:"AWS",children:(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"region"}),": The name of your chosen AWS data center region, e.g., ",(0,t.jsx)(n.code,{children:"us-east-2"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Constellation OS images are currently replicated to the following regions:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-central-1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-west-1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-west-3"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"us-east-2"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"ap-south-1"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+AWS+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find a list of all ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions",children:"regions in AWS's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"zone"}),": The name of your chosen AWS data center availability zone, e.g., ",(0,t.jsx)(n.code,{children:"us-east-2a"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Learn more about ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-availability-zones",children:"availability zones in AWS's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"iamProfileControlPlane"}),": The name of an IAM instance profile attached to all control-plane nodes."]}),"\n",(0,t.jsxs)(n.p,{children:["You can create the resource with ",(0,t.jsx)(n.a,{href:"https://www.terraform.io/",children:"Terraform"}),". For that, use the ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/tree/release/v2.2/hack/terraform/aws/iam",children:"provided Terraform script"})," to generate the necessary profile. The profile name will be provided as Terraform output value: ",(0,t.jsx)(n.code,{children:"control_plane_instance_profile_name"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Alternatively, you can create the AWS profile with a tool of your choice. Use the JSON policy in ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/tree/release/v2.2/hack/terraform/aws/iam/main.tf",children:"main.tf"})," in the resource ",(0,t.jsx)(n.code,{children:"aws_iam_policy.control_plane_policy"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"iamProfileWorkerNodes"}),": The name of an IAM instance profile attached to all worker nodes."]}),"\n",(0,t.jsxs)(n.p,{children:["You can create the resource with ",(0,t.jsx)(n.a,{href:"https://www.terraform.io/",children:"Terraform"}),". For that, use the ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/tree/release/v2.2/hack/terraform/aws/iam",children:"provided Terraform script"})," to generate the necessary profile. The profile name will be provided as Terraform output value: ",(0,t.jsx)(n.code,{children:"worker_nodes_instance_profile_name"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Alternatively, you can create the AWS profile with a tool of your choice. Use the JSON policy in ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/tree/release/v2.2/hack/terraform/aws/iam/main.tf",children:"main.tf"})," in the resource ",(0,t.jsx)(n.code,{children:"aws_iam_policy.worker_node_policy"}),"."]}),"\n"]}),"\n"]})}),(0,t.jsx)(o,{value:"azure",label:"Azure",children:(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"subscription"}),": The UUID of your Azure subscription, e.g., ",(0,t.jsx)(n.code,{children:"8b8bd01f-efd9-4113-9bd1-c82137c32da7"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can view your subscription UUID via ",(0,t.jsx)(n.code,{children:"az account show"})," and read the ",(0,t.jsx)(n.code,{children:"id"})," field. For more information refer to ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id#find-your-azure-subscription",children:"Azure's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"tenant"}),": The UUID of your Azure tenant, e.g., ",(0,t.jsx)(n.code,{children:"3400e5a2-8fe2-492a-886c-38cb66170f25"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can view your tenant UUID via ",(0,t.jsx)(n.code,{children:"az account show"})," and read the ",(0,t.jsx)(n.code,{children:"tenant"})," field. For more information refer to ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id#find-your-azure-ad-tenant",children:"Azure's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"location"}),": The Azure datacenter location you want to deploy your cluster in, e.g., ",(0,t.jsx)(n.code,{children:"westus"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"CVMs are available in several Azure regions. Constellation OS images are currently replicated to the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"germanywestcentral"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"westus"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eastus"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"northeurope"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"westeurope"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"southeastasia"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+Azure+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find a list of all ",(0,t.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/global-infrastructure/services/?products=virtual-machines®ions=all",children:"regions in Azure's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"resourceGroup"}),": ",(0,t.jsx)(n.a,{href:"https://learn.microsoft.com/azure/azure-resource-manager/management/manage-resource-groups-portal",children:"Create a new resource group in Azure"})," for your Constellation cluster. Set this configuration field to the name of the created resource group."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"userAssignedIdentity"}),": ",(0,t.jsx)(n.a,{href:"https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/how-manage-user-assigned-managed-identities",children:"Create a new managed identity in Azure"}),". You should create the identity in a different resource group as all resources within the cluster resource group will be deleted on cluster termination."]}),"\n",(0,t.jsxs)(n.p,{children:["Add three role assignments to the identity: ",(0,t.jsx)(n.code,{children:"Owner"}),", ",(0,t.jsx)(n.code,{children:"Virtual Machine Contributor"}),", and ",(0,t.jsx)(n.code,{children:"Application Insights Component Contributor"}),". The ",(0,t.jsx)(n.code,{children:"scope"})," of all three should refer to the previously created cluster resource group."]}),"\n",(0,t.jsxs)(n.p,{children:["Set the configuration value to the full ID of the created identity, e.g., ",(0,t.jsx)(n.code,{children:"/subscriptions/8b8bd01f-efd9-4113-9bd1-c82137c32da7/resourcegroups/constellation-identity/providers/Microsoft.ManagedIdentity/userAssignedIdentities/constellation-identity"}),". You can get it by opening the ",(0,t.jsx)(n.code,{children:"JSON View"})," from the ",(0,t.jsx)(n.code,{children:"Overview"})," section of the identity."]}),"\n",(0,t.jsxs)(n.p,{children:["The user-assigned identity is used by instances of the cluster to access other cloud resources.\nFor more information about managed identities refer to ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-manage-user-assigned-managed-identities",children:"Azure's documentation"}),"."]}),"\n"]}),"\n"]})}),(0,t.jsx)(o,{value:"gcp",label:"GCP",children:(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"project"}),": The ID of your GCP project, e.g., ",(0,t.jsx)(n.code,{children:"constellation-129857"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find it on the ",(0,t.jsx)(n.a,{href:"https://console.cloud.google.com/welcome",children:"welcome screen of your GCP project"}),". For more information refer to ",(0,t.jsx)(n.a,{href:"https://support.google.com/googleapi/answer/7014113",children:"Google's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"region"}),": The GCP region you want to deploy your cluster in, e.g., ",(0,t.jsx)(n.code,{children:"us-central1"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find a ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones#available",children:"list of all regions in Google's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"zone"}),": The GCP zone you want to deploy your cluster in, e.g., ",(0,t.jsx)(n.code,{children:"us-central1-a"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find a ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones#available",children:"list of all zones in Google's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"serviceAccountKeyPath"}),": To configure this, you need to create a GCP ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/iam/docs/service-accounts",children:"service account"})," with the following permissions:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Compute Instance Admin (v1) (roles/compute.instanceAdmin.v1)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Compute Network Admin (roles/compute.networkAdmin)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Compute Security Admin (roles/compute.securityAdmin)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Compute Storage Admin (roles/compute.storageAdmin)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Service Account User (roles/iam.serviceAccountUser)"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Afterward, create and download a new JSON key for this service account. Place the downloaded file in your Constellation workspace, and set the config parameter to the filename, e.g., ",(0,t.jsx)(n.code,{children:"constellation-129857-15343dba46cb.json"}),"."]}),"\n"]}),"\n"]})}),(0,t.jsx)(o,{value:"stackit",label:"STACKIT",children:(0,t.jsxs)(n.p,{children:["STACKIT requires manual creation and configuration of service accounts. Look at the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps",children:"first steps"})," for more information."]})})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Now that you've configured your CSP, you can ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/create",children:"create your cluster"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"deleting-an-iam-configuration",children:"Deleting an IAM configuration"}),"\n",(0,t.jsx)(n.p,{children:"You can keep a created IAM configuration and reuse it for new clusters. Alternatively, you can also delete it if you don't want to use it anymore."}),"\n",(0,t.jsxs)(n.p,{children:["Delete the IAM configuration by executing the following command in the same directory where you executed ",(0,t.jsx)(n.code,{children:"constellation iam create"})," (the directory that contains ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/reference/terraform",children:(0,t.jsx)(n.code,{children:"constellation-iam-terraform"})})," as a subdirectory):"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation iam destroy\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsxs)(n.p,{children:["For Azure, deleting the IAM configuration by executing ",(0,t.jsx)(n.code,{children:"constellation iam destroy"})," will delete the whole resource group created by ",(0,t.jsx)(n.code,{children:"constellation iam create"}),".\nThis also includes any additional resources in the resource group that weren't created by Constellation."]})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}function u(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>l});var i=s(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/0b1ac180.5fc2d03f.js b/pr-preview/pr-4027/assets/js/0b1ac180.5fc2d03f.js deleted file mode 100644 index 4fcf69a94..000000000 --- a/pr-preview/pr-4027/assets/js/0b1ac180.5fc2d03f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5863],{13336:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"architecture/overview","title":"Overview","description":"Constellation is a cloud-based confidential orchestration platform.","source":"@site/docs/architecture/overview.md","sourceDirName":"architecture","slug":"/architecture/overview","permalink":"/constellation/pr-preview/pr-4027/next/architecture/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/architecture/overview.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Architecture","permalink":"/constellation/pr-preview/pr-4027/next/category/architecture"},"next":{"title":"Cluster orchestration","permalink":"/constellation/pr-preview/pr-4027/next/architecture/orchestration"}}');var n=r(74848),o=r(28453);const a={},s="Overview",c={},l=[{value:"About orchestration and updates",id:"about-orchestration-and-updates",level:2},{value:"About microservices and attestation",id:"about-microservices-and-attestation",level:2},{value:"About node images and verified boot",id:"about-node-images-and-verified-boot",level:2},{value:"About key management and cryptographic primitives",id:"about-key-management-and-cryptographic-primitives",level:2},{value:"About observability",id:"about-observability",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,n.jsxs)(t.p,{children:["Constellation is a cloud-based confidential orchestration platform.\nThe foundation of Constellation is Kubernetes and therefore shares the same technology stack and architecture principles.\nTo learn more about Constellation and Kubernetes, see ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/overview/product",children:"product overview"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"about-orchestration-and-updates",children:"About orchestration and updates"}),"\n",(0,n.jsxs)(t.p,{children:["As a cluster administrator, you can use the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/orchestration",children:"Constellation CLI"})," to install and deploy a cluster.\nUpdates are provided in accordance with the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/versions",children:"support policy"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"about-microservices-and-attestation",children:"About microservices and attestation"}),"\n",(0,n.jsxs)(t.p,{children:["Constellation manages the nodes and network in your cluster. All nodes are bootstrapped by the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#bootstrapper",children:(0,n.jsx)(t.em,{children:"Bootstrapper"})}),". They're verified and authenticated by the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#joinservice",children:(0,n.jsx)(t.em,{children:"JoinService"})})," before being added to the cluster and the network. Finally, the entire cluster can be verified via the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#verificationservice",children:(0,n.jsx)(t.em,{children:"VerificationService"})})," using ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/attestation",children:"remote attestation"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"about-node-images-and-verified-boot",children:"About node images and verified boot"}),"\n",(0,n.jsxs)(t.p,{children:["Constellation comes with operating system images for Kubernetes control-plane and worker nodes.\nThey're highly optimized for running containerized workloads and specifically prepared for running inside confidential VMs.\nYou can learn more about ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/images",children:"the images"})," and how verified boot ensures their integrity during boot and beyond."]}),"\n",(0,n.jsx)(t.h2,{id:"about-key-management-and-cryptographic-primitives",children:"About key management and cryptographic primitives"}),"\n",(0,n.jsxs)(t.p,{children:["Encryption of data at-rest, in-transit, and in-use is the fundamental building block for confidential computing and Constellation. Learn more about the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys",children:"keys and cryptographic primitives"})," used in Constellation, ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage",children:"encrypted persistent storage"}),", and ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/networking",children:"network encryption"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"about-observability",children:"About observability"}),"\n",(0,n.jsxs)(t.p,{children:["Observability in Kubernetes refers to the capability to troubleshoot issues using telemetry signals such as logs, metrics, and traces.\nIn the realm of Confidential Computing, it's crucial that observability aligns with confidentiality, necessitating careful implementation.\nLearn more about the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/observability",children:"observability capabilities in Constellation"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>a,x:()=>s});var i=r(96540);const n={},o=i.createContext(n);function a(e){const t=i.useContext(o);return i.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/0b338d1c.6cb8df9a.js b/pr-preview/pr-4027/assets/js/0b338d1c.6cb8df9a.js deleted file mode 100644 index 65ead177a..000000000 --- a/pr-preview/pr-4027/assets/js/0b338d1c.6cb8df9a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8043],{28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var r=n(96540);const i={},s=r.createContext(i);function o(e){const t=r.useContext(s);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(s.Provider,{value:t},e.children)}},63398:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"overview/confidential-kubernetes","title":"Confidential Kubernetes","description":"We use the term Confidential Kubernetes to refer to the concept of using confidential-computing technology to shield entire Kubernetes clusters from the infrastructure. The three defining properties of this concept are:","source":"@site/versioned_docs/version-2.22/overview/confidential-kubernetes.md","sourceDirName":"overview","slug":"/overview/confidential-kubernetes","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/confidential-kubernetes","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/overview/confidential-kubernetes.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Basics","permalink":"/constellation/pr-preview/pr-4027/2.22/category/basics"},"next":{"title":"Security benefits","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/security-benefits"}}');var i=n(74848),s=n(28453);const o={},a="Confidential Kubernetes",l={},c=[{value:"Constellation security features",id:"constellation-security-features",level:2},{value:"Comparison: Managed Kubernetes with CVMs",id:"comparison-managed-kubernetes-with-cvms",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"confidential-kubernetes",children:"Confidential Kubernetes"})}),"\n",(0,i.jsxs)(t.p,{children:["We use the term ",(0,i.jsx)(t.em,{children:"Confidential Kubernetes"})," to refer to the concept of using confidential-computing technology to shield entire Kubernetes clusters from the infrastructure. The three defining properties of this concept are:"]}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Workload shielding"}),": the confidentiality and integrity of all workload-related data and code are enforced."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Control plane shielding"}),": the confidentiality and integrity of the cluster's control plane, state, and workload configuration are enforced."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Attestation and verifiability"}),": the two properties above can be verified remotely based on hardware-rooted cryptographic certificates."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Each of the above properties is equally important. Only with all three in conjunction, an entire cluster can be shielded without gaps."}),"\n",(0,i.jsx)(t.h2,{id:"constellation-security-features",children:"Constellation security features"}),"\n",(0,i.jsx)(t.p,{children:"Constellation implements the Confidential Kubernetes concept with the following security features."}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Runtime encryption"}),": Constellation runs all Kubernetes nodes inside Confidential VMs (CVMs). This gives runtime encryption for the entire cluster."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Network and storage encryption"}),": Constellation augments this with transparent encryption of the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/networking",children:"network"}),", ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage",children:"persistent storage"}),", and other managed storage like ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage#encrypted-s3-object-storage",children:"AWS S3"}),". Thus, workloads and control plane are truly end-to-end encrypted: at rest, in transit, and at runtime."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Transparent key management"}),": Constellation manages the corresponding ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys",children:"cryptographic keys"})," inside CVMs."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Node attestation and verification"}),": Constellation verifies the integrity of each new CVM-based node using ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation",children:"remote attestation"}),'. Only "good" nodes receive the cryptographic keys required to access the network and storage of a cluster.']}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Confidential computing-optimized images"}),': A node is "good" if it\'s running a signed Constellation ',(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/images",children:"node image"})," inside a CVM and is in the expected state. (Node images are hardware-measured during boot. The measurements are reflected in the attestation statements that are produced by nodes and verified by Constellation.)"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:'"Whole cluster" attestation'}),": Towards the DevOps engineer, Constellation provides a single hardware-rooted certificate from which all of the above can be verified."]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["With the above, Constellation wraps an entire cluster into one coherent and verifiable ",(0,i.jsx)(t.em,{children:"confidential context"}),". The concept is depicted in the following."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Confidential Kubernetes",src:n(64759).A+"",width:"3767",height:"1902"})}),"\n",(0,i.jsx)(t.h2,{id:"comparison-managed-kubernetes-with-cvms",children:"Comparison: Managed Kubernetes with CVMs"}),"\n",(0,i.jsxs)(t.p,{children:["In comparison, managed Kubernetes with CVMs, as it's for example offered in ",(0,i.jsx)(t.a,{href:"https://azure.microsoft.com/en-us/services/kubernetes-service/",children:"AKS"})," and ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/kubernetes-engine",children:"GKE"}),", only provides runtime encryption for certain worker nodes. Here, each worker node is a separate (and typically unverified) confidential context. This only provides limited security benefits as it only prevents direct access to a worker node's memory. The large majority of potential attacks through the infrastructure remain unaffected. This includes attacks through the control plane, access to external key management, and the corruption of worker node images. This leaves many problems unsolved. For instance, ",(0,i.jsx)(t.em,{children:"Node A"})," has no means to verify if ",(0,i.jsx)(t.em,{children:"Node B"}),' is "good" and if it\'s OK to share data with it. Consequently, this approach leaves a large attack surface, as is depicted in the following.']}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Concept: Managed Kubernetes plus CVMs",src:n(76161).A+"",width:"3767",height:"1902"})}),"\n",(0,i.jsx)(t.p,{children:"The following table highlights the key differences in terms of features."}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{}),(0,i.jsx)(t.th,{children:"Managed Kubernetes with CVMs"}),(0,i.jsx)(t.th,{children:"Confidential Kubernetes (Constellation\u2728)"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Runtime encryption"}),(0,i.jsx)(t.td,{children:"Partial (data plane only)"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Node image verification"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Full cluster attestation"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Transparent network encryption"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Transparent storage encryption"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Confidential key management"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Cloud agnostic / multi-cloud"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},64759:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/concept-constellation-f869032711a972295d5ddce42c37995c.svg"},76161:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/concept-managed-33482ac199f949182872dc32d69bd3bc.svg"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/0b615bd7.252ed8ba.js b/pr-preview/pr-4027/assets/js/0b615bd7.252ed8ba.js deleted file mode 100644 index bd52d6a26..000000000 --- a/pr-preview/pr-4027/assets/js/0b615bd7.252ed8ba.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7320],{28453:(e,n,r)=>{r.d(n,{R:()=>d,x:()=>l});var i=r(96540);const s={},o=i.createContext(s);function d(e){const n=i.useContext(o);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),i.createElement(o.Provider,{value:n},e.children)}},57723:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>d,metadata:()=>i,toc:()=>t});const i=JSON.parse('{"id":"reference/migration","title":"Migrations","description":"This document describes breaking changes and migrations between Constellation releases.","source":"@site/versioned_docs/version-2.23/reference/migration.md","sourceDirName":"reference","slug":"/reference/migration","permalink":"/constellation/pr-preview/pr-4027/2.23/reference/migration","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/reference/migration.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"CLI","permalink":"/constellation/pr-preview/pr-4027/2.23/reference/cli"},"next":{"title":"Terraform usage","permalink":"/constellation/pr-preview/pr-4027/2.23/reference/terraform"}}');var s=r(74848),o=r(28453);const d={},l="Migrations",c={},t=[{value:"Migrations to v2.23.0",id:"migrations-to-v2230",level:2},{value:"GCP",id:"gcp",level:3},{value:"Migrations to v2.19.1",id:"migrations-to-v2191",level:2},{value:"Azure",id:"azure",level:3},{value:"Migrating from CLI versions before 2.21.1",id:"migrating-from-cli-versions-before-2211",level:2},{value:"AWS",id:"aws",level:3},{value:"Migrating from CLI versions before 2.19.0",id:"migrating-from-cli-versions-before-2190",level:2},{value:"Azure",id:"azure-1",level:3},{value:"Migrating from CLI versions before 2.18.0",id:"migrating-from-cli-versions-before-2180",level:2},{value:"Migrating from CLI versions before 2.10",id:"migrating-from-cli-versions-before-210",level:2},{value:"Migrating from CLI versions before 2.9",id:"migrating-from-cli-versions-before-29",level:2},{value:"Migrating from CLI versions before 2.8",id:"migrating-from-cli-versions-before-28",level:2},{value:"Migrating from CLI versions before 2.3",id:"migrating-from-cli-versions-before-23",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components},{Details:r}=n;return r||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"migrations",children:"Migrations"})}),"\n",(0,s.jsxs)(n.p,{children:["This document describes breaking changes and migrations between Constellation releases.\nUse ",(0,s.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/reference/cli#constellation-config-migrate",children:(0,s.jsx)(n.code,{children:"constellation config migrate"})})," to automatically update an old config file to a new format."]}),"\n",(0,s.jsx)(n.h2,{id:"migrations-to-v2230",children:"Migrations to v2.23.0"}),"\n",(0,s.jsx)(n.h3,{id:"gcp",children:"GCP"}),"\n",(0,s.jsxs)(n.p,{children:["GCP will require the additional permission ",(0,s.jsx)(n.code,{children:"compute.forwardingRules.list"}),". Please update your IAM roles using ",(0,s.jsx)(n.code,{children:"constellation iam upgrade apply"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"migrations-to-v2191",children:"Migrations to v2.19.1"}),"\n",(0,s.jsx)(n.h3,{id:"azure",children:"Azure"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"During the upgrade, security rules are migrated and the old ones need to be cleaned up manually by the user. The below script shows how to delete them through the Azure CLI:"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'#!/usr/bin/env bash\nname="" # the name provided in the config\nuid="" # the cluster id can be retrieved via `yq \'.infrastructure.uid\' constellation-state.yaml`\nresource_group="" # the RG can be retrieved via `yq \'.provider.azure.resourceGroup\' constellation-conf.yaml`\n\nrules=(\n "kubernetes"\n "bootstrapper"\n "verify"\n "recovery"\n "join"\n "debugd"\n "konnectivity"\n)\n\nfor rule in "${rules[@]}"; do\n echo "Deleting rule: ${rule}"\n az network nsg rule delete \\\n --resource-group "${resource_group}" \\\n --nsg-name "${name}-${uid}" \\\n --name "${rule}"\ndone\n\necho "All specified rules have been deleted."\n'})}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-2211",children:"Migrating from CLI versions before 2.21.1"}),"\n",(0,s.jsx)(n.h3,{id:"aws",children:"AWS"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["AWS clusters that use ",(0,s.jsx)(n.code,{children:"LoadBalancer"})," resources require more IAM permissions. Please upgrade your IAM roles using ",(0,s.jsx)(n.code,{children:"constellation iam upgrade apply"}),". This will show necessary changes and apply them, if desired."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-2190",children:"Migrating from CLI versions before 2.19.0"}),"\n",(0,s.jsx)(n.h3,{id:"azure-1",children:"Azure"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["To allow seamless upgrades on Azure when Kubernetes services of type ",(0,s.jsx)(n.code,{children:"LoadBalancer"})," are deployed, the target\nload balancer in which the ",(0,s.jsx)(n.code,{children:"cloud-controller-manager"})," creates load balancing rules was changed. Instead of using the load balancer\ncreated and maintained by the CLI's Terraform code, the ",(0,s.jsx)(n.code,{children:"cloud-controller-manager"})," now creates its own load balancer in Azure.\nIf your Constellation has services of type ",(0,s.jsx)(n.code,{children:"LoadBalancer"}),", please remove them before the upgrade and re-apply them\nafterward."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-2180",children:"Migrating from CLI versions before 2.18.0"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"provider.azure.appClientID"})," and ",(0,s.jsx)(n.code,{children:"provider.azure.appClientSecret"})," fields are no longer supported and should be removed."]}),"\n",(0,s.jsxs)(n.li,{children:["To keep using an existing UAMI, add the ",(0,s.jsx)(n.code,{children:"Owner"})," permission with the scope of your ",(0,s.jsx)(n.code,{children:"resourceGroup"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["Otherwise, simply ",(0,s.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/config#creating-an-iam-configuration",children:"create new Constellation IAM credentials"})," and use the created UAMI."]}),"\n",(0,s.jsxs)(n.li,{children:["To migrate the authentication for an existing cluster on Azure to an UAMI with the necessary permissions:","\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Remove the ",(0,s.jsx)(n.code,{children:"aadClientId"})," and ",(0,s.jsx)(n.code,{children:"aadClientSecret"})," from the azureconfig secret."]}),"\n",(0,s.jsxs)(n.li,{children:["Set ",(0,s.jsx)(n.code,{children:"useManagedIdentityExtension"})," to ",(0,s.jsx)(n.code,{children:"true"})," and use the ",(0,s.jsx)(n.code,{children:"userAssignedIdentity"})," from the Constellation config for the value of ",(0,s.jsx)(n.code,{children:"userAssignedIdentityID"}),"."]}),"\n",(0,s.jsx)(n.li,{children:"Restart the CSI driver, cloud controller manager, cluster autoscaler, and Constellation operator pods."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-210",children:"Migrating from CLI versions before 2.10"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["AWS cluster upgrades require additional IAM permissions for the newly introduced ",(0,s.jsx)(n.code,{children:"aws-load-balancer-controller"}),". Please upgrade your IAM roles using ",(0,s.jsx)(n.code,{children:"iam upgrade apply"}),". This will show necessary changes and apply them, if desired."]}),"\n",(0,s.jsxs)(n.li,{children:["The global ",(0,s.jsx)(n.code,{children:"nodeGroups"})," field was added."]}),"\n",(0,s.jsxs)(n.li,{children:["The fields ",(0,s.jsx)(n.code,{children:"instanceType"}),", ",(0,s.jsx)(n.code,{children:"stateDiskSizeGB"}),", and ",(0,s.jsx)(n.code,{children:"stateDiskType"})," for each cloud provider are now part of the configuration of individual node groups."]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"constellation create"})," command no longer uses the flags ",(0,s.jsx)(n.code,{children:"--control-plane-count"})," and ",(0,s.jsx)(n.code,{children:"--worker-count"}),". Instead, the initial node count is configured per node group in the ",(0,s.jsx)(n.code,{children:"nodeGroups"})," field."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-29",children:"Migrating from CLI versions before 2.9"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"provider.azure.appClientID"})," and ",(0,s.jsx)(n.code,{children:"provider.azure.clientSecretValue"})," fields were removed to enforce migration to managed identity authentication"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-28",children:"Migrating from CLI versions before 2.8"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"measurements"})," field for each cloud service provider was replaced with a global ",(0,s.jsx)(n.code,{children:"attestation"})," field."]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"confidentialVM"}),", ",(0,s.jsx)(n.code,{children:"idKeyDigest"}),", and ",(0,s.jsx)(n.code,{children:"enforceIdKeyDigest"})," fields for the Azure cloud service provider were removed in favor of using the global ",(0,s.jsx)(n.code,{children:"attestation"})," field."]}),"\n",(0,s.jsxs)(n.li,{children:["The optional global field ",(0,s.jsx)(n.code,{children:"attestationVariant"})," was replaced by the now required ",(0,s.jsx)(n.code,{children:"attestation"})," field."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-23",children:"Migrating from CLI versions before 2.3"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"sshUsers"})," field was deprecated in v2.2 and has been removed from the configuration in v2.3.\nAs an alternative for SSH, check the workflow section ",(0,s.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/troubleshooting#node-shell-access",children:"Connect to nodes"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"image"})," field for each cloud service provider has been replaced with a global ",(0,s.jsx)(n.code,{children:"image"})," field. Use the following mapping to migrate your configuration:"]}),"\n",(0,s.jsxs)(r,{children:[(0,s.jsx)("summary",{children:"Show all"}),(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"CSP"}),(0,s.jsx)(n.th,{children:"old image"}),(0,s.jsx)(n.th,{children:"new image"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-06b8cbf4837a0a57c"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-02e96dc04a9e438cd"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-028ead928a9034b2f"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-032ac10dd8d8266e3"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-032e0d57cc4395088"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-053c3e49e19b96bdd"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-0e27ebcefc38f648b"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-098cd37f66523b7c3"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-04a87d302e2509aad"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.2"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.2"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.1"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.1"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.1.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.1.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.1.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.1.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.0.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.0.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.0.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.0.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"GCP"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"projects/constellation-images/global/images/constellation-v2-2-2"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"GCP"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"projects/constellation-images/global/images/constellation-v2-2-1"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"GCP"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"projects/constellation-images/global/images/constellation-v2-2-0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"GCP"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"projects/constellation-images/global/images/constellation-v2-1-0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.1.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"GCP"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"projects/constellation-images/global/images/constellation-v2-0-0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.0.0"})})]})]})]})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"enforcedMeasurements"})," field has been removed and merged with the ",(0,s.jsx)(n.code,{children:"measurements"})," field."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["To migrate your config containing a new image (",(0,s.jsx)(n.code,{children:"v2.3"})," or greater), remove the old ",(0,s.jsx)(n.code,{children:"measurements"})," and ",(0,s.jsx)(n.code,{children:"enforcedMeasurements"})," entries from your config and run ",(0,s.jsx)(n.code,{children:"constellation fetch-measurements"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["To migrate your config containing an image older than ",(0,s.jsx)(n.code,{children:"v2.3"}),", remove the ",(0,s.jsx)(n.code,{children:"enforcedMeasurements"})," entry and replace the entries in ",(0,s.jsx)(n.code,{children:"measurements"})," as shown in the example below:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-diff",children:"measurements:\n- 0: DzXCFGCNk8em5ornNZtKi+Wg6Z7qkQfs5CfE3qTkOc8=\n+ 0:\n+ expected: DzXCFGCNk8em5ornNZtKi+Wg6Z7qkQfs5CfE3qTkOc8=\n+ warnOnly: true\n- 8: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\n+ 8:\n+ expected: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\n+ warnOnly: false\n-enforcedMeasurements:\n- - 8\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/0bfd0c91.25d5f4dd.js b/pr-preview/pr-4027/assets/js/0bfd0c91.25d5f4dd.js deleted file mode 100644 index d1669b04f..000000000 --- a/pr-preview/pr-4027/assets/js/0bfd0c91.25d5f4dd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[470],{28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>l});var n=r(96540);const o={},s=n.createContext(o);function i(e){const t=n.useContext(s);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(s.Provider,{value:t},e.children)}},30778:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>l,default:()=>d,frontMatter:()=>i,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"workflows/create","title":"Create your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","source":"@site/versioned_docs/version-2.24/workflows/create.md","sourceDirName":"workflows","slug":"/workflows/create","permalink":"/constellation/pr-preview/pr-4027/workflows/create","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/workflows/create.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Configure your cluster","permalink":"/constellation/pr-preview/pr-4027/workflows/config"},"next":{"title":"Scale your cluster","permalink":"/constellation/pr-preview/pr-4027/workflows/scale"}}');var o=r(74848),s=r(28453);const i={},l="Create your cluster",a={},c=[{value:"Troubleshooting",id:"troubleshooting",level:3}];function u(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h3:"h3",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.R)(),...e.components},{AsciinemaWidget:r,TabItem:n,Tabs:i}=t;return r||h("AsciinemaWidget",!0),n||h("TabItem",!0),i||h("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"create-your-cluster",children:"Create your cluster"})}),"\n",(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsx)(t.p,{children:"This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details."})}),"\n",(0,o.jsx)(r,{src:"/constellation/assets/create-cluster.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,o.jsx)(t.hr,{}),"\n",(0,o.jsx)(t.p,{children:"Creating your cluster happens through multiple phases.\nThe most significant ones are:"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsx)(t.li,{children:"Creating the necessary resources in your cloud environment"}),"\n",(0,o.jsx)(t.li,{children:"Bootstrapping the Constellation cluster and setting up a connection"}),"\n",(0,o.jsx)(t.li,{children:"Installing the necessary Kubernetes components"}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.code,{children:"constellation apply"})," handles all this in a single command.\nYou can use the ",(0,o.jsx)(t.code,{children:"--skip-phases"})," flag to skip specific phases of the process.\nFor example, if you created the infrastructure manually, you can skip the cloud resource creation phase."]}),"\n",(0,o.jsxs)(t.p,{children:["See the ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/orchestration",children:"architecture"})," section for details on the inner workings of this process."]}),"\n",(0,o.jsx)(t.admonition,{type:"tip",children:(0,o.jsxs)(t.p,{children:["If you don't have a cloud subscription, you can also set up a ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/getting-started/first-steps-local",children:"local Constellation cluster using virtualization"})," for testing."]})}),"\n",(0,o.jsxs)(t.p,{children:["Before you create the cluster, make sure to have a ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/config",children:"valid configuration file"}),"."]}),"\n",(0,o.jsxs)(i,{groupId:"usage",children:[(0,o.jsxs)(n,{value:"cli",label:"CLI",children:[(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation apply\n"})}),(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.code,{children:"apply"})," stores the state of your cluster's cloud resources in a ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/orchestration#cluster-creation-process",children:(0,o.jsx)(t.code,{children:"constellation-terraform"})})," directory in your workspace."]})]}),(0,o.jsxs)(n,{value:"self-managed",label:"Self-managed",children:[(0,o.jsx)(t.p,{children:"Self-managed infrastructure allows for more flexibility in the setup, by separating the infrastructure setup from the Constellation cluster management.\nThis provides flexibility in DevOps and can meet potential regulatory requirements.\nIt's recommended to use Terraform for infrastructure management, but you can use any tool of your choice."}),(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsxs)(t.p,{children:["When using Terraform, you can use the ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/terraform-provider",children:"Constellation Terraform provider"})," to manage the entire Constellation cluster lifecycle."]})}),(0,o.jsxs)(t.p,{children:["You can refer to the Terraform files for the selected CSP from the ",(0,o.jsx)(t.a,{href:"https://github.com/edgelesssys/constellation/tree/main/terraform/infrastructure",children:"Constellation GitHub repository"})," for a minimum Constellation cluster configuration. From this base, you can now add, edit, or substitute resources per your own requirements with the infrastructure\nmanagement tooling of your choice. You need to keep the essential functionality of the base configuration in order for your cluster to function correctly."]}),(0,o.jsxs)(t.admonition,{type:"info",children:[(0,o.jsxs)(t.p,{children:["On Azure, a manual update to the MAA provider's policy is necessary.\nYou can apply the update with the following command after creating the infrastructure, with ",(0,o.jsx)(t.code,{children:""})," being the URL of the MAA provider (i.e., ",(0,o.jsx)(t.code,{children:"$(terraform output attestation_url | jq -r)"}),", when using the minimal Terraform configuration)."]}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation maa-patch \n"})})]}),(0,o.jsxs)(t.p,{children:["Make sure all necessary resources are created, e.g., through checking your CSP's portal and retrieve the necessary values, aligned with the outputs (specified in ",(0,o.jsx)(t.code,{children:"outputs.tf"}),") of the base configuration."]}),(0,o.jsxs)(t.p,{children:["Fill these outputs into the corresponding fields of the ",(0,o.jsx)(t.code,{children:"Infrastructure"})," block inside the ",(0,o.jsx)(t.code,{children:"constellation-state.yaml"})," file. For example, fill the IP or DNS name your cluster can be reached at into the ",(0,o.jsx)(t.code,{children:".Infrastructure.ClusterEndpoint"})," field."]}),(0,o.jsx)(t.p,{children:"With the required cloud resources set up, continue with initializing your cluster."}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation apply --skip-phases=infrastructure\n"})})]})]}),"\n",(0,o.jsxs)(t.p,{children:["Finally, configure ",(0,o.jsx)(t.code,{children:"kubectl"})," for your cluster:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:'export KUBECONFIG="$PWD/constellation-admin.conf"\n'})}),"\n",(0,o.jsx)(t.p,{children:"\ud83c\udfc1 That's it. You've successfully created a Constellation cluster."}),"\n",(0,o.jsx)(t.h3,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,o.jsxs)(t.p,{children:["In case ",(0,o.jsx)(t.code,{children:"apply"})," fails, the CLI collects logs from the bootstrapping instance and stores them inside ",(0,o.jsx)(t.code,{children:"constellation-cluster.log"}),"."]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}function h(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/0c363123.1f1d7162.js b/pr-preview/pr-4027/assets/js/0c363123.1f1d7162.js deleted file mode 100644 index 289ec2e39..000000000 --- a/pr-preview/pr-4027/assets/js/0c363123.1f1d7162.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7934],{28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>a});var n=s(96540);const o={},i=n.createContext(o);function r(e){const t=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(i.Provider,{value:t},e.children)}},47380:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"workflows/s3proxy","title":"Install s3proxy","description":"Constellation includes a transparent client-side encryption proxy for AWS S3 and compatible stores.","source":"@site/versioned_docs/version-2.24/workflows/s3proxy.md","sourceDirName":"workflows","slug":"/workflows/s3proxy","permalink":"/constellation/pr-preview/pr-4027/workflows/s3proxy","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/workflows/s3proxy.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Install cert-manager","permalink":"/constellation/pr-preview/pr-4027/workflows/cert-manager"},"next":{"title":"Terminate your cluster","permalink":"/constellation/pr-preview/pr-4027/workflows/terminate"}}');var o=s(74848),i=s(28453);const r={},a="Install s3proxy",l={},c=[{value:"Limitations",id:"limitations",level:2},{value:"Deployment",id:"deployment",level:2},{value:"Technical details",id:"technical-details",level:2},{value:"Encryption",id:"encryption",level:3},{value:"Traffic interception",id:"traffic-interception",level:3}];function p(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"install-s3proxy",children:"Install s3proxy"})}),"\n",(0,o.jsxs)(t.p,{children:["Constellation includes a transparent client-side encryption proxy for ",(0,o.jsx)(t.a,{href:"https://aws.amazon.com/de/s3/",children:"AWS S3"})," and compatible stores.\ns3proxy encrypts objects before sending them to S3 and automatically decrypts them on retrieval, without requiring changes to your application.\nWith s3proxy, you can use S3 for storage in a confidential way without having to trust the storage provider."]}),"\n",(0,o.jsx)(t.h2,{id:"limitations",children:"Limitations"}),"\n",(0,o.jsx)(t.p,{children:"Currently, s3proxy has the following limitations:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["Only ",(0,o.jsx)(t.code,{children:"PutObject"})," and ",(0,o.jsx)(t.code,{children:"GetObject"})," requests are encrypted/decrypted by s3proxy.\nBy default, s3proxy will block requests that may expose unencrypted data to S3 (e.g. UploadPart).\nThe ",(0,o.jsx)(t.code,{children:"allow-multipart"})," flag disables request blocking for evaluation purposes."]}),"\n",(0,o.jsxs)(t.li,{children:["Using the ",(0,o.jsx)(t.a,{href:"https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html#API_GetObject_RequestSyntax",children:"Range"})," header on ",(0,o.jsx)(t.code,{children:"GetObject"})," is currently not supported and will result in an error."]}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:["These limitations will be removed with future iterations of s3proxy.\nIf you want to use s3proxy but these limitations stop you from doing so, consider ",(0,o.jsx)(t.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&projects=&template=feature_request.yml",children:"opening an issue"}),"."]}),"\n",(0,o.jsx)(t.h2,{id:"deployment",children:"Deployment"}),"\n",(0,o.jsx)(t.p,{children:"You can add the s3proxy to your Constellation cluster as follows:"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsxs)(t.li,{children:["Add the Edgeless Systems chart repository:","\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"helm repo add edgeless https://helm.edgeless.systems/stable\nhelm repo update\n"})}),"\n"]}),"\n",(0,o.jsx)(t.li,{children:"Set ACCESS_KEY and ACCESS_SECRET to valid credentials you want s3proxy to use to interact with S3."}),"\n",(0,o.jsxs)(t.li,{children:["Deploy s3proxy:","\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:'helm install s3proxy edgeless/s3proxy --set awsAccessKeyID="$ACCESS_KEY" --set awsSecretAccessKey="$ACCESS_SECRET"\n'})}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:["If you want to run a demo application, check out the ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/getting-started/examples/filestash-s3proxy",children:"Filestash with s3proxy"})," example."]}),"\n",(0,o.jsx)(t.h2,{id:"technical-details",children:"Technical details"}),"\n",(0,o.jsx)(t.h3,{id:"encryption",children:"Encryption"}),"\n",(0,o.jsxs)(t.p,{children:["s3proxy relies on Google's ",(0,o.jsx)(t.a,{href:"https://developers.google.com/tink",children:"Tink Cryptographic Library"})," to implement cryptographic operations securely.\nThe used cryptographic primitives are ",(0,o.jsx)(t.a,{href:"https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf",children:"NIST SP 800 38f"})," for key wrapping and ",(0,o.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Advanced_Encryption_Standard",children:"AES"}),"-",(0,o.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Galois/counter_(GCM)",children:"GCM"})," with 256 bit keys for data encryption."]}),"\n",(0,o.jsxs)(t.p,{children:["s3proxy uses ",(0,o.jsx)(t.a,{href:"https://cloud.google.com/kms/docs/envelope-encryption",children:"envelope encryption"})," to encrypt objects.\nThis means s3proxy uses a key encryption key (KEK) issued by the ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#keyservice",children:"KeyService"})," to encrypt data encryption keys (DEKs).\nEach S3 object is encrypted with its own DEK.\nThe encrypted DEK is then saved as metadata of the encrypted object.\nThis enables key rotation of the KEK without re-encrypting the data in S3.\nThe approach also allows access to objects from different locations, as long as each location has access to the KEK."]}),"\n",(0,o.jsx)(t.h3,{id:"traffic-interception",children:"Traffic interception"}),"\n",(0,o.jsx)(t.p,{children:"To use s3proxy, you have to redirect your outbound S3 traffic to s3proxy.\nThis can either be done by modifying your client application or by changing the deployment of your application."}),"\n",(0,o.jsxs)(t.p,{children:["The necessary deployment modifications are to add DNS redirection and a trusted TLS certificate to the client's trust store.\nDNS redirection can be defined for each pod, allowing you to use s3proxy for one application without changing other applications in the same cluster.\nAdding a trusted TLS certificate is necessary as clients communicate with s3proxy via HTTPS.\nTo have your client application trust s3proxy's TLS certificate, the certificate has to be added to the client's certificate trust store.\nThe ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/getting-started/examples/filestash-s3proxy",children:"Filestash with s3proxy"})," example shows how to do this."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/0c605e3b.36848557.js b/pr-preview/pr-4027/assets/js/0c605e3b.36848557.js deleted file mode 100644 index a0c6cab1f..000000000 --- a/pr-preview/pr-4027/assets/js/0c605e3b.36848557.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2307],{28453:(e,t,r)=>{r.d(t,{R:()=>a,x:()=>s});var i=r(96540);const n={},o=i.createContext(n);function a(e){const t=i.useContext(o);return i.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),i.createElement(o.Provider,{value:t},e.children)}},43888:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"architecture/overview","title":"Overview","description":"Constellation is a cloud-based confidential orchestration platform.","source":"@site/versioned_docs/version-2.23/architecture/overview.md","sourceDirName":"architecture","slug":"/architecture/overview","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/architecture/overview.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Architecture","permalink":"/constellation/pr-preview/pr-4027/2.23/category/architecture"},"next":{"title":"Cluster orchestration","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/orchestration"}}');var n=r(74848),o=r(28453);const a={},s="Overview",c={},l=[{value:"About orchestration and updates",id:"about-orchestration-and-updates",level:2},{value:"About microservices and attestation",id:"about-microservices-and-attestation",level:2},{value:"About node images and verified boot",id:"about-node-images-and-verified-boot",level:2},{value:"About key management and cryptographic primitives",id:"about-key-management-and-cryptographic-primitives",level:2},{value:"About observability",id:"about-observability",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,n.jsxs)(t.p,{children:["Constellation is a cloud-based confidential orchestration platform.\nThe foundation of Constellation is Kubernetes and therefore shares the same technology stack and architecture principles.\nTo learn more about Constellation and Kubernetes, see ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/overview/product",children:"product overview"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"about-orchestration-and-updates",children:"About orchestration and updates"}),"\n",(0,n.jsxs)(t.p,{children:["As a cluster administrator, you can use the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/orchestration",children:"Constellation CLI"})," to install and deploy a cluster.\nUpdates are provided in accordance with the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/versions",children:"support policy"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"about-microservices-and-attestation",children:"About microservices and attestation"}),"\n",(0,n.jsxs)(t.p,{children:["Constellation manages the nodes and network in your cluster. All nodes are bootstrapped by the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#bootstrapper",children:(0,n.jsx)(t.em,{children:"Bootstrapper"})}),". They're verified and authenticated by the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#joinservice",children:(0,n.jsx)(t.em,{children:"JoinService"})})," before being added to the cluster and the network. Finally, the entire cluster can be verified via the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#verificationservice",children:(0,n.jsx)(t.em,{children:"VerificationService"})})," using ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation",children:"remote attestation"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"about-node-images-and-verified-boot",children:"About node images and verified boot"}),"\n",(0,n.jsxs)(t.p,{children:["Constellation comes with operating system images for Kubernetes control-plane and worker nodes.\nThey're highly optimized for running containerized workloads and specifically prepared for running inside confidential VMs.\nYou can learn more about ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/images",children:"the images"})," and how verified boot ensures their integrity during boot and beyond."]}),"\n",(0,n.jsx)(t.h2,{id:"about-key-management-and-cryptographic-primitives",children:"About key management and cryptographic primitives"}),"\n",(0,n.jsxs)(t.p,{children:["Encryption of data at-rest, in-transit, and in-use is the fundamental building block for confidential computing and Constellation. Learn more about the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys",children:"keys and cryptographic primitives"})," used in Constellation, ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage",children:"encrypted persistent storage"}),", and ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/networking",children:"network encryption"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"about-observability",children:"About observability"}),"\n",(0,n.jsxs)(t.p,{children:["Observability in Kubernetes refers to the capability to troubleshoot issues using telemetry signals such as logs, metrics, and traces.\nIn the realm of Confidential Computing, it's crucial that observability aligns with confidentiality, necessitating careful implementation.\nLearn more about the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/observability",children:"observability capabilities in Constellation"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/0cee1087.21f6746b.js b/pr-preview/pr-4027/assets/js/0cee1087.21f6746b.js deleted file mode 100644 index 687075f7b..000000000 --- a/pr-preview/pr-4027/assets/js/0cee1087.21f6746b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1086],{7688:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"workflows/upgrade","title":"Upgrade your cluster","description":"Constellation provides an easy way to upgrade all components of your cluster, without disrupting its availability.","source":"@site/versioned_docs/version-2.24/workflows/upgrade.md","sourceDirName":"workflows","slug":"/workflows/upgrade","permalink":"/constellation/pr-preview/pr-4027/workflows/upgrade","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/workflows/upgrade.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Scale your cluster","permalink":"/constellation/pr-preview/pr-4027/workflows/scale"},"next":{"title":"Expose a service","permalink":"/constellation/pr-preview/pr-4027/workflows/lb"}}');var t=r(74848),o=r(28453);const i={},a="Upgrade your cluster",l={},c=[{value:"Update the CLI",id:"update-the-cli",level:2},{value:"Migrate the configuration",id:"migrate-the-configuration",level:2},{value:"Check for upgrades",id:"check-for-upgrades",level:2},{value:"Apply the upgrade",id:"apply-the-upgrade",level:2},{value:"Check the status",id:"check-the-status",level:2},{value:"Apply further upgrades",id:"apply-further-upgrades",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"upgrade-your-cluster",children:"Upgrade your cluster"})}),"\n",(0,t.jsxs)(n.p,{children:["Constellation provides an easy way to upgrade all components of your cluster, without disrupting its availability.\nSpecifically, you can upgrade the Kubernetes version, the nodes' image, and the Constellation microservices.\nYou configure the desired versions in your local Constellation configuration and trigger upgrades with the ",(0,t.jsx)(n.code,{children:"apply"})," command.\nTo learn about available versions you use the ",(0,t.jsx)(n.code,{children:"upgrade check"})," command.\nWhich versions are available depends on the CLI version you are using."]}),"\n",(0,t.jsx)(n.h2,{id:"update-the-cli",children:"Update the CLI"}),"\n",(0,t.jsx)(n.p,{children:"Each CLI comes with a set of supported microservice and Kubernetes versions.\nMost importantly, a given CLI version can only upgrade a cluster of the previous minor version, but not older ones.\nThis means that you have to upgrade your CLI and cluster one minor version at a time."}),"\n",(0,t.jsx)(n.p,{children:"For example, if you are currently on CLI version v2.6 and the latest version is v2.8, you should"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"upgrade the CLI to v2.7,"}),"\n",(0,t.jsx)(n.li,{children:"upgrade the cluster to v2.7,"}),"\n",(0,t.jsx)(n.li,{children:"and only then continue upgrading the CLI (and the cluster) to v2.8 after."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Also note that if your current Kubernetes version isn't supported by the next CLI version, use your current CLI to upgrade to a newer Kubernetes version first."}),"\n",(0,t.jsxs)(n.p,{children:["To learn which Kubernetes versions are supported by a particular CLI, run ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/reference/cli#constellation-config-kubernetes-versions",children:"constellation config kubernetes-versions"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"migrate-the-configuration",children:"Migrate the configuration"}),"\n",(0,t.jsxs)(n.p,{children:["The Constellation configuration file is located in the file ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," in your workspace.\nRefer to the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/reference/migration",children:"migration reference"})," to check if you need to update fields in your configuration file.\nUse ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/reference/cli#constellation-config-migrate",children:(0,t.jsx)(n.code,{children:"constellation config migrate"})})," to automatically update an old config file to a new format."]}),"\n",(0,t.jsx)(n.h2,{id:"check-for-upgrades",children:"Check for upgrades"}),"\n",(0,t.jsx)(n.p,{children:"To learn which versions the current CLI can upgrade to and what's installed in your cluster, run:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# Show possible upgrades\nconstellation upgrade check\n\n# Show possible upgrades and write them to config file\nconstellation upgrade check --update-config\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You can either enter the reported target versions into your config manually or run the above command with the ",(0,t.jsx)(n.code,{children:"--update-config"})," flag.\nWhen using this flag, the ",(0,t.jsx)(n.code,{children:"kubernetesVersion"}),", ",(0,t.jsx)(n.code,{children:"image"}),", ",(0,t.jsx)(n.code,{children:"microserviceVersion"}),", and ",(0,t.jsx)(n.code,{children:"attestation"})," fields are overwritten with the smallest available upgrade."]}),"\n",(0,t.jsx)(n.h2,{id:"apply-the-upgrade",children:"Apply the upgrade"}),"\n",(0,t.jsx)(n.p,{children:"Once you updated your config with the desired versions, you can trigger the upgrade with this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation apply\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Microservice upgrades will be finished within a few minutes, depending on the cluster size.\nIf you are interested, you can monitor pods restarting in the ",(0,t.jsx)(n.code,{children:"kube-system"})," namespace with your tool of choice."]}),"\n",(0,t.jsx)(n.p,{children:"Image and Kubernetes upgrades take longer.\nFor each node in your cluster, a new node has to be created and joined.\nThe process usually takes up to ten minutes per node."}),"\n",(0,t.jsxs)(n.p,{children:["When applying an upgrade, the Helm charts for the upgrade as well as backup files of Constellation-managed Custom Resource Definitions, Custom Resources, and Terraform state are created.\nYou can use the Terraform state backup to restore previous resources in case an upgrade misconfigured or erroneously deleted a resource.\nYou can use the Custom Resource (Definition) backup files to restore Custom Resources and Definitions manually (e.g., via ",(0,t.jsx)(n.code,{children:"kubectl apply"}),") if the automatic migration of those resources fails.\nYou can use the Helm charts to manually apply upgrades to the Kubernetes resources, should an upgrade fail."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["For advanced users: the upgrade consists of several phases that can be individually skipped through the ",(0,t.jsx)(n.code,{children:"--skip-phases"})," flag.\nThe phases are ",(0,t.jsx)(n.code,{children:"infrastracture"})," for the cloud resource management through Terraform, ",(0,t.jsx)(n.code,{children:"helm"})," for the chart management of the microservices, ",(0,t.jsx)(n.code,{children:"image"})," for OS image upgrades, and ",(0,t.jsx)(n.code,{children:"k8s"})," for Kubernetes version upgrades."]})}),"\n",(0,t.jsx)(n.h2,{id:"check-the-status",children:"Check the status"}),"\n",(0,t.jsxs)(n.p,{children:["Upgrades are asynchronous operations.\nAfter you run ",(0,t.jsx)(n.code,{children:"apply"}),", it will take a while until the upgrade has completed.\nTo understand if an upgrade is finished, you can run:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation status\n"})}),"\n",(0,t.jsx)(n.p,{children:"This command displays the following information:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The installed services and their versions"}),"\n",(0,t.jsx)(n.li,{children:"The image and Kubernetes version the cluster is expecting on each node"}),"\n",(0,t.jsx)(n.li,{children:"How many nodes are up to date"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here's an example output:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell-session",children:"Target versions:\n Image: v2.6.0\n Kubernetes: v1.25.8\nService versions:\n Cilium: v1.12.1\n cert-manager: v1.10.0\n constellation-operators: v2.6.0\n constellation-services: v2.6.0\nCluster status: Some node versions are out of date\n Image: 23/25\n Kubernetes: 25/25\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This output indicates that the cluster is running Kubernetes version ",(0,t.jsx)(n.code,{children:"1.25.8"}),", and all nodes have the appropriate binaries installed.\n23 out of 25 nodes have already upgraded to the targeted image version of ",(0,t.jsx)(n.code,{children:"2.6.0"}),", while two are still in progress."]}),"\n",(0,t.jsx)(n.h2,{id:"apply-further-upgrades",children:"Apply further upgrades"}),"\n",(0,t.jsxs)(n.p,{children:["After the upgrade is finished, you can run ",(0,t.jsx)(n.code,{children:"constellation upgrade check"})," again to see if there are more upgrades available. If so, repeat the process."]})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>a});var s=r(96540);const t={},o=s.createContext(t);function i(e){const n=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/0e384e19.e9a6d738.js b/pr-preview/pr-4027/assets/js/0e384e19.e9a6d738.js deleted file mode 100644 index fac220a0f..000000000 --- a/pr-preview/pr-4027/assets/js/0e384e19.e9a6d738.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3976],{28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var s=t(96540);const i={},o=s.createContext(i);function r(e){const n=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:n},e.children)}},60420:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/concept-d3a09a16a8e7ca14a7bdf274ea7bce40.svg"},73700:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"intro","title":"Introduction","description":"Constellation is no longer actively maintained by Edgeless Systems.","source":"@site/docs/intro.md","sourceDirName":".","slug":"/","permalink":"/constellation/pr-preview/pr-4027/next/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/intro.md","tags":[],"version":"current","frontMatter":{"slug":"/","id":"intro"},"sidebar":"docs","next":{"title":"Basics","permalink":"/constellation/pr-preview/pr-4027/next/category/basics"}}');var i=t(74848),o=t(28453);const r={slug:"/",id:"intro"},a="Introduction",l={},c=[{value:"Goals",id:"goals",level:2},{value:"Use cases",id:"use-cases",level:2},{value:"Next steps",id:"next-steps",level:2}];function d(e){const n={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"introduction",children:"Introduction"})}),"\n",(0,i.jsxs)(n.admonition,{title:"Maintenance Notice",type:"caution",children:[(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Constellation is no longer actively maintained by Edgeless Systems."})}),(0,i.jsx)(n.p,{children:"This project is no longer receiving updates or support from Edgeless Systems. The repository and documentation remain available for archival purposes and community use."})]}),"\n",(0,i.jsx)(n.p,{children:"Welcome to the documentation of Constellation! Constellation is a Kubernetes engine that aims to provide the best possible data security."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Constellation concept",src:t(60420).A+"",width:"1776",height:"746"})}),"\n",(0,i.jsxs)(n.p,{children:["Constellation shields your entire Kubernetes cluster from the underlying cloud infrastructure. Everything inside is always encrypted, including at runtime in memory. For this, Constellation leverages a technology called ",(0,i.jsx)(n.em,{children:"confidential computing"})," and more specifically Confidential VMs."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["See the \ud83d\udcc4",(0,i.jsx)(n.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"})," for more information on confidential computing."]})}),"\n",(0,i.jsx)(n.h2,{id:"goals",children:"Goals"}),"\n",(0,i.jsx)(n.p,{children:"From a security perspective, Constellation is designed to keep all data always encrypted and to prevent any access from the underlying (cloud) infrastructure. This includes access from datacenter employees, privileged cloud admins, and attackers coming through the infrastructure. Such attackers could be malicious co-tenants escalating their privileges or hackers who managed to compromise a cloud server."}),"\n",(0,i.jsx)(n.p,{children:"From a DevOps perspective, Constellation is designed to work just like what you would expect from a modern Kubernetes engine."}),"\n",(0,i.jsx)(n.h2,{id:"use-cases",children:"Use cases"}),"\n",(0,i.jsxs)(n.p,{children:["Constellation provides unique security ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/overview/confidential-kubernetes",children:"features"})," and ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/overview/security-benefits",children:"benefits"}),". The core use cases are:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Increasing the overall security of your clusters"}),"\n",(0,i.jsx)(n.li,{children:"Increasing the trustworthiness of your SaaS offerings"}),"\n",(0,i.jsx)(n.li,{children:"Moving sensitive workloads from on-prem to the cloud"}),"\n",(0,i.jsx)(n.li,{children:"Meeting regulatory requirements"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,i.jsxs)(n.p,{children:["You can learn more about the concept of Confidential Kubernetes, features, security benefits, and performance of Constellation in the ",(0,i.jsx)(n.em,{children:"Basics"})," section. To jump right into the action head to ",(0,i.jsx)(n.em,{children:"Getting started"}),"."]})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/0eb3e611.16087d6f.js b/pr-preview/pr-4027/assets/js/0eb3e611.16087d6f.js deleted file mode 100644 index c414146d6..000000000 --- a/pr-preview/pr-4027/assets/js/0eb3e611.16087d6f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9912],{28453:(e,s,r)=>{r.d(s,{R:()=>o,x:()=>a});var n=r(96540);const t={},i=n.createContext(t);function o(e){const s=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),n.createElement(i.Provider,{value:s},e.children)}},99434:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>c,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"reference/slsa","title":"Supply chain levels for software artifacts (SLSA) adoption","description":"Supply chain Levels for Software Artifacts, or SLSA (salsa) is a framework for improving and grading a project\'s build system and engineering processes. SLSA focuses on security improvements for source code storage as well as build system definition, execution, and observation. SLSA is structured in four levels. This page describes the adoption of SLSA for Constellation.","source":"@site/versioned_docs/version-2.23/reference/slsa.md","sourceDirName":"reference","slug":"/reference/slsa","permalink":"/constellation/pr-preview/pr-4027/2.23/reference/slsa","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/reference/slsa.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Terraform usage","permalink":"/constellation/pr-preview/pr-4027/2.23/reference/terraform"}}');var t=r(74848),i=r(28453);const o={},a="Supply chain levels for software artifacts (SLSA) adoption",l={},d=[{value:"Level 1 - Adopted",id:"level-1---adopted",level:2},{value:"Level 2 - Adopted",id:"level-2---adopted",level:2},{value:"Level 3 - Adopted",id:"level-3---adopted",level:2},{value:"Level 4 - In Progress",id:"level-4---in-progress",level:2}];function h(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"supply-chain-levels-for-software-artifacts-slsa-adoption",children:"Supply chain levels for software artifacts (SLSA) adoption"})}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"https://slsa.dev/",children:"Supply chain Levels for Software Artifacts, or SLSA (salsa)"})," is a framework for improving and grading a project's build system and engineering processes. SLSA focuses on security improvements for source code storage as well as build system definition, execution, and observation. SLSA is structured in ",(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/levels",children:"four levels"}),". This page describes the adoption of SLSA for Constellation."]}),"\n",(0,t.jsx)(s.admonition,{type:"info",children:(0,t.jsx)(s.p,{children:"SLSA is still in alpha status. The presented levels and their requirements might change in the future. We will adopt any changes into our engineering processes, as they get defined."})}),"\n",(0,t.jsx)(s.h2,{id:"level-1---adopted",children:"Level 1 - Adopted"}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#scripted-build",children:"Build - Scripted"})})}),"\n",(0,t.jsxs)(s.p,{children:["All build steps are automated via ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/tree/main/bazel/ci",children:"Bazel"})," and ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/tree/main/.github",children:"GitHub Actions"}),"."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#available",children:"Provenance - Available"})})}),"\n",(0,t.jsxs)(s.p,{children:["Provenance for the CLI is generated using the ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator",children:"slsa-github-generator"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"level-2---adopted",children:"Level 2 - Adopted"}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#version-controlled",children:"Source - Version Controlled"})})}),"\n",(0,t.jsx)(s.p,{children:"Constellation is hosted on GitHub using git."}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#build-service",children:"Build - Build Service"})})}),"\n",(0,t.jsxs)(s.p,{children:["All builds are carried out by ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/tree/main/.github",children:"GitHub Actions"}),"."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#authenticated",children:"Provenance - Authenticated"})})}),"\n",(0,t.jsxs)(s.p,{children:["Provenance for the CLI is signed using the ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator",children:"slsa-github-generator"}),". Learn ",(0,t.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cli",children:"how to verify the CLI"})," using the signed provenance, before using it for the first time."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#service-generated",children:"Provenance - Service Generated"})})}),"\n",(0,t.jsxs)(s.p,{children:["Provenance for the CLI is generated using the ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator",children:"slsa-github-generator"})," in GitHub Actions."]}),"\n",(0,t.jsx)(s.h2,{id:"level-3---adopted",children:"Level 3 - Adopted"}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#verified-history",children:"Source - Verified History"})})}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys",children:"Edgeless Systems"})," GitHub organization ",(0,t.jsx)(s.a,{href:"https://docs.github.com/en/organizations/keeping-your-organization-secure/managing-two-factor-authentication-for-your-organization/requiring-two-factor-authentication-in-your-organization",children:"requires two-factor authentication"})," for all members."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#retained-indefinitely",children:"Source - Retained Indefinitely"})})}),"\n",(0,t.jsxs)(s.p,{children:["Since we use GitHub to host the repository, an external person can't modify or delete the history. Before a pull request can be merged, an explicit approval from an ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys",children:"Edgeless Systems"})," team member is required."]}),"\n",(0,t.jsxs)(s.p,{children:["The same holds true for changes proposed by team members. Each change to ",(0,t.jsx)(s.code,{children:"main"})," needs to be proposed via a pull request and requires at least one approval."]}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys",children:"Edgeless Systems"})," GitHub organization admins control these settings and are able to make changes to the repository's history should legal requirements necessitate it. These changes require two-party approval following the obliterate policy."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#build-as-code",children:"Build - Build as Code"})})}),"\n",(0,t.jsxs)(s.p,{children:["All build files for Constellation are stored in ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/tree/main/.github",children:"the same repository"}),"."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#ephemeral-environment",children:"Build - Ephemeral Environment"})})}),"\n",(0,t.jsxs)(s.p,{children:["All GitHub Action workflows are executed on ",(0,t.jsx)(s.a,{href:"https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners",children:"GitHub-hosted runners"}),". These runners are only available during workflow."]}),"\n",(0,t.jsxs)(s.p,{children:["We currently don't use ",(0,t.jsx)(s.a,{href:"https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners",children:"self-hosted runners"}),"."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#isolated",children:"Build - Isolated"})})}),"\n",(0,t.jsx)(s.p,{children:"As outlined in the previous section, we use GitHub-hosted runners, which provide a new, isolated and ephemeral environment for each build."}),"\n",(0,t.jsxs)(s.p,{children:["Additionally, the ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator#generation-of-provenance",children:"SLSA GitHub generator"})," itself is run in an isolated workflow with the artifact hash as defined inputs."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#non-falsifiable",children:"Provenance - Non-falsifiable"})})}),"\n",(0,t.jsxs)(s.p,{children:["As outlined by ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator",children:"SLSA GitHub generator"})," it already fulfills the non-falsifiable requirements for SLSA Level 3. The generated provenance is signed using ",(0,t.jsx)(s.a,{href:"https://sigstore.dev/",children:"sigstore"})," with an OIDC based proof of identity."]}),"\n",(0,t.jsx)(s.h2,{id:"level-4---in-progress",children:"Level 4 - In Progress"}),"\n",(0,t.jsx)(s.p,{children:"We strive to adopt certain aspect of SLSA Level 4 that support our engineering process. At the same time, SLSA is still in alpha status and the biggest changes to SLSA are expected to be around Level 4."})]})}function c(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/1000.89c3dd98.js b/pr-preview/pr-4027/assets/js/1000.89c3dd98.js deleted file mode 100644 index 096d6ba8f..000000000 --- a/pr-preview/pr-4027/assets/js/1000.89c3dd98.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1e3],{91e3:(e,a,s)=>{s.d(a,{createRadarServices:()=>c.f});var c=s(87846);s(87960)}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/1036ee0b.bc80d0c2.js b/pr-preview/pr-4027/assets/js/1036ee0b.bc80d0c2.js deleted file mode 100644 index 7067e9471..000000000 --- a/pr-preview/pr-4027/assets/js/1036ee0b.bc80d0c2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1603],{14901:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/max_latency-ae0fad7be416fae0d31ab35bb8284234.png"},25099:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/min_latency-87ed51de18ebede26c314ff00d0e8e23.png"},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}},63764:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"overview/performance/application","title":"Application benchmarks","description":"HashiCorp Vault","source":"@site/docs/overview/performance/application.md","sourceDirName":"overview/performance","slug":"/overview/performance/application","permalink":"/constellation/pr-preview/pr-4027/next/overview/performance/application","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/overview/performance/application.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"I/O benchmarks","permalink":"/constellation/pr-preview/pr-4027/next/overview/performance/io"},"next":{"title":"License","permalink":"/constellation/pr-preview/pr-4027/next/overview/license"}}');var s=t(74848),i=t(28453);const r={},o="Application benchmarks",c={},l=[{value:"HashiCorp Vault",id:"hashicorp-vault",level:2},{value:"Results",id:"results",level:2},{value:"Visualization",id:"visualization",level:3}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components},{Details:a}=n;return a||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"application-benchmarks",children:"Application benchmarks"})}),"\n",(0,s.jsx)(n.h2,{id:"hashicorp-vault",children:"HashiCorp Vault"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://www.vaultproject.io/",children:"HashiCorp Vault"})," is a distributed secrets management software that can be deployed to Kubernetes.\nHashiCorp maintains a benchmarking tool for vault, ",(0,s.jsx)(n.a,{href:"https://github.com/hashicorp/vault-benchmark/",children:"vault-benchmark"}),".\nVault-benchmark generates load on a Vault deployment and measures response times."]}),"\n",(0,s.jsxs)(n.p,{children:["This article describes the results from running vault-benchmark on Constellation, AKS, and GKE.\nYou can find the setup for producing the data discussed in this article in the ",(0,s.jsx)(n.a,{href:"https://github.com/edgelesssys/vault-benchmarks",children:"vault-benchmarks"})," repository."]}),"\n",(0,s.jsxs)(n.p,{children:["The Vault API used during benchmarking is the ",(0,s.jsx)(n.a,{href:"https://developer.hashicorp.com/vault/docs/secrets/transit",children:"transits secret engine"}),".\nThis allows services to send data to Vault for encryption, decryption, signing, and verification."]}),"\n",(0,s.jsx)(n.h2,{id:"results",children:"Results"}),"\n",(0,s.jsx)(n.p,{children:"On each run, vault-benchmark sends requests and measures the latencies.\nThe measured latencies are aggregated through various statistical features.\nAfter running the benchmark n times, the arithmetic mean over a subset of the reported statistics is calculated.\nThe selected features are arithmetic mean, 99th percentile, minimum, and maximum."}),"\n",(0,s.jsx)(n.p,{children:"Arithmetic mean gives a general sense of the latency on each target.\nThe 99th percentile shows performance in (most likely) erroneous states.\nMinimum and maximum mark the range within which latency varies each run."}),"\n",(0,s.jsx)(n.p,{children:"The benchmark was configured with 1300 workers and 10 seconds per run.\nThose numbers were chosen empirically.\nThe latency was stabilizing at 10 seconds runtime, not changing with further increase.\nIncreasing the number of workers beyond 1300 leads to request failures, marking the limit Vault was able to handle in this setup.\nAll results are based on 100 runs."}),"\n",(0,s.jsx)(n.p,{children:"The following data was generated while running five replicas, one primary, and four standby nodes.\nAll numbers are in seconds if not indicated otherwise."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"========== Results AKS ==========\nMean: mean: 1.632200, variance: 0.002057\nP99: mean: 5.480679, variance: 2.263700\nMax: mean: 6.651001, variance: 2.808401\nMin: mean: 0.011415, variance: 0.000133\n========== Results GKE ==========\nMean: mean: 1.656435, variance: 0.003615\nP99: mean: 6.030807, variance: 3.955051\nMax: mean: 7.164843, variance: 3.300004\nMin: mean: 0.010233, variance: 0.000111\n========== Results C11n ==========\nMean: mean: 1.651549, variance: 0.001610\nP99: mean: 5.780422, variance: 3.016106\nMax: mean: 6.942997, variance: 3.075796\nMin: mean: 0.013774, variance: 0.000228\n========== AKS vs C11n ==========\nMean: +1.171577 % (AKS is faster)\nP99: +5.185495 % (AKS is faster)\nMax: +4.205618 % (AKS is faster)\nMin: +17.128781 % (AKS is faster)\n========== GKE vs C11n ==========\nMean: -0.295851 % (GKE is slower)\nP99: -4.331603 % (GKE is slower)\nMax: -3.195248 % (GKE is slower)\nMin: +25.710886 % (GKE is faster)\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Interpretation"}),": Latencies are all within ~5% of each other.\nAKS performs slightly better than GKE and Constellation (C11n) in all cases except minimum latency.\nMinimum latency is the lowest for GKE.\nCompared to GKE, Constellation had slightly lower peak latencies (99th percentile and maximum), indicating that Constellation could have handled slightly more concurrent accesses than GKE.\nOverall, performance is at comparable levels across all three distributions.\nBased on these numbers, you can use a similarly sized Constellation cluster to run your existing Vault deployment."]}),"\n",(0,s.jsx)(n.h3,{id:"visualization",children:"Visualization"}),"\n",(0,s.jsxs)(n.p,{children:["The following plots visualize the data presented above as ",(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Box_plot",children:"box plots"}),".\nThe whiskers denote the minimum and maximum.\nThe box stretches from the 25th to the 75th percentile, with the dividing bar marking the 50th percentile.\nThe circles outside the whiskers denote outliers."]}),"\n",(0,s.jsxs)(a,{children:[(0,s.jsx)("summary",{children:"Mean Latency"}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Mean Latency",src:t(73958).A+"",width:"576",height:"576"})})]}),"\n",(0,s.jsxs)(a,{children:[(0,s.jsx)("summary",{children:"99th Percentile Latency"}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"99th Percentile Latency",src:t(85557).A+"",width:"576",height:"576"})})]}),"\n",(0,s.jsxs)(a,{children:[(0,s.jsx)("summary",{children:"Maximum Latency"}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Maximum Latency",src:t(14901).A+"",width:"576",height:"576"})})]}),"\n",(0,s.jsxs)(a,{children:[(0,s.jsx)("summary",{children:"Minimum Latency"}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Minimum Latency",src:t(25099).A+"",width:"576",height:"576"})})]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},73958:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/mean_latency-4c041d48ebb1b521c92d464040e94031.png"},85557:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/p99_latency-fd60c7ae80666133370f9b8e47404994.png"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/11b4c29f.5f60ca1d.js b/pr-preview/pr-4027/assets/js/11b4c29f.5f60ca1d.js deleted file mode 100644 index ae8bc8c1a..000000000 --- a/pr-preview/pr-4027/assets/js/11b4c29f.5f60ca1d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[945],{28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>r});var a=s(96540);const n={},l=a.createContext(n);function o(e){const t=a.useContext(l);return a.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),a.createElement(l.Provider,{value:t},e.children)}},44845:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>c});const a=JSON.parse('{"id":"getting-started/marketplaces","title":"Using Constellation via Cloud Marketplaces","description":"Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please contact us.","source":"@site/versioned_docs/version-2.24/getting-started/marketplaces.md","sourceDirName":"getting-started","slug":"/getting-started/marketplaces","permalink":"/constellation/pr-preview/pr-4027/getting-started/marketplaces","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/getting-started/marketplaces.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"First steps (local)","permalink":"/constellation/pr-preview/pr-4027/getting-started/first-steps-local"},"next":{"title":"Examples","permalink":"/constellation/pr-preview/pr-4027/getting-started/examples"}}');var n=s(74848),l=s(28453);const o={},r="Using Constellation via Cloud Marketplaces",i={},c=[];function p(e){const t={a:"a",code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,l.R)(),...e.components},{TabItem:s,Tabs:a}=t;return s||h("TabItem",!0),a||h("Tabs",!0),(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"using-constellation-via-cloud-marketplaces",children:"Using Constellation via Cloud Marketplaces"})}),"\n",(0,n.jsxs)(t.p,{children:["Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please ",(0,n.jsx)(t.a,{href:"https://www.edgeless.systems/enterprise-support/",children:"contact us"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"This document explains how to run Constellation with the dynamically billed cloud marketplace images."}),"\n",(0,n.jsxs)(a,{groupId:"csp",children:[(0,n.jsxs)(s,{value:"aws",label:"AWS",children:[(0,n.jsxs)(t.p,{children:["To use Constellation's marketplace images, ensure that you are subscribed to the ",(0,n.jsx)(t.a,{href:"https://aws.amazon.com/marketplace/pp/prodview-2mbn65nv57oys",children:"marketplace offering"})," through the web portal."]}),(0,n.jsxs)(t.p,{children:["Then, enable the use of marketplace images in your Constellation ",(0,n.jsx)(t.code,{children:"constellation-conf.yaml"})," ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/config",children:"config file"}),":"]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:'yq eval -i ".provider.aws.useMarketplaceImage = true" constellation-conf.yaml\n'})})]}),(0,n.jsxs)(s,{value:"azure",label:"Azure",children:[(0,n.jsxs)(t.p,{children:["Constellation has a private marketplace plan. Please ",(0,n.jsx)(t.a,{href:"https://www.edgeless.systems/enterprise-support/",children:"contact us"})," to gain access."]}),(0,n.jsxs)(t.p,{children:["To use a marketplace image, you need to accept the marketplace image's terms once for your subscription with the ",(0,n.jsx)(t.a,{href:"https://learn.microsoft.com/en-us/cli/azure/vm/image/terms?view=azure-cli-latest",children:"Azure CLI"}),":"]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"az vm image terms accept --publisher edgelesssystems --offer constellation --plan constellation\n"})}),(0,n.jsxs)(t.p,{children:["Then, enable the use of marketplace images in your Constellation ",(0,n.jsx)(t.code,{children:"constellation-conf.yaml"})," ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/config",children:"config file"}),":"]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:'yq eval -i ".provider.azure.useMarketplaceImage = true" constellation-conf.yaml\n'})})]}),(0,n.jsxs)(s,{value:"gcp",label:"GCP",children:[(0,n.jsxs)(t.p,{children:["To use a marketplace image, ensure that the account is entitled to use marketplace images by Edgeless Systems by accepting the terms through the ",(0,n.jsx)(t.a,{href:"https://console.cloud.google.com/marketplace/vm/config/edgeless-systems-public/constellation",children:"web portal"}),"."]}),(0,n.jsxs)(t.p,{children:["Then, enable the use of marketplace images in your Constellation ",(0,n.jsx)(t.code,{children:"constellation-conf.yaml"})," ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/config",children:"config file"}),":"]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:'yq eval -i ".provider.gcp.useMarketplaceImage = true" constellation-conf.yaml\n'})})]}),(0,n.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,n.jsx)(t.p,{children:"On STACKIT, the selected Constellation image is always a marketplace image. You can find more information on the STACKIT portal."})})]}),"\n",(0,n.jsxs)(t.p,{children:["Ensure that the cluster uses an official release image version (i.e., ",(0,n.jsx)(t.code,{children:".image=vX.Y.Z"})," in the ",(0,n.jsx)(t.code,{children:"constellation-conf.yaml"})," file)."]}),"\n",(0,n.jsxs)(t.p,{children:["From there, you can proceed with the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/create",children:"cluster creation"})," as usual."]})]})}function d(e={}){const{wrapper:t}={...(0,l.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}function h(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/11dcff96.801ce7eb.js b/pr-preview/pr-4027/assets/js/11dcff96.801ce7eb.js deleted file mode 100644 index 356b1bad7..000000000 --- a/pr-preview/pr-4027/assets/js/11dcff96.801ce7eb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1799],{28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>l});var n=r(96540);const o={},s=n.createContext(o);function i(e){const t=n.useContext(s);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(s.Provider,{value:t},e.children)}},46377:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>l,default:()=>d,frontMatter:()=>i,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"workflows/create","title":"Create your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","source":"@site/versioned_docs/version-2.22/workflows/create.md","sourceDirName":"workflows","slug":"/workflows/create","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/create","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/workflows/create.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Configure your cluster","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/config"},"next":{"title":"Scale your cluster","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/scale"}}');var o=r(74848),s=r(28453);const i={},l="Create your cluster",a={},c=[{value:"Troubleshooting",id:"troubleshooting",level:3}];function u(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h3:"h3",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.R)(),...e.components},{AsciinemaWidget:r,TabItem:n,Tabs:i}=t;return r||h("AsciinemaWidget",!0),n||h("TabItem",!0),i||h("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"create-your-cluster",children:"Create your cluster"})}),"\n",(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsx)(t.p,{children:"This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details."})}),"\n",(0,o.jsx)(r,{src:"/constellation/assets/create-cluster.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,o.jsx)(t.hr,{}),"\n",(0,o.jsx)(t.p,{children:"Creating your cluster happens through multiple phases.\nThe most significant ones are:"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsx)(t.li,{children:"Creating the necessary resources in your cloud environment"}),"\n",(0,o.jsx)(t.li,{children:"Bootstrapping the Constellation cluster and setting up a connection"}),"\n",(0,o.jsx)(t.li,{children:"Installing the necessary Kubernetes components"}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.code,{children:"constellation apply"})," handles all this in a single command.\nYou can use the ",(0,o.jsx)(t.code,{children:"--skip-phases"})," flag to skip specific phases of the process.\nFor example, if you created the infrastructure manually, you can skip the cloud resource creation phase."]}),"\n",(0,o.jsxs)(t.p,{children:["See the ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration",children:"architecture"})," section for details on the inner workings of this process."]}),"\n",(0,o.jsx)(t.admonition,{type:"tip",children:(0,o.jsxs)(t.p,{children:["If you don't have a cloud subscription, you can also set up a ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local",children:"local Constellation cluster using virtualization"})," for testing."]})}),"\n",(0,o.jsxs)(t.p,{children:["Before you create the cluster, make sure to have a ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/config",children:"valid configuration file"}),"."]}),"\n",(0,o.jsxs)(i,{groupId:"usage",children:[(0,o.jsxs)(n,{value:"cli",label:"CLI",children:[(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation apply\n"})}),(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.code,{children:"apply"})," stores the state of your cluster's cloud resources in a ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration#cluster-creation-process",children:(0,o.jsx)(t.code,{children:"constellation-terraform"})})," directory in your workspace."]})]}),(0,o.jsxs)(n,{value:"self-managed",label:"Self-managed",children:[(0,o.jsx)(t.p,{children:"Self-managed infrastructure allows for more flexibility in the setup, by separating the infrastructure setup from the Constellation cluster management.\nThis provides flexibility in DevOps and can meet potential regulatory requirements.\nIt's recommended to use Terraform for infrastructure management, but you can use any tool of your choice."}),(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsxs)(t.p,{children:["When using Terraform, you can use the ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/terraform-provider",children:"Constellation Terraform provider"})," to manage the entire Constellation cluster lifecycle."]})}),(0,o.jsxs)(t.p,{children:["You can refer to the Terraform files for the selected CSP from the ",(0,o.jsx)(t.a,{href:"https://github.com/edgelesssys/constellation/tree/main/terraform/infrastructure",children:"Constellation GitHub repository"})," for a minimum Constellation cluster configuration. From this base, you can now add, edit, or substitute resources per your own requirements with the infrastructure\nmanagement tooling of your choice. You need to keep the essential functionality of the base configuration in order for your cluster to function correctly."]}),(0,o.jsxs)(t.admonition,{type:"info",children:[(0,o.jsxs)(t.p,{children:["On Azure, a manual update to the MAA provider's policy is necessary.\nYou can apply the update with the following command after creating the infrastructure, with ",(0,o.jsx)(t.code,{children:""})," being the URL of the MAA provider (i.e., ",(0,o.jsx)(t.code,{children:"$(terraform output attestation_url | jq -r)"}),", when using the minimal Terraform configuration)."]}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation maa-patch \n"})})]}),(0,o.jsxs)(t.p,{children:["Make sure all necessary resources are created, e.g., through checking your CSP's portal and retrieve the necessary values, aligned with the outputs (specified in ",(0,o.jsx)(t.code,{children:"outputs.tf"}),") of the base configuration."]}),(0,o.jsxs)(t.p,{children:["Fill these outputs into the corresponding fields of the ",(0,o.jsx)(t.code,{children:"Infrastructure"})," block inside the ",(0,o.jsx)(t.code,{children:"constellation-state.yaml"})," file. For example, fill the IP or DNS name your cluster can be reached at into the ",(0,o.jsx)(t.code,{children:".Infrastructure.ClusterEndpoint"})," field."]}),(0,o.jsx)(t.p,{children:"With the required cloud resources set up, continue with initializing your cluster."}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation apply --skip-phases=infrastructure\n"})})]})]}),"\n",(0,o.jsxs)(t.p,{children:["Finally, configure ",(0,o.jsx)(t.code,{children:"kubectl"})," for your cluster:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:'export KUBECONFIG="$PWD/constellation-admin.conf"\n'})}),"\n",(0,o.jsx)(t.p,{children:"\ud83c\udfc1 That's it. You've successfully created a Constellation cluster."}),"\n",(0,o.jsx)(t.h3,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,o.jsxs)(t.p,{children:["In case ",(0,o.jsx)(t.code,{children:"apply"})," fails, the CLI collects logs from the bootstrapping instance and stores them inside ",(0,o.jsx)(t.code,{children:"constellation-cluster.log"}),"."]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}function h(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/1203.72b741a7.js b/pr-preview/pr-4027/assets/js/1203.72b741a7.js deleted file mode 100644 index fd30b17b2..000000000 --- a/pr-preview/pr-4027/assets/js/1203.72b741a7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1203],{51203:(t,e,i)=>{i.d(e,{diagram:()=>I});var a=i(67633),n=i(40797),s=i(70451),r=function(){var t=(0,n.K2)(function(t,e,i,a){for(i=i||{},a=t.length;a--;i[t[a]]=e);return i},"o"),e=[1,3],i=[1,4],a=[1,5],s=[1,6],r=[1,7],o=[1,4,5,10,12,13,14,18,25,35,37,39,41,42,48,50,51,52,53,54,55,56,57,60,61,63,64,65,66,67],l=[1,4,5,10,12,13,14,18,25,28,35,37,39,41,42,48,50,51,52,53,54,55,56,57,60,61,63,64,65,66,67],h=[55,56,57],c=[2,36],d=[1,37],u=[1,36],x=[1,38],g=[1,35],f=[1,43],p=[1,41],y=[1,14],T=[1,23],m=[1,18],q=[1,19],A=[1,20],_=[1,21],b=[1,22],S=[1,24],k=[1,25],F=[1,26],P=[1,27],C=[1,28],L=[1,29],v=[1,32],I=[1,33],E=[1,34],D=[1,39],z=[1,40],w=[1,42],K=[1,44],U=[1,62],N=[1,61],R=[4,5,8,10,12,13,14,18,44,47,49,55,56,57,63,64,65,66,67],B=[1,65],W=[1,66],$=[1,67],Q=[1,68],O=[1,69],X=[1,70],H=[1,71],M=[1,72],Y=[1,73],j=[1,74],G=[1,75],V=[1,76],Z=[4,5,6,7,8,9,10,11,12,13,14,15,18],J=[1,90],tt=[1,91],et=[1,92],it=[1,99],at=[1,93],nt=[1,96],st=[1,94],rt=[1,95],ot=[1,97],lt=[1,98],ht=[1,102],ct=[10,55,56,57],dt=[4,5,6,8,10,11,13,17,18,19,20,55,56,57],ut={trace:(0,n.K2)(function(){},"trace"),yy:{},symbols_:{error:2,idStringToken:3,ALPHA:4,NUM:5,NODE_STRING:6,DOWN:7,MINUS:8,DEFAULT:9,COMMA:10,COLON:11,AMP:12,BRKT:13,MULT:14,UNICODE_TEXT:15,styleComponent:16,UNIT:17,SPACE:18,STYLE:19,PCT:20,idString:21,style:22,stylesOpt:23,classDefStatement:24,CLASSDEF:25,start:26,eol:27,QUADRANT:28,document:29,line:30,statement:31,axisDetails:32,quadrantDetails:33,points:34,title:35,title_value:36,acc_title:37,acc_title_value:38,acc_descr:39,acc_descr_value:40,acc_descr_multiline_value:41,section:42,text:43,point_start:44,point_x:45,point_y:46,class_name:47,"X-AXIS":48,"AXIS-TEXT-DELIMITER":49,"Y-AXIS":50,QUADRANT_1:51,QUADRANT_2:52,QUADRANT_3:53,QUADRANT_4:54,NEWLINE:55,SEMI:56,EOF:57,alphaNumToken:58,textNoTagsToken:59,STR:60,MD_STR:61,alphaNum:62,PUNCTUATION:63,PLUS:64,EQUALS:65,DOT:66,UNDERSCORE:67,$accept:0,$end:1},terminals_:{2:"error",4:"ALPHA",5:"NUM",6:"NODE_STRING",7:"DOWN",8:"MINUS",9:"DEFAULT",10:"COMMA",11:"COLON",12:"AMP",13:"BRKT",14:"MULT",15:"UNICODE_TEXT",17:"UNIT",18:"SPACE",19:"STYLE",20:"PCT",25:"CLASSDEF",28:"QUADRANT",35:"title",36:"title_value",37:"acc_title",38:"acc_title_value",39:"acc_descr",40:"acc_descr_value",41:"acc_descr_multiline_value",42:"section",44:"point_start",45:"point_x",46:"point_y",47:"class_name",48:"X-AXIS",49:"AXIS-TEXT-DELIMITER",50:"Y-AXIS",51:"QUADRANT_1",52:"QUADRANT_2",53:"QUADRANT_3",54:"QUADRANT_4",55:"NEWLINE",56:"SEMI",57:"EOF",60:"STR",61:"MD_STR",63:"PUNCTUATION",64:"PLUS",65:"EQUALS",66:"DOT",67:"UNDERSCORE"},productions_:[0,[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[21,1],[21,2],[22,1],[22,2],[23,1],[23,3],[24,5],[26,2],[26,2],[26,2],[29,0],[29,2],[30,2],[31,0],[31,1],[31,2],[31,1],[31,1],[31,1],[31,2],[31,2],[31,2],[31,1],[31,1],[34,4],[34,5],[34,5],[34,6],[32,4],[32,3],[32,2],[32,4],[32,3],[32,2],[33,2],[33,2],[33,2],[33,2],[27,1],[27,1],[27,1],[43,1],[43,2],[43,1],[43,1],[62,1],[62,2],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[59,1],[59,1],[59,1]],performAction:(0,n.K2)(function(t,e,i,a,n,s,r){var o=s.length-1;switch(n){case 23:case 68:this.$=s[o];break;case 24:case 69:this.$=s[o-1]+""+s[o];break;case 26:this.$=s[o-1]+s[o];break;case 27:this.$=[s[o].trim()];break;case 28:s[o-2].push(s[o].trim()),this.$=s[o-2];break;case 29:this.$=s[o-4],a.addClass(s[o-2],s[o]);break;case 37:this.$=[];break;case 42:this.$=s[o].trim(),a.setDiagramTitle(this.$);break;case 43:this.$=s[o].trim(),a.setAccTitle(this.$);break;case 44:case 45:this.$=s[o].trim(),a.setAccDescription(this.$);break;case 46:a.addSection(s[o].substr(8)),this.$=s[o].substr(8);break;case 47:a.addPoint(s[o-3],"",s[o-1],s[o],[]);break;case 48:a.addPoint(s[o-4],s[o-3],s[o-1],s[o],[]);break;case 49:a.addPoint(s[o-4],"",s[o-2],s[o-1],s[o]);break;case 50:a.addPoint(s[o-5],s[o-4],s[o-2],s[o-1],s[o]);break;case 51:a.setXAxisLeftText(s[o-2]),a.setXAxisRightText(s[o]);break;case 52:s[o-1].text+=" \u27f6 ",a.setXAxisLeftText(s[o-1]);break;case 53:a.setXAxisLeftText(s[o]);break;case 54:a.setYAxisBottomText(s[o-2]),a.setYAxisTopText(s[o]);break;case 55:s[o-1].text+=" \u27f6 ",a.setYAxisBottomText(s[o-1]);break;case 56:a.setYAxisBottomText(s[o]);break;case 57:a.setQuadrant1Text(s[o]);break;case 58:a.setQuadrant2Text(s[o]);break;case 59:a.setQuadrant3Text(s[o]);break;case 60:a.setQuadrant4Text(s[o]);break;case 64:case 66:this.$={text:s[o],type:"text"};break;case 65:this.$={text:s[o-1].text+""+s[o],type:s[o-1].type};break;case 67:this.$={text:s[o],type:"markdown"}}},"anonymous"),table:[{18:e,26:1,27:2,28:i,55:a,56:s,57:r},{1:[3]},{18:e,26:8,27:2,28:i,55:a,56:s,57:r},{18:e,26:9,27:2,28:i,55:a,56:s,57:r},t(o,[2,33],{29:10}),t(l,[2,61]),t(l,[2,62]),t(l,[2,63]),{1:[2,30]},{1:[2,31]},t(h,c,{30:11,31:12,24:13,32:15,33:16,34:17,43:30,58:31,1:[2,32],4:d,5:u,10:x,12:g,13:f,14:p,18:y,25:T,35:m,37:q,39:A,41:_,42:b,48:S,50:k,51:F,52:P,53:C,54:L,60:v,61:I,63:E,64:D,65:z,66:w,67:K}),t(o,[2,34]),{27:45,55:a,56:s,57:r},t(h,[2,37]),t(h,c,{24:13,32:15,33:16,34:17,43:30,58:31,31:46,4:d,5:u,10:x,12:g,13:f,14:p,18:y,25:T,35:m,37:q,39:A,41:_,42:b,48:S,50:k,51:F,52:P,53:C,54:L,60:v,61:I,63:E,64:D,65:z,66:w,67:K}),t(h,[2,39]),t(h,[2,40]),t(h,[2,41]),{36:[1,47]},{38:[1,48]},{40:[1,49]},t(h,[2,45]),t(h,[2,46]),{18:[1,50]},{4:d,5:u,10:x,12:g,13:f,14:p,43:51,58:31,60:v,61:I,63:E,64:D,65:z,66:w,67:K},{4:d,5:u,10:x,12:g,13:f,14:p,43:52,58:31,60:v,61:I,63:E,64:D,65:z,66:w,67:K},{4:d,5:u,10:x,12:g,13:f,14:p,43:53,58:31,60:v,61:I,63:E,64:D,65:z,66:w,67:K},{4:d,5:u,10:x,12:g,13:f,14:p,43:54,58:31,60:v,61:I,63:E,64:D,65:z,66:w,67:K},{4:d,5:u,10:x,12:g,13:f,14:p,43:55,58:31,60:v,61:I,63:E,64:D,65:z,66:w,67:K},{4:d,5:u,10:x,12:g,13:f,14:p,43:56,58:31,60:v,61:I,63:E,64:D,65:z,66:w,67:K},{4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,44:[1,57],47:[1,58],58:60,59:59,63:E,64:D,65:z,66:w,67:K},t(R,[2,64]),t(R,[2,66]),t(R,[2,67]),t(R,[2,70]),t(R,[2,71]),t(R,[2,72]),t(R,[2,73]),t(R,[2,74]),t(R,[2,75]),t(R,[2,76]),t(R,[2,77]),t(R,[2,78]),t(R,[2,79]),t(R,[2,80]),t(o,[2,35]),t(h,[2,38]),t(h,[2,42]),t(h,[2,43]),t(h,[2,44]),{3:64,4:B,5:W,6:$,7:Q,8:O,9:X,10:H,11:M,12:Y,13:j,14:G,15:V,21:63},t(h,[2,53],{59:59,58:60,4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,49:[1,77],63:E,64:D,65:z,66:w,67:K}),t(h,[2,56],{59:59,58:60,4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,49:[1,78],63:E,64:D,65:z,66:w,67:K}),t(h,[2,57],{59:59,58:60,4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,63:E,64:D,65:z,66:w,67:K}),t(h,[2,58],{59:59,58:60,4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,63:E,64:D,65:z,66:w,67:K}),t(h,[2,59],{59:59,58:60,4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,63:E,64:D,65:z,66:w,67:K}),t(h,[2,60],{59:59,58:60,4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,63:E,64:D,65:z,66:w,67:K}),{45:[1,79]},{44:[1,80]},t(R,[2,65]),t(R,[2,81]),t(R,[2,82]),t(R,[2,83]),{3:82,4:B,5:W,6:$,7:Q,8:O,9:X,10:H,11:M,12:Y,13:j,14:G,15:V,18:[1,81]},t(Z,[2,23]),t(Z,[2,1]),t(Z,[2,2]),t(Z,[2,3]),t(Z,[2,4]),t(Z,[2,5]),t(Z,[2,6]),t(Z,[2,7]),t(Z,[2,8]),t(Z,[2,9]),t(Z,[2,10]),t(Z,[2,11]),t(Z,[2,12]),t(h,[2,52],{58:31,43:83,4:d,5:u,10:x,12:g,13:f,14:p,60:v,61:I,63:E,64:D,65:z,66:w,67:K}),t(h,[2,55],{58:31,43:84,4:d,5:u,10:x,12:g,13:f,14:p,60:v,61:I,63:E,64:D,65:z,66:w,67:K}),{46:[1,85]},{45:[1,86]},{4:J,5:tt,6:et,8:it,11:at,13:nt,16:89,17:st,18:rt,19:ot,20:lt,22:88,23:87},t(Z,[2,24]),t(h,[2,51],{59:59,58:60,4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,63:E,64:D,65:z,66:w,67:K}),t(h,[2,54],{59:59,58:60,4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,63:E,64:D,65:z,66:w,67:K}),t(h,[2,47],{22:88,16:89,23:100,4:J,5:tt,6:et,8:it,11:at,13:nt,17:st,18:rt,19:ot,20:lt}),{46:[1,101]},t(h,[2,29],{10:ht}),t(ct,[2,27],{16:103,4:J,5:tt,6:et,8:it,11:at,13:nt,17:st,18:rt,19:ot,20:lt}),t(dt,[2,25]),t(dt,[2,13]),t(dt,[2,14]),t(dt,[2,15]),t(dt,[2,16]),t(dt,[2,17]),t(dt,[2,18]),t(dt,[2,19]),t(dt,[2,20]),t(dt,[2,21]),t(dt,[2,22]),t(h,[2,49],{10:ht}),t(h,[2,48],{22:88,16:89,23:104,4:J,5:tt,6:et,8:it,11:at,13:nt,17:st,18:rt,19:ot,20:lt}),{4:J,5:tt,6:et,8:it,11:at,13:nt,16:89,17:st,18:rt,19:ot,20:lt,22:105},t(dt,[2,26]),t(h,[2,50],{10:ht}),t(ct,[2,28],{16:103,4:J,5:tt,6:et,8:it,11:at,13:nt,17:st,18:rt,19:ot,20:lt})],defaultActions:{8:[2,30],9:[2,31]},parseError:(0,n.K2)(function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)},"parseError"),parse:(0,n.K2)(function(t){var e=this,i=[0],a=[],s=[null],r=[],o=this.table,l="",h=0,c=0,d=0,u=r.slice.call(arguments,1),x=Object.create(this.lexer),g={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(g.yy[f]=this.yy[f]);x.setInput(t,g.yy),g.yy.lexer=x,g.yy.parser=this,void 0===x.yylloc&&(x.yylloc={});var p=x.yylloc;r.push(p);var y=x.options&&x.options.ranges;function T(){var t;return"number"!=typeof(t=a.pop()||x.lex()||1)&&(t instanceof Array&&(t=(a=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,n.K2)(function(t){i.length=i.length-2*t,s.length=s.length-t,r.length=r.length-t},"popStack"),(0,n.K2)(T,"lex");for(var m,q,A,_,b,S,k,F,P,C={};;){if(A=i[i.length-1],this.defaultActions[A]?_=this.defaultActions[A]:(null==m&&(m=T()),_=o[A]&&o[A][m]),void 0===_||!_.length||!_[0]){var L="";for(S in P=[],o[A])this.terminals_[S]&&S>2&&P.push("'"+this.terminals_[S]+"'");L=x.showPosition?"Parse error on line "+(h+1)+":\n"+x.showPosition()+"\nExpecting "+P.join(", ")+", got '"+(this.terminals_[m]||m)+"'":"Parse error on line "+(h+1)+": Unexpected "+(1==m?"end of input":"'"+(this.terminals_[m]||m)+"'"),this.parseError(L,{text:x.match,token:this.terminals_[m]||m,line:x.yylineno,loc:p,expected:P})}if(_[0]instanceof Array&&_.length>1)throw new Error("Parse Error: multiple actions possible at state: "+A+", token: "+m);switch(_[0]){case 1:i.push(m),s.push(x.yytext),r.push(x.yylloc),i.push(_[1]),m=null,q?(m=q,q=null):(c=x.yyleng,l=x.yytext,h=x.yylineno,p=x.yylloc,d>0&&d--);break;case 2:if(k=this.productions_[_[1]][1],C.$=s[s.length-k],C._$={first_line:r[r.length-(k||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(k||1)].first_column,last_column:r[r.length-1].last_column},y&&(C._$.range=[r[r.length-(k||1)].range[0],r[r.length-1].range[1]]),void 0!==(b=this.performAction.apply(C,[l,c,h,g.yy,_[1],s,r].concat(u))))return b;k&&(i=i.slice(0,-1*k*2),s=s.slice(0,-1*k),r=r.slice(0,-1*k)),i.push(this.productions_[_[1]][0]),s.push(C.$),r.push(C._$),F=o[i[i.length-2]][i[i.length-1]],i.push(F);break;case 3:return!0}}return!0},"parse")},xt=function(){return{EOF:1,parseError:(0,n.K2)(function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},"parseError"),setInput:(0,n.K2)(function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:(0,n.K2)(function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},"input"),unput:(0,n.K2)(function(t){var e=t.length,i=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var a=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===a.length?this.yylloc.first_column:0)+a[a.length-i.length].length-i[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},"unput"),more:(0,n.K2)(function(){return this._more=!0,this},"more"),reject:(0,n.K2)(function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"reject"),less:(0,n.K2)(function(t){this.unput(this.match.slice(t))},"less"),pastInput:(0,n.K2)(function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:(0,n.K2)(function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:(0,n.K2)(function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},"showPosition"),test_match:(0,n.K2)(function(t,e){var i,a,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(a=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=a.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:a?a[a.length-1].length-a[a.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var s in n)this[s]=n[s];return!1}return!1},"test_match"),next:(0,n.K2)(function(){if(this.done)return this.EOF;var t,e,i,a;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),s=0;se[0].length)){if(e=i,a=s,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,n[s])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,n[a]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:(0,n.K2)(function(){var t=this.next();return t||this.lex()},"lex"),begin:(0,n.K2)(function(t){this.conditionStack.push(t)},"begin"),popState:(0,n.K2)(function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:(0,n.K2)(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:(0,n.K2)(function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},"topState"),pushState:(0,n.K2)(function(t){this.begin(t)},"pushState"),stateStackSize:(0,n.K2)(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,n.K2)(function(t,e,i,a){switch(i){case 0:case 1:case 3:break;case 2:return 55;case 4:return this.begin("title"),35;case 5:return this.popState(),"title_value";case 6:return this.begin("acc_title"),37;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),39;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 23:case 25:case 31:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:return 48;case 14:return 50;case 15:return 49;case 16:return 51;case 17:return 52;case 18:return 53;case 19:return 54;case 20:return 25;case 21:this.begin("md_string");break;case 22:return"MD_STR";case 24:this.begin("string");break;case 26:return"STR";case 27:this.begin("class_name");break;case 28:return this.popState(),47;case 29:return this.begin("point_start"),44;case 30:return this.begin("point_x"),45;case 32:this.popState(),this.begin("point_y");break;case 33:return this.popState(),46;case 34:return 28;case 35:return 4;case 36:return 11;case 37:return 64;case 38:return 10;case 39:case 40:return 65;case 41:return 14;case 42:return 13;case 43:return 67;case 44:return 66;case 45:return 12;case 46:return 8;case 47:return 5;case 48:return 18;case 49:return 56;case 50:return 63;case 51:return 57}},"anonymous"),rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?: *x-axis *)/i,/^(?: *y-axis *)/i,/^(?: *--+> *)/i,/^(?: *quadrant-1 *)/i,/^(?: *quadrant-2 *)/i,/^(?: *quadrant-3 *)/i,/^(?: *quadrant-4 *)/i,/^(?:classDef\b)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?::::)/i,/^(?:^\w+)/i,/^(?:\s*:\s*\[\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?:\s*\] *)/i,/^(?:\s*,\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?: *quadrantChart *)/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s)/i,/^(?:;)/i,/^(?:[!"#$%&'*+,-.`?\\_/])/i,/^(?:$)/i],conditions:{class_name:{rules:[28],inclusive:!1},point_y:{rules:[33],inclusive:!1},point_x:{rules:[32],inclusive:!1},point_start:{rules:[30,31],inclusive:!1},acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},title:{rules:[5],inclusive:!1},md_string:{rules:[22,23],inclusive:!1},string:{rules:[25,26],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,6,8,10,13,14,15,16,17,18,19,20,21,24,27,29,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],inclusive:!0}}}}();function gt(){this.yy={}}return ut.lexer=xt,(0,n.K2)(gt,"Parser"),gt.prototype=ut,ut.Parser=gt,new gt}();r.parser=r;var o=r,l=(0,a.P$)(),h=class{constructor(){this.classes=new Map,this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData()}static{(0,n.K2)(this,"QuadrantBuilder")}getDefaultData(){return{titleText:"",quadrant1Text:"",quadrant2Text:"",quadrant3Text:"",quadrant4Text:"",xAxisLeftText:"",xAxisRightText:"",yAxisBottomText:"",yAxisTopText:"",points:[]}}getDefaultConfig(){return{showXAxis:!0,showYAxis:!0,showTitle:!0,chartHeight:a.UI.quadrantChart?.chartWidth||500,chartWidth:a.UI.quadrantChart?.chartHeight||500,titlePadding:a.UI.quadrantChart?.titlePadding||10,titleFontSize:a.UI.quadrantChart?.titleFontSize||20,quadrantPadding:a.UI.quadrantChart?.quadrantPadding||5,xAxisLabelPadding:a.UI.quadrantChart?.xAxisLabelPadding||5,yAxisLabelPadding:a.UI.quadrantChart?.yAxisLabelPadding||5,xAxisLabelFontSize:a.UI.quadrantChart?.xAxisLabelFontSize||16,yAxisLabelFontSize:a.UI.quadrantChart?.yAxisLabelFontSize||16,quadrantLabelFontSize:a.UI.quadrantChart?.quadrantLabelFontSize||16,quadrantTextTopPadding:a.UI.quadrantChart?.quadrantTextTopPadding||5,pointTextPadding:a.UI.quadrantChart?.pointTextPadding||5,pointLabelFontSize:a.UI.quadrantChart?.pointLabelFontSize||12,pointRadius:a.UI.quadrantChart?.pointRadius||5,xAxisPosition:a.UI.quadrantChart?.xAxisPosition||"top",yAxisPosition:a.UI.quadrantChart?.yAxisPosition||"left",quadrantInternalBorderStrokeWidth:a.UI.quadrantChart?.quadrantInternalBorderStrokeWidth||1,quadrantExternalBorderStrokeWidth:a.UI.quadrantChart?.quadrantExternalBorderStrokeWidth||2}}getDefaultThemeConfig(){return{quadrant1Fill:l.quadrant1Fill,quadrant2Fill:l.quadrant2Fill,quadrant3Fill:l.quadrant3Fill,quadrant4Fill:l.quadrant4Fill,quadrant1TextFill:l.quadrant1TextFill,quadrant2TextFill:l.quadrant2TextFill,quadrant3TextFill:l.quadrant3TextFill,quadrant4TextFill:l.quadrant4TextFill,quadrantPointFill:l.quadrantPointFill,quadrantPointTextFill:l.quadrantPointTextFill,quadrantXAxisTextFill:l.quadrantXAxisTextFill,quadrantYAxisTextFill:l.quadrantYAxisTextFill,quadrantTitleFill:l.quadrantTitleFill,quadrantInternalBorderStrokeFill:l.quadrantInternalBorderStrokeFill,quadrantExternalBorderStrokeFill:l.quadrantExternalBorderStrokeFill}}clear(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData(),this.classes=new Map,n.Rm.info("clear called")}setData(t){this.data={...this.data,...t}}addPoints(t){this.data.points=[...t,...this.data.points]}addClass(t,e){this.classes.set(t,e)}setConfig(t){n.Rm.trace("setConfig called with: ",t),this.config={...this.config,...t}}setThemeConfig(t){n.Rm.trace("setThemeConfig called with: ",t),this.themeConfig={...this.themeConfig,...t}}calculateSpace(t,e,i,a){const n=2*this.config.xAxisLabelPadding+this.config.xAxisLabelFontSize,s={top:"top"===t&&e?n:0,bottom:"bottom"===t&&e?n:0},r=2*this.config.yAxisLabelPadding+this.config.yAxisLabelFontSize,o={left:"left"===this.config.yAxisPosition&&i?r:0,right:"right"===this.config.yAxisPosition&&i?r:0},l=this.config.titleFontSize+2*this.config.titlePadding,h={top:a?l:0},c=this.config.quadrantPadding+o.left,d=this.config.quadrantPadding+s.top+h.top,u=this.config.chartWidth-2*this.config.quadrantPadding-o.left-o.right,x=this.config.chartHeight-2*this.config.quadrantPadding-s.top-s.bottom-h.top;return{xAxisSpace:s,yAxisSpace:o,titleSpace:h,quadrantSpace:{quadrantLeft:c,quadrantTop:d,quadrantWidth:u,quadrantHalfWidth:u/2,quadrantHeight:x,quadrantHalfHeight:x/2}}}getAxisLabels(t,e,i,a){const{quadrantSpace:n,titleSpace:s}=a,{quadrantHalfHeight:r,quadrantHeight:o,quadrantLeft:l,quadrantHalfWidth:h,quadrantTop:c,quadrantWidth:d}=n,u=Boolean(this.data.xAxisRightText),x=Boolean(this.data.yAxisTopText),g=[];return this.data.xAxisLeftText&&e&&g.push({text:this.data.xAxisLeftText,fill:this.themeConfig.quadrantXAxisTextFill,x:l+(u?h/2:0),y:"top"===t?this.config.xAxisLabelPadding+s.top:this.config.xAxisLabelPadding+c+o+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:0}),this.data.xAxisRightText&&e&&g.push({text:this.data.xAxisRightText,fill:this.themeConfig.quadrantXAxisTextFill,x:l+h+(u?h/2:0),y:"top"===t?this.config.xAxisLabelPadding+s.top:this.config.xAxisLabelPadding+c+o+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:0}),this.data.yAxisBottomText&&i&&g.push({text:this.data.yAxisBottomText,fill:this.themeConfig.quadrantYAxisTextFill,x:"left"===this.config.yAxisPosition?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+l+d+this.config.quadrantPadding,y:c+o-(x?r/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:x?"center":"left",horizontalPos:"top",rotation:-90}),this.data.yAxisTopText&&i&&g.push({text:this.data.yAxisTopText,fill:this.themeConfig.quadrantYAxisTextFill,x:"left"===this.config.yAxisPosition?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+l+d+this.config.quadrantPadding,y:c+r-(x?r/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:x?"center":"left",horizontalPos:"top",rotation:-90}),g}getQuadrants(t){const{quadrantSpace:e}=t,{quadrantHalfHeight:i,quadrantLeft:a,quadrantHalfWidth:n,quadrantTop:s}=e,r=[{text:{text:this.data.quadrant1Text,fill:this.themeConfig.quadrant1TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a+n,y:s,width:n,height:i,fill:this.themeConfig.quadrant1Fill},{text:{text:this.data.quadrant2Text,fill:this.themeConfig.quadrant2TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a,y:s,width:n,height:i,fill:this.themeConfig.quadrant2Fill},{text:{text:this.data.quadrant3Text,fill:this.themeConfig.quadrant3TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a,y:s+i,width:n,height:i,fill:this.themeConfig.quadrant3Fill},{text:{text:this.data.quadrant4Text,fill:this.themeConfig.quadrant4TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a+n,y:s+i,width:n,height:i,fill:this.themeConfig.quadrant4Fill}];for(const o of r)o.text.x=o.x+o.width/2,0===this.data.points.length?(o.text.y=o.y+o.height/2,o.text.horizontalPos="middle"):(o.text.y=o.y+this.config.quadrantTextTopPadding,o.text.horizontalPos="top");return r}getQuadrantPoints(t){const{quadrantSpace:e}=t,{quadrantHeight:i,quadrantLeft:a,quadrantTop:n,quadrantWidth:r}=e,o=(0,s.m4Y)().domain([0,1]).range([a,r+a]),l=(0,s.m4Y)().domain([0,1]).range([i+n,n]);return this.data.points.map(t=>{const e=this.classes.get(t.className);e&&(t={...e,...t});return{x:o(t.x),y:l(t.y),fill:t.color??this.themeConfig.quadrantPointFill,radius:t.radius??this.config.pointRadius,text:{text:t.text,fill:this.themeConfig.quadrantPointTextFill,x:o(t.x),y:l(t.y)+this.config.pointTextPadding,verticalPos:"center",horizontalPos:"top",fontSize:this.config.pointLabelFontSize,rotation:0},strokeColor:t.strokeColor??this.themeConfig.quadrantPointFill,strokeWidth:t.strokeWidth??"0px"}})}getBorders(t){const e=this.config.quadrantExternalBorderStrokeWidth/2,{quadrantSpace:i}=t,{quadrantHalfHeight:a,quadrantHeight:n,quadrantLeft:s,quadrantHalfWidth:r,quadrantTop:o,quadrantWidth:l}=i;return[{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s-e,y1:o,x2:s+l+e,y2:o},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s+l,y1:o+e,x2:s+l,y2:o+n-e},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s-e,y1:o+n,x2:s+l+e,y2:o+n},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s,y1:o+e,x2:s,y2:o+n-e},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:s+r,y1:o+e,x2:s+r,y2:o+n-e},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:s+e,y1:o+a,x2:s+l-e,y2:o+a}]}getTitle(t){if(t)return{text:this.data.titleText,fill:this.themeConfig.quadrantTitleFill,fontSize:this.config.titleFontSize,horizontalPos:"top",verticalPos:"center",rotation:0,y:this.config.titlePadding,x:this.config.chartWidth/2}}build(){const t=this.config.showXAxis&&!(!this.data.xAxisLeftText&&!this.data.xAxisRightText),e=this.config.showYAxis&&!(!this.data.yAxisTopText&&!this.data.yAxisBottomText),i=this.config.showTitle&&!!this.data.titleText,a=this.data.points.length>0?"bottom":this.config.xAxisPosition,n=this.calculateSpace(a,t,e,i);return{points:this.getQuadrantPoints(n),quadrants:this.getQuadrants(n),axisLabels:this.getAxisLabels(a,t,e,n),borderLines:this.getBorders(n),title:this.getTitle(i)}}},c=class extends Error{static{(0,n.K2)(this,"InvalidStyleError")}constructor(t,e,i){super(`value for ${t} ${e} is invalid, please use a valid ${i}`),this.name="InvalidStyleError"}};function d(t){return!/^#?([\dA-Fa-f]{6}|[\dA-Fa-f]{3})$/.test(t)}function u(t){return!/^\d+$/.test(t)}function x(t){return!/^\d+px$/.test(t)}(0,n.K2)(d,"validateHexCode"),(0,n.K2)(u,"validateNumber"),(0,n.K2)(x,"validateSizeInPixels");var g=(0,a.D7)();function f(t){return(0,a.jZ)(t.trim(),g)}(0,n.K2)(f,"textSanitizer");var p=new h;function y(t){p.setData({quadrant1Text:f(t.text)})}function T(t){p.setData({quadrant2Text:f(t.text)})}function m(t){p.setData({quadrant3Text:f(t.text)})}function q(t){p.setData({quadrant4Text:f(t.text)})}function A(t){p.setData({xAxisLeftText:f(t.text)})}function _(t){p.setData({xAxisRightText:f(t.text)})}function b(t){p.setData({yAxisTopText:f(t.text)})}function S(t){p.setData({yAxisBottomText:f(t.text)})}function k(t){const e={};for(const i of t){const[t,a]=i.trim().split(/\s*:\s*/);if("radius"===t){if(u(a))throw new c(t,a,"number");e.radius=parseInt(a)}else if("color"===t){if(d(a))throw new c(t,a,"hex code");e.color=a}else if("stroke-color"===t){if(d(a))throw new c(t,a,"hex code");e.strokeColor=a}else{if("stroke-width"!==t)throw new Error(`style named ${t} is not supported.`);if(x(a))throw new c(t,a,"number of pixels (eg. 10px)");e.strokeWidth=a}}return e}function F(t,e,i,a,n){const s=k(n);p.addPoints([{x:i,y:a,text:f(t.text),className:e,...s}])}function P(t,e){p.addClass(t,k(e))}function C(t){p.setConfig({chartWidth:t})}function L(t){p.setConfig({chartHeight:t})}function v(){const t=(0,a.D7)(),{themeVariables:e,quadrantChart:i}=t;return i&&p.setConfig(i),p.setThemeConfig({quadrant1Fill:e.quadrant1Fill,quadrant2Fill:e.quadrant2Fill,quadrant3Fill:e.quadrant3Fill,quadrant4Fill:e.quadrant4Fill,quadrant1TextFill:e.quadrant1TextFill,quadrant2TextFill:e.quadrant2TextFill,quadrant3TextFill:e.quadrant3TextFill,quadrant4TextFill:e.quadrant4TextFill,quadrantPointFill:e.quadrantPointFill,quadrantPointTextFill:e.quadrantPointTextFill,quadrantXAxisTextFill:e.quadrantXAxisTextFill,quadrantYAxisTextFill:e.quadrantYAxisTextFill,quadrantExternalBorderStrokeFill:e.quadrantExternalBorderStrokeFill,quadrantInternalBorderStrokeFill:e.quadrantInternalBorderStrokeFill,quadrantTitleFill:e.quadrantTitleFill}),p.setData({titleText:(0,a.ab)()}),p.build()}(0,n.K2)(y,"setQuadrant1Text"),(0,n.K2)(T,"setQuadrant2Text"),(0,n.K2)(m,"setQuadrant3Text"),(0,n.K2)(q,"setQuadrant4Text"),(0,n.K2)(A,"setXAxisLeftText"),(0,n.K2)(_,"setXAxisRightText"),(0,n.K2)(b,"setYAxisTopText"),(0,n.K2)(S,"setYAxisBottomText"),(0,n.K2)(k,"parseStyles"),(0,n.K2)(F,"addPoint"),(0,n.K2)(P,"addClass"),(0,n.K2)(C,"setWidth"),(0,n.K2)(L,"setHeight"),(0,n.K2)(v,"getQuadrantData");var I={parser:o,db:{setWidth:C,setHeight:L,setQuadrant1Text:y,setQuadrant2Text:T,setQuadrant3Text:m,setQuadrant4Text:q,setXAxisLeftText:A,setXAxisRightText:_,setYAxisTopText:b,setYAxisBottomText:S,parseStyles:k,addPoint:F,addClass:P,getQuadrantData:v,clear:(0,n.K2)(function(){p.clear(),(0,a.IU)()},"clear"),setAccTitle:a.SV,getAccTitle:a.iN,setDiagramTitle:a.ke,getDiagramTitle:a.ab,getAccDescription:a.m7,setAccDescription:a.EI},renderer:{draw:(0,n.K2)((t,e,i,r)=>{function o(t){return"top"===t?"hanging":"middle"}function l(t){return"left"===t?"start":"middle"}function h(t){return`translate(${t.x}, ${t.y}) rotate(${t.rotation||0})`}(0,n.K2)(o,"getDominantBaseLine"),(0,n.K2)(l,"getTextAnchor"),(0,n.K2)(h,"getTransformation");const c=(0,a.D7)();n.Rm.debug("Rendering quadrant chart\n"+t);const d=c.securityLevel;let u;"sandbox"===d&&(u=(0,s.Ltv)("#i"+e));const x=("sandbox"===d?(0,s.Ltv)(u.nodes()[0].contentDocument.body):(0,s.Ltv)("body")).select(`[id="${e}"]`),g=x.append("g").attr("class","main"),f=c.quadrantChart?.chartWidth??500,p=c.quadrantChart?.chartHeight??500;(0,a.a$)(x,p,f,c.quadrantChart?.useMaxWidth??!0),x.attr("viewBox","0 0 "+f+" "+p),r.db.setHeight(p),r.db.setWidth(f);const y=r.db.getQuadrantData(),T=g.append("g").attr("class","quadrants"),m=g.append("g").attr("class","border"),q=g.append("g").attr("class","data-points"),A=g.append("g").attr("class","labels"),_=g.append("g").attr("class","title");y.title&&_.append("text").attr("x",0).attr("y",0).attr("fill",y.title.fill).attr("font-size",y.title.fontSize).attr("dominant-baseline",o(y.title.horizontalPos)).attr("text-anchor",l(y.title.verticalPos)).attr("transform",h(y.title)).text(y.title.text),y.borderLines&&m.selectAll("line").data(y.borderLines).enter().append("line").attr("x1",t=>t.x1).attr("y1",t=>t.y1).attr("x2",t=>t.x2).attr("y2",t=>t.y2).style("stroke",t=>t.strokeFill).style("stroke-width",t=>t.strokeWidth);const b=T.selectAll("g.quadrant").data(y.quadrants).enter().append("g").attr("class","quadrant");b.append("rect").attr("x",t=>t.x).attr("y",t=>t.y).attr("width",t=>t.width).attr("height",t=>t.height).attr("fill",t=>t.fill),b.append("text").attr("x",0).attr("y",0).attr("fill",t=>t.text.fill).attr("font-size",t=>t.text.fontSize).attr("dominant-baseline",t=>o(t.text.horizontalPos)).attr("text-anchor",t=>l(t.text.verticalPos)).attr("transform",t=>h(t.text)).text(t=>t.text.text);A.selectAll("g.label").data(y.axisLabels).enter().append("g").attr("class","label").append("text").attr("x",0).attr("y",0).text(t=>t.text).attr("fill",t=>t.fill).attr("font-size",t=>t.fontSize).attr("dominant-baseline",t=>o(t.horizontalPos)).attr("text-anchor",t=>l(t.verticalPos)).attr("transform",t=>h(t));const S=q.selectAll("g.data-point").data(y.points).enter().append("g").attr("class","data-point");S.append("circle").attr("cx",t=>t.x).attr("cy",t=>t.y).attr("r",t=>t.radius).attr("fill",t=>t.fill).attr("stroke",t=>t.strokeColor).attr("stroke-width",t=>t.strokeWidth),S.append("text").attr("x",0).attr("y",0).text(t=>t.text.text).attr("fill",t=>t.text.fill).attr("font-size",t=>t.text.fontSize).attr("dominant-baseline",t=>o(t.text.horizontalPos)).attr("text-anchor",t=>l(t.text.verticalPos)).attr("transform",t=>h(t.text))},"draw")},styles:(0,n.K2)(()=>"","styles")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/142263a9.262679e8.js b/pr-preview/pr-4027/assets/js/142263a9.262679e8.js deleted file mode 100644 index 2eb9a8846..000000000 --- a/pr-preview/pr-4027/assets/js/142263a9.262679e8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3531],{2135:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"workflows/terminate","title":"Terminate your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","source":"@site/versioned_docs/version-2.23/workflows/terminate.md","sourceDirName":"workflows","slug":"/workflows/terminate","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/terminate","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/workflows/terminate.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Install s3proxy","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/s3proxy"},"next":{"title":"Recover your cluster","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/recovery"}}');var o=n(74848),s=n(28453);const a={},i="Terminate your cluster",l={},c=[];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",header:"header",hr:"hr",p:"p",pre:"pre",...(0,s.R)(),...e.components},{AsciinemaWidget:n,TabItem:r,Tabs:a}=t;return n||u("AsciinemaWidget",!0),r||u("TabItem",!0),a||u("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"terminate-your-cluster",children:"Terminate your cluster"})}),"\n",(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsx)(t.p,{children:"This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details."})}),"\n",(0,o.jsx)(n,{src:"/constellation/assets/terminate-cluster.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,o.jsx)(t.hr,{}),"\n",(0,o.jsxs)(t.p,{children:["You can terminate your cluster using the CLI. For this, you need the Terraform state directory named ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/reference/terraform",children:(0,o.jsx)(t.code,{children:"constellation-terraform"})})," in the current directory."]}),"\n",(0,o.jsx)(t.admonition,{type:"danger",children:(0,o.jsx)(t.p,{children:"All ephemeral storage and state of your cluster will be lost. Make sure any data is safely stored in persistent storage. Constellation can recreate your cluster and the associated encryption keys, but won't backup your application data automatically."})}),"\n",(0,o.jsxs)(a,{groupId:"provider",children:[(0,o.jsxs)(r,{value:"cli",label:"CLI",children:[(0,o.jsx)(t.p,{children:"Terminate the cluster by running:"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation terminate\n"})}),(0,o.jsx)(t.p,{children:"Or without confirmation (e.g., for automation purposes):"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation terminate --yes\n"})}),(0,o.jsxs)(t.p,{children:["This deletes all resources created by Constellation in your cloud environment.\nAll local files created by the ",(0,o.jsx)(t.code,{children:"apply"})," command are deleted as well, except for ",(0,o.jsx)(t.code,{children:"constellation-mastersecret.json"})," and the configuration file."]}),(0,o.jsx)(t.admonition,{type:"caution",children:(0,o.jsxs)(t.p,{children:["Termination can fail if additional resources have been created that depend on the ones managed by Constellation. In this case, you need to delete these additional\nresources manually. Just run the ",(0,o.jsx)(t.code,{children:"terminate"})," command again afterward to continue the termination process of the cluster."]})})]}),(0,o.jsxs)(r,{value:"terraform",label:"Terraform",children:[(0,o.jsx)(t.p,{children:"Terminate the cluster by running:"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"terraform destroy\n"})}),(0,o.jsx)(t.p,{children:"Delete all files that are no longer needed:"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"rm constellation-state.yaml constellation-admin.conf\n"})}),(0,o.jsxs)(t.p,{children:["Only the ",(0,o.jsx)(t.code,{children:"constellation-mastersecret.json"})," and the configuration file remain."]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}function u(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var r=n(96540);const o={},s=r.createContext(o);function a(e){const t=r.useContext(s);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/14eb3368.770f55ac.js b/pr-preview/pr-4027/assets/js/14eb3368.770f55ac.js deleted file mode 100644 index adfe32cc2..000000000 --- a/pr-preview/pr-4027/assets/js/14eb3368.770f55ac.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6969],{62400:(e,s,n)=>{n.d(s,{A:()=>c});n(96540);var t=n(34164),r=n(23230),a=n(14783),i=n(74848);function l(e){const{permalink:s,title:n,subLabel:r,isNext:l}=e;return(0,i.jsxs)(a.A,{className:(0,t.A)("pagination-nav__link",l?"pagination-nav__link--next":"pagination-nav__link--prev"),to:s,children:[r&&(0,i.jsx)("div",{className:"pagination-nav__sublabel",children:r}),(0,i.jsx)("div",{className:"pagination-nav__label",children:n})]})}function c(e){const{className:s,previous:n,next:a}=e;return(0,i.jsxs)("nav",{className:(0,t.A)(s,"pagination-nav"),"aria-label":(0,r.T)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[n&&(0,i.jsx)(l,{...n,subLabel:(0,i.jsx)(r.A,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),a&&(0,i.jsx)(l,{...a,subLabel:(0,i.jsx)(r.A,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}},62529:(e,s,n)=>{n.d(s,{A:()=>j});n(96540);var t=n(34164),r=n(18630),a=n(45357),i=n(80260),l=n(14783),c=n(23230),o=n(98180),d=n(74848);function u(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,d.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const m={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function h(){const e=(0,o.Ay)("/");return(0,d.jsx)("li",{className:"breadcrumbs__item",children:(0,d.jsx)(l.A,{"aria-label":(0,c.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,d.jsx)(u,{className:m.breadcrumbHomeIcon})})})}var b=n(21141),x=n(97639);function p(e){const s=function({breadcrumbs:e}){const{siteConfig:s}=(0,x.A)();return{"@context":"https://schema.org","@type":"BreadcrumbList",itemListElement:e.filter(e=>e.href).map((e,n)=>({"@type":"ListItem",position:n+1,name:e.label,item:`${s.url}${e.href}`}))}}({breadcrumbs:e.breadcrumbs});return(0,d.jsx)(b.A,{children:(0,d.jsx)("script",{type:"application/ld+json",children:JSON.stringify(s)})})}const g={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function v({children:e,href:s,isLast:n}){const t="breadcrumbs__link";return n?(0,d.jsx)("span",{className:t,children:e}):s?(0,d.jsx)(l.A,{className:t,href:s,children:(0,d.jsx)("span",{children:e})}):(0,d.jsx)("span",{className:t,children:e})}function f({children:e,active:s}){return(0,d.jsx)("li",{className:(0,t.A)("breadcrumbs__item",{"breadcrumbs__item--active":s}),children:e})}function j(){const e=(0,a.OF)(),s=(0,i.Dt)();return e?(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(p,{breadcrumbs:e}),(0,d.jsx)("nav",{className:(0,t.A)(r.G.docs.docBreadcrumbs,g.breadcrumbsContainer),"aria-label":(0,c.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,d.jsxs)("ul",{className:"breadcrumbs",children:[s&&(0,d.jsx)(h,{}),e.map((s,n)=>{const t=n===e.length-1,r="category"===s.type&&s.linkUnlisted?void 0:s.href;return(0,d.jsx)(f,{active:t,children:(0,d.jsx)(v,{href:r,isLast:t,children:s.label})},n)})]})})]}):null}},63790:(e,s,n)=>{n.r(s),n.d(s,{default:()=>P});var t=n(96540),r=n(17153),a=n(45357),i=n(98180),l=n(34164),c=n(14783),o=n(97639);const d=["zero","one","two","few","many","other"];function u(e){return d.filter(s=>e.includes(s))}const m={locale:"en",pluralForms:u(["one","other"]),select:e=>1===e?"one":"other"};function h(){const{i18n:{currentLocale:e}}=(0,o.A)();return(0,t.useMemo)(()=>{try{return function(e){const s=new Intl.PluralRules(e);return{locale:e,pluralForms:u(s.resolvedOptions().pluralCategories),select:e=>s.select(e)}}(e)}catch(s){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${s.message}\n`),m}},[e])}function b(){const e=h();return{selectMessage:(s,n)=>function(e,s,n){const t=e.split("|");if(1===t.length)return t[0];t.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${t.length}: ${e}`);const r=n.select(s),a=n.pluralForms.indexOf(r);return t[Math.min(a,t.length-1)]}(n,s,e)}}var x=n(40877),p=n(23230),g=n(85225);const v={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var f=n(74848);function j({className:e,href:s,children:n}){return(0,f.jsx)(c.A,{href:s,className:(0,l.A)("card padding--lg",v.cardContainer,e),children:n})}function N({className:e,href:s,icon:n,title:t,description:r}){return(0,f.jsxs)(j,{href:s,className:e,children:[(0,f.jsxs)(g.A,{as:"h2",className:(0,l.A)("text--truncate",v.cardTitle),title:t,children:[n," ",t]}),r&&(0,f.jsx)("p",{className:(0,l.A)("text--truncate",v.cardDescription),title:r,children:r})]})}function A({item:e}){const s=(0,a.Nr)(e),n=function(){const{selectMessage:e}=b();return s=>e(s,(0,p.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:s}))}();return s?(0,f.jsx)(N,{className:e.className,href:s,icon:"\ud83d\uddc3\ufe0f",title:e.label,description:e.description??n(e.items.length)}):null}function L({item:e}){const s=(0,x.A)(e.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",n=(0,a.cC)(e.docId??void 0);return(0,f.jsx)(N,{className:e.className,href:e.href,icon:s,title:e.label,description:e.description??n?.description})}function _({item:e}){switch(e.type){case"link":return(0,f.jsx)(L,{item:e});case"category":return(0,f.jsx)(A,{item:e});default:throw new Error(`unknown item type ${JSON.stringify(e)}`)}}const T={docCardListItem:"docCardListItem_W1sv"};function k({className:e}){const s=(0,a.a4)();return(0,f.jsx)(I,{items:s,className:e})}function y({item:e}){return(0,f.jsx)("article",{className:(0,l.A)(T.docCardListItem,"col col--6"),children:(0,f.jsx)(_,{item:e})})}function I(e){const{items:s,className:n}=e;if(!s)return(0,f.jsx)(k,{...e});const t=(0,a.d1)(s);return(0,f.jsx)("section",{className:(0,l.A)("row",n),children:t.map((e,s)=>(0,f.jsx)(y,{item:e},s))})}var C=n(62400),w=n(84799),F=n(79436),V=n(62529);const M={generatedIndexPage:"generatedIndexPage_vN6x",title:"title_kItE"};function $({categoryGeneratedIndex:e}){return(0,f.jsx)(r.be,{title:e.title,description:e.description,keywords:e.keywords,image:(0,i.Ay)(e.image)})}function D({categoryGeneratedIndex:e}){const s=(0,a.$S)();return(0,f.jsxs)("div",{className:M.generatedIndexPage,children:[(0,f.jsx)(w.A,{}),(0,f.jsx)(V.A,{}),(0,f.jsx)(F.A,{}),(0,f.jsxs)("header",{children:[(0,f.jsx)(g.A,{as:"h1",className:M.title,children:e.title}),e.description&&(0,f.jsx)("p",{children:e.description})]}),(0,f.jsx)("article",{className:"margin-top--lg",children:(0,f.jsx)(I,{items:s.items,className:M.list})}),(0,f.jsx)("footer",{className:"margin-top--md",children:(0,f.jsx)(C.A,{previous:e.navigation.previous,next:e.navigation.next})})]})}function P(e){return(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)($,{...e}),(0,f.jsx)(D,{...e})]})}},79436:(e,s,n)=>{n.d(s,{A:()=>c});n(96540);var t=n(34164),r=n(23230),a=n(18630),i=n(91704),l=n(74848);function c({className:e}){const s=(0,i.r)();return s.badge?(0,l.jsx)("span",{className:(0,t.A)(e,a.G.docs.docVersionBadge,"badge badge--secondary"),children:(0,l.jsx)(r.A,{id:"theme.docs.versionBadge.label",values:{versionLabel:s.label},children:"Version: {versionLabel}"})}):null}},84799:(e,s,n)=>{n.d(s,{A:()=>p});n(96540);var t=n(34164),r=n(97639),a=n(14783),i=n(23230),l=n(19802),c=n(18630),o=n(86457),d=n(91704),u=n(74848);const m={unreleased:function({siteTitle:e,versionMetadata:s}){return(0,u.jsx)(i.A,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:e,versionLabel:(0,u.jsx)("b",{children:s.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function({siteTitle:e,versionMetadata:s}){return(0,u.jsx)(i.A,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:e,versionLabel:(0,u.jsx)("b",{children:s.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function h(e){const s=m[e.versionMetadata.banner];return(0,u.jsx)(s,{...e})}function b({versionLabel:e,to:s,onClick:n}){return(0,u.jsx)(i.A,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:e,latestVersionLink:(0,u.jsx)("b",{children:(0,u.jsx)(a.A,{to:s,onClick:n,children:(0,u.jsx)(i.A,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function x({className:e,versionMetadata:s}){const{siteConfig:{title:n}}=(0,r.A)(),{pluginId:a}=(0,l.vT)({failfast:!0}),{savePreferredVersionName:i}=(0,o.g1)(a),{latestDocSuggestion:d,latestVersionSuggestion:m}=(0,l.HW)(a),x=d??(p=m).docs.find(e=>e.id===p.mainDocId);var p;return(0,u.jsxs)("div",{className:(0,t.A)(e,c.G.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,u.jsx)("div",{children:(0,u.jsx)(h,{siteTitle:n,versionMetadata:s})}),(0,u.jsx)("div",{className:"margin-top--md",children:(0,u.jsx)(b,{versionLabel:m.label,to:x.path,onClick:()=>i(m.name)})})]})}function p({className:e}){const s=(0,d.r)();return s.banner?(0,u.jsx)(x,{className:e,versionMetadata:s}):null}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/15c6e37c.d85a6cae.js b/pr-preview/pr-4027/assets/js/15c6e37c.d85a6cae.js deleted file mode 100644 index 1775b7a66..000000000 --- a/pr-preview/pr-4027/assets/js/15c6e37c.d85a6cae.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1268],{28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>l});var o=n(96540);const s={},a=o.createContext(s);function r(e){const t=o.useContext(a);return o.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(a.Provider,{value:t},e.children)}},75514:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>p,frontMatter:()=>r,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"workflows/cert-manager","title":"Install cert-manager","description":"If you want to use cert-manager with Constellation, pay attention to the following to avoid potential pitfalls.","source":"@site/docs/workflows/cert-manager.md","sourceDirName":"workflows","slug":"/workflows/cert-manager","permalink":"/constellation/pr-preview/pr-4027/next/workflows/cert-manager","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/workflows/cert-manager.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Expose a service","permalink":"/constellation/pr-preview/pr-4027/next/workflows/lb"},"next":{"title":"Install s3proxy","permalink":"/constellation/pr-preview/pr-4027/next/workflows/s3proxy"}}');var s=n(74848),a=n(28453);const r={},l="Install cert-manager",i={},c=[];function d(e){const t={admonition:"admonition",code:"code",h1:"h1",header:"header",p:"p",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"install-cert-manager",children:"Install cert-manager"})}),"\n",(0,s.jsx)(t.admonition,{type:"caution",children:(0,s.jsx)(t.p,{children:"If you want to use cert-manager with Constellation, pay attention to the following to avoid potential pitfalls."})}),"\n",(0,s.jsxs)(t.p,{children:["Constellation ships with cert-manager preinstalled.\nThe default installation is part of the ",(0,s.jsx)(t.code,{children:"kube-system"})," namespace, as all other Constellation-managed microservices.\nYou are free to install more instances of cert-manager into other namespaces.\nHowever, be aware that any new installation needs to use the same version as the one installed with Constellation or rely on the same CRD versions.\nAlso remember to set the ",(0,s.jsx)(t.code,{children:"installCRDs"})," value to ",(0,s.jsx)(t.code,{children:"false"})," when installing new cert-manager instances.\nIt will create problems if you have two installations of cert-manager depending on different versions of the installed CRDs.\nCRDs are cluster-wide resources and cert-manager depends on specific versions of those CRDs for each release."]})]})}function p(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/15e5e9ad.32e35ac7.js b/pr-preview/pr-4027/assets/js/15e5e9ad.32e35ac7.js deleted file mode 100644 index 86001dbeb..000000000 --- a/pr-preview/pr-4027/assets/js/15e5e9ad.32e35ac7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1298],{28453:(e,s,n)=>{n.d(s,{R:()=>r,x:()=>a});var t=n(96540);const i={},o=t.createContext(i);function r(e){const s=t.useContext(o);return t.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),t.createElement(o.Provider,{value:s},e.children)}},62663:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"workflows/verify-cli","title":"Verify the CLI","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","source":"@site/versioned_docs/version-2.24/workflows/verify-cli.md","sourceDirName":"workflows","slug":"/workflows/verify-cli","permalink":"/constellation/pr-preview/pr-4027/workflows/verify-cli","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/workflows/verify-cli.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Workflows","permalink":"/constellation/pr-preview/pr-4027/category/workflows"},"next":{"title":"Configure your cluster","permalink":"/constellation/pr-preview/pr-4027/workflows/config"}}');var i=n(74848),o=n(28453);const r={},a="Verify the CLI",l={},c=[{value:"Verify the signature",id:"verify-the-signature",level:2},{value:"Optional: Manually inspect the transparency log",id:"optional-manually-inspect-the-transparency-log",level:3},{value:"Verify the provenance",id:"verify-the-provenance",level:2}];function d(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",...(0,o.R)(),...e.components},{AsciinemaWidget:n}=s;return n||function(e,s){throw new Error("Expected "+(s?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("AsciinemaWidget",!0),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.header,{children:(0,i.jsx)(s.h1,{id:"verify-the-cli",children:"Verify the CLI"})}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details."})}),"\n",(0,i.jsx)(n,{src:"/constellation/assets/verify-cli.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsxs)(s.p,{children:["Edgeless Systems uses ",(0,i.jsx)(s.a,{href:"https://www.sigstore.dev/",children:"sigstore"})," and ",(0,i.jsx)(s.a,{href:"https://slsa.dev",children:"SLSA"}),' to ensure supply-chain security for the Constellation CLI and node images ("artifacts"). sigstore consists of three components: ',(0,i.jsx)(s.a,{href:"https://docs.sigstore.dev/cosign/signing/overview/",children:"Cosign"}),", ",(0,i.jsx)(s.a,{href:"https://docs.sigstore.dev/logging/overview",children:"Rekor"}),", and Fulcio. Edgeless Systems uses Cosign to sign artifacts. All signatures are uploaded to the public Rekor transparency log, which resides at ",(0,i.jsx)(s.code,{children:"https://rekor.sigstore.dev"}),"."]}),"\n",(0,i.jsxs)(s.admonition,{type:"note",children:[(0,i.jsx)(s.p,{children:"The public key for Edgeless Systems' long-term code-signing key is:"}),(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT\nJmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==\n-----END PUBLIC KEY-----\n"})}),(0,i.jsxs)(s.p,{children:["The public key is also available for download at ",(0,i.jsx)(s.a,{href:"https://edgeless.systems/es.pub",children:"https://edgeless.systems/es.pub"})," and in the Twitter profile ",(0,i.jsx)(s.a,{href:"https://twitter.com/EdgelessSystems",children:"@EdgelessSystems"}),"."]})]}),"\n",(0,i.jsx)(s.p,{children:"The Rekor transparency log is a public append-only ledger that verifies and records signatures and associated metadata. The Rekor transparency log enables everyone to observe the sequence of (software) signatures issued by Edgeless Systems and many other parties. The transparency log allows for the public identification of dubious or malicious signatures."}),"\n",(0,i.jsx)(s.p,{children:"You should always ensure that (1) your CLI executable was signed with the private key corresponding to the above public key and that (2) there is a corresponding entry in the Rekor transparency log. Both can be done as described in the following."}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"You don't need to verify the Constellation node images. This is done automatically by your CLI and the rest of Constellation."})}),"\n",(0,i.jsx)(s.h2,{id:"verify-the-signature",children:"Verify the signature"}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"This guide assumes Linux on an amd64 processor. The exact steps for other platforms differ slightly."})}),"\n",(0,i.jsxs)(s.p,{children:["First, ",(0,i.jsx)(s.a,{href:"https://docs.sigstore.dev/cosign/system_config/installation/",children:"install the Cosign CLI"}),". Next, ",(0,i.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"download"})," and verify the signature that accompanies your CLI executable, for example:"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:"$ cosign verify-blob --key https://edgeless.systems/es.pub --signature constellation-linux-amd64.sig constellation-linux-amd64\n\nVerified OK\n"})}),"\n",(0,i.jsxs)(s.p,{children:["The above performs an offline verification of the provided public key, signature, and executable. To also verify that a corresponding entry exists in the public Rekor transparency log, add the variable ",(0,i.jsx)(s.code,{children:"COSIGN_EXPERIMENTAL=1"}),":"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:"$ COSIGN_EXPERIMENTAL=1 cosign verify-blob --key https://edgeless.systems/es.pub --signature constellation-linux-amd64.sig constellation-linux-amd64\n\ntlog entry verified with uuid: afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13 index: 3477047\nVerified OK\n"})}),"\n",(0,i.jsx)(s.p,{children:"\ud83c\udfc1 You now know that your CLI executable was officially released and signed by Edgeless Systems."}),"\n",(0,i.jsx)(s.h3,{id:"optional-manually-inspect-the-transparency-log",children:"Optional: Manually inspect the transparency log"}),"\n",(0,i.jsxs)(s.p,{children:["To further inspect the public Rekor transparency log, ",(0,i.jsx)(s.a,{href:"https://docs.sigstore.dev/logging/installation",children:"install the Rekor CLI"}),". A search for the CLI executable should give a single UUID. (Note that this UUID contains the UUID from the previous ",(0,i.jsx)(s.code,{children:"cosign"})," command.)"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:"$ rekor-cli search --artifact constellation-linux-amd64\n\nFound matching entries (listed by UUID):\n362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13\n"})}),"\n",(0,i.jsx)(s.p,{children:"With this UUID you can get the full entry from the transparency log:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:'$ rekor-cli get --uuid=362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13\n\nLogID: c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d\nIndex: 3477047\nIntegratedTime: 2022-09-12T22:28:16Z\nUUID: afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13\nBody: {\n "HashedRekordObj": {\n "data": {\n "hash": {\n "algorithm": "sha256",\n "value": "40e137b9b9b8204d672642fd1e181c6d5ccb50cfc5cc7fcbb06a8c2c78f44aff"\n }\n },\n "signature": {\n "content": "MEUCIQCSER3mGj+j5Pr2kOXTlCIHQC3gT30I7qkLr9Awt6eUUQIgcLUKRIlY50UN8JGwVeNgkBZyYD8HMxwC/LFRWoMn180=",\n "publicKey": {\n "content": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFZjhGMWhwbXdFK1lDRlh6akd0YVFjckw2WFpWVApKbUVlNWlTTHZHMVN5UVNBZXc3V2RNS0Y2bzl0OGUyVEZ1Q2t6bE9oaGx3czJPSFdiaUZabkZXQ0Z3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=="\n }\n }\n }\n}\n'})}),"\n",(0,i.jsxs)(s.p,{children:["The field ",(0,i.jsx)(s.code,{children:"publicKey"})," should contain Edgeless Systems' public key in Base64 encoding."]}),"\n",(0,i.jsx)(s.p,{children:"You can get an exhaustive list of artifact signatures issued by Edgeless Systems via the following command:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-bash",children:"rekor-cli search --public-key https://edgeless.systems/es.pub --pki-format x509\n"})}),"\n",(0,i.jsx)(s.p,{children:"Edgeless Systems monitors this list to detect potential unauthorized use of its private key."}),"\n",(0,i.jsx)(s.h2,{id:"verify-the-provenance",children:"Verify the provenance"}),"\n",(0,i.jsxs)(s.p,{children:["Provenance attests that a software artifact was produced by a specific repository and build system invocation. For more information on provenance visit ",(0,i.jsx)(s.a,{href:"https://slsa.dev/provenance/v0.2",children:"slsa.dev"})," and learn about the ",(0,i.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/reference/slsa",children:"adoption of SLSA for Constellation"}),"."]}),"\n",(0,i.jsx)(s.p,{children:"Just as checking its signature proves that the CLI hasn't been manipulated, checking the provenance proves that the artifact was produced by the expected build process and hasn't been tampered with."}),"\n",(0,i.jsxs)(s.p,{children:["To verify the provenance, first install the ",(0,i.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-verifier",children:"slsa-verifier"}),". Then make sure you have the provenance file (",(0,i.jsx)(s.code,{children:"constellation.intoto.jsonl"}),") and Constellation CLI downloaded. Both are available on the ",(0,i.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub release page"}),"."]}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"The same provenance file is valid for all Constellation CLI executables of a given version independent of the target platform."})}),"\n",(0,i.jsx)(s.p,{children:"Use the verifier to perform the check:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:"$ slsa-verifier verify-artifact constellation-linux-amd64 \\\n --provenance-path constellation.intoto.jsonl \\\n --source-uri github.com/edgelesssys/constellation\n\nVerified signature against tlog entry index 7771317 at URL: https://rekor.sigstore.dev/api/v1/log/entries/24296fb24b8ad77af2c04c8b4ae0d5bc5...\nVerified build using builder https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v1.2.2 at commit 18e9924b416323c37b9cdfd6cc728de8a947424a\nPASSED: Verified SLSA provenance\n"})})]})}function h(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/165.fdd19a26.js b/pr-preview/pr-4027/assets/js/165.fdd19a26.js deleted file mode 100644 index 5093f9da0..000000000 --- a/pr-preview/pr-4027/assets/js/165.fdd19a26.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see 165.fdd19a26.js.LICENSE.txt */ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[165],{90165:(e,t,n)=>{function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,o=!0,s=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return o=e.done,e},e:function(e){s=!0,i=e},f:function(){try{o||null==n.return||n.return()}finally{if(s)throw i}}}}function s(e,t,n){return(t=c(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,a,i,o,s=[],l=!0,u=!1;try{if(i=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;l=!1}else for(;!(l=(r=i.call(n)).done)&&(s.push(r.value),s.length!==t);l=!0);}catch(e){u=!0,a=e}finally{try{if(!l&&null!=n.return&&(o=n.return(),Object(o)!==o))return}finally{if(u)throw a}}return s}}(e,t)||h(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function u(e){return function(e){if(Array.isArray(e))return r(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||h(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function c(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t);if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e,"string");return"symbol"==typeof t?t:t+""}function d(e){return d="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},d(e)}function h(e,t){if(e){if("string"==typeof e)return r(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(e,t):void 0}}n.d(t,{A:()=>Kh});var f="undefined"==typeof window?null:window,p=f?f.navigator:null;f&&f.document;var v,g,y,m,b,x,w,E,k,T,C,P,S,B,D,_,A,M,R,I,N,L,z,O,V,F,X,j,Y=d(""),q=d({}),W=d(function(){}),U="undefined"==typeof HTMLElement?"undefined":d(HTMLElement),H=function(e){return e&&e.instanceString&&G(e.instanceString)?e.instanceString():null},K=function(e){return null!=e&&d(e)==Y},G=function(e){return null!=e&&d(e)===W},Z=function(e){return!ee(e)&&(Array.isArray?Array.isArray(e):null!=e&&e instanceof Array)},$=function(e){return null!=e&&d(e)===q&&!Z(e)&&e.constructor===Object},Q=function(e){return null!=e&&d(e)===d(1)&&!isNaN(e)},J=function(e){return"undefined"===U?void 0:null!=e&&e instanceof HTMLElement},ee=function(e){return te(e)||ne(e)},te=function(e){return"collection"===H(e)&&e._private.single},ne=function(e){return"collection"===H(e)&&!e._private.single},re=function(e){return"core"===H(e)},ae=function(e){return"stylesheet"===H(e)},ie=function(e){return null==e||!(""!==e&&!e.match(/^\s+$/))},oe=function(e){return function(e){return null!=e&&d(e)===q}(e)&&G(e.then)},se=function(e,t){t||(t=function(){if(1===arguments.length)return arguments[0];if(0===arguments.length)return"undefined";for(var e=[],t=0;tt?1:0},be=null!=Object.assign?Object.assign.bind(Object):function(e){for(var t=arguments,n=1;n255)return;t.push(Math.floor(i))}var o=r[1]||r[2]||r[3],s=r[1]&&r[2]&&r[3];if(o&&!s)return;var l=n[4];if(void 0!==l){if((l=parseFloat(l))<0||l>1)return;t.push(l)}}return t}(e)||function(e){var t,n,r,a,i,o,s,l;function u(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}var c=new RegExp("^"+ge+"$").exec(e);if(c){if((n=parseInt(c[1]))<0?n=(360- -1*n%360)%360:n>360&&(n%=360),n/=360,(r=parseFloat(c[2]))<0||r>100)return;if(r/=100,(a=parseFloat(c[3]))<0||a>100)return;if(a/=100,void 0!==(i=c[4])&&((i=parseFloat(i))<0||i>1))return;if(0===r)o=s=l=Math.round(255*a);else{var d=a<.5?a*(1+r):a+r-a*r,h=2*a-d;o=Math.round(255*u(h,d,n+1/3)),s=Math.round(255*u(h,d,n)),l=Math.round(255*u(h,d,n-1/3))}t=[o,s,l,i]}return t}(e)},we={transparent:[0,0,0,0],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},Ee=function(e){for(var t=e.map,n=e.keys,r=n.length,a=0;a=o||t<0||g&&e-p>=c}function x(){var e=t();if(b(e))return w(e);h=setTimeout(x,function(e){var t=o-(e-f);return g?a(t,c-(e-p)):t}(e))}function w(e){return h=void 0,y&&l?m(e):(l=u=void 0,d)}function E(){var e=t(),n=b(e);if(l=arguments,u=this,f=e,n){if(void 0===h)return function(e){return p=e,h=setTimeout(x,o),v?m(e):d}(f);if(g)return clearTimeout(h),h=setTimeout(x,o),m(f)}return void 0===h&&(h=setTimeout(x,o)),d}return o=n(o)||0,e(s)&&(v=!!s.leading,c=(g="maxWait"in s)?r(n(s.maxWait)||0,o):c,y="trailing"in s?!!s.trailing:y),E.cancel=function(){void 0!==h&&clearTimeout(h),p=0,l=f=u=h=void 0},E.flush=function(){return void 0===h?d:w(t())},E}}()),Re=f?f.performance:null,Ie=Re&&Re.now?function(){return Re.now()}:function(){return Date.now()},Ne=function(){if(f){if(f.requestAnimationFrame)return function(e){f.requestAnimationFrame(e)};if(f.mozRequestAnimationFrame)return function(e){f.mozRequestAnimationFrame(e)};if(f.webkitRequestAnimationFrame)return function(e){f.webkitRequestAnimationFrame(e)};if(f.msRequestAnimationFrame)return function(e){f.msRequestAnimationFrame(e)}}return function(e){e&&setTimeout(function(){e(Ie())},1e3/60)}}(),Le=function(e){return Ne(e)},ze=Ie,Oe=9261,Ve=5381,Fe=function(e){for(var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Oe;!(t=e.next()).done;)n=65599*n+t.value|0;return n},Xe=function(e){return 65599*(arguments.length>1&&void 0!==arguments[1]?arguments[1]:Oe)+e|0},je=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Ve;return(t<<5)+t+e|0},Ye=function(e){return 2097152*e[0]+e[1]},qe=function(e,t){return[Xe(e[0],t[0]),je(e[1],t[1])]},We=function(e,t){var n={value:0,done:!1},r=0,a=e.length;return Fe({next:function(){return r=0;r--)e[r]===t&&e.splice(r,1)},ft=function(e){e.splice(0,e.length)},pt=function(e,t,n){return n&&(t=ce(n,t)),e[t]},vt=function(e,t,n,r){n&&(t=ce(n,t)),e[t]=r},gt="undefined"!=typeof Map?Map:function(){return i(function e(){a(this,e),this._obj={}},[{key:"set",value:function(e,t){return this._obj[e]=t,this}},{key:"delete",value:function(e){return this._obj[e]=void 0,this}},{key:"clear",value:function(){this._obj={}}},{key:"has",value:function(e){return void 0!==this._obj[e]}},{key:"get",value:function(e){return this._obj[e]}}])}(),yt=function(){return i(function e(t){if(a(this,e),this._obj=Object.create(null),this.size=0,null!=t){var n;n=null!=t.instanceString&&t.instanceString()===this.instanceString()?t.toArray():t;for(var r=0;r2&&void 0!==arguments[2])||arguments[2];if(void 0!==e&&void 0!==t&&re(e)){var r=t.group;if(null==r&&(r=t.data&&null!=t.data.source&&null!=t.data.target?"edges":"nodes"),"nodes"===r||"edges"===r){this.length=1,this[0]=this;var a=this._private={cy:e,single:!0,data:t.data||{},position:t.position||{x:0,y:0},autoWidth:void 0,autoHeight:void 0,autoPadding:void 0,compoundBoundsClean:!1,listeners:[],group:r,style:{},rstyle:{},styleCxts:[],styleKeys:{},removed:!0,selected:!!t.selected,selectable:void 0===t.selectable||!!t.selectable,locked:!!t.locked,grabbed:!1,grabbable:void 0===t.grabbable||!!t.grabbable,pannable:void 0===t.pannable?"edges"===r:!!t.pannable,active:!1,classes:new mt,animation:{current:[],queue:[]},rscratch:{},scratch:t.scratch||{},edges:[],children:[],parent:t.parent&&t.parent.isNode()?t.parent:null,traversalCache:{},backgrounding:!1,bbCache:null,bbCacheShift:{x:0,y:0},bodyBounds:null,overlayBounds:null,labelBounds:{all:null,source:null,target:null,main:null},arrowBounds:{source:null,target:null,"mid-source":null,"mid-target":null}};if(null==a.position.x&&(a.position.x=0),null==a.position.y&&(a.position.y=0),t.renderedPosition){var i=t.renderedPosition,o=e.pan(),s=e.zoom();a.position={x:(i.x-o.x)/s,y:(i.y-o.y)/s}}var l=[];Z(t.classes)?l=t.classes:K(t.classes)&&(l=t.classes.split(/\s+/));for(var u=0,c=l.length;ut?1:0},u=function(e,t,a,i,o){var s;if(null==a&&(a=0),null==o&&(o=n),a<0)throw new Error("lo must be non-negative");for(null==i&&(i=e.length);an;0<=n?t++:t--)u.push(t);return u}.apply(this).reverse()).length;iv;0<=v?++h:--h)g.push(i(e,r));return g},p=function(e,t,r,a){var i,o,s;for(null==a&&(a=n),i=e[r];r>t&&a(i,o=e[s=r-1>>1])<0;)e[r]=o,r=s;return e[r]=i},v=function(e,t,r){var a,i,o,s,l;for(null==r&&(r=n),i=e.length,l=t,o=e[t],a=2*t+1;a0;){var w=y.pop(),E=v(w),k=w.id();if(d[k]=E,E!==1/0)for(var T=w.neighborhood().intersect(f),C=0;C0)for(n.unshift(t);c[a];){var i=c[a];n.unshift(i.edge),n.unshift(i.node),a=(r=i.node).id()}return o.spawn(n)}}}},Mt={kruskal:function(e){e=e||function(e){return 1};for(var t=this.byGroup(),n=t.nodes,r=t.edges,a=n.length,i=new Array(a),o=n,s=function(e){for(var t=0;t0;){if(x(),E++,u===d){for(var k=[],T=a,C=d,P=m[C];k.unshift(T),null!=P&&k.unshift(P),null!=(T=y[C]);)P=m[C=T.id()];return{found:!0,distance:h[u],path:this.spawn(k),steps:E}}p[u]=!0;for(var S=l._private.edges,B=0;BP&&(f[C]=P,y[C]=T,m[C]=x),!a){var S=T*u+k;!a&&f[S]>P&&(f[S]=P,y[S]=k,m[S]=x)}}}for(var B=0;B1&&void 0!==arguments[1]?arguments[1]:i,r=[],a=m(e);;){if(null==a)return t.spawn();var o=y(a),l=o.edge,u=o.pred;if(r.unshift(a[0]),a.same(n)&&r.length>0)break;null!=l&&r.unshift(l),a=u}return s.spawn(r)},hasNegativeWeightCycle:p,negativeWeightCycles:v}}},Vt=Math.sqrt(2),Ft=function(e,t,n){0===n.length&&at("Karger-Stein must be run on a connected (sub)graph");for(var r=n[e],a=r[1],i=r[2],o=t[a],s=t[i],l=n,u=l.length-1;u>=0;u--){var c=l[u],d=c[1],h=c[2];(t[d]===o&&t[h]===s||t[d]===s&&t[h]===o)&&l.splice(u,1)}for(var f=0;fr;){var a=Math.floor(Math.random()*t.length);t=Ft(a,e,t),n--}return t},jt={kargerStein:function(){var e=this,t=this.byGroup(),n=t.nodes,r=t.edges;r.unmergeBy(function(e){return e.isLoop()});var a=n.length,i=r.length,o=Math.ceil(Math.pow(Math.log(a)/Math.LN2,2)),s=Math.floor(a/Vt);if(!(a<2)){for(var l=[],u=0;u0?1:e<0?-1:0},Gt=function(e,t){return Math.sqrt(Zt(e,t))},Zt=function(e,t){var n=t.x-e.x,r=t.y-e.y;return n*n+r*r},$t=function(e){for(var t=e.length,n=0,r=0;r=e.x1&&e.y2>=e.y1)return{x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2,w:e.x2-e.x1,h:e.y2-e.y1};if(null!=e.w&&null!=e.h&&e.w>=0&&e.h>=0)return{x1:e.x1,y1:e.y1,x2:e.x1+e.w,y2:e.y1+e.h,w:e.w,h:e.h}}},nn=function(e,t){e.x1=Math.min(e.x1,t.x1),e.x2=Math.max(e.x2,t.x2),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,t.y1),e.y2=Math.max(e.y2,t.y2),e.h=e.y2-e.y1},rn=function(e,t,n){e.x1=Math.min(e.x1,t),e.x2=Math.max(e.x2,t),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,n),e.y2=Math.max(e.y2,n),e.h=e.y2-e.y1},an=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return e.x1-=t,e.x2+=t,e.y1-=t,e.y2+=t,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},on=function(e){var t,n,r,a,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[0];if(1===i.length)t=n=r=a=i[0];else if(2===i.length)t=r=i[0],a=n=i[1];else if(4===i.length){var o=l(i,4);t=o[0],n=o[1],r=o[2],a=o[3]}return e.x1-=a,e.x2+=n,e.y1-=t,e.y2+=r,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},sn=function(e,t){e.x1=t.x1,e.y1=t.y1,e.x2=t.x2,e.y2=t.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1},ln=function(e,t){return!(e.x1>t.x2)&&(!(t.x1>e.x2)&&(!(e.x2t.y2)&&!(t.y1>e.y2)))))))},un=function(e,t,n){return e.x1<=t&&t<=e.x2&&e.y1<=n&&n<=e.y2},cn=function(e,t){return un(e,t.x,t.y)},dn=function(e,t){return un(e,t.x1,t.y1)&&un(e,t.x2,t.y2)},hn=null!==(Bt=Math.hypot)&&void 0!==Bt?Bt:function(e,t){return Math.sqrt(e*e+t*t)};function fn(e,t,n,r,a,i){var o=function(e,t){if(e.length<3)throw new Error("Need at least 3 vertices");var n=function(e,t){return{x:e.x+t.x,y:e.y+t.y}},r=function(e,t){return{x:e.x-t.x,y:e.y-t.y}},a=function(e,t){return{x:e.x*t,y:e.y*t}},i=function(e,t){return e.x*t.y-e.y*t.x},o=function(e){var t=hn(e.x,e.y);return 0===t?{x:0,y:0}:{x:e.x/t,y:e.y/t}},s=function(e,t,o,s){var l=r(t,e),u=r(s,o),c=i(l,u);if(Math.abs(c)<1e-9)return n(e,a(l,.5));var d=i(r(o,e),u)/c;return n(e,a(l,d))},l=e.map(function(e){return{x:e.x,y:e.y}});(function(e){for(var t=0,n=0;n7&&void 0!==arguments[7]?arguments[7]:"auto",c="auto"===u?Rn(a,i):u,d=a/2,h=i/2,f=(c=Math.min(c,d,h))!==d,p=c!==h;if(f){var v=r-h-o;if((s=Pn(e,t,n,r,n-d+c-o,v,n+d-c+o,v,!1)).length>0)return s}if(p){var g=n+d+o;if((s=Pn(e,t,n,r,g,r-h+c-o,g,r+h-c+o,!1)).length>0)return s}if(f){var y=r+h+o;if((s=Pn(e,t,n,r,n-d+c-o,y,n+d-c+o,y,!1)).length>0)return s}if(p){var m=n-d-o;if((s=Pn(e,t,n,r,m,r-h+c-o,m,r+h-c+o,!1)).length>0)return s}var b=n-d+c,x=r-h+c;if((l=Tn(e,t,n,r,b,x,c+o)).length>0&&l[0]<=b&&l[1]<=x)return[l[0],l[1]];var w=n+d-c,E=r-h+c;if((l=Tn(e,t,n,r,w,E,c+o)).length>0&&l[0]>=w&&l[1]<=E)return[l[0],l[1]];var k=n+d-c,T=r+h-c;if((l=Tn(e,t,n,r,k,T,c+o)).length>0&&l[0]>=k&&l[1]>=T)return[l[0],l[1]];var C=n-d+c,P=r+h-c;return(l=Tn(e,t,n,r,C,P,c+o)).length>0&&l[0]<=C&&l[1]>=P?[l[0],l[1]]:[]},vn=function(e,t,n,r,a,i,o){var s=o,l=Math.min(n,a),u=Math.max(n,a),c=Math.min(r,i),d=Math.max(r,i);return l-s<=e&&e<=u+s&&c-s<=t&&t<=d+s},gn=function(e,t,n,r,a,i,o,s,l){var u=Math.min(n,o,a)-l,c=Math.max(n,o,a)+l,d=Math.min(r,s,i)-l,h=Math.max(r,s,i)+l;return!(ec||th)},yn=function(e,t,n,r,a,i,o,s){var l=[];!function(e,t,n,r,a){var i,o,s,l,u,c,d,h;0===e&&(e=1e-5),s=-27*(r/=e)+(t/=e)*(9*(n/=e)-t*t*2),i=(o=(3*n-t*t)/9)*o*o+(s/=54)*s,a[1]=0,d=t/3,i>0?(u=(u=s+Math.sqrt(i))<0?-Math.pow(-u,1/3):Math.pow(u,1/3),c=(c=s-Math.sqrt(i))<0?-Math.pow(-c,1/3):Math.pow(c,1/3),a[0]=-d+u+c,d+=(u+c)/2,a[4]=a[2]=-d,d=Math.sqrt(3)*(-c+u)/2,a[3]=d,a[5]=-d):(a[5]=a[3]=0,0===i?(h=s<0?-Math.pow(-s,1/3):Math.pow(s,1/3),a[0]=2*h-d,a[4]=a[2]=-(h+d)):(l=(o=-o)*o*o,l=Math.acos(s/Math.sqrt(l)),h=2*Math.sqrt(o),a[0]=-d+h*Math.cos(l/3),a[2]=-d+h*Math.cos((l+2*Math.PI)/3),a[4]=-d+h*Math.cos((l+4*Math.PI)/3)))}(1*n*n-4*n*a+2*n*o+4*a*a-4*a*o+o*o+r*r-4*r*i+2*r*s+4*i*i-4*i*s+s*s,9*n*a-3*n*n-3*n*o-6*a*a+3*a*o+9*r*i-3*r*r-3*r*s-6*i*i+3*i*s,3*n*n-6*n*a+n*o-n*e+2*a*a+2*a*e-o*e+3*r*r-6*r*i+r*s-r*t+2*i*i+2*i*t-s*t,1*n*a-n*n+n*e-a*e+r*i-r*r+r*t-i*t,l);for(var u=[],c=0;c<6;c+=2)Math.abs(l[c+1])<1e-7&&l[c]>=0&&l[c]<=1&&u.push(l[c]);u.push(1),u.push(0);for(var d,h,f,p=-1,v=0;v=0?fl?(e-a)*(e-a)+(t-i)*(t-i):u-d},bn=function(e,t,n){for(var r,a,i,o,s=0,l=0;l=e&&e>=i||r<=e&&e<=i))continue;(e-r)/(i-r)*(o-a)+a>t&&s++}return s%2!=0},xn=function(e,t,n,r,a,i,o,s,l){var u,c=new Array(n.length);null!=s[0]?(u=Math.atan(s[1]/s[0]),s[0]<0?u+=Math.PI/2:u=-u-Math.PI/2):u=s;for(var d,h=Math.cos(-u),f=Math.sin(-u),p=0;p0){var v=En(c,-l);d=wn(v)}else d=c;return bn(e,t,d)},wn=function(e){for(var t,n,r,a,i,o,s,l,u=new Array(e.length/2),c=0;c=0&&p<=1&&g.push(p),v>=0&&v<=1&&g.push(v),0===g.length)return[];var y=g[0]*s[0]+e,m=g[0]*s[1]+t;return g.length>1?g[0]==g[1]?[y,m]:[y,m,g[1]*s[0]+e,g[1]*s[1]+t]:[y,m]},Cn=function(e,t,n){return t<=e&&e<=n||n<=e&&e<=t?e:e<=t&&t<=n||n<=t&&t<=e?t:n},Pn=function(e,t,n,r,a,i,o,s,l){var u=e-a,c=n-e,d=o-a,h=t-i,f=r-t,p=s-i,v=d*h-p*u,g=c*h-f*u,y=p*c-d*f;if(0!==y){var m=v/y,b=g/y,x=-.001;return x<=m&&m<=1.001&&x<=b&&b<=1.001||l?[e+m*c,t+m*f]:[]}return 0===v||0===g?Cn(e,n,o)===o?[o,s]:Cn(e,n,a)===a?[a,i]:Cn(a,o,n)===n?[n,r]:[]:[]},Sn=function(e,t,n,r,a){var i=[],o=r/2,s=a/2,l=t,u=n;i.push({x:l+o*e[0],y:u+s*e[1]});for(var c=1;c0){var m=En(v,-s);u=wn(m)}else u=v}else u=n;for(var b=0;bu&&(u=t)},d=function(e){return l[e]},h=0;h0?b.edgesTo(m)[0]:m.edgesTo(b)[0];var w=r(x);m=m.id(),u[m]>u[v]+w&&(u[m]=u[v]+w,h.nodes.indexOf(m)<0?h.push(m):h.updateItem(m),l[m]=0,n[m]=[]),u[m]==u[v]+w&&(l[m]=l[m]+l[v],n[m].push(v))}else for(var E=0;E0;){for(var P=t.pop(),S=0;S0&&o.push(n[s]);0!==o.length&&a.push(r.collection(o))}return a}(c,l,t,r);return b=function(e){for(var t=0;t5&&void 0!==arguments[5]?arguments[5]:tr,o=r,s=0;s=2?sr(e,t,n,0,ar,ir):sr(e,t,n,0,rr)},squaredEuclidean:function(e,t,n){return sr(e,t,n,0,ar)},manhattan:function(e,t,n){return sr(e,t,n,0,rr)},max:function(e,t,n){return sr(e,t,n,-1/0,or)}};function ur(e,t,n,r,a,i){var o;return o=G(e)?e:lr[e]||lr.euclidean,0===t&&G(e)?o(a,i):o(t,n,r,a,i)}lr["squared-euclidean"]=lr.squaredEuclidean,lr.squaredeuclidean=lr.squaredEuclidean;var cr=dt({k:2,m:2,sensitivityThreshold:1e-4,distance:"euclidean",maxIterations:10,attributes:[],testMode:!1,testCentroids:null}),dr=function(e){return cr(e)},hr=function(e,t,n,r,a){var i="kMedoids"!==a?function(e){return n[e]}:function(e){return r[e](n)},o=n,s=t;return ur(e,r.length,i,function(e){return r[e](t)},o,s)},fr=function(e,t,n){for(var r=n.length,a=new Array(r),i=new Array(r),o=new Array(t),s=null,l=0;ln)return!1}return!0},mr=function(e,t,n){for(var r=0;ra&&(a=t[l][u],i=u);o[i].push(e[l])}for(var c=0;c=a.threshold||"dendrogram"===a.mode&&1===e.length)return!1;var f,p=t[o],v=t[r[o]];f="dendrogram"===a.mode?{left:p,right:v,key:p.key}:{value:p.value.concat(v.value),key:p.key},e[p.index]=f,e.splice(v.index,1),t[p.key]=f;for(var g=0;gn[v.key][y.key]&&(i=n[v.key][y.key])):"max"===a.linkage?(i=n[p.key][y.key],n[p.key][y.key]1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],a=!(arguments.length>5&&void 0!==arguments[5])||arguments[5];arguments.length>3&&void 0!==arguments[3]&&!arguments[3]?(n0&&e.splice(0,t)):e=e.slice(t,n);for(var i=0,o=e.length-1;o>=0;o--){var s=e[o];a?isFinite(s)||(e[o]=-1/0,i++):e.splice(o,1)}r&&e.sort(function(e,t){return e-t});var l=e.length,u=Math.floor(l/2);return l%2!=0?e[u+1+i]:(e[u-1+i]+e[u+i])/2}(e):"mean"===t?function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=0,a=0,i=t;i1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=1/0,a=t;a1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=-1/0,a=t;ao&&(i=l,o=t[a*e+l])}i>0&&r.push(i)}for(var u=0;u=P?(S=P,P=D,B=_):D>S&&(S=D);for(var A=0;A0?1:0;k[E%u.minIterations*t+z]=O,L+=O}if(L>0&&(E>=u.minIterations-1||E==u.maxIterations-1)){for(var V=0,F=0;F0&&r.push(a);return r}(t,i,o),Y=function(e,t,n){for(var r=Lr(e,t,n),a=0;al&&(s=u,l=c)}n[a]=i[s]}return Lr(e,t,n)}(t,r,j),q={},W=0;W1)}});var l=Object.keys(t).filter(function(e){return t[e].cutVertex}).map(function(t){return e.getElementById(t)});return{cut:e.spawn(l),components:a}},Xr=function(){var e=this,t={},n=0,r=[],a=[],i=e.spawn(e),o=function(s){if(a.push(s),t[s]={index:n,low:n++,explored:!1},e.getElementById(s).connectedEdges().intersection(e).forEach(function(e){var n=e.target().id();n!==s&&(n in t||o(n),t[n].explored||(t[s].low=Math.min(t[s].low,t[n].low)))}),t[s].index===t[s].low){for(var l=e.spawn();;){var u=a.pop();if(l.merge(e.getElementById(u)),t[u].low=t[s].index,t[u].explored=!0,u===s)break}var c=l.edgesWith(l),d=l.merge(c);r.push(d),i=i.difference(d)}};return e.forEach(function(e){if(e.isNode()){var n=e.id();n in t||o(n)}}),{cut:i,components:r}},jr={};[wt,At,Mt,It,Lt,Ot,jt,On,Fn,jn,qn,er,Tr,Mr,Or,{hierholzer:function(e){if(!$(e)){var t=arguments;e={root:t[0],directed:t[1]}}var n,r,a,i=Vr(e),o=i.root,s=i.directed,l=this,u=!1;o&&(a=K(o)?this.filter(o)[0].id():o[0].id());var c={},d={};s?l.forEach(function(e){var t=e.id();if(e.isNode()){var a=e.indegree(!0),i=e.outdegree(!0),o=a-i,s=i-a;1==o?n?u=!0:n=t:1==s?r?u=!0:r=t:(s>1||o>1)&&(u=!0),c[t]=[],e.outgoers().forEach(function(e){e.isEdge()&&c[t].push(e.id())})}else d[t]=[void 0,e.target().id()]}):l.forEach(function(e){var t=e.id();e.isNode()?(e.degree(!0)%2&&(n?r?u=!0:r=t:n=t),c[t]=[],e.connectedEdges().forEach(function(e){return c[t].push(e.id())})):d[t]=[e.source().id(),e.target().id()]});var h={found:!1,trail:void 0};if(u)return h;if(r&&n)if(s){if(a&&r!=a)return h;a=r}else{if(a&&r!=a&&n!=a)return h;a||(a=r)}else a||(a=l[0].id());var f=function(e){for(var t,n,r,a=e,i=[e];c[a].length;)t=c[a].shift(),n=d[t][0],a!=(r=d[t][1])?(c[r]=c[r].filter(function(e){return e!=t}),a=r):s||a==n||(c[n]=c[n].filter(function(e){return e!=t}),a=n),i.unshift(t),i.unshift(a);return i},p=[],v=[];for(v=f(a);1!=v.length;)0==c[v[0]].length?(p.unshift(l.getElementById(v.shift())),p.unshift(l.getElementById(v.shift()))):v=f(v.shift()).concat(v);for(var g in p.unshift(l.getElementById(v.shift())),c)if(c[g].length)return h;return h.found=!0,h.trail=this.spawn(p,!0),h}},{hopcroftTarjanBiconnected:Fr,htbc:Fr,htb:Fr,hopcroftTarjanBiconnectedComponents:Fr},{tarjanStronglyConnected:Xr,tsc:Xr,tscc:Xr,tarjanStronglyConnectedComponents:Xr}].forEach(function(e){be(jr,e)});var Yr=function(e){if(!(this instanceof Yr))return new Yr(e);this.id="Thenable/1.0.7",this.state=0,this.fulfillValue=void 0,this.rejectReason=void 0,this.onFulfilled=[],this.onRejected=[],this.proxy={then:this.then.bind(this)},"function"==typeof e&&e.call(this,this.fulfill.bind(this),this.reject.bind(this))};Yr.prototype={fulfill:function(e){return qr(this,1,"fulfillValue",e)},reject:function(e){return qr(this,2,"rejectReason",e)},then:function(e,t){var n=this,r=new Yr;return n.onFulfilled.push(Hr(e,r,"fulfill")),n.onRejected.push(Hr(t,r,"reject")),Wr(n),r.proxy}};var qr=function(e,t,n,r){return 0===e.state&&(e.state=t,e[n]=r,Wr(e)),e},Wr=function(e){1===e.state?Ur(e,"onFulfilled",e.fulfillValue):2===e.state&&Ur(e,"onRejected",e.rejectReason)},Ur=function(e,t,n){if(0!==e[t].length){var r=e[t];e[t]=[];var a=function(){for(var e=0;e0:void 0}},clearQueue:function(){return function(){var e=this,t=void 0!==e.length?e:[e];if(!(this._private.cy||this).styleEnabled())return this;for(var n=0;n-1}}(),a=function(){if(Ya)return ja;Ya=1;var e=Oi();return ja=function(t,n){var r=this.__data__,a=e(r,t);return a<0?(++this.size,r.push([t,n])):r[a][1]=n,this},ja}();function i(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t-1&&t%1==0&&t0&&this.spawn(r).updateStyle().emit("class"),t},addClass:function(e){return this.toggleClass(e,!0)},hasClass:function(e){var t=this[0];return null!=t&&t._private.classes.has(e)},toggleClass:function(e,t){Z(e)||(e=e.match(/\S+/g)||[]);for(var n=this,r=void 0===t,a=[],i=0,o=n.length;i0&&this.spawn(a).updateStyle().emit("class"),n},removeClass:function(e){return this.toggleClass(e,!1)},flashClass:function(e,t){var n=this;if(null==t)t=250;else if(0===t)return n;return n.addClass(e),setTimeout(function(){n.removeClass(e)},t),n}};To.className=To.classNames=To.classes;var Co={metaChar:"[\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]",comparatorOp:"=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=",boolOp:"\\?|\\!|\\^",string:"\"(?:\\\\\"|[^\"])*\"|'(?:\\\\'|[^'])*'",number:fe,meta:"degree|indegree|outdegree",separator:"\\s*,\\s*",descendant:"\\s+",child:"\\s+>\\s+",subject:"\\$",group:"node|edge|\\*",directedEdge:"\\s+->\\s+",undirectedEdge:"\\s+<->\\s+"};Co.variable="(?:[\\w-.]|(?:\\\\"+Co.metaChar+"))+",Co.className="(?:[\\w-]|(?:\\\\"+Co.metaChar+"))+",Co.value=Co.string+"|"+Co.number,Co.id=Co.variable,function(){var e,t,n;for(e=Co.comparatorOp.split("|"),n=0;n=0||"="!==t&&(Co.comparatorOp+="|\\!"+t)}();var Po=0,So=1,Bo=2,Do=3,_o=4,Ao=5,Mo=6,Ro=7,Io=8,No=9,Lo=10,zo=11,Oo=12,Vo=13,Fo=14,Xo=15,jo=16,Yo=17,qo=18,Wo=19,Uo=20,Ho=[{selector:":selected",matches:function(e){return e.selected()}},{selector:":unselected",matches:function(e){return!e.selected()}},{selector:":selectable",matches:function(e){return e.selectable()}},{selector:":unselectable",matches:function(e){return!e.selectable()}},{selector:":locked",matches:function(e){return e.locked()}},{selector:":unlocked",matches:function(e){return!e.locked()}},{selector:":visible",matches:function(e){return e.visible()}},{selector:":hidden",matches:function(e){return!e.visible()}},{selector:":transparent",matches:function(e){return e.transparent()}},{selector:":grabbed",matches:function(e){return e.grabbed()}},{selector:":free",matches:function(e){return!e.grabbed()}},{selector:":removed",matches:function(e){return e.removed()}},{selector:":inside",matches:function(e){return!e.removed()}},{selector:":grabbable",matches:function(e){return e.grabbable()}},{selector:":ungrabbable",matches:function(e){return!e.grabbable()}},{selector:":animated",matches:function(e){return e.animated()}},{selector:":unanimated",matches:function(e){return!e.animated()}},{selector:":parent",matches:function(e){return e.isParent()}},{selector:":childless",matches:function(e){return e.isChildless()}},{selector:":child",matches:function(e){return e.isChild()}},{selector:":orphan",matches:function(e){return e.isOrphan()}},{selector:":nonorphan",matches:function(e){return e.isChild()}},{selector:":compound",matches:function(e){return e.isNode()?e.isParent():e.source().isParent()||e.target().isParent()}},{selector:":loop",matches:function(e){return e.isLoop()}},{selector:":simple",matches:function(e){return e.isSimple()}},{selector:":active",matches:function(e){return e.active()}},{selector:":inactive",matches:function(e){return!e.active()}},{selector:":backgrounding",matches:function(e){return e.backgrounding()}},{selector:":nonbackgrounding",matches:function(e){return!e.backgrounding()}}].sort(function(e,t){return function(e,t){return-1*me(e,t)}(e.selector,t.selector)}),Ko=function(){for(var e,t={},n=0;n0&&u.edgeCount>0)return ot("The selector `"+e+"` is invalid because it uses both a compound selector and an edge selector"),!1;if(u.edgeCount>1)return ot("The selector `"+e+"` is invalid because it uses multiple edge selectors"),!1;1===u.edgeCount&&ot("The selector `"+e+"` is deprecated. Edge selectors do not take effect on changes to source and target nodes after an edge is added, for performance reasons. Use a class or data selector on edges instead, updating the class or data of an edge when your app detects a change in source or target nodes.")}return!0},toString:function(){if(null!=this.toStringCache)return this.toStringCache;for(var e=function(e){return null==e?"":e},t=function(t){return K(t)?'"'+t+'"':e(t)},n=function(e){return" "+e+" "},r=function(r,i){var o=r.type,s=r.value;switch(o){case Po:var l=e(s);return l.substring(0,l.length-1);case Do:var u=r.field,c=r.operator;return"["+u+n(e(c))+t(s)+"]";case Ao:var d=r.operator,h=r.field;return"["+e(d)+h+"]";case _o:return"["+r.field+"]";case Mo:var f=r.operator;return"[["+r.field+n(e(f))+t(s)+"]]";case Ro:return s;case Io:return"#"+s;case No:return"."+s;case Yo:case Xo:return a(r.parent,i)+n(">")+a(r.child,i);case qo:case jo:return a(r.ancestor,i)+" "+a(r.descendant,i);case Wo:var p=a(r.left,i),v=a(r.subject,i),g=a(r.right,i);return p+(p.length>0?" ":"")+v+g;case Uo:return""}},a=function(e,t){return e.checks.reduce(function(n,a,i){return n+(t===e&&0===i?"$":"")+r(a,t)},"")},i="",o=0;o1&&o=0&&(t=t.replace("!",""),c=!0),t.indexOf("@")>=0&&(t=t.replace("@",""),u=!0),(o||l||u)&&(a=o||s?""+e:"",i=""+n),u&&(e=a=a.toLowerCase(),n=i=i.toLowerCase()),t){case"*=":r=a.indexOf(i)>=0;break;case"$=":r=a.indexOf(i,a.length-i.length)>=0;break;case"^=":r=0===a.indexOf(i);break;case"=":r=e===n;break;case">":d=!0,r=e>n;break;case">=":d=!0,r=e>=n;break;case"<":d=!0,r=e0;){var u=a.shift();t(u),i.add(u.id()),o&&r(a,i,u)}return e}function ps(e,t,n){if(n.isParent())for(var r=n._private.children,a=0;a1&&void 0!==arguments[1])||arguments[1],ps)},hs.forEachUp=function(e){return fs(this,e,!(arguments.length>1&&void 0!==arguments[1])||arguments[1],vs)},hs.forEachUpAndDown=function(e){return fs(this,e,!(arguments.length>1&&void 0!==arguments[1])||arguments[1],gs)},hs.ancestors=hs.parents,(us=cs={data:Eo.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),removeData:Eo.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),scratch:Eo.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:Eo.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),rscratch:Eo.data({field:"rscratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeRscratch:Eo.removeData({field:"rscratch",triggerEvent:!1}),id:function(){var e=this[0];if(e)return e._private.data.id}}).attr=us.data,us.removeAttr=us.removeData;var ys,ms,bs=cs,xs={};function ws(e){return function(t){var n=this;if(void 0===t&&(t=!0),0!==n.length&&n.isNode()&&!n.removed()){for(var r=0,a=n[0],i=a._private.edges,o=0;ot}),minIndegree:Es("indegree",function(e,t){return et}),minOutdegree:Es("outdegree",function(e,t){return et})}),be(xs,{totalDegree:function(e){for(var t=0,n=this.nodes(),r=0;r0,c=u;u&&(l=l[0]);var d=c?l.position():{x:0,y:0};return a={x:s.x-d.x,y:s.y-d.y},void 0===e?a:a[e]}for(var h=0;h0,g=v;v&&(p=p[0]);var y=g?p.position():{x:0,y:0};void 0!==t?f.position(e,t+y[e]):void 0!==a&&f.position({x:a.x+y.x,y:a.y+y.y})}}else if(!i)return;return this}},ys.modelPosition=ys.point=ys.position,ys.modelPositions=ys.points=ys.positions,ys.renderedPoint=ys.renderedPosition,ys.relativePoint=ys.relativePosition;var Cs,Ps,Ss=ms;Cs=Ps={},Ps.renderedBoundingBox=function(e){var t=this.boundingBox(e),n=this.cy(),r=n.zoom(),a=n.pan(),i=t.x1*r+a.x,o=t.x2*r+a.x,s=t.y1*r+a.y,l=t.y2*r+a.y;return{x1:i,x2:o,y1:s,y2:l,w:o-i,h:l-s}},Ps.dirtyCompoundBoundsCache=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.cy();return t.styleEnabled()&&t.hasCompoundNodes()?(this.forEachUp(function(t){if(t.isParent()){var n=t._private;n.compoundBoundsClean=!1,n.bbCache=null,e||t.emitAndNotify("bounds")}}),this):this},Ps.updateCompoundBounds=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.cy();if(!t.styleEnabled()||!t.hasCompoundNodes())return this;if(!e&&t.batching())return this;function n(e){if(e.isParent()){var t=e._private,n=e.children(),r="include"===e.pstyle("compound-sizing-wrt-labels").value,a={width:{val:e.pstyle("min-width").pfValue,left:e.pstyle("min-width-bias-left"),right:e.pstyle("min-width-bias-right")},height:{val:e.pstyle("min-height").pfValue,top:e.pstyle("min-height-bias-top"),bottom:e.pstyle("min-height-bias-bottom")}},i=n.boundingBox({includeLabels:r,includeOverlays:!1,useCache:!1}),o=t.position;0!==i.w&&0!==i.h||((i={w:e.pstyle("width").pfValue,h:e.pstyle("height").pfValue}).x1=o.x-i.w/2,i.x2=o.x+i.w/2,i.y1=o.y-i.h/2,i.y2=o.y+i.h/2);var s=a.width.left.value;"px"===a.width.left.units&&a.width.val>0&&(s=100*s/a.width.val);var l=a.width.right.value;"px"===a.width.right.units&&a.width.val>0&&(l=100*l/a.width.val);var u=a.height.top.value;"px"===a.height.top.units&&a.height.val>0&&(u=100*u/a.height.val);var c=a.height.bottom.value;"px"===a.height.bottom.units&&a.height.val>0&&(c=100*c/a.height.val);var d=y(a.width.val-i.w,s,l),h=d.biasDiff,f=d.biasComplementDiff,p=y(a.height.val-i.h,u,c),v=p.biasDiff,g=p.biasComplementDiff;t.autoPadding=function(e,t,n,r){if("%"!==n.units)return"px"===n.units?n.pfValue:0;switch(r){case"width":return e>0?n.pfValue*e:0;case"height":return t>0?n.pfValue*t:0;case"average":return e>0&&t>0?n.pfValue*(e+t)/2:0;case"min":return e>0&&t>0?e>t?n.pfValue*t:n.pfValue*e:0;case"max":return e>0&&t>0?e>t?n.pfValue*e:n.pfValue*t:0;default:return 0}}(i.w,i.h,e.pstyle("padding"),e.pstyle("padding-relative-to").value),t.autoWidth=Math.max(i.w,a.width.val),o.x=(-h+i.x1+i.x2+f)/2,t.autoHeight=Math.max(i.h,a.height.val),o.y=(-v+i.y1+i.y2+g)/2}function y(e,t,n){var r=0,a=0,i=t+n;return e>0&&i>0&&(r=t/i*e,a=n/i*e),{biasDiff:r,biasComplementDiff:a}}}for(var r=0;re.x2?r:e.x2,e.y1=ne.y2?a:e.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1)},_s=function(e,t){return null==t?e:Ds(e,t.x1,t.y1,t.x2,t.y2)},As=function(e,t,n){return pt(e,t,n)},Ms=function(e,t,n){if(!t.cy().headless()){var r,a,i=t._private,o=i.rstyle,s=o.arrowWidth/2;if("none"!==t.pstyle(n+"-arrow-shape").value){"source"===n?(r=o.srcX,a=o.srcY):"target"===n?(r=o.tgtX,a=o.tgtY):(r=o.midX,a=o.midY);var l=i.arrowBounds=i.arrowBounds||{},u=l[n]=l[n]||{};u.x1=r-s,u.y1=a-s,u.x2=r+s,u.y2=a+s,u.w=u.x2-u.x1,u.h=u.y2-u.y1,an(u,1),Ds(e,u.x1,u.y1,u.x2,u.y2)}}},Rs=function(e,t,n){if(!t.cy().headless()){var r;r=n?n+"-":"";var a=t._private,i=a.rstyle;if(t.pstyle(r+"label").strValue){var o,s,l,u,c=t.pstyle("text-halign"),d=t.pstyle("text-valign"),h=As(i,"labelWidth",n),f=As(i,"labelHeight",n),p=As(i,"labelX",n),v=As(i,"labelY",n),g=t.pstyle(r+"text-margin-x").pfValue,y=t.pstyle(r+"text-margin-y").pfValue,m=t.isEdge(),b=t.pstyle(r+"text-rotation"),x=t.pstyle("text-outline-width").pfValue,w=t.pstyle("text-border-width").pfValue/2,E=t.pstyle("text-background-padding").pfValue,k=f,T=h,C=T/2,P=k/2;if(m)o=p-C,s=p+C,l=v-P,u=v+P;else{switch(c.value){case"left":o=p-T,s=p;break;case"center":o=p-C,s=p+C;break;case"right":o=p,s=p+T}switch(d.value){case"top":l=v-k,u=v;break;case"center":l=v-P,u=v+P;break;case"bottom":l=v,u=v+k}}var S=g-Math.max(x,w)-E-2,B=g+Math.max(x,w)+E+2,D=y-Math.max(x,w)-E-2,_=y+Math.max(x,w)+E+2;o+=S,s+=B,l+=D,u+=_;var A=n||"main",M=a.labelBounds,R=M[A]=M[A]||{};R.x1=o,R.y1=l,R.x2=s,R.y2=u,R.w=s-o,R.h=u-l,R.leftPad=S,R.rightPad=B,R.topPad=D,R.botPad=_;var I=m&&"autorotate"===b.strValue,N=null!=b.pfValue&&0!==b.pfValue;if(I||N){var L=I?As(a.rstyle,"labelAngle",n):b.pfValue,z=Math.cos(L),O=Math.sin(L),V=(o+s)/2,F=(l+u)/2;if(!m){switch(c.value){case"left":V=s;break;case"right":V=o}switch(d.value){case"top":F=u;break;case"bottom":F=l}}var X=function(e,t){return{x:(e-=V)*z-(t-=F)*O+V,y:e*O+t*z+F}},j=X(o,l),Y=X(o,u),q=X(s,l),W=X(s,u);o=Math.min(j.x,Y.x,q.x,W.x),s=Math.max(j.x,Y.x,q.x,W.x),l=Math.min(j.y,Y.y,q.y,W.y),u=Math.max(j.y,Y.y,q.y,W.y)}var U=A+"Rot",H=M[U]=M[U]||{};H.x1=o,H.y1=l,H.x2=s,H.y2=u,H.w=s-o,H.h=u-l,Ds(e,o,l,s,u),Ds(a.labelBounds.all,o,l,s,u)}return e}},Is=function(e,t){if(!t.cy().headless()){var n=t.pstyle("outline-opacity").value,r=t.pstyle("outline-width").value+t.pstyle("outline-offset").value;Ns(e,t,n,r,"outside",r/2)}},Ns=function(e,t,n,r,a,i){if(!(0===n||r<=0||"inside"===a)){var o=t.cy(),s=t.pstyle("shape").value,l=o.renderer().nodeShapes[s],u=t.position(),c=u.x,d=u.y,h=t.width(),f=t.height();if(l.hasMiterBounds){"center"===a&&(r/=2);var p=l.miterBounds(c,d,h,f,r);_s(e,p)}else null!=i&&i>0&&on(e,[i,i,i,i])}},Ls=function(e,t){var n,r,a,i,o,s,l,u=e._private.cy,c=u.styleEnabled(),d=u.headless(),h=tn(),f=e._private,p=e.isNode(),v=e.isEdge(),g=f.rstyle,y=p&&c?e.pstyle("bounds-expansion").pfValue:[0],m=function(e){return"none"!==e.pstyle("display").value},b=!c||m(e)&&(!v||m(e.source())&&m(e.target()));if(b){var x=0;c&&t.includeOverlays&&0!==e.pstyle("overlay-opacity").value&&(x=e.pstyle("overlay-padding").value);var w=0;c&&t.includeUnderlays&&0!==e.pstyle("underlay-opacity").value&&(w=e.pstyle("underlay-padding").value);var E=Math.max(x,w),k=0;if(c&&(k=e.pstyle("width").pfValue/2),p&&t.includeNodes){var T=e.position();o=T.x,s=T.y;var C=e.outerWidth()/2,P=e.outerHeight()/2;Ds(h,n=o-C,a=s-P,r=o+C,i=s+P),c&&Is(h,e),c&&t.includeOutlines&&!d&&Is(h,e),c&&function(e,t){if(!t.cy().headless()){var n=t.pstyle("border-opacity").value,r=t.pstyle("border-width").pfValue,a=t.pstyle("border-position").value;Ns(e,t,n,r,a)}}(h,e)}else if(v&&t.includeEdges)if(c&&!d){var S=e.pstyle("curve-style").strValue;if(n=Math.min(g.srcX,g.midX,g.tgtX),r=Math.max(g.srcX,g.midX,g.tgtX),a=Math.min(g.srcY,g.midY,g.tgtY),i=Math.max(g.srcY,g.midY,g.tgtY),Ds(h,n-=k,a-=k,r+=k,i+=k),"haystack"===S){var B=g.haystackPts;if(B&&2===B.length){if(n=B[0].x,a=B[0].y,n>(r=B[1].x)){var D=n;n=r,r=D}if(a>(i=B[1].y)){var _=a;a=i,i=_}Ds(h,n-k,a-k,r+k,i+k)}}else if("bezier"===S||"unbundled-bezier"===S||he(S,"segments")||he(S,"taxi")){var A;switch(S){case"bezier":case"unbundled-bezier":A=g.bezierPts;break;case"segments":case"taxi":case"round-segments":case"round-taxi":A=g.linePts}if(null!=A)for(var M=0;M(r=N.x)){var L=n;n=r,r=L}if((a=I.y)>(i=N.y)){var z=a;a=i,i=z}Ds(h,n-=k,a-=k,r+=k,i+=k)}if(c&&t.includeEdges&&v&&(Ms(h,e,"mid-source"),Ms(h,e,"mid-target"),Ms(h,e,"source"),Ms(h,e,"target")),c)if("yes"===e.pstyle("ghost").value){var O=e.pstyle("ghost-offset-x").pfValue,V=e.pstyle("ghost-offset-y").pfValue;Ds(h,h.x1+O,h.y1+V,h.x2+O,h.y2+V)}var F=f.bodyBounds=f.bodyBounds||{};sn(F,h),on(F,y),an(F,1),c&&(n=h.x1,r=h.x2,a=h.y1,i=h.y2,Ds(h,n-E,a-E,r+E,i+E));var X=f.overlayBounds=f.overlayBounds||{};sn(X,h),on(X,y),an(X,1);var j=f.labelBounds=f.labelBounds||{};null!=j.all?((l=j.all).x1=1/0,l.y1=1/0,l.x2=-1/0,l.y2=-1/0,l.w=0,l.h=0):j.all=tn(),c&&t.includeLabels&&(t.includeMainLabels&&Rs(h,e,null),v&&(t.includeSourceLabels&&Rs(h,e,"source"),t.includeTargetLabels&&Rs(h,e,"target")))}return h.x1=Bs(h.x1),h.y1=Bs(h.y1),h.x2=Bs(h.x2),h.y2=Bs(h.y2),h.w=Bs(h.x2-h.x1),h.h=Bs(h.y2-h.y1),h.w>0&&h.h>0&&b&&(on(h,y),an(h,1)),h},zs=function(e){var t=0,n=function(e){return(e?1:0)<0&&void 0!==arguments[0]?arguments[0]:rl,t=arguments.length>1?arguments[1]:void 0,n=0;n=0;s--)o(s);return this},il.removeAllListeners=function(){return this.removeListener("*")},il.emit=il.trigger=function(e,t,n){var r=this.listeners,a=r.length;return this.emitting++,Z(t)||(t=[t]),ll(this,function(e,i){null!=n&&(r=[{event:i.event,type:i.type,namespace:i.namespace,callback:n}],a=r.length);for(var o=function(){var n=r[s];if(n.type===i.type&&(!n.namespace||n.namespace===i.namespace||".*"===n.namespace)&&e.eventMatches(e.context,n,i)){var a=[i];null!=t&&function(e,t){for(var n=0;n1&&!r){var a=this.length-1,i=this[a],o=i._private.data.id;this[a]=void 0,this[e]=i,n.set(o,{ele:i,index:e})}return this.length--,this},unmergeOne:function(e){e=e[0];var t=this._private,n=e._private.data.id,r=t.map.get(n);if(!r)return this;var a=r.index;return this.unmergeAt(a),this},unmerge:function(e){var t=this._private.cy;if(!e)return this;if(e&&K(e)){var n=e;e=t.mutableElements().filter(n)}for(var r=0;r=0;t--){e(this[t])&&this.unmergeAt(t)}return this},map:function(e,t){for(var n=[],r=this,a=0;ar&&(r=s,n=o)}return{value:r,ele:n}},min:function(e,t){for(var n,r=1/0,a=this,i=0;i=0&&a1&&void 0!==arguments[1])||arguments[1],n=this[0],r=n.cy();if(r.styleEnabled()&&n){n._private.styleDirty&&(n._private.styleDirty=!1,r.style().apply(n));var a=n._private.style[e];return null!=a?a:t?r.style().getDefaultProperty(e):null}},numericStyle:function(e){var t=this[0];if(t.cy().styleEnabled()&&t){var n=t.pstyle(e);return void 0!==n.pfValue?n.pfValue:n.value}},numericStyleUnits:function(e){var t=this[0];if(t.cy().styleEnabled())return t?t.pstyle(e).units:void 0},renderedStyle:function(e){var t=this.cy();if(!t.styleEnabled())return this;var n=this[0];return n?t.style().getRenderedStyle(n,e):void 0},style:function(e,t){var n=this.cy();if(!n.styleEnabled())return this;var r=!1,a=n.style();if($(e)){var i=e;a.applyBypass(this,i,r),this.emitAndNotify("style")}else if(K(e)){if(void 0===t){var o=this[0];return o?a.getStylePropertyValue(o,e):void 0}a.applyBypass(this,e,t,r),this.emitAndNotify("style")}else if(void 0===e){var s=this[0];return s?a.getRawStyle(s):void 0}return this},removeStyle:function(e){var t=this.cy();if(!t.styleEnabled())return this;var n=!1,r=t.style(),a=this;if(void 0===e)for(var i=0;i0&&t.push(c[0]),t.push(s[0])}return this.spawn(t,!0).filter(e)},"neighborhood"),closedNeighborhood:function(e){return this.neighborhood().add(this).filter(e)},openNeighborhood:function(e){return this.neighborhood(e)}}),Rl.neighbourhood=Rl.neighborhood,Rl.closedNeighbourhood=Rl.closedNeighborhood,Rl.openNeighbourhood=Rl.openNeighborhood,be(Rl,{source:ds(function(e){var t,n=this[0];return n&&(t=n._private.source||n.cy().collection()),t&&e?t.filter(e):t},"source"),target:ds(function(e){var t,n=this[0];return n&&(t=n._private.target||n.cy().collection()),t&&e?t.filter(e):t},"target"),sources:zl({attr:"source"}),targets:zl({attr:"target"})}),be(Rl,{edgesWith:ds(Ol(),"edgesWith"),edgesTo:ds(Ol({thisIsSrc:!0}),"edgesTo")}),be(Rl,{connectedEdges:ds(function(e){for(var t=[],n=0;n0);return i},component:function(){var e=this[0];return e.cy().mutableElements().components(e)[0]}}),Rl.componentsOf=Rl.components;var Fl=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(void 0!==e){var a=new gt,i=!1;if(t){if(t.length>0&&$(t[0])&&!te(t[0])){i=!0;for(var o=[],s=new mt,l=0,u=t.length;l0&&void 0!==arguments[0])||arguments[0],r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],a=this,i=a.cy(),o=i._private,s=[],l=[],u=0,c=a.length;u0){for(var I=e.length===a.length?a:new Fl(i,e),N=0;N0&&void 0!==arguments[0])||arguments[0],t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=this,r=[],a={},i=n._private.cy;function o(e){var n=a[e.id()];t&&e.removed()||n||(a[e.id()]=!0,e.isNode()?(r.push(e),function(e){for(var t=e._private.edges,n=0;n0&&(e?k.emitAndNotify("remove"):t&&k.emit("remove"));for(var T=0;T=.001?function(t,r){for(var a=0;a<4;++a){var i=h(r,e,n);if(0===i)return r;r-=(d(r,e,n)-t)/i}return r}(t,o):0===l?o:function(t,r,a){var i,o,s=0;do{(i=d(o=r+(a-r)/2,e,n)-t)>0?a=o:r=o}while(Math.abs(i)>1e-7&&++s<10);return o}(t,r,r+a)}var p=!1;function v(){p=!0,e===t&&n===r||function(){for(var t=0;t<11;++t)s[t]=d(t*a,e,n)}()}var g=function(a){return p||v(),e===t&&n===r?a:0===a?0:1===a?1:d(f(a),t,r)};g.getControlPoints=function(){return[{x:e,y:t},{x:n,y:r}]};var y="generateBezier("+[e,t,n,r]+")";return g.toString=function(){return y},g}var ql=function(){function e(e){return-e.tension*e.x-e.friction*e.v}function t(t,n,r){var a={x:t.x+r.dx*n,v:t.v+r.dv*n,tension:t.tension,friction:t.friction};return{dx:a.v,dv:e(a)}}function n(n,r){var a={dx:n.v,dv:e(n)},i=t(n,.5*r,a),o=t(n,.5*r,i),s=t(n,r,o),l=1/6*(a.dx+2*(i.dx+o.dx)+s.dx),u=1/6*(a.dv+2*(i.dv+o.dv)+s.dv);return n.x=n.x+l*r,n.v=n.v+u*r,n}return function e(t,r,a){var i,o,s,l={x:-1,v:0,tension:null,friction:null},u=[0],c=0,d=1e-4;for(t=parseFloat(t)||500,r=parseFloat(r)||20,a=a||null,l.tension=t,l.friction=r,o=(i=null!==a)?(c=e(t,r))/a*.016:.016;s=n(s||l,o),u.push(1+s.x),c+=16,Math.abs(s.x)>d&&Math.abs(s.v)>d;);return i?function(e){return u[e*(u.length-1)|0]}:c}}(),Wl=function(e,t,n,r){var a=Yl(e,t,n,r);return function(e,t,n){return e+(t-e)*a(n)}},Ul={linear:function(e,t,n){return e+(t-e)*n},ease:Wl(.25,.1,.25,1),"ease-in":Wl(.42,0,1,1),"ease-out":Wl(0,0,.58,1),"ease-in-out":Wl(.42,0,.58,1),"ease-in-sine":Wl(.47,0,.745,.715),"ease-out-sine":Wl(.39,.575,.565,1),"ease-in-out-sine":Wl(.445,.05,.55,.95),"ease-in-quad":Wl(.55,.085,.68,.53),"ease-out-quad":Wl(.25,.46,.45,.94),"ease-in-out-quad":Wl(.455,.03,.515,.955),"ease-in-cubic":Wl(.55,.055,.675,.19),"ease-out-cubic":Wl(.215,.61,.355,1),"ease-in-out-cubic":Wl(.645,.045,.355,1),"ease-in-quart":Wl(.895,.03,.685,.22),"ease-out-quart":Wl(.165,.84,.44,1),"ease-in-out-quart":Wl(.77,0,.175,1),"ease-in-quint":Wl(.755,.05,.855,.06),"ease-out-quint":Wl(.23,1,.32,1),"ease-in-out-quint":Wl(.86,0,.07,1),"ease-in-expo":Wl(.95,.05,.795,.035),"ease-out-expo":Wl(.19,1,.22,1),"ease-in-out-expo":Wl(1,0,0,1),"ease-in-circ":Wl(.6,.04,.98,.335),"ease-out-circ":Wl(.075,.82,.165,1),"ease-in-out-circ":Wl(.785,.135,.15,.86),spring:function(e,t,n){if(0===n)return Ul.linear;var r=ql(e,t,n);return function(e,t,n){return e+(t-e)*r(n)}},"cubic-bezier":Wl};function Hl(e,t,n,r,a){if(1===r)return n;if(t===n)return n;var i=a(t,n,r);return null==e||((e.roundValue||e.color)&&(i=Math.round(i)),void 0!==e.min&&(i=Math.max(i,e.min)),void 0!==e.max&&(i=Math.min(i,e.max))),i}function Kl(e,t){return null!=e.pfValue||null!=e.value?null==e.pfValue||null!=t&&"%"===t.type.units?e.value:e.pfValue:e}function Gl(e,t,n,r,a){var i=null!=a?a.type:null;n<0?n=0:n>1&&(n=1);var o=Kl(e,a),s=Kl(t,a);if(Q(o)&&Q(s))return Hl(i,o,s,n,r);if(Z(o)&&Z(s)){for(var l=[],u=0;u0?("spring"===d&&h.push(o.duration),o.easingImpl=Ul[d].apply(null,h)):o.easingImpl=Ul[d]}var f,p=o.easingImpl;if(f=0===o.duration?1:(n-l)/o.duration,o.applying&&(f=o.progress),f<0?f=0:f>1&&(f=1),null==o.delay){var v=o.startPosition,g=o.position;if(g&&a&&!e.locked()){var y={};$l(v.x,g.x)&&(y.x=Gl(v.x,g.x,f,p)),$l(v.y,g.y)&&(y.y=Gl(v.y,g.y,f,p)),e.position(y)}var m=o.startPan,b=o.pan,x=i.pan,w=null!=b&&r;w&&($l(m.x,b.x)&&(x.x=Gl(m.x,b.x,f,p)),$l(m.y,b.y)&&(x.y=Gl(m.y,b.y,f,p)),e.emit("pan"));var E=o.startZoom,k=o.zoom,T=null!=k&&r;T&&($l(E,k)&&(i.zoom=en(i.minZoom,Gl(E,k,f,p),i.maxZoom)),e.emit("zoom")),(w||T)&&e.emit("viewport");var C=o.style;if(C&&C.length>0&&a){for(var P=0;P=0;t--){(0,e[t])()}e.splice(0,e.length)},c=i.length-1;c>=0;c--){var d=i[c],h=d._private;h.stopped?(i.splice(c,1),h.hooked=!1,h.playing=!1,h.started=!1,u(h.frames)):(h.playing||h.applying)&&(h.playing&&h.applying&&(h.applying=!1),h.started||Ql(0,d,e),Zl(t,d,e,n),h.applying&&(h.applying=!1),u(h.frames),null!=h.step&&h.step(e),d.completed()&&(i.splice(c,1),h.hooked=!1,h.playing=!1,h.started=!1,u(h.completes)),s=!0)}return n||0!==i.length||0!==o.length||r.push(t),s}for(var i=!1,o=0;o0?t.notify("draw",n):t.notify("draw")),n.unmerge(r),t.emit("step")}var eu={animate:Eo.animate(),animation:Eo.animation(),animated:Eo.animated(),clearQueue:Eo.clearQueue(),delay:Eo.delay(),delayAnimation:Eo.delayAnimation(),stop:Eo.stop(),addToAnimationPool:function(e){this.styleEnabled()&&this._private.aniEles.merge(e)},stopAnimationLoop:function(){this._private.animationsRunning=!1},startAnimationLoop:function(){var e=this;if(e._private.animationsRunning=!0,e.styleEnabled()){var t=e.renderer();t&&t.beforeRender?t.beforeRender(function(t,n){Jl(n,e)},t.beforeRenderPriorities.animations):function t(){e._private.animationsRunning&&Le(function(n){Jl(n,e),t()})}()}}},tu={qualifierCompare:function(e,t){return null==e||null==t?null==e&&null==t:e.sameText(t)},eventMatches:function(e,t,n){var r=t.qualifier;return null==r||e!==n.target&&te(n.target)&&r.matches(n.target)},addEventFields:function(e,t){t.cy=e,t.target=e},callbackContext:function(e,t,n){return null!=t.qualifier?n.target:e}},nu=function(e){return K(e)?new os(e):e},ru={createEmitter:function(){var e=this._private;return e.emitter||(e.emitter=new al(tu,this)),this},emitter:function(){return this._private.emitter},on:function(e,t,n){return this.emitter().on(e,nu(t),n),this},removeListener:function(e,t,n){return this.emitter().removeListener(e,nu(t),n),this},removeAllListeners:function(){return this.emitter().removeAllListeners(),this},one:function(e,t,n){return this.emitter().one(e,nu(t),n),this},once:function(e,t,n){return this.emitter().one(e,nu(t),n),this},emit:function(e,t){return this.emitter().emit(e,t),this},emitAndNotify:function(e,t){return this.emit(e),this.notify(e,t),this}};Eo.eventAliasesOn(ru);var au={png:function(e){return e=e||{},this._private.renderer.png(e)},jpg:function(e){var t=this._private.renderer;return(e=e||{}).bg=e.bg||"#fff",t.jpg(e)}};au.jpeg=au.jpg;var iu={layout:function(e){var t=this;if(null!=e)if(null!=e.name){var n=e.name,r=t.extension("layout",n);if(null!=r){var a;a=K(e.eles)?t.$(e.eles):null!=e.eles?e.eles:t.$();var i=new r(be({},e,{cy:t,eles:a}));return i}at("No such layout `"+n+"` found. Did you forget to import it and `cytoscape.use()` it?")}else at("A `name` must be specified to make a layout");else at("Layout options must be specified to make a layout")}};iu.createLayout=iu.makeLayout=iu.layout;var ou={notify:function(e,t){var n=this._private;if(this.batching()){n.batchNotifications=n.batchNotifications||{};var r=n.batchNotifications[e]=n.batchNotifications[e]||this.collection();null!=t&&r.merge(t)}else if(n.notificationsEnabled){var a=this.renderer();!this.destroyed()&&a&&a.notify(e,t)}},notifications:function(e){var t=this._private;return void 0===e?t.notificationsEnabled:(t.notificationsEnabled=!!e,this)},noNotifications:function(e){this.notifications(!1),e(),this.notifications(!0)},batching:function(){return this._private.batchCount>0},startBatch:function(){var e=this._private;return null==e.batchCount&&(e.batchCount=0),0===e.batchCount&&(e.batchStyleEles=this.collection(),e.batchNotifications={}),e.batchCount++,this},endBatch:function(){var e=this._private;if(0===e.batchCount)return this;if(e.batchCount--,0===e.batchCount){e.batchStyleEles.updateStyle();var t=this.renderer();Object.keys(e.batchNotifications).forEach(function(n){var r=e.batchNotifications[n];r.empty()?t.notify(n):t.notify(n,r)})}return this},batch:function(e){return this.startBatch(),e(),this.endBatch(),this},batchData:function(e){var t=this;return this.batch(function(){for(var n=Object.keys(e),r=0;r0;)t.removeChild(t.childNodes[0]);e._private.renderer=null,e.mutableElements().forEach(function(e){var t=e._private;t.rscratch={},t.rstyle={},t.animation.current=[],t.animation.queue=[]})},onRender:function(e){return this.on("render",e)},offRender:function(e){return this.off("render",e)}};lu.invalidateDimensions=lu.resize;var uu={collection:function(e,t){return K(e)?this.$(e):ee(e)?e.collection():Z(e)?(t||(t={}),new Fl(this,e,t.unique,t.removed)):new Fl(this)},nodes:function(e){var t=this.$(function(e){return e.isNode()});return e?t.filter(e):t},edges:function(e){var t=this.$(function(e){return e.isEdge()});return e?t.filter(e):t},$:function(e){var t=this._private.elements;return e?t.filter(e):t.spawnSelf()},mutableElements:function(){return this._private.elements}};uu.elements=uu.filter=uu.$;var cu={},du="t";cu.apply=function(e){for(var t=this,n=t._private.cy.collection(),r=0;r0;if(h||d&&f){var p=void 0;h&&f||h?p=u.properties:f&&(p=u.mappedProperties);for(var v=0;v1&&(g=1),s.color){var w=a.valueMin[0],E=a.valueMax[0],k=a.valueMin[1],T=a.valueMax[1],C=a.valueMin[2],P=a.valueMax[2],S=null==a.valueMin[3]?1:a.valueMin[3],B=null==a.valueMax[3]?1:a.valueMax[3],D=[Math.round(w+(E-w)*g),Math.round(k+(T-k)*g),Math.round(C+(P-C)*g),Math.round(S+(B-S)*g)];n={bypass:a.bypass,name:a.name,value:D,strValue:"rgb("+D[0]+", "+D[1]+", "+D[2]+")"}}else{if(!s.number)return!1;var _=a.valueMin+(a.valueMax-a.valueMin)*g;n=this.parse(a.name,_,a.bypass,h)}if(!n)return v(),!1;n.mapping=a,a=n;break;case o.data:for(var A=a.field.split("."),M=d.data,R=0;R0&&i>0){for(var s={},l=!1,u=0;u0?e.delayAnimation(o).play().promise().then(t):t()}).then(function(){return e.animation({style:s,duration:i,easing:e.pstyle("transition-timing-function").value,queue:!1}).play().promise()}).then(function(){n.removeBypasses(e,a),e.emitAndNotify("style"),r.transitioning=!1})}else r.transitioning&&(this.removeBypasses(e,a),e.emitAndNotify("style"),r.transitioning=!1)},cu.checkTrigger=function(e,t,n,r,a,i){var o=this.properties[t],s=a(o);e.removed()||null!=s&&s(n,r,e)&&i(o)},cu.checkZOrderTrigger=function(e,t,n,r){var a=this;this.checkTrigger(e,t,n,r,function(e){return e.triggersZOrder},function(){a._private.cy.notify("zorder",e)})},cu.checkBoundsTrigger=function(e,t,n,r){this.checkTrigger(e,t,n,r,function(e){return e.triggersBounds},function(t){e.dirtyCompoundBoundsCache(),e.dirtyBoundingBoxCache()})},cu.checkConnectedEdgesBoundsTrigger=function(e,t,n,r){this.checkTrigger(e,t,n,r,function(e){return e.triggersBoundsOfConnectedEdges},function(t){e.connectedEdges().forEach(function(e){e.dirtyBoundingBoxCache()})})},cu.checkParallelEdgesBoundsTrigger=function(e,t,n,r){this.checkTrigger(e,t,n,r,function(e){return e.triggersBoundsOfParallelEdges},function(t){e.parallelEdges().forEach(function(e){e.dirtyBoundingBoxCache()})})},cu.checkTriggers=function(e,t,n,r){e.dirtyStyleCache(),this.checkZOrderTrigger(e,t,n,r),this.checkBoundsTrigger(e,t,n,r),this.checkConnectedEdgesBoundsTrigger(e,t,n,r),this.checkParallelEdgesBoundsTrigger(e,t,n,r)};var hu={applyBypass:function(e,t,n,r){var a=[];if("*"===t||"**"===t){if(void 0!==n)for(var i=0;it.length?i.substr(t.length):""}function s(){n=n.length>r.length?n.substr(r.length):""}for(i=i.replace(/[/][*](\s|.)+?[*][/]/g,"");;){if(i.match(/^\s*$/))break;var l=i.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/);if(!l){ot("Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: "+i);break}t=l[0];var u=l[1];if("core"!==u)if(new os(u).invalid){ot("Skipping parsing of block: Invalid selector found in string stylesheet: "+u),o();continue}var c=l[2],d=!1;n=c;for(var h=[];;){if(n.match(/^\s*$/))break;var f=n.match(/^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/);if(!f){ot("Skipping parsing of block: Invalid formatting of style property and value definitions found in:"+c),d=!0;break}r=f[0];var p=f[1],v=f[2];if(this.properties[p])a.parse(p,v)?(h.push({name:p,val:v}),s()):(ot("Skipping property: Invalid property definition in: "+r),s());else ot("Skipping property: Invalid property name in: "+r),s()}if(d){o();break}a.selector(u);for(var g=0;g=7&&"d"===t[0]&&(u=new RegExp(s.data.regex).exec(t))){if(n)return!1;var h=s.data;return{name:e,value:u,strValue:""+t,mapped:h,field:u[1],bypass:n}}if(t.length>=10&&"m"===t[0]&&(c=new RegExp(s.mapData.regex).exec(t))){if(n)return!1;if(d.multiple)return!1;var f=s.mapData;if(!d.color&&!d.number)return!1;var p=this.parse(e,c[4]);if(!p||p.mapped)return!1;var v=this.parse(e,c[5]);if(!v||v.mapped)return!1;if(p.pfValue===v.pfValue||p.strValue===v.strValue)return ot("`"+e+": "+t+"` is not a valid mapper because the output range is zero; converting to `"+e+": "+p.strValue+"`"),this.parse(e,p.strValue);if(d.color){var g=p.value,y=v.value;if(!(g[0]!==y[0]||g[1]!==y[1]||g[2]!==y[2]||g[3]!==y[3]&&(null!=g[3]&&1!==g[3]||null!=y[3]&&1!==y[3])))return!1}return{name:e,value:c,strValue:""+t,mapped:f,field:c[1],fieldMin:parseFloat(c[2]),fieldMax:parseFloat(c[3]),valueMin:p.value,valueMax:v.value,bypass:n}}}if(d.multiple&&"multiple"!==r){var m;if(m=l?t.split(/\s+/):Z(t)?t:[t],d.evenMultiple&&m.length%2!=0)return null;for(var b=[],x=[],w=[],E="",k=!1,T=0;T0?" ":"")+C.strValue}return d.validate&&!d.validate(b,x)?null:d.singleEnum&&k?1===b.length&&K(b[0])?{name:e,value:b[0],strValue:b[0],bypass:n}:null:{name:e,value:b,pfValue:w,strValue:E,bypass:n,units:x}}var P,S,B=function(){for(var r=0;rd.max||d.strictMax&&t===d.max))return null;var R={name:e,value:t,strValue:""+t+(D||""),units:D,bypass:n};return d.unitless||"px"!==D&&"em"!==D?R.pfValue=t:R.pfValue="px"!==D&&D?this.getEmSizeInPixels()*t:t,"ms"!==D&&"s"!==D||(R.pfValue="ms"===D?t:1e3*t),"deg"!==D&&"rad"!==D||(R.pfValue="rad"===D?t:(P=t,Math.PI*P/180)),"%"===D&&(R.pfValue=t/100),R}if(d.propList){var I=[],N=""+t;if("none"===N);else{for(var L=N.split(/\s*,\s*|\s+/),z=0;z0&&l>0&&!isNaN(n.w)&&!isNaN(n.h)&&n.w>0&&n.h>0)return{zoom:o=(o=(o=Math.min((s-2*t)/n.w,(l-2*t)/n.h))>this._private.maxZoom?this._private.maxZoom:o)=n.minZoom&&(n.maxZoom=t),this},minZoom:function(e){return void 0===e?this._private.minZoom:this.zoomRange({min:e})},maxZoom:function(e){return void 0===e?this._private.maxZoom:this.zoomRange({max:e})},getZoomedViewport:function(e){var t,n,r=this._private,a=r.pan,i=r.zoom,o=!1;if(r.zoomingEnabled||(o=!0),Q(e)?n=e:$(e)&&(n=e.level,null!=e.position?t=Yt(e.position,i,a):null!=e.renderedPosition&&(t=e.renderedPosition),null==t||r.panningEnabled||(o=!0)),n=(n=n>r.maxZoom?r.maxZoom:n)t.maxZoom||!t.zoomingEnabled?i=!0:(t.zoom=s,a.push("zoom"))}if(r&&(!i||!e.cancelOnFailedZoom)&&t.panningEnabled){var l=e.pan;Q(l.x)&&(t.pan.x=l.x,o=!1),Q(l.y)&&(t.pan.y=l.y,o=!1),o||a.push("pan")}return a.length>0&&(a.push("viewport"),this.emit(a.join(" ")),this.notify("viewport")),this},center:function(e){var t=this.getCenterPan(e);return t&&(this._private.pan=t,this.emit("pan viewport"),this.notify("viewport")),this},getCenterPan:function(e,t){if(this._private.panningEnabled){if(K(e)){var n=e;e=this.mutableElements().filter(n)}else ee(e)||(e=this.mutableElements());if(0!==e.length){var r=e.boundingBox(),a=this.width(),i=this.height();return{x:(a-(t=void 0===t?this._private.zoom:t)*(r.x1+r.x2))/2,y:(i-t*(r.y1+r.y2))/2}}}},reset:function(){return this._private.panningEnabled&&this._private.zoomingEnabled?(this.viewport({pan:{x:0,y:0},zoom:1}),this):this},invalidateSize:function(){this._private.sizeCache=null},size:function(){var e,t,n=this._private,r=n.container,a=this;return n.sizeCache=n.sizeCache||(r?(e=a.window().getComputedStyle(r),t=function(t){return parseFloat(e.getPropertyValue(t))},{width:r.clientWidth-t("padding-left")-t("padding-right"),height:r.clientHeight-t("padding-top")-t("padding-bottom")}):{width:1,height:1})},width:function(){return this.size().width},height:function(){return this.size().height},extent:function(){var e=this._private.pan,t=this._private.zoom,n=this.renderedExtent(),r={x1:(n.x1-e.x)/t,x2:(n.x2-e.x)/t,y1:(n.y1-e.y)/t,y2:(n.y2-e.y)/t};return r.w=r.x2-r.x1,r.h=r.y2-r.y1,r},renderedExtent:function(){var e=this.width(),t=this.height();return{x1:0,y1:0,x2:e,y2:t,w:e,h:t}},multiClickDebounceTime:function(e){return e?(this._private.multiClickDebounceTime=e,this):this._private.multiClickDebounceTime}};Eu.centre=Eu.center,Eu.autolockNodes=Eu.autolock,Eu.autoungrabifyNodes=Eu.autoungrabify;var ku={data:Eo.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeData:Eo.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),scratch:Eo.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:Eo.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0})};ku.attr=ku.data,ku.removeAttr=ku.removeData;var Tu=function(e){var t=this,n=(e=be({},e)).container;n&&!J(n)&&J(n[0])&&(n=n[0]);var r=n?n._cyreg:null;(r=r||{})&&r.cy&&(r.cy.destroy(),r={});var a=r.readies=r.readies||[];n&&(n._cyreg=r),r.cy=t;var i=void 0!==f&&void 0!==n&&!e.headless,o=e;o.layout=be({name:i?"grid":"null"},o.layout),o.renderer=be({name:i?"canvas":"null"},o.renderer);var s=function(e,t,n){return void 0!==t?t:void 0!==n?n:e},l=this._private={container:n,ready:!1,options:o,elements:new Fl(this),listeners:[],aniEles:new Fl(this),data:o.data||{},scratch:{},layout:null,renderer:null,destroyed:!1,notificationsEnabled:!0,minZoom:1e-50,maxZoom:1e50,zoomingEnabled:s(!0,o.zoomingEnabled),userZoomingEnabled:s(!0,o.userZoomingEnabled),panningEnabled:s(!0,o.panningEnabled),userPanningEnabled:s(!0,o.userPanningEnabled),boxSelectionEnabled:s(!0,o.boxSelectionEnabled),autolock:s(!1,o.autolock,o.autolockNodes),autoungrabify:s(!1,o.autoungrabify,o.autoungrabifyNodes),autounselectify:s(!1,o.autounselectify),styleEnabled:void 0===o.styleEnabled?i:o.styleEnabled,zoom:Q(o.zoom)?o.zoom:1,pan:{x:$(o.pan)&&Q(o.pan.x)?o.pan.x:0,y:$(o.pan)&&Q(o.pan.y)?o.pan.y:0},animation:{current:[],queue:[]},hasCompoundNodes:!1,multiClickDebounceTime:s(250,o.multiClickDebounceTime)};this.createEmitter(),this.selectionType(o.selectionType),this.zoomRange({min:o.minZoom,max:o.maxZoom});l.styleEnabled&&t.setStyle([]);var u=be({},o,o.renderer);t.initRenderer(u);!function(e,t){if(e.some(oe))return Gr.all(e).then(t);t(e)}([o.style,o.elements],function(e){var n=e[0],i=e[1];l.styleEnabled&&t.style().append(n),function(e,n,r){t.notifications(!1);var a=t.mutableElements();a.length>0&&a.remove(),null!=e&&($(e)||Z(e))&&t.add(e),t.one("layoutready",function(e){t.notifications(!0),t.emit(e),t.one("load",n),t.emitAndNotify("load")}).one("layoutstop",function(){t.one("done",r),t.emit("done")});var i=be({},t._private.options.layout);i.eles=t.elements(),t.layout(i).run()}(i,function(){t.startAnimationLoop(),l.ready=!0,G(o.ready)&&t.on("ready",o.ready);for(var e=0;e0,l=!!t.boundingBox,u=tn(l?t.boundingBox:structuredClone(n.extent()));if(ee(t.roots))e=t.roots;else if(Z(t.roots)){for(var c=[],d=0;d0;){var D=B(),_=T(D,P);if(_)D.outgoers().filter(function(e){return e.isNode()&&r.has(e)}).forEach(S);else if(null===_){ot("Detected double maximal shift for node `"+D.id()+"`. Bailing maximal adjustment due to cycle. Use `options.maximal: true` only on DAGs.");break}}}var A=0;if(t.avoidOverlap)for(var M=0;M0&&y[0].length<=3?i/2:0),s=2*Math.PI/y[r].length*a;return 0===r&&1===y[0].length&&(o=1),{x:W+o*Math.cos(s),y:U+o*Math.sin(s)}}var c=y[r].length,d=Math.max(1===c?0:l?(u.w-2*t.padding-H.w)/((t.grid?$:c)-1):(u.w-2*t.padding-H.w)/((t.grid?$:c)+1),A);return{x:W+(a+1-(c+1)/2)*d,y:U+(r+1-(V+1)/2)*G}}(e),u,Q[t.direction])}),this};var Au={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,radius:void 0,startAngle:1.5*Math.PI,sweep:void 0,clockwise:!0,sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function Mu(e){this.options=be({},Au,e)}Mu.prototype.run=function(){var e=this.options,t=e,n=e.cy,r=t.eles,a=void 0!==t.counterclockwise?!t.counterclockwise:t.clockwise,i=r.nodes().not(":parent");t.sort&&(i=i.sort(t.sort));for(var o,s=tn(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()}),l=s.x1+s.w/2,u=s.y1+s.h/2,c=(void 0===t.sweep?2*Math.PI-2*Math.PI/i.length:t.sweep)/Math.max(1,i.length-1),d=0,h=0;h1&&t.avoidOverlap){d*=1.75;var g=Math.cos(c)-Math.cos(0),y=Math.sin(c)-Math.sin(0),m=Math.sqrt(d*d/(g*g+y*y));o=Math.max(m,o)}return r.nodes().layoutPositions(this,t,function(e,n){var r=t.startAngle+n*c*(a?1:-1),i=o*Math.cos(r),s=o*Math.sin(r);return{x:l+i,y:u+s}}),this};var Ru,Iu={fit:!0,padding:30,startAngle:1.5*Math.PI,sweep:void 0,clockwise:!0,equidistant:!1,minNodeSpacing:10,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,height:void 0,width:void 0,spacingFactor:void 0,concentric:function(e){return e.degree()},levelWidth:function(e){return e.maxDegree()/4},animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function Nu(e){this.options=be({},Iu,e)}Nu.prototype.run=function(){for(var e=this.options,t=e,n=void 0!==t.counterclockwise?!t.counterclockwise:t.clockwise,r=e.cy,a=t.eles,i=a.nodes().not(":parent"),o=tn(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()}),s=o.x1+o.w/2,l=o.y1+o.h/2,u=[],c=0,d=0;d0)Math.abs(m[0].value-x.value)>=g&&(m=[],y.push(m));m.push(x)}var w=c+t.minNodeSpacing;if(!t.avoidOverlap){var E=y.length>0&&y[0].length>1,k=(Math.min(o.w,o.h)/2-w)/(y.length+E?1:0);w=Math.min(w,k)}for(var T=0,C=0;C1&&t.avoidOverlap){var D=Math.cos(B)-Math.cos(0),_=Math.sin(B)-Math.sin(0),A=Math.sqrt(w*w/(D*D+_*_));T=Math.max(A,T)}P.r=T,T+=w}if(t.equidistant){for(var M=0,R=0,I=0;I=e.numIter)&&(qu(r,e),r.temperature=r.temperature*e.coolingFactor,!(r.temperature=e.animationThreshold&&i(),Le(c)):(nc(r,e),s())};c()}else{for(;u;)u=o(l),l++;nc(r,e),s()}return this},zu.prototype.stop=function(){return this.stopped=!0,this.thread&&this.thread.stop(),this.emit("layoutstop"),this},zu.prototype.destroy=function(){return this.thread&&this.thread.stop(),this};var Ou=function(e,t,n){for(var r=n.eles.edges(),a=n.eles.nodes(),i=tn(n.boundingBox?n.boundingBox:{x1:0,y1:0,w:e.width(),h:e.height()}),o={isCompound:e.hasCompoundNodes(),layoutNodes:[],idToIndex:{},nodeSize:a.size(),graphSet:[],indexToGraph:[],layoutEdges:[],edgeSize:r.size(),temperature:n.initialTemp,clientWidth:i.w,clientHeight:i.h,boundingBox:i},s=n.eles.components(),l={},u=0;u0){o.graphSet.push(w);for(u=0;ur.count?0:r.graph},Fu=function(e,t,n,r){var a=r.graphSet[n];if(-10)var s=(u=r.nodeOverlap*o)*a/(v=Math.sqrt(a*a+i*i)),l=u*i/v;else{var u,c=Gu(e,a,i),d=Gu(t,-1*a,-1*i),h=d.x-c.x,f=d.y-c.y,p=h*h+f*f,v=Math.sqrt(p);s=(u=(e.nodeRepulsion+t.nodeRepulsion)/p)*h/v,l=u*f/v}e.isLocked||(e.offsetX-=s,e.offsetY-=l),t.isLocked||(t.offsetX+=s,t.offsetY+=l)}},Ku=function(e,t,n,r){if(n>0)var a=e.maxX-t.minX;else a=t.maxX-e.minX;if(r>0)var i=e.maxY-t.minY;else i=t.maxY-e.minY;return a>=0&&i>=0?Math.sqrt(a*a+i*i):0},Gu=function(e,t,n){var r=e.positionX,a=e.positionY,i=e.height||1,o=e.width||1,s=n/t,l=i/o,u={};return 0===t&&0n?(u.x=r,u.y=a+i/2,u):0t&&-1*l<=s&&s<=l?(u.x=r-o/2,u.y=a-o*n/2/t,u):0=l)?(u.x=r+i*t/2/n,u.y=a+i/2,u):0>n&&(s<=-1*l||s>=l)?(u.x=r-i*t/2/n,u.y=a-i/2,u):u},Zu=function(e,t){for(var n=0;n1){var p=t.gravity*d/f,v=t.gravity*h/f;c.offsetX+=p,c.offsetY+=v}}}}},Qu=function(e,t){var n=[],r=0,a=-1;for(n.push.apply(n,e.graphSet[0]),a+=e.graphSet[0].length;r<=a;){var i=n[r++],o=e.idToIndex[i],s=e.layoutNodes[o],l=s.children;if(0n)var a={x:n*e/r,y:n*t/r};else a={x:e,y:t};return a},tc=function(e,t){var n=e.parentId;if(null!=n){var r=t.layoutNodes[t.idToIndex[n]],a=!1;return(null==r.maxX||e.maxX+r.padRight>r.maxX)&&(r.maxX=e.maxX+r.padRight,a=!0),(null==r.minX||e.minX-r.padLeftr.maxY)&&(r.maxY=e.maxY+r.padBottom,a=!0),(null==r.minY||e.minY-r.padTopp&&(d+=f+t.componentSpacing,c=0,h=0,f=0)}}},rc={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,avoidOverlapPadding:10,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,condense:!1,rows:void 0,cols:void 0,position:function(e){},sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function ac(e){this.options=be({},rc,e)}ac.prototype.run=function(){var e=this.options,t=e,n=e.cy,r=t.eles,a=r.nodes().not(":parent");t.sort&&(a=a.sort(t.sort));var i=tn(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()});if(0===i.h||0===i.w)r.nodes().layoutPositions(this,t,function(e){return{x:i.x1,y:i.y1}});else{var o=a.size(),s=Math.sqrt(o*i.h/i.w),l=Math.round(s),u=Math.round(i.w/i.h*s),c=function(e){if(null==e)return Math.min(l,u);Math.min(l,u)==l?l=e:u=e},d=function(e){if(null==e)return Math.max(l,u);Math.max(l,u)==l?l=e:u=e},h=t.rows,f=null!=t.cols?t.cols:t.columns;if(null!=h&&null!=f)l=h,u=f;else if(null!=h&&null==f)l=h,u=Math.ceil(o/l);else if(null==h&&null!=f)u=f,l=Math.ceil(o/u);else if(u*l>o){var p=c(),v=d();(p-1)*v>=o?c(p-1):(v-1)*p>=o&&d(v-1)}else for(;u*l=o?d(y+1):c(g+1)}var m=i.w/u,b=i.h/l;if(t.condense&&(m=0,b=0),t.avoidOverlap)for(var x=0;x=u&&(A=0,_++)},R={},I=0;I(r=mn(e,t,x[w],x[w+1],x[w+2],x[w+3])))return g(n,r),!0}else if("bezier"===i.edgeType||"multibezier"===i.edgeType||"self"===i.edgeType||"compound"===i.edgeType)for(x=i.allpts,w=0;w+5(r=yn(e,t,x[w],x[w+1],x[w+2],x[w+3],x[w+4],x[w+5])))return g(n,r),!0;m=m||a.source,b=b||a.target;var E=o.getArrowWidth(l,c),k=[{name:"source",x:i.arrowStartX,y:i.arrowStartY,angle:i.srcArrowAngle},{name:"target",x:i.arrowEndX,y:i.arrowEndY,angle:i.tgtArrowAngle},{name:"mid-source",x:i.midX,y:i.midY,angle:i.midsrcArrowAngle},{name:"mid-target",x:i.midX,y:i.midY,angle:i.midtgtArrowAngle}];for(w=0;w0&&(y(m),y(b))}function b(e,t,n){return pt(e,t,n)}function x(n,r){var a,i=n._private,o=p;a=r?r+"-":"",n.boundingBox();var s=i.labelBounds[r||"main"],l=n.pstyle(a+"label").value;if("yes"===n.pstyle("text-events").strValue&&l){var u=b(i.rscratch,"labelX",r),c=b(i.rscratch,"labelY",r),d=b(i.rscratch,"labelAngle",r),h=n.pstyle(a+"text-margin-x").pfValue,f=n.pstyle(a+"text-margin-y").pfValue,v=s.x1-o-h,y=s.x2+o-h,m=s.y1-o-f,x=s.y2+o-f;if(d){var w=Math.cos(d),E=Math.sin(d),k=function(e,t){return{x:(e-=u)*w-(t-=c)*E+u,y:e*E+t*w+c}},T=k(v,m),C=k(v,x),P=k(y,m),S=k(y,x),B=[T.x+h,T.y+f,P.x+h,P.y+f,S.x+h,S.y+f,C.x+h,C.y+f];if(bn(e,t,B))return g(n),!0}else if(un(s,e,t))return g(n),!0}}n&&(l=l.interactive);for(var w=l.length-1;w>=0;w--){var E=l[w];E.isNode()?y(E)||x(E):m(E)||x(E)||x(E,"source")||x(E,"target")}return u},getAllInBox:function(e,t,n,r){var a=this.getCachedZSortedEles().interactive,i=2/this.cy.zoom(),o=[],s=Math.min(e,n),u=Math.max(e,n),c=Math.min(t,r),d=Math.max(t,r),h=tn({x1:e=s,y1:t=c,x2:n=u,y2:r=d}),f=[{x:h.x1,y:h.y1},{x:h.x2,y:h.y1},{x:h.x2,y:h.y2},{x:h.x1,y:h.y2}],p=[[f[0],f[1]],[f[1],f[2]],[f[2],f[3]],[f[3],f[0]]];function v(e,t,n){return pt(e,t,n)}function g(e,t){var n=e._private,r=i;e.boundingBox();var a=n.labelBounds.main;if(!a)return null;var o=v(n.rscratch,"labelX",t),s=v(n.rscratch,"labelY",t),l=v(n.rscratch,"labelAngle",t),u=e.pstyle("text-margin-x").pfValue,c=e.pstyle("text-margin-y").pfValue,d=a.x1-r-u,h=a.x2+r-u,f=a.y1-r-c,p=a.y2+r-c;if(l){var g=Math.cos(l),y=Math.sin(l),m=function(e,t){return{x:(e-=o)*g-(t-=s)*y+o,y:e*y+t*g+s}};return[m(d,f),m(h,f),m(h,p),m(d,p)]}return[{x:d,y:f},{x:h,y:f},{x:h,y:p},{x:d,y:p}]}function y(e,t,n,r){function a(e,t,n){return(n.y-e.y)*(t.x-e.x)>(t.y-e.y)*(n.x-e.x)}return a(e,n,r)!==a(t,n,r)&&a(e,t,n)!==a(e,t,r)}for(var m=0;m0?-(Math.PI-i.ang):Math.PI+i.ang),zc(t,n,Lc),xc=Nc.nx*Lc.ny-Nc.ny*Lc.nx,wc=Nc.nx*Lc.nx-Nc.ny*-Lc.ny,Tc=Math.asin(Math.max(-1,Math.min(1,xc))),Math.abs(Tc)<1e-6)return mc=t.x,bc=t.y,void(Pc=Bc=0);Ec=1,kc=!1,wc<0?Tc<0?Tc=Math.PI+Tc:(Tc=Math.PI-Tc,Ec=-1,kc=!0):Tc>0&&(Ec=-1,kc=!0),Bc=void 0!==t.radius?t.radius:r,Cc=Tc/2,Dc=Math.min(Nc.len/2,Lc.len/2),a?(Sc=Math.abs(Math.cos(Cc)*Bc/Math.sin(Cc)))>Dc?(Sc=Dc,Pc=Math.abs(Sc*Math.sin(Cc)/Math.cos(Cc))):Pc=Bc:(Sc=Math.min(Dc,Bc),Pc=Math.abs(Sc*Math.sin(Cc)/Math.cos(Cc))),Mc=t.x+Lc.nx*Sc,Rc=t.y+Lc.ny*Sc,mc=Mc-Lc.ny*Pc*Ec,bc=Rc+Lc.nx*Pc*Ec,_c=t.x+Nc.nx*Sc,Ac=t.y+Nc.ny*Sc,Ic=t};function Vc(e,t){0===t.radius?e.lineTo(t.cx,t.cy):e.arc(t.cx,t.cy,t.radius,t.startAngle,t.endAngle,t.counterClockwise)}function Fc(e,t,n,r){var a=!(arguments.length>4&&void 0!==arguments[4])||arguments[4];return 0===r||0===t.radius?{cx:t.x,cy:t.y,radius:0,startX:t.x,startY:t.y,stopX:t.x,stopY:t.y,startAngle:void 0,endAngle:void 0,counterClockwise:void 0}:(Oc(e,t,n,r,a),{cx:mc,cy:bc,radius:Pc,startX:_c,startY:Ac,stopX:Mc,stopY:Rc,startAngle:Nc.ang+Math.PI/2*Ec,endAngle:Lc.ang-Math.PI/2*Ec,counterClockwise:kc})}var Xc=.01,jc=Math.sqrt(.02),Yc={};function qc(e){var t=[];if(null!=e){for(var n=0;n0?Math.max(e-t,0):Math.min(e+t,0)},S=P(T,E),B=P(C,k),D=!1;"auto"===g?v=Math.abs(S)>Math.abs(B)?a:r:g===l||g===s?(v=r,D=!0):g!==i&&g!==o||(v=a,D=!0);var _,A=v===r,M=A?B:S,R=A?C:T,I=Kt(R),N=!1;(D&&(m||x)||!(g===s&&R<0||g===l&&R>0||g===i&&R>0||g===o&&R<0)||(M=(I*=-1)*Math.abs(M),N=!0),m)?_=(b<0?1+b:b)*M:_=(b<0?M:0)+b*I;var L=function(e){return Math.abs(e)=Math.abs(M)},z=L(_),O=L(Math.abs(M)-Math.abs(_));if((z||O)&&!N)if(A){var V=Math.abs(R)<=d/2,F=Math.abs(T)<=h/2;if(V){var X=(u.x1+u.x2)/2,j=u.y1,Y=u.y2;n.segpts=[X,j,X,Y]}else if(F){var q=(u.y1+u.y2)/2,W=u.x1,U=u.x2;n.segpts=[W,q,U,q]}else n.segpts=[u.x1,u.y2]}else{var H=Math.abs(R)<=c/2,K=Math.abs(C)<=f/2;if(H){var G=(u.y1+u.y2)/2,Z=u.x1,$=u.x2;n.segpts=[Z,G,$,G]}else if(K){var Q=(u.x1+u.x2)/2,J=u.y1,ee=u.y2;n.segpts=[Q,J,Q,ee]}else n.segpts=[u.x2,u.y1]}else if(A){var te=u.y1+_+(p?d/2*I:0),ne=u.x1,re=u.x2;n.segpts=[ne,te,re,te]}else{var ae=u.x1+_+(p?c/2*I:0),ie=u.y1,oe=u.y2;n.segpts=[ae,ie,ae,oe]}if(n.isRound){var se=e.pstyle("taxi-radius").value,le="arc-radius"===e.pstyle("radius-type").value[0];n.radii=new Array(n.segpts.length/2).fill(se),n.isArcRadius=new Array(n.segpts.length/2).fill(le)}},Yc.tryToCorrectInvalidPoints=function(e,t){var n=e._private.rscratch;if("bezier"===n.edgeType){var r=t.srcPos,a=t.tgtPos,i=t.srcW,o=t.srcH,s=t.tgtW,l=t.tgtH,u=t.srcShape,c=t.tgtShape,d=t.srcCornerRadius,h=t.tgtCornerRadius,f=t.srcRs,p=t.tgtRs,v=!Q(n.startX)||!Q(n.startY),g=!Q(n.arrowStartX)||!Q(n.arrowStartY),y=!Q(n.endX)||!Q(n.endY),m=!Q(n.arrowEndX)||!Q(n.arrowEndY),b=3*(this.getArrowWidth(e.pstyle("width").pfValue,e.pstyle("arrow-scale").value)*this.arrowShapeWidth),x=Gt({x:n.ctrlpts[0],y:n.ctrlpts[1]},{x:n.startX,y:n.startY}),w=xv.poolIndex()){var g=p;p=v,v=g}var y=d.srcPos=p.position(),m=d.tgtPos=v.position(),b=d.srcW=p.outerWidth(),x=d.srcH=p.outerHeight(),E=d.tgtW=v.outerWidth(),k=d.tgtH=v.outerHeight(),T=d.srcShape=n.nodeShapes[t.getNodeShape(p)],C=d.tgtShape=n.nodeShapes[t.getNodeShape(v)],P=d.srcCornerRadius="auto"===p.pstyle("corner-radius").value?"auto":p.pstyle("corner-radius").pfValue,S=d.tgtCornerRadius="auto"===v.pstyle("corner-radius").value?"auto":v.pstyle("corner-radius").pfValue,B=d.tgtRs=v._private.rscratch,D=d.srcRs=p._private.rscratch;d.dirCounts={north:0,west:0,south:0,east:0,northwest:0,southwest:0,northeast:0,southeast:0};for(var _=0;_=jc||(q=Math.sqrt(Math.max(Y*Y,Xc)+Math.max(j*j,Xc)));var W=d.vector={x:Y,y:j},U=d.vectorNorm={x:W.x/q,y:W.y/q},H={x:-U.y,y:U.x};d.nodesOverlap=!Q(q)||C.checkPoint(L[0],L[1],0,E,k,m.x,m.y,S,B)||T.checkPoint(O[0],O[1],0,b,x,y.x,y.y,P,D),d.vectorNormInverse=H,e={nodesOverlap:d.nodesOverlap,dirCounts:d.dirCounts,calculatedIntersection:!0,hasBezier:d.hasBezier,hasUnbundled:d.hasUnbundled,eles:d.eles,srcPos:m,srcRs:B,tgtPos:y,tgtRs:D,srcW:E,srcH:k,tgtW:b,tgtH:x,srcIntn:V,tgtIntn:z,srcShape:C,tgtShape:T,posPts:{x1:X.x2,y1:X.y2,x2:X.x1,y2:X.y1},intersectionPts:{x1:F.x2,y1:F.y2,x2:F.x1,y2:F.y1},vector:{x:-W.x,y:-W.y},vectorNorm:{x:-U.x,y:-U.y},vectorNormInverse:{x:-H.x,y:-H.y}}}var K=N?e:d;M.nodesOverlap=K.nodesOverlap,M.srcIntn=K.srcIntn,M.tgtIntn=K.tgtIntn,M.isRound=R.startsWith("round"),r&&(p.isParent()||p.isChild()||v.isParent()||v.isChild())&&(p.parents().anySame(v)||v.parents().anySame(p)||p.same(v)&&p.isParent())?t.findCompoundLoopPoints(A,K,_,I):p===v?t.findLoopPoints(A,K,_,I):R.endsWith("segments")?t.findSegmentsPoints(A,K):R.endsWith("taxi")?t.findTaxiPoints(A,K):"straight"===R||!I&&d.eles.length%2==1&&_===Math.floor(d.eles.length/2)?t.findStraightEdgePoints(A):t.findBezierPoints(A,K,_,I,N),t.findEndpoints(A),t.tryToCorrectInvalidPoints(A,K),t.checkForInvalidEdgeWarning(A),t.storeAllpts(A),t.storeEdgeProjections(A),t.calculateArrowAngles(A),t.recalculateEdgeLabelProjections(A),t.calculateLabelAngles(A)}},w=0;w0){var J=f,ee=Zt(J,Wt(i)),te=Zt(J,Wt($)),ne=ee;if(te2)Zt(J,{x:$[2],y:$[3]})0){var ge=p,ye=Zt(ge,Wt(i)),me=Zt(ge,Wt(ve)),be=ye;if(me2)Zt(ge,{x:ve[2],y:ve[3]})=u||m){c={cp:v,segment:y};break}}if(c)break}var b=c.cp,x=c.segment,w=(u-h)/x.length,E=x.t1-x.t0,k=s?x.t0+E*w:x.t1-E*w;k=en(0,k,1),t=Jt(b.p0,b.p1,b.p2,k),a=function(e,t,n,r){var a=en(0,r-.001,1),i=en(0,r+.001,1),o=Jt(e,t,n,a),s=Jt(e,t,n,i);return Zc(o,s)}(b.p0,b.p1,b.p2,k);break;case"straight":case"segments":case"haystack":for(var T,C,P,S,B=0,D=r.allpts.length,_=0;_+3=u));_+=2);var A=(u-C)/T;A=en(0,A,1),t=function(e,t,n,r){var a=t.x-e.x,i=t.y-e.y,o=Gt(e,t),s=a/o,l=i/o;return n=null==n?0:n,r=null!=r?r:n*o,{x:e.x+s*r,y:e.y+l*r}}(P,S,A),a=Zc(P,S)}o("labelX",n,t.x),o("labelY",n,t.y),o("labelAutoAngle",n,a)}};u("source"),u("target"),this.applyLabelDimensions(e)}},Kc.applyLabelDimensions=function(e){this.applyPrefixedLabelDimensions(e),e.isEdge()&&(this.applyPrefixedLabelDimensions(e,"source"),this.applyPrefixedLabelDimensions(e,"target"))},Kc.applyPrefixedLabelDimensions=function(e,t){var n=e._private,r=this.getLabelText(e,t),a=Ue(r,e._private.labelDimsKey);if(pt(n.rscratch,"prefixedLabelDimsKey",t)!==a){vt(n.rscratch,"prefixedLabelDimsKey",t,a);var i=this.calculateLabelDimensions(e,r),o=e.pstyle("line-height").pfValue,s=e.pstyle("text-wrap").strValue,l=pt(n.rscratch,"labelWrapCachedLines",t)||[],u="wrap"!==s?1:Math.max(l.length,1),c=i.height/u,d=c*o,h=i.width,f=i.height+(u-1)*(o-1)*c;vt(n.rstyle,"labelWidth",t,h),vt(n.rscratch,"labelWidth",t,h),vt(n.rstyle,"labelHeight",t,f),vt(n.rscratch,"labelHeight",t,f),vt(n.rscratch,"labelLineHeight",t,d)}},Kc.getLabelText=function(e,t){var n=e._private,r=t?t+"-":"",a=e.pstyle(r+"label").strValue,i=e.pstyle("text-transform").value,s=function(e,r){return r?(vt(n.rscratch,e,t,r),r):pt(n.rscratch,e,t)};if(!a)return"";"none"==i||("uppercase"==i?a=a.toUpperCase():"lowercase"==i&&(a=a.toLowerCase()));var l=e.pstyle("text-wrap").value;if("wrap"===l){var u=s("labelKey");if(null!=u&&s("labelWrapKey")===u)return s("labelWrapCachedText");for(var c=a.split("\n"),d=e.pstyle("text-max-width").pfValue,h="anywhere"===e.pstyle("text-overflow-wrap").value,f=[],p=/[\s\u200b]+|$/g,v=0;vd){var b,x="",w=0,E=o(g.matchAll(p));try{for(E.s();!(b=E.n()).done;){var k=b.value,T=k[0],C=g.substring(w,k.index);w=k.index+T.length;var P=0===x.length?C:x+C+T;this.calculateLabelDimensions(e,P).width<=d?x+=C+T:(x&&f.push(x),x=C+T)}}catch(A){E.e(A)}finally{E.f()}x.match(/^[\s\u200b]+$/)||f.push(x)}else f.push(g)}s("labelWrapCachedLines",f),a=s("labelWrapCachedText",f.join("\n")),s("labelWrapKey",u)}else if("ellipsis"===l){var S=e.pstyle("text-max-width").pfValue,B="",D=!1;if(this.calculateLabelDimensions(e,a).widthS)break;B+=a[_],_===a.length-1&&(D=!0)}return D||(B+="\u2026"),B}return a},Kc.getLabelJustification=function(e){var t=e.pstyle("text-justification").strValue,n=e.pstyle("text-halign").strValue;if("auto"!==t)return t;if(!e.isNode())return"center";switch(n){case"left":return"right";case"right":return"left";default:return"center"}},Kc.calculateLabelDimensions=function(e,t){var n=this.cy.window().document,r=e.pstyle("font-style").strValue,a=e.pstyle("font-size").pfValue,i=e.pstyle("font-family").strValue,o=e.pstyle("font-weight").strValue,s=this.labelCalcCanvas,l=this.labelCalcCanvasContext;if(!s){s=this.labelCalcCanvas=n.createElement("canvas"),l=this.labelCalcCanvasContext=s.getContext("2d");var u=s.style;u.position="absolute",u.left="-9999px",u.top="-9999px",u.zIndex="-1",u.visibility="hidden",u.pointerEvents="none"}l.font="".concat(r," ").concat(o," ").concat(a,"px ").concat(i);for(var c=0,d=0,h=t.split("\n"),f=0;f1&&void 0!==arguments[1])||arguments[1];if(t.merge(e),n)for(var r=0;r=e.desktopTapThreshold2}var P=a(t);g&&(e.hoverData.tapholdCancelled=!0);n=!0,r(v,["mousemove","vmousemove","tapdrag"],t,{x:c[0],y:c[1]});var S=function(e){return{originalEvent:t,type:e,position:{x:c[0],y:c[1]}}},B=function(){e.data.bgActivePosistion=void 0,e.hoverData.selecting||o.emit(S("boxstart")),p[4]=1,e.hoverData.selecting=!0,e.redrawHint("select",!0),e.redraw()};if(3===e.hoverData.which){if(g){var D=S("cxtdrag");b?b.emit(D):o.emit(D),e.hoverData.cxtDragged=!0,e.hoverData.cxtOver&&v===e.hoverData.cxtOver||(e.hoverData.cxtOver&&e.hoverData.cxtOver.emit(S("cxtdragout")),e.hoverData.cxtOver=v,v&&v.emit(S("cxtdragover")))}}else if(e.hoverData.dragging){if(n=!0,o.panningEnabled()&&o.userPanningEnabled()){var _;if(e.hoverData.justStartedPan){var A=e.hoverData.mdownPos;_={x:(c[0]-A[0])*s,y:(c[1]-A[1])*s},e.hoverData.justStartedPan=!1}else _={x:x[0]*s,y:x[1]*s};o.panBy(_),o.emit(S("dragpan")),e.hoverData.dragged=!0}c=e.projectIntoViewport(t.clientX,t.clientY)}else if(1!=p[4]||null!=b&&!b.pannable()){if(b&&b.pannable()&&b.active()&&b.unactivate(),b&&b.grabbed()||v==y||(y&&r(y,["mouseout","tapdragout"],t,{x:c[0],y:c[1]}),v&&r(v,["mouseover","tapdragover"],t,{x:c[0],y:c[1]}),e.hoverData.last=v),b)if(g){if(o.boxSelectionEnabled()&&P)b&&b.grabbed()&&(d(w),b.emit(S("freeon")),w.emit(S("free")),e.dragData.didDrag&&(b.emit(S("dragfreeon")),w.emit(S("dragfree")))),B();else if(b&&b.grabbed()&&e.nodeIsDraggable(b)){var M=!e.dragData.didDrag;M&&e.redrawHint("eles",!0),e.dragData.didDrag=!0,e.hoverData.draggingEles||u(w,{inDragLayer:!0});var R={x:0,y:0};if(Q(x[0])&&Q(x[1])&&(R.x+=x[0],R.y+=x[1],M)){var I=e.hoverData.dragDelta;I&&Q(I[0])&&Q(I[1])&&(R.x+=I[0],R.y+=I[1])}e.hoverData.draggingEles=!0,w.silentShift(R).emit(S("position")).emit(S("drag")),e.redrawHint("drag",!0),e.redraw()}}else!function(){var t=e.hoverData.dragDelta=e.hoverData.dragDelta||[];0===t.length?(t.push(x[0]),t.push(x[1])):(t[0]+=x[0],t[1]+=x[1])}();n=!0}else if(g){if(e.hoverData.dragging||!o.boxSelectionEnabled()||!P&&o.panningEnabled()&&o.userPanningEnabled()){if(!e.hoverData.selecting&&o.panningEnabled()&&o.userPanningEnabled()){i(b,e.hoverData.downs)&&(e.hoverData.dragging=!0,e.hoverData.justStartedPan=!0,p[4]=0,e.data.bgActivePosistion=Wt(h),e.redrawHint("select",!0),e.redraw())}}else B();b&&b.pannable()&&b.active()&&b.unactivate()}return p[2]=c[0],p[3]=c[1],n?(t.stopPropagation&&t.stopPropagation(),t.preventDefault&&t.preventDefault(),!1):void 0}},!1),e.registerBinding(t,"mouseup",function(t){if((1!==e.hoverData.which||1===t.which||!e.hoverData.capture)&&e.hoverData.capture){e.hoverData.capture=!1;var i=e.cy,o=e.projectIntoViewport(t.clientX,t.clientY),s=e.selection,l=e.findNearestElement(o[0],o[1],!0,!1),u=e.dragData.possibleDragElements,c=e.hoverData.down,h=a(t);e.data.bgActivePosistion&&(e.redrawHint("select",!0),e.redraw()),e.hoverData.tapholdCancelled=!0,e.data.bgActivePosistion=void 0,c&&c.unactivate();var f=function(e){return{originalEvent:t,type:e,position:{x:o[0],y:o[1]}}};if(3===e.hoverData.which){var p=f("cxttapend");if(c?c.emit(p):i.emit(p),!e.hoverData.cxtDragged){var v=f("cxttap");c?c.emit(v):i.emit(v)}e.hoverData.cxtDragged=!1,e.hoverData.which=null}else if(1===e.hoverData.which){if(r(l,["mouseup","tapend","vmouseup"],t,{x:o[0],y:o[1]}),e.dragData.didDrag||e.hoverData.dragged||e.hoverData.selecting||e.hoverData.isOverThresholdDrag||(r(c,["click","tap","vclick"],t,{x:o[0],y:o[1]}),x=!1,t.timeStamp-w<=i.multiClickDebounceTime()?(b&&clearTimeout(b),x=!0,w=null,r(c,["dblclick","dbltap","vdblclick"],t,{x:o[0],y:o[1]})):(b=setTimeout(function(){x||r(c,["oneclick","onetap","voneclick"],t,{x:o[0],y:o[1]})},i.multiClickDebounceTime()),w=t.timeStamp)),null!=c||e.dragData.didDrag||e.hoverData.selecting||e.hoverData.dragged||a(t)||(i.$(n).unselect(["tapunselect"]),u.length>0&&e.redrawHint("eles",!0),e.dragData.possibleDragElements=u=i.collection()),l!=c||e.dragData.didDrag||e.hoverData.selecting||null!=l&&l._private.selectable&&(e.hoverData.dragging||("additive"===i.selectionType()||h?l.selected()?l.unselect(["tapunselect"]):l.select(["tapselect"]):h||(i.$(n).unmerge(l).unselect(["tapunselect"]),l.select(["tapselect"]))),e.redrawHint("eles",!0)),e.hoverData.selecting){var g=i.collection(e.getAllInBox(s[0],s[1],s[2],s[3]));e.redrawHint("select",!0),g.length>0&&e.redrawHint("eles",!0),i.emit(f("boxend"));var y=function(e){return e.selectable()&&!e.selected()};"additive"===i.selectionType()||h||i.$(n).unmerge(g).unselect(),g.emit(f("box")).stdFilter(y).select().emit(f("boxselect")),e.redraw()}if(e.hoverData.dragging&&(e.hoverData.dragging=!1,e.redrawHint("select",!0),e.redrawHint("eles",!0),e.redraw()),!s[4]){e.redrawHint("drag",!0),e.redrawHint("eles",!0);var m=c&&c.grabbed();d(u),m&&(c.emit(f("freeon")),u.emit(f("free")),e.dragData.didDrag&&(c.emit(f("dragfreeon")),u.emit(f("dragfree"))))}}s[4]=0,e.hoverData.down=null,e.hoverData.cxtStarted=!1,e.hoverData.draggingEles=!1,e.hoverData.selecting=!1,e.hoverData.isOverThresholdDrag=!1,e.dragData.didDrag=!1,e.hoverData.dragged=!1,e.hoverData.dragDelta=[],e.hoverData.mdownPos=null,e.hoverData.mdownGPos=null,e.hoverData.which=null}},!1);var k,T,C,P,S,B,D,_,A,M,R,I,N,L,z=[],O=1e5,V=function(t){var n=!1,r=t.deltaY;if(null==r&&(null!=t.wheelDeltaY?r=t.wheelDeltaY/4:null!=t.wheelDelta&&(r=t.wheelDelta/4)),0!==r){if(null==k)if(z.length>=4){var a=z;if(k=function(e,t){for(var n=0;n5}if(k)for(var o=0;o5&&(r=5*Kt(r)),h=r/-250,k&&(h/=O,h*=3),h*=e.wheelSensitivity,1===t.deltaMode&&(h*=33);var f=s.zoom()*Math.pow(10,h);"gesturechange"===t.type&&(f=e.gestureStartZoom*t.scale),s.zoom({level:f,renderedPosition:{x:d[0],y:d[1]}}),s.emit({type:"gesturechange"===t.type?"pinchzoom":"scrollzoom",originalEvent:t,position:{x:c[0],y:c[1]}})}}}};e.registerBinding(e.container,"wheel",V,!0),e.registerBinding(t,"scroll",function(t){e.scrollingPage=!0,clearTimeout(e.scrollingPageTimeout),e.scrollingPageTimeout=setTimeout(function(){e.scrollingPage=!1},250)},!0),e.registerBinding(e.container,"gesturestart",function(t){e.gestureStartZoom=e.cy.zoom(),e.hasTouchStarted||t.preventDefault()},!0),e.registerBinding(e.container,"gesturechange",function(t){e.hasTouchStarted||V(t)},!0),e.registerBinding(e.container,"mouseout",function(t){var n=e.projectIntoViewport(t.clientX,t.clientY);e.cy.emit({originalEvent:t,type:"mouseout",position:{x:n[0],y:n[1]}})},!1),e.registerBinding(e.container,"mouseover",function(t){var n=e.projectIntoViewport(t.clientX,t.clientY);e.cy.emit({originalEvent:t,type:"mouseover",position:{x:n[0],y:n[1]}})},!1);var F,X,j,Y,q,W,U,H=function(e,t,n,r){return Math.sqrt((n-e)*(n-e)+(r-t)*(r-t))},K=function(e,t,n,r){return(n-e)*(n-e)+(r-t)*(r-t)};if(e.registerBinding(e.container,"touchstart",F=function(t){if(e.hasTouchStarted=!0,m(t)){f(),e.touchData.capture=!0,e.data.bgActivePosistion=void 0;var n=e.cy,a=e.touchData.now,i=e.touchData.earlier;if(t.touches[0]){var o=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);a[0]=o[0],a[1]=o[1]}if(t.touches[1]){o=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY);a[2]=o[0],a[3]=o[1]}if(t.touches[2]){o=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY);a[4]=o[0],a[5]=o[1]}var l=function(e){return{originalEvent:t,type:e,position:{x:a[0],y:a[1]}}};if(t.touches[1]){e.touchData.singleTouchMoved=!0,d(e.dragData.touchDragEles);var h=e.findContainerClientCoords();M=h[0],R=h[1],I=h[2],N=h[3],T=t.touches[0].clientX-M,C=t.touches[0].clientY-R,P=t.touches[1].clientX-M,S=t.touches[1].clientY-R,L=0<=T&&T<=I&&0<=P&&P<=I&&0<=C&&C<=N&&0<=S&&S<=N;var p=n.pan(),v=n.zoom();B=H(T,C,P,S),D=K(T,C,P,S),A=[((_=[(T+P)/2,(C+S)/2])[0]-p.x)/v,(_[1]-p.y)/v];if(D<4e4&&!t.touches[2]){var g=e.findNearestElement(a[0],a[1],!0,!0),y=e.findNearestElement(a[2],a[3],!0,!0);return g&&g.isNode()?(g.activate().emit(l("cxttapstart")),e.touchData.start=g):y&&y.isNode()?(y.activate().emit(l("cxttapstart")),e.touchData.start=y):n.emit(l("cxttapstart")),e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxt=!0,e.touchData.cxtDragged=!1,e.data.bgActivePosistion=void 0,void e.redraw()}}if(t.touches[2])n.boxSelectionEnabled()&&t.preventDefault();else if(t.touches[1]);else if(t.touches[0]){var b=e.findNearestElements(a[0],a[1],!0,!0),x=b[0];if(null!=x&&(x.activate(),e.touchData.start=x,e.touchData.starts=b,e.nodeIsGrabbable(x))){var w=e.dragData.touchDragEles=n.collection(),E=null;e.redrawHint("eles",!0),e.redrawHint("drag",!0),x.selected()?(E=n.$(function(t){return t.selected()&&e.nodeIsGrabbable(t)}),u(E,{addToList:w})):c(x,{addToList:w}),s(x),x.emit(l("grabon")),E?E.forEach(function(e){e.emit(l("grab"))}):x.emit(l("grab"))}r(x,["touchstart","tapstart","vmousedown"],t,{x:a[0],y:a[1]}),null==x&&(e.data.bgActivePosistion={x:o[0],y:o[1]},e.redrawHint("select",!0),e.redraw()),e.touchData.singleTouchMoved=!1,e.touchData.singleTouchStartTime=+new Date,clearTimeout(e.touchData.tapholdTimeout),e.touchData.tapholdTimeout=setTimeout(function(){!1!==e.touchData.singleTouchMoved||e.pinching||e.touchData.selecting||r(e.touchData.start,["taphold"],t,{x:a[0],y:a[1]})},e.tapholdDuration)}if(t.touches.length>=1){for(var k=e.touchData.startPosition=[null,null,null,null,null,null],z=0;z=e.touchTapThreshold2}if(n&&e.touchData.cxt){t.preventDefault();var E=t.touches[0].clientX-M,k=t.touches[0].clientY-R,_=t.touches[1].clientX-M,I=t.touches[1].clientY-R,N=K(E,k,_,I);if(N/D>=2.25||N>=22500){e.touchData.cxt=!1,e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);var z=p("cxttapend");e.touchData.start?(e.touchData.start.unactivate().emit(z),e.touchData.start=null):o.emit(z)}}if(n&&e.touchData.cxt){z=p("cxtdrag");e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),e.touchData.start?e.touchData.start.emit(z):o.emit(z),e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxtDragged=!0;var O=e.findNearestElement(s[0],s[1],!0,!0);e.touchData.cxtOver&&O===e.touchData.cxtOver||(e.touchData.cxtOver&&e.touchData.cxtOver.emit(p("cxtdragout")),e.touchData.cxtOver=O,O&&O.emit(p("cxtdragover")))}else if(n&&t.touches[2]&&o.boxSelectionEnabled())t.preventDefault(),e.data.bgActivePosistion=void 0,this.lastThreeTouch=+new Date,e.touchData.selecting||o.emit(p("boxstart")),e.touchData.selecting=!0,e.touchData.didSelect=!0,a[4]=1,a&&0!==a.length&&void 0!==a[0]?(a[2]=(s[0]+s[2]+s[4])/3,a[3]=(s[1]+s[3]+s[5])/3):(a[0]=(s[0]+s[2]+s[4])/3,a[1]=(s[1]+s[3]+s[5])/3,a[2]=(s[0]+s[2]+s[4])/3+1,a[3]=(s[1]+s[3]+s[5])/3+1),e.redrawHint("select",!0),e.redraw();else if(n&&t.touches[1]&&!e.touchData.didSelect&&o.zoomingEnabled()&&o.panningEnabled()&&o.userZoomingEnabled()&&o.userPanningEnabled()){if(t.preventDefault(),e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),te=e.dragData.touchDragEles){e.redrawHint("drag",!0);for(var V=0;V0&&!e.hoverData.draggingEles&&!e.swipePanning&&null!=e.data.bgActivePosistion&&(e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),e.redraw())}},!1),e.registerBinding(t,"touchcancel",j=function(t){var n=e.touchData.start;e.touchData.capture=!1,n&&n.unactivate()}),e.registerBinding(t,"touchend",Y=function(t){var a=e.touchData.start;if(e.touchData.capture){0===t.touches.length&&(e.touchData.capture=!1),t.preventDefault();var i=e.selection;e.swipePanning=!1,e.hoverData.draggingEles=!1;var o=e.cy,s=o.zoom(),l=e.touchData.now,u=e.touchData.earlier;if(t.touches[0]){var c=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);l[0]=c[0],l[1]=c[1]}if(t.touches[1]){c=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY);l[2]=c[0],l[3]=c[1]}if(t.touches[2]){c=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY);l[4]=c[0],l[5]=c[1]}var h,f=function(e){return{originalEvent:t,type:e,position:{x:l[0],y:l[1]}}};if(a&&a.unactivate(),e.touchData.cxt){if(h=f("cxttapend"),a?a.emit(h):o.emit(h),!e.touchData.cxtDragged){var p=f("cxttap");a?a.emit(p):o.emit(p)}return e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxt=!1,e.touchData.start=null,void e.redraw()}if(!t.touches[2]&&o.boxSelectionEnabled()&&e.touchData.selecting){e.touchData.selecting=!1;var v=o.collection(e.getAllInBox(i[0],i[1],i[2],i[3]));i[0]=void 0,i[1]=void 0,i[2]=void 0,i[3]=void 0,i[4]=0,e.redrawHint("select",!0),o.emit(f("boxend"));v.emit(f("box")).stdFilter(function(e){return e.selectable()&&!e.selected()}).select().emit(f("boxselect")),v.nonempty()&&e.redrawHint("eles",!0),e.redraw()}if(null!=a&&a.unactivate(),t.touches[2])e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);else if(t.touches[1]);else if(t.touches[0]);else if(!t.touches[0]){e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);var g=e.dragData.touchDragEles;if(null!=a){var y=a._private.grabbed;d(g),e.redrawHint("drag",!0),e.redrawHint("eles",!0),y&&(a.emit(f("freeon")),g.emit(f("free")),e.dragData.didDrag&&(a.emit(f("dragfreeon")),g.emit(f("dragfree")))),r(a,["touchend","tapend","vmouseup","tapdragout"],t,{x:l[0],y:l[1]}),a.unactivate(),e.touchData.start=null}else{var m=e.findNearestElement(l[0],l[1],!0,!0);r(m,["touchend","tapend","vmouseup","tapdragout"],t,{x:l[0],y:l[1]})}var b=e.touchData.startPosition[0]-l[0],x=b*b,w=e.touchData.startPosition[1]-l[1],E=(x+w*w)*s*s;e.touchData.singleTouchMoved||(a||o.$(":selected").unselect(["tapunselect"]),r(a,["tap","vclick"],t,{x:l[0],y:l[1]}),q=!1,t.timeStamp-U<=o.multiClickDebounceTime()?(W&&clearTimeout(W),q=!0,U=null,r(a,["dbltap","vdblclick"],t,{x:l[0],y:l[1]})):(W=setTimeout(function(){q||r(a,["onetap","voneclick"],t,{x:l[0],y:l[1]})},o.multiClickDebounceTime()),U=t.timeStamp)),null!=a&&!e.dragData.didDrag&&a._private.selectable&&E2){for(var f=[c[0],c[1]],p=Math.pow(f[0]-e,2)+Math.pow(f[1]-t,2),v=1;v0)return v[0]}return null},f=Object.keys(d),p=0;p0?u:pn(a,i,e,t,n,r,o,s)},checkPoint:function(e,t,n,r,a,i,o,s){var l=2*(s="auto"===s?Rn(r,a):s);if(xn(e,t,this.points,i,o,r,a-l,[0,-1],n))return!0;if(xn(e,t,this.points,i,o,r-l,a,[0,-1],n))return!0;var u=r/2+2*n,c=a/2+2*n;return!!bn(e,t,[i-u,o-c,i-u,o,i+u,o,i+u,o-c])||(!!kn(e,t,l,l,i+r/2-s,o+a/2-s,n)||!!kn(e,t,l,l,i-r/2+s,o+a/2-s,n))}}},ad.registerNodeShapes=function(){var e=this.nodeShapes={},t=this;this.generateEllipse(),this.generatePolygon("triangle",_n(3,0)),this.generateRoundPolygon("round-triangle",_n(3,0)),this.generatePolygon("rectangle",_n(4,0)),e.square=e.rectangle,this.generateRoundRectangle(),this.generateCutRectangle(),this.generateBarrel(),this.generateBottomRoundrectangle();var n=[0,1,1,0,0,-1,-1,0];this.generatePolygon("diamond",n),this.generateRoundPolygon("round-diamond",n),this.generatePolygon("pentagon",_n(5,0)),this.generateRoundPolygon("round-pentagon",_n(5,0)),this.generatePolygon("hexagon",_n(6,0)),this.generateRoundPolygon("round-hexagon",_n(6,0)),this.generatePolygon("heptagon",_n(7,0)),this.generateRoundPolygon("round-heptagon",_n(7,0)),this.generatePolygon("octagon",_n(8,0)),this.generateRoundPolygon("round-octagon",_n(8,0));var r=new Array(20),a=Mn(5,0),i=Mn(5,Math.PI/5),o=.5*(3-Math.sqrt(5));o*=1.57;for(var s=0;s=e.deqFastCost*v)break}else if(a){if(f>=e.deqCost*l||f>=e.deqAvgCost*s)break}else if(p>=e.deqNoDrawCost*ud)break;var g=e.deq(t,d,c);if(!(g.length>0))break;for(var y=0;y0&&(e.onDeqd(t,u),!a&&e.shouldRedraw(t,u,d,c)&&r())},a(t))}}},dd=function(){return i(function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:tt;a(this,e),this.idsByKey=new gt,this.keyForId=new gt,this.cachesByLvl=new gt,this.lvls=[],this.getKey=t,this.doesEleInvalidateKey=n},[{key:"getIdsFor",value:function(e){null==e&&at("Can not get id list for null key");var t=this.idsByKey,n=this.idsByKey.get(e);return n||(n=new mt,t.set(e,n)),n}},{key:"addIdForKey",value:function(e,t){null!=e&&this.getIdsFor(e).add(t)}},{key:"deleteIdForKey",value:function(e,t){null!=e&&this.getIdsFor(e).delete(t)}},{key:"getNumberOfIdsForKey",value:function(e){return null==e?0:this.getIdsFor(e).size}},{key:"updateKeyMappingFor",value:function(e){var t=e.id(),n=this.keyForId.get(t),r=this.getKey(e);this.deleteIdForKey(n,t),this.addIdForKey(r,t),this.keyForId.set(t,r)}},{key:"deleteKeyMappingFor",value:function(e){var t=e.id(),n=this.keyForId.get(t);this.deleteIdForKey(n,t),this.keyForId.delete(t)}},{key:"keyHasChangedFor",value:function(e){var t=e.id();return this.keyForId.get(t)!==this.getKey(e)}},{key:"isInvalid",value:function(e){return this.keyHasChangedFor(e)||this.doesEleInvalidateKey(e)}},{key:"getCachesAt",value:function(e){var t=this.cachesByLvl,n=this.lvls,r=t.get(e);return r||(r=new gt,t.set(e,r),n.push(e)),r}},{key:"getCache",value:function(e,t){return this.getCachesAt(t).get(e)}},{key:"get",value:function(e,t){var n=this.getKey(e),r=this.getCache(n,t);return null!=r&&this.updateKeyMappingFor(e),r}},{key:"getForCachedKey",value:function(e,t){var n=this.keyForId.get(e.id());return this.getCache(n,t)}},{key:"hasCache",value:function(e,t){return this.getCachesAt(t).has(e)}},{key:"has",value:function(e,t){var n=this.getKey(e);return this.hasCache(n,t)}},{key:"setCache",value:function(e,t,n){n.key=e,this.getCachesAt(t).set(e,n)}},{key:"set",value:function(e,t,n){var r=this.getKey(e);this.setCache(r,t,n),this.updateKeyMappingFor(e)}},{key:"deleteCache",value:function(e,t){this.getCachesAt(t).delete(e)}},{key:"delete",value:function(e,t){var n=this.getKey(e);this.deleteCache(n,t)}},{key:"invalidateKey",value:function(e){var t=this;this.lvls.forEach(function(n){return t.deleteCache(e,n)})}},{key:"invalidate",value:function(e){var t=e.id(),n=this.keyForId.get(t);this.deleteKeyMappingFor(e);var r=this.doesEleInvalidateKey(e);return r&&this.invalidateKey(n),r||0===this.getNumberOfIdsForKey(n)}}])}(),hd=7.99,fd={dequeue:"dequeue",downscale:"downscale",highQuality:"highQuality"},pd=dt({getKey:null,doesEleInvalidateKey:tt,drawElement:null,getBoundingBox:null,getRotationPoint:null,getRotationOffset:null,isVisible:et,allowEdgeTxrCaching:!0,allowParentTxrCaching:!0}),vd=function(e,t){var n=this;n.renderer=e,n.onDequeues=[];var r=pd(t);be(n,r),n.lookup=new dd(r.getKey,r.doesEleInvalidateKey),n.setupDequeueing()},gd=vd.prototype;gd.reasons=fd,gd.getTextureQueue=function(e){var t=this;return t.eleImgCaches=t.eleImgCaches||{},t.eleImgCaches[e]=t.eleImgCaches[e]||[]},gd.getRetiredTextureQueue=function(e){var t=this.eleImgCaches.retired=this.eleImgCaches.retired||{};return t[e]=t[e]||[]},gd.getElementQueue=function(){return this.eleCacheQueue=this.eleCacheQueue||new Dt(function(e,t){return t.reqs-e.reqs})},gd.getElementKeyToQueue=function(){return this.eleKeyToCacheQueue=this.eleKeyToCacheQueue||{}},gd.getElement=function(e,t,n,r,a){var i=this,o=this.renderer,s=o.cy.zoom(),l=this.lookup;if(!t||0===t.w||0===t.h||isNaN(t.w)||isNaN(t.h)||!e.visible()||e.removed())return null;if(!i.allowEdgeTxrCaching&&e.isEdge()||!i.allowParentTxrCaching&&e.isParent())return null;if(null==r&&(r=Math.ceil(Ht(s*n))),r<-4)r=-4;else if(s>=7.99||r>3)return null;var u=Math.pow(2,r),c=t.h*u,d=t.w*u,h=o.eleTextBiggerThanMin(e,u);if(!this.isVisible(e,h))return null;var f,p=l.get(e,r);if(p&&p.invalidated&&(p.invalidated=!1,p.texture.invalidatedWidth-=p.width),p)return p;if(f=c<=25?25:c<=50?50:50*Math.ceil(c/50),c>1024||d>1024)return null;var v=i.getTextureQueue(f),g=v[v.length-2],y=function(){return i.recycleTexture(f,d)||i.addTexture(f,d)};g||(g=v[v.length-1]),g||(g=y()),g.width-g.usedWidthr;S--)C=i.getElement(e,t,n,S,fd.downscale);P()}else{var B;if(!x&&!w&&!E)for(var D=r-1;D>=-4;D--){var _=l.get(e,D);if(_){B=_;break}}if(b(B))return i.queueElement(e,r),B;g.context.translate(g.usedWidth,0),g.context.scale(u,u),this.drawElement(g.context,e,t,h,!1),g.context.scale(1/u,1/u),g.context.translate(-g.usedWidth,0)}return p={x:g.usedWidth,texture:g,level:r,scale:u,width:d,height:c,scaledLabelShown:h},g.usedWidth+=Math.ceil(d+8),g.eleCaches.push(p),l.set(e,r,p),i.checkTextureFullness(g),p},gd.invalidateElements=function(e){for(var t=0;t=.2*e.width&&this.retireTexture(e)},gd.checkTextureFullness=function(e){var t=this.getTextureQueue(e.height);e.usedWidth/e.width>.8&&e.fullnessChecks>=10?ht(t,e):e.fullnessChecks++},gd.retireTexture=function(e){var t=e.height,n=this.getTextureQueue(t),r=this.lookup;ht(n,e),e.retired=!0;for(var a=e.eleCaches,i=0;i=t)return i.retired=!1,i.usedWidth=0,i.invalidatedWidth=0,i.fullnessChecks=0,ft(i.eleCaches),i.context.setTransform(1,0,0,1,0,0),i.context.clearRect(0,0,i.width,i.height),ht(r,i),n.push(i),i}},gd.queueElement=function(e,t){var n=this.getElementQueue(),r=this.getElementKeyToQueue(),a=this.getKey(e),i=r[a];if(i)i.level=Math.max(i.level,t),i.eles.merge(e),i.reqs++,n.updateItem(i);else{var o={eles:e.spawn().merge(e),level:t,reqs:1,key:a};n.push(o),r[a]=o}},gd.dequeue=function(e){for(var t=this,n=t.getElementQueue(),r=t.getElementKeyToQueue(),a=[],i=t.lookup,o=0;o<1&&n.size()>0;o++){var s=n.pop(),l=s.key,u=s.eles[0],c=i.hasCache(u,s.level);if(r[l]=null,!c){a.push(s);var d=t.getBoundingBox(u);t.getElement(u,d,e,s.level,fd.dequeue)}}return a},gd.removeFromQueue=function(e){var t=this.getElementQueue(),n=this.getElementKeyToQueue(),r=this.getKey(e),a=n[r];null!=a&&(1===a.eles.length?(a.reqs=Je,t.updateItem(a),t.pop(),n[r]=null):a.eles.unmerge(e))},gd.onDequeue=function(e){this.onDequeues.push(e)},gd.offDequeue=function(e){ht(this.onDequeues,e)},gd.setupDequeueing=cd({deqRedrawThreshold:100,deqCost:.15,deqAvgCost:.1,deqNoDrawCost:.9,deqFastCost:.9,deq:function(e,t,n){return e.dequeue(t,n)},onDeqd:function(e,t){for(var n=0;n=3.99||n>2)return null;r.validateLayersElesOrdering(n,e);var o,s,l=r.layersByLevel,u=Math.pow(2,n),c=l[n]=l[n]||[];if(r.levelIsComplete(n,e))return c;!function(){var t=function(t){if(r.validateLayersElesOrdering(t,e),r.levelIsComplete(t,e))return s=l[t],!0},a=function(e){if(!s)for(var r=n+e;-4<=r&&r<=2&&!t(r);r+=e);};a(1),a(-1);for(var i=c.length-1;i>=0;i--){var o=c[i];o.invalid&&ht(c,o)}}();var d=function(t){var a=(t=t||{}).after;!function(){if(!o){o=tn();for(var t=0;t32767||s>32767)return null;if(i*s>16e6)return null;var l=r.makeLayer(o,n);if(null!=a){var d=c.indexOf(a)+1;c.splice(d,0,l)}else(void 0===t.insert||t.insert)&&c.unshift(l);return l};if(r.skipping&&!i)return null;for(var h=null,f=e.length/1,p=!i,v=0;v=f||!dn(h.bb,g.boundingBox()))&&!(h=d({insert:!0,after:h})))return null;s||p?r.queueLayer(h,g):r.drawEleInLayer(h,g,n,t),h.eles.push(g),m[n]=h}}return s||(p?null:c)},md.getEleLevelForLayerLevel=function(e,t){return e},md.drawEleInLayer=function(e,t,n,r){var a=this.renderer,i=e.context,o=t.boundingBox();0!==o.w&&0!==o.h&&t.visible()&&(n=this.getEleLevelForLayerLevel(n,r),a.setImgSmoothing(i,!1),a.drawCachedElement(i,t,null,null,n,true),a.setImgSmoothing(i,!0))},md.levelIsComplete=function(e,t){var n=this.layersByLevel[e];if(!n||0===n.length)return!1;for(var r=0,a=0;a0)return!1;if(i.invalid)return!1;r+=i.eles.length}return r===t.length},md.validateLayersElesOrdering=function(e,t){var n=this.layersByLevel[e];if(n)for(var r=0;r0){e=!0;break}}return e},md.invalidateElements=function(e){var t=this;0!==e.length&&(t.lastInvalidationTime=ze(),0!==e.length&&t.haveLayers()&&t.updateElementsInLayers(e,function(e,n,r){t.invalidateLayer(e)}))},md.invalidateLayer=function(e){if(this.lastInvalidationTime=ze(),!e.invalid){var t=e.level,n=e.eles,r=this.layersByLevel[t];ht(r,e),e.elesQueue=[],e.invalid=!0,e.replacement&&(e.replacement.invalid=!0);for(var a=0;a3&&void 0!==arguments[3])||arguments[3],a=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],i=!(arguments.length>5&&void 0!==arguments[5])||arguments[5],o=this,s=t._private.rscratch;if((!i||t.visible())&&!s.badLine&&null!=s.allpts&&!isNaN(s.allpts[0])){var l;n&&(l=n,e.translate(-l.x1,-l.y1));var u=i?t.pstyle("opacity").value:1,c=i?t.pstyle("line-opacity").value:1,d=t.pstyle("curve-style").value,h=t.pstyle("line-style").value,f=t.pstyle("width").pfValue,p=t.pstyle("line-cap").value,v=t.pstyle("line-outline-width").value,g=t.pstyle("line-outline-color").value,y=u*c,m=u*c,b=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:y;"straight-triangle"===d?(o.eleStrokeStyle(e,t,n),o.drawEdgeTrianglePath(t,e,s.allpts)):(e.lineWidth=f,e.lineCap=p,o.eleStrokeStyle(e,t,n),o.drawEdgePath(t,e,s.allpts,h),e.lineCap="butt")},x=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:m;o.drawArrowheads(e,t,n)};if(e.lineJoin="round","yes"===t.pstyle("ghost").value){var w=t.pstyle("ghost-offset-x").pfValue,E=t.pstyle("ghost-offset-y").pfValue,k=t.pstyle("ghost-opacity").value,T=y*k;e.translate(w,E),b(T),x(T),e.translate(-w,-E)}else!function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:y;e.lineWidth=f+v,e.lineCap=p,v>0?(o.colorStrokeStyle(e,g[0],g[1],g[2],n),"straight-triangle"===d?o.drawEdgeTrianglePath(t,e,s.allpts):(o.drawEdgePath(t,e,s.allpts,h),e.lineCap="butt")):e.lineCap="butt"}();a&&o.drawEdgeUnderlay(e,t),b(),x(),a&&o.drawEdgeOverlay(e,t),o.drawElementText(e,t,null,r),n&&e.translate(l.x1,l.y1)}}},Ld=function(e){if(!["overlay","underlay"].includes(e))throw new Error("Invalid state");return function(t,n){if(n.visible()){var r=n.pstyle("".concat(e,"-opacity")).value;if(0!==r){var a=this,i=a.usePaths(),o=n._private.rscratch,s=2*n.pstyle("".concat(e,"-padding")).pfValue,l=n.pstyle("".concat(e,"-color")).value;t.lineWidth=s,"self"!==o.edgeType||i?t.lineCap="round":t.lineCap="butt",a.colorStrokeStyle(t,l[0],l[1],l[2],r),a.drawEdgePath(n,t,o.allpts,"solid")}}}};Nd.drawEdgeOverlay=Ld("overlay"),Nd.drawEdgeUnderlay=Ld("underlay"),Nd.drawEdgePath=function(e,t,n,r){var a,i=e._private.rscratch,s=t,l=!1,u=this.usePaths(),c=e.pstyle("line-dash-pattern").pfValue,d=e.pstyle("line-dash-offset").pfValue;if(u){var h=n.join("$");i.pathCacheKey&&i.pathCacheKey===h?(a=t=i.pathCache,l=!0):(a=t=new Path2D,i.pathCacheKey=h,i.pathCache=a)}if(s.setLineDash)switch(r){case"dotted":s.setLineDash([1,1]);break;case"dashed":s.setLineDash(c),s.lineDashOffset=d;break;case"solid":s.setLineDash([])}if(!l&&!i.badLine)switch(t.beginPath&&t.beginPath(),t.moveTo(n[0],n[1]),i.edgeType){case"bezier":case"self":case"compound":case"multibezier":for(var f=2;f+35&&void 0!==arguments[5]?arguments[5]:5,o=Math.min(i,r/2,a/2);e.beginPath(),e.moveTo(t+o,n),e.lineTo(t+r-o,n),e.quadraticCurveTo(t+r,n,t+r,n+o),e.lineTo(t+r,n+a-o),e.quadraticCurveTo(t+r,n+a,t+r-o,n+a),e.lineTo(t+o,n+a),e.quadraticCurveTo(t,n+a,t,n+a-o),e.lineTo(t,n+o),e.quadraticCurveTo(t,n,t+o,n),e.closePath()}Od.eleTextBiggerThanMin=function(e,t){if(!t){var n=e.cy().zoom(),r=this.getPixelRatio(),a=Math.ceil(Ht(n*r));t=Math.pow(2,a)}return!(e.pstyle("font-size").pfValue*t5&&void 0!==arguments[5])||arguments[5],o=this;if(null==r){if(i&&!o.eleTextBiggerThanMin(t))return}else if(!1===r)return;if(t.isNode()){var s=t.pstyle("label");if(!s||!s.value)return;var l=o.getLabelJustification(t);e.textAlign=l,e.textBaseline="bottom"}else{var u=t.element()._private.rscratch.badLine,c=t.pstyle("label"),d=t.pstyle("source-label"),h=t.pstyle("target-label");if(u||(!c||!c.value)&&(!d||!d.value)&&(!h||!h.value))return;e.textAlign="center",e.textBaseline="bottom"}var f,p=!n;n&&(f=n,e.translate(-f.x1,-f.y1)),null==a?(o.drawText(e,t,null,p,i),t.isEdge()&&(o.drawText(e,t,"source",p,i),o.drawText(e,t,"target",p,i))):o.drawText(e,t,a,p,i),n&&e.translate(f.x1,f.y1)},Od.getFontCache=function(e){var t;this.fontCaches=this.fontCaches||[];for(var n=0;n2&&void 0!==arguments[2])||arguments[2],r=t.pstyle("font-style").strValue,a=t.pstyle("font-size").pfValue+"px",i=t.pstyle("font-family").strValue,o=t.pstyle("font-weight").strValue,s=n?t.effectiveOpacity()*t.pstyle("text-opacity").value:1,l=t.pstyle("text-outline-opacity").value*s,u=t.pstyle("color").value,c=t.pstyle("text-outline-color").value;e.font=r+" "+o+" "+a+" "+i,e.lineJoin="round",this.colorFillStyle(e,u[0],u[1],u[2],s),this.colorStrokeStyle(e,c[0],c[1],c[2],l)},Od.getTextAngle=function(e,t){var n,r=e._private.rscratch,a=t?t+"-":"",i=e.pstyle(a+"text-rotation");if("autorotate"===i.strValue){var o=pt(r,"labelAngle",t);n=e.isEdge()?o:0}else n="none"===i.strValue?0:i.pfValue;return n},Od.drawText=function(e,t,n){var r=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],a=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],i=t._private.rscratch,o=a?t.effectiveOpacity():1;if(!a||0!==o&&0!==t.pstyle("text-opacity").value){"main"===n&&(n=null);var s,l,u=pt(i,"labelX",n),c=pt(i,"labelY",n),d=this.getLabelText(t,n);if(null!=d&&""!==d&&!isNaN(u)&&!isNaN(c)){this.setupTextStyle(e,t,a);var h,f=n?n+"-":"",p=pt(i,"labelWidth",n),v=pt(i,"labelHeight",n),g=t.pstyle(f+"text-margin-x").pfValue,y=t.pstyle(f+"text-margin-y").pfValue,m=t.isEdge(),b=t.pstyle("text-halign").value,x=t.pstyle("text-valign").value;switch(m&&(b="center",x="center"),u+=g,c+=y,0!==(h=r?this.getTextAngle(t,n):0)&&(s=u,l=c,e.translate(s,l),e.rotate(h),u=0,c=0),x){case"top":break;case"center":c+=v/2;break;case"bottom":c+=v}var w=t.pstyle("text-background-opacity").value,E=t.pstyle("text-border-opacity").value,k=t.pstyle("text-border-width").pfValue,T=t.pstyle("text-background-padding").pfValue,C=t.pstyle("text-background-shape").strValue,P="round-rectangle"===C||"roundrectangle"===C,S="circle"===C;if(w>0||k>0&&E>0){var B=e.fillStyle,D=e.strokeStyle,_=e.lineWidth,A=t.pstyle("text-background-color").value,M=t.pstyle("text-border-color").value,R=t.pstyle("text-border-style").value,I=w>0,N=k>0&&E>0,L=u-T;switch(b){case"left":L-=p;break;case"center":L-=p/2}var z=c-v-T,O=p+2*T,V=v+2*T;if(I&&(e.fillStyle="rgba(".concat(A[0],",").concat(A[1],",").concat(A[2],",").concat(w*o,")")),N&&(e.strokeStyle="rgba(".concat(M[0],",").concat(M[1],",").concat(M[2],",").concat(E*o,")"),e.lineWidth=k,e.setLineDash))switch(R){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"double":e.lineWidth=k/4,e.setLineDash([]);break;default:e.setLineDash([])}if(P?(e.beginPath(),Vd(e,L,z,O,V,2)):S?(e.beginPath(),function(e,t,n,r,a){var i=Math.min(r,a)/2,o=t+r/2,s=n+a/2;e.beginPath(),e.arc(o,s,i,0,2*Math.PI),e.closePath()}(e,L,z,O,V)):(e.beginPath(),e.rect(L,z,O,V)),I&&e.fill(),N&&e.stroke(),N&&"double"===R){var F=k/2;e.beginPath(),P?Vd(e,L+F,z+F,O-2*F,V-2*F,2):e.rect(L+F,z+F,O-2*F,V-2*F),e.stroke()}e.fillStyle=B,e.strokeStyle=D,e.lineWidth=_,e.setLineDash&&e.setLineDash([])}var X=2*t.pstyle("text-outline-width").pfValue;if(X>0&&(e.lineWidth=X),"wrap"===t.pstyle("text-wrap").value){var j=pt(i,"labelWrapCachedLines",n),Y=pt(i,"labelLineHeight",n),q=p/2,W=this.getLabelJustification(t);switch("auto"===W||("left"===b?"left"===W?u+=-p:"center"===W&&(u+=-q):"center"===b?"left"===W?u+=-q:"right"===W&&(u+=q):"right"===b&&("center"===W?u+=q:"right"===W&&(u+=p))),x){case"top":case"center":case"bottom":c-=(j.length-1)*Y}for(var U=0;U0&&e.strokeText(j[U],u,c),e.fillText(j[U],u,c),c+=Y}else X>0&&e.strokeText(d,u,c),e.fillText(d,u,c);0!==h&&(e.rotate(-h),e.translate(-s,-l))}}};var Fd={drawNode:function(e,t,n){var r,a,i=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],o=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],s=!(arguments.length>5&&void 0!==arguments[5])||arguments[5],l=this,u=t._private,c=u.rscratch,d=t.position();if(Q(d.x)&&Q(d.y)&&(!s||t.visible())){var h,f,p=s?t.effectiveOpacity():1,v=l.usePaths(),g=!1,y=t.padding();r=t.width()+2*y,a=t.height()+2*y,n&&(f=n,e.translate(-f.x1,-f.y1));for(var m=t.pstyle("background-image").value,b=new Array(m.length),x=new Array(m.length),w=0,E=0;E0&&void 0!==arguments[0]?arguments[0]:S;l.eleFillStyle(e,t,n)},Y=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:N;l.colorStrokeStyle(e,B[0],B[1],B[2],t)},q=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:V;l.colorStrokeStyle(e,z[0],z[1],z[2],t)},W=function(e,t,n,r){var a,i=l.nodePathCache=l.nodePathCache||[],o=He("polygon"===n?n+","+r.join(","):n,""+t,""+e,""+X),s=i[o],u=!1;return null!=s?(a=s,u=!0,c.pathCache=a):(a=new Path2D,i[o]=c.pathCache=a),{path:a,cacheHit:u}},U=t.pstyle("shape").strValue,H=t.pstyle("shape-polygon-points").pfValue;if(v){e.translate(d.x,d.y);var K=W(r,a,U,H);h=K.path,g=K.cacheHit}var G=function(){if(!g){var n=d;v&&(n={x:0,y:0}),l.nodeShapes[l.getNodeShape(t)].draw(h||e,n.x,n.y,r,a,X,c)}v?e.fill(h):e.fill()},Z=function(){for(var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:p,r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],a=u.backgrounding,i=0,o=0;o0&&void 0!==arguments[0]&&arguments[0],i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:p;l.hasPie(t)&&(l.drawPie(e,t,i),n&&(v||l.nodeShapes[l.getNodeShape(t)].draw(e,d.x,d.y,r,a,X,c)))},J=function(){var n=arguments.length>0&&void 0!==arguments[0]&&arguments[0],i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:p;l.hasStripe(t)&&(e.save(),v?e.clip(c.pathCache):(l.nodeShapes[l.getNodeShape(t)].draw(e,d.x,d.y,r,a,X,c),e.clip()),l.drawStripe(e,t,i),e.restore(),n&&(v||l.nodeShapes[l.getNodeShape(t)].draw(e,d.x,d.y,r,a,X,c)))},ee=function(){var t=(C>0?C:-C)*(arguments.length>0&&void 0!==arguments[0]?arguments[0]:p),n=C>0?0:255;0!==C&&(l.colorFillStyle(e,n,n,n,t),v?e.fill(h):e.fill())},te=function(){if(P>0){if(e.lineWidth=P,e.lineCap=A,e.lineJoin=_,e.setLineDash)switch(D){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash(R),e.lineDashOffset=I;break;case"solid":case"double":e.setLineDash([])}if("center"!==M){if(e.save(),e.lineWidth*=2,"inside"===M)v?e.clip(h):e.clip();else{var t=new Path2D;t.rect(-r/2-P,-a/2-P,r+2*P,a+2*P),t.addPath(h),e.clip(t,"evenodd")}v?e.stroke(h):e.stroke(),e.restore()}else v?e.stroke(h):e.stroke();if("double"===D){e.lineWidth=P/3;var n=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",v?e.stroke(h):e.stroke(),e.globalCompositeOperation=n}e.setLineDash&&e.setLineDash([])}},ne=function(){if(L>0){if(e.lineWidth=L,e.lineCap="butt",e.setLineDash)switch(O){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"solid":case"double":e.setLineDash([])}var n=d;v&&(n={x:0,y:0});var i=l.getNodeShape(t),o=P;"inside"===M&&(o=0),"outside"===M&&(o*=2);var s,u=(r+o+(L+F))/r,c=(a+o+(L+F))/a,h=r*u,f=a*c,p=l.nodeShapes[i].points;if(v)s=W(h,f,i,p).path;if("ellipse"===i)l.drawEllipsePath(s||e,n.x,n.y,h,f);else if(["round-diamond","round-heptagon","round-hexagon","round-octagon","round-pentagon","round-polygon","round-triangle","round-tag"].includes(i)){var g=0,y=0,m=0;"round-diamond"===i?g=1.4*(o+F+L):"round-heptagon"===i?(g=1.075*(o+F+L),m=-(o/2+F+L)/35):"round-hexagon"===i?g=1.12*(o+F+L):"round-pentagon"===i?(g=1.13*(o+F+L),m=-(o/2+F+L)/15):"round-tag"===i?(g=1.12*(o+F+L),y=.07*(o/2+L+F)):"round-triangle"===i&&(g=(o+F+L)*(Math.PI/2),m=-(o+F/2+L)/Math.PI),0!==g&&(h=r*(u=(r+g)/r),["round-hexagon","round-tag"].includes(i)||(f=a*(c=(a+g)/a)));for(var b=h/2,x=f/2,w=(X="auto"===X?In(h,f):X)+(o+L+F)/2,E=new Array(p.length/2),k=new Array(p.length/2),T=0;T0){if(r=r||n.position(),null==a||null==i){var d=n.padding();a=n.width()+2*d,i=n.height()+2*d}this.colorFillStyle(t,l[0],l[1],l[2],s),this.nodeShapes[u].draw(t,r.x,r.y,a+2*o,i+2*o,c),t.fill()}}}};Fd.drawNodeOverlay=Xd("overlay"),Fd.drawNodeUnderlay=Xd("underlay"),Fd.hasPie=function(e){return(e=e[0])._private.hasPie},Fd.hasStripe=function(e){return(e=e[0])._private.hasStripe},Fd.drawPie=function(e,t,n,r){t=t[0],r=r||t.position();var a,i=t.cy().style(),o=t.pstyle("pie-size"),s=t.pstyle("pie-hole"),l=t.pstyle("pie-start-angle").pfValue,u=r.x,c=r.y,d=t.width(),h=t.height(),f=Math.min(d,h)/2,p=0;if(this.usePaths()&&(u=0,c=0),"%"===o.units?f*=o.pfValue:void 0!==o.pfValue&&(f=o.pfValue/2),"%"===s.units?a=f*s.pfValue:void 0!==s.pfValue&&(a=s.pfValue/2),!(a>=f))for(var v=1;v<=i.pieBackgroundN;v++){var g=t.pstyle("pie-"+v+"-background-size").value,y=t.pstyle("pie-"+v+"-background-color").value,m=t.pstyle("pie-"+v+"-background-opacity").value*n,b=g/100;b+p>1&&(b=1-p);var x=1.5*Math.PI+2*Math.PI*p,w=(x+=l)+2*Math.PI*b;0===g||p>=1||p+b>1||(0===a?(e.beginPath(),e.moveTo(u,c),e.arc(u,c,f,x,w),e.closePath()):(e.beginPath(),e.arc(u,c,f,x,w),e.arc(u,c,a,w,x,!0),e.closePath()),this.colorFillStyle(e,y[0],y[1],y[2],m),e.fill(),p+=b)}},Fd.drawStripe=function(e,t,n,r){t=t[0],r=r||t.position();var a=t.cy().style(),i=r.x,o=r.y,s=t.width(),l=t.height(),u=0,c=this.usePaths();e.save();var d=t.pstyle("stripe-direction").value,h=t.pstyle("stripe-size");switch(d){case"vertical":break;case"righward":e.rotate(-Math.PI/2)}var f=s,p=l;"%"===h.units?(f*=h.pfValue,p*=h.pfValue):void 0!==h.pfValue&&(f=h.pfValue,p=h.pfValue),c&&(i=0,o=0),o-=f/2,i-=p/2;for(var v=1;v<=a.stripeBackgroundN;v++){var g=t.pstyle("stripe-"+v+"-background-size").value,y=t.pstyle("stripe-"+v+"-background-color").value,m=t.pstyle("stripe-"+v+"-background-opacity").value*n,b=g/100;b+u>1&&(b=1-u),0===g||u>=1||u+b>1||(e.beginPath(),e.rect(i,o+p*u,f,p*b),e.closePath(),this.colorFillStyle(e,y[0],y[1],y[2],m),e.fill(),u+=b)}e.restore()};var jd,Yd={};function qd(e,t,n){var r=e.createShader(t);if(e.shaderSource(r,n),e.compileShader(r),!e.getShaderParameter(r,e.COMPILE_STATUS))throw new Error(e.getShaderInfoLog(r));return r}function Wd(e,t,n){void 0===n&&(n=t);var r=e.makeOffscreenCanvas(t,n),a=r.context=r.getContext("2d");return r.clear=function(){return a.clearRect(0,0,r.width,r.height)},r.clear(),r}function Ud(e){var t=e.pixelRatio,n=e.cy.zoom(),r=e.cy.pan();return{zoom:n*t,pan:{x:r.x*t,y:r.y*t}}}function Hd(e){return"solid"===e.pstyle("background-fill").value&&("none"===e.pstyle("background-image").strValue&&(0===e.pstyle("border-width").value||(0===e.pstyle("border-opacity").value||"solid"===e.pstyle("border-style").value)))}function Kd(e,t){if(e.length!==t.length)return!1;for(var n=0;n>8&255)/255,n[2]=(e>>16&255)/255,n[3]=(e>>24&255)/255,n}function $d(e){return e[0]+(e[1]<<8)+(e[2]<<16)+(e[3]<<24)}function Qd(e,t){switch(t){case"float":return[1,e.FLOAT,4];case"vec2":return[2,e.FLOAT,4];case"vec3":return[3,e.FLOAT,4];case"vec4":return[4,e.FLOAT,4];case"int":return[1,e.INT,4];case"ivec2":return[2,e.INT,4]}}function Jd(e,t,n){switch(t){case e.FLOAT:return new Float32Array(n);case e.INT:return new Int32Array(n)}}function eh(e,t,n,r,a,i){switch(t){case e.FLOAT:return new Float32Array(n.buffer,i*r,a);case e.INT:return new Int32Array(n.buffer,i*r,a)}}function th(e,t,n,r){var a=l(Qd(e,n),3),i=a[0],o=a[1],s=a[2],u=Jd(e,o,t*i),c=i*s,d=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,d),e.bufferData(e.ARRAY_BUFFER,t*c,e.DYNAMIC_DRAW),e.enableVertexAttribArray(r),o===e.FLOAT?e.vertexAttribPointer(r,i,o,!1,c,0):o===e.INT&&e.vertexAttribIPointer(r,i,o,c,0),e.vertexAttribDivisor(r,1),e.bindBuffer(e.ARRAY_BUFFER,null);for(var h=new Array(t),f=0;ft.minMbLowQualFrames&&(t.motionBlurPxRatio=t.mbPxRBlurry)),t.clearingMotionBlur&&(t.motionBlurPxRatio=1),t.textureDrawLastFrame&&!d&&(c[t.NODE]=!0,c[t.SELECT_BOX]=!0);var m=n.style(),b=n.zoom(),x=void 0!==o?o:b,w=n.pan(),E={x:w.x,y:w.y},k={zoom:b,pan:{x:w.x,y:w.y}},T=t.prevViewport;void 0===T||k.zoom!==T.zoom||k.pan.x!==T.pan.x||k.pan.y!==T.pan.y||v&&!p||(t.motionBlurPxRatio=1),s&&(E=s),x*=l,E.x*=l,E.y*=l;var C=t.getCachedZSortedEles();function P(e,n,r,a,i){var o=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",t.colorFillStyle(e,255,255,255,t.motionBlurTransparency),e.fillRect(n,r,a,i),e.globalCompositeOperation=o}function S(e,n){var i,l,c,d;t.clearingMotionBlur||e!==u.bufferContexts[t.MOTIONBLUR_BUFFER_NODE]&&e!==u.bufferContexts[t.MOTIONBLUR_BUFFER_DRAG]?(i=E,l=x,c=t.canvasWidth,d=t.canvasHeight):(i={x:w.x*f,y:w.y*f},l=b*f,c=t.canvasWidth*f,d=t.canvasHeight*f),e.setTransform(1,0,0,1,0,0),"motionBlur"===n?P(e,0,0,c,d):r||void 0!==n&&!n||e.clearRect(0,0,c,d),a||(e.translate(i.x,i.y),e.scale(l,l)),s&&e.translate(s.x,s.y),o&&e.scale(o,o)}if(d||(t.textureDrawLastFrame=!1),d){if(t.textureDrawLastFrame=!0,!t.textureCache){t.textureCache={},t.textureCache.bb=n.mutableElements().boundingBox(),t.textureCache.texture=t.data.bufferCanvases[t.TEXTURE_BUFFER];var B=t.data.bufferContexts[t.TEXTURE_BUFFER];B.setTransform(1,0,0,1,0,0),B.clearRect(0,0,t.canvasWidth*t.textureMult,t.canvasHeight*t.textureMult),t.render({forcedContext:B,drawOnlyNodeLayer:!0,forcedPxRatio:l*t.textureMult}),(k=t.textureCache.viewport={zoom:n.zoom(),pan:n.pan(),width:t.canvasWidth,height:t.canvasHeight}).mpan={x:(0-k.pan.x)/k.zoom,y:(0-k.pan.y)/k.zoom}}c[t.DRAG]=!1,c[t.NODE]=!1;var D=u.contexts[t.NODE],_=t.textureCache.texture;k=t.textureCache.viewport;D.setTransform(1,0,0,1,0,0),h?P(D,0,0,k.width,k.height):D.clearRect(0,0,k.width,k.height);var A=m.core("outside-texture-bg-color").value,M=m.core("outside-texture-bg-opacity").value;t.colorFillStyle(D,A[0],A[1],A[2],M),D.fillRect(0,0,k.width,k.height);b=n.zoom();S(D,!1),D.clearRect(k.mpan.x,k.mpan.y,k.width/k.zoom/l,k.height/k.zoom/l),D.drawImage(_,k.mpan.x,k.mpan.y,k.width/k.zoom/l,k.height/k.zoom/l)}else t.textureOnViewport&&!r&&(t.textureCache=null);var R=n.extent(),I=t.pinching||t.hoverData.dragging||t.swipePanning||t.data.wheelZooming||t.hoverData.draggingEles||t.cy.animated(),N=t.hideEdgesOnViewport&&I,L=[];if(L[t.NODE]=!c[t.NODE]&&h&&!t.clearedForMotionBlur[t.NODE]||t.clearingMotionBlur,L[t.NODE]&&(t.clearedForMotionBlur[t.NODE]=!0),L[t.DRAG]=!c[t.DRAG]&&h&&!t.clearedForMotionBlur[t.DRAG]||t.clearingMotionBlur,L[t.DRAG]&&(t.clearedForMotionBlur[t.DRAG]=!0),c[t.NODE]||a||i||L[t.NODE]){var z=h&&!L[t.NODE]&&1!==f;S(D=r||(z?t.data.bufferContexts[t.MOTIONBLUR_BUFFER_NODE]:u.contexts[t.NODE]),h&&!z?"motionBlur":void 0),N?t.drawCachedNodes(D,C.nondrag,l,R):t.drawLayeredElements(D,C.nondrag,l,R),t.debug&&t.drawDebugPoints(D,C.nondrag),a||h||(c[t.NODE]=!1)}if(!i&&(c[t.DRAG]||a||L[t.DRAG])){z=h&&!L[t.DRAG]&&1!==f;S(D=r||(z?t.data.bufferContexts[t.MOTIONBLUR_BUFFER_DRAG]:u.contexts[t.DRAG]),h&&!z?"motionBlur":void 0),N?t.drawCachedNodes(D,C.drag,l,R):t.drawCachedElements(D,C.drag,l,R),t.debug&&t.drawDebugPoints(D,C.drag),a||h||(c[t.DRAG]=!1)}if(this.drawSelectionRectangle(e,S),h&&1!==f){var O=u.contexts[t.NODE],V=t.data.bufferCanvases[t.MOTIONBLUR_BUFFER_NODE],F=u.contexts[t.DRAG],X=t.data.bufferCanvases[t.MOTIONBLUR_BUFFER_DRAG],j=function(e,n,r){e.setTransform(1,0,0,1,0,0),r||!y?e.clearRect(0,0,t.canvasWidth,t.canvasHeight):P(e,0,0,t.canvasWidth,t.canvasHeight);var a=f;e.drawImage(n,0,0,t.canvasWidth*a,t.canvasHeight*a,0,0,t.canvasWidth,t.canvasHeight)};(c[t.NODE]||L[t.NODE])&&(j(O,V,L[t.NODE]),c[t.NODE]=!1),(c[t.DRAG]||L[t.DRAG])&&(j(F,X,L[t.DRAG]),c[t.DRAG]=!1)}t.prevViewport=k,t.clearingMotionBlur&&(t.clearingMotionBlur=!1,t.motionBlurCleared=!0,t.motionBlur=!0),h&&(t.motionBlurTimeout=setTimeout(function(){t.motionBlurTimeout=null,t.clearedForMotionBlur[t.NODE]=!1,t.clearedForMotionBlur[t.DRAG]=!1,t.motionBlur=!1,t.clearingMotionBlur=!d,t.mbFrames=0,c[t.NODE]=!0,c[t.DRAG]=!0,t.redraw()},100)),r||n.emit("render")},Yd.drawSelectionRectangle=function(e,t){var n=this,r=n.cy,a=n.data,i=r.style(),o=e.drawOnlyNodeLayer,s=e.drawAllLayers,l=a.canvasNeedsRedraw,u=e.forcedContext;if(n.showFps||!o&&l[n.SELECT_BOX]&&!s){var c=u||a.contexts[n.SELECT_BOX];if(t(c),1==n.selection[4]&&(n.hoverData.selecting||n.touchData.selecting)){var d=n.cy.zoom(),h=i.core("selection-box-border-width").value/d;c.lineWidth=h,c.fillStyle="rgba("+i.core("selection-box-color").value[0]+","+i.core("selection-box-color").value[1]+","+i.core("selection-box-color").value[2]+","+i.core("selection-box-opacity").value+")",c.fillRect(n.selection[0],n.selection[1],n.selection[2]-n.selection[0],n.selection[3]-n.selection[1]),h>0&&(c.strokeStyle="rgba("+i.core("selection-box-border-color").value[0]+","+i.core("selection-box-border-color").value[1]+","+i.core("selection-box-border-color").value[2]+","+i.core("selection-box-opacity").value+")",c.strokeRect(n.selection[0],n.selection[1],n.selection[2]-n.selection[0],n.selection[3]-n.selection[1]))}if(a.bgActivePosistion&&!n.hoverData.selecting){d=n.cy.zoom();var f=a.bgActivePosistion;c.fillStyle="rgba("+i.core("active-bg-color").value[0]+","+i.core("active-bg-color").value[1]+","+i.core("active-bg-color").value[2]+","+i.core("active-bg-opacity").value+")",c.beginPath(),c.arc(f.x,f.y,i.core("active-bg-size").pfValue/d,0,2*Math.PI),c.fill()}var p=n.lastRedrawTime;if(n.showFps&&p){p=Math.round(p);var v=Math.round(1e3/p),g="1 frame = "+p+" ms = "+v+" fps";if(c.setTransform(1,0,0,1,0,0),c.fillStyle="rgba(255, 0, 0, 0.75)",c.strokeStyle="rgba(255, 0, 0, 0.75)",c.font="30px Arial",!jd){var y=c.measureText(g);jd=y.actualBoundingBoxAscent}c.fillText(g,0,jd);c.strokeRect(0,jd+10,250,20),c.fillRect(0,jd+10,250*Math.min(v/60,1),20)}s||(l[n.SELECT_BOX]=!1)}};var nh="undefined"!=typeof Float32Array?Float32Array:Array;function rh(){var e=new nh(9);return nh!=Float32Array&&(e[1]=0,e[2]=0,e[3]=0,e[5]=0,e[6]=0,e[7]=0),e[0]=1,e[4]=1,e[8]=1,e}function ah(e){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=1,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e}function ih(e,t,n){var r=t[0],a=t[1],i=t[2],o=t[3],s=t[4],l=t[5],u=t[6],c=t[7],d=t[8],h=n[0],f=n[1];return e[0]=r,e[1]=a,e[2]=i,e[3]=o,e[4]=s,e[5]=l,e[6]=h*r+f*o+u,e[7]=h*a+f*s+c,e[8]=h*i+f*l+d,e}function oh(e,t,n){var r=t[0],a=t[1],i=t[2],o=t[3],s=t[4],l=t[5],u=t[6],c=t[7],d=t[8],h=Math.sin(n),f=Math.cos(n);return e[0]=f*r+h*o,e[1]=f*a+h*s,e[2]=f*i+h*l,e[3]=f*o-h*r,e[4]=f*s-h*a,e[5]=f*l-h*i,e[6]=u,e[7]=c,e[8]=d,e}function sh(e,t,n){var r=n[0],a=n[1];return e[0]=r*t[0],e[1]=r*t[1],e[2]=r*t[2],e[3]=a*t[3],e[4]=a*t[4],e[5]=a*t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e}Math.hypot||(Math.hypot=function(){for(var e=0,t=arguments.length;t--;)e+=arguments[t]*arguments[t];return Math.sqrt(e)});var lh=function(){return i(function e(t,n,r,i){a(this,e),this.debugID=Math.floor(1e4*Math.random()),this.r=t,this.texSize=n,this.texRows=r,this.texHeight=Math.floor(n/r),this.enableWrapping=!0,this.locked=!1,this.texture=null,this.needsBuffer=!0,this.freePointer={x:0,row:0},this.keyToLocation=new Map,this.canvas=i(t,n,n),this.scratch=i(t,n,this.texHeight,"scratch")},[{key:"lock",value:function(){this.locked=!0}},{key:"getKeys",value:function(){return new Set(this.keyToLocation.keys())}},{key:"getScale",value:function(e){var t=e.w,n=e.h,r=this.texHeight,a=this.texSize,i=r/n,o=t*i,s=n*i;return o>a&&(o=t*(i=a/t),s=n*i),{scale:i,texW:o,texH:s}}},{key:"draw",value:function(e,t,n){var r=this;if(this.locked)throw new Error("can't draw, atlas is locked");var a=this.texSize,i=this.texRows,o=this.texHeight,s=this.getScale(t),l=s.scale,u=s.texW,c=s.texH,d=function(e,r){if(n&&r){var a=r.context,i=e.x,s=e.row,u=i,c=o*s;a.save(),a.translate(u,c),a.scale(l,l),n(a,t),a.restore()}},h=[null,null],f=function(){d(r.freePointer,r.canvas),h[0]={x:r.freePointer.x,y:r.freePointer.row*o,w:u,h:c},h[1]={x:r.freePointer.x+u,y:r.freePointer.row*o,w:0,h:c},r.freePointer.x+=u,r.freePointer.x==a&&(r.freePointer.x=0,r.freePointer.row++)},p=function(){r.freePointer.x=0,r.freePointer.row++};if(this.freePointer.x+u<=a)f();else{if(this.freePointer.row>=i-1)return!1;this.freePointer.x===a?(p(),f()):this.enableWrapping?function(){var e=r.scratch,t=r.canvas;e.clear(),d({x:0,row:0},e);var n=a-r.freePointer.x,i=u-n,s=o,l=r.freePointer.x,f=r.freePointer.row*o,p=n;t.context.drawImage(e,0,0,p,s,l,f,p,s),h[0]={x:l,y:f,w:p,h:c};var v=n,g=(r.freePointer.row+1)*o,y=i;t&&t.context.drawImage(e,v,0,y,s,0,g,y,s),h[1]={x:0,y:g,w:y,h:c},r.freePointer.x=i,r.freePointer.row++}():(p(),f())}return this.keyToLocation.set(e,h),this.needsBuffer=!0,h}},{key:"getOffsets",value:function(e){return this.keyToLocation.get(e)}},{key:"isEmpty",value:function(){return 0===this.freePointer.x&&0===this.freePointer.row}},{key:"canFit",value:function(e){if(this.locked)return!1;var t=this.texSize,n=this.texRows,r=this.getScale(e).texW;return!(this.freePointer.x+r>t)||this.freePointer.row1&&void 0!==arguments[1]?arguments[1]:{},a=r.forceRedraw,i=void 0!==a&&a,s=r.filterEle,l=void 0===s?function(){return!0}:s,u=r.filterType,c=void 0===u?function(){return!0}:u,d=!1,h=!1,f=o(e);try{for(f.s();!(t=f.n()).done;){var p=t.value;if(l(p)){var v,g=o(this.renderTypes.values());try{var y=function(){var e=v.value,t=e.type;if(c(t)){var r=n.collections.get(e.collection),a=e.getKey(p),o=Array.isArray(a)?a:[a];if(i)o.forEach(function(e){return r.markKeyForGC(e)}),h=!0;else{var s=e.getID?e.getID(p):p.id(),l=n._key(t,s),u=n.typeAndIdToKey.get(l);void 0===u||Kd(o,u)||(d=!0,n.typeAndIdToKey.delete(l),u.forEach(function(e){return r.markKeyForGC(e)}))}}};for(g.s();!(v=g.n()).done;)y()}catch(m){g.e(m)}finally{g.f()}}}}catch(m){f.e(m)}finally{f.f()}return h&&(this.gc(),d=!1),d}},{key:"gc",value:function(){var e,t=o(this.collections.values());try{for(t.s();!(e=t.n()).done;){e.value.gc()}}catch(n){t.e(n)}finally{t.f()}}},{key:"getOrCreateAtlas",value:function(e,t,n,r){var a=this.renderTypes.get(t),i=this.collections.get(a.collection),o=!1,s=i.draw(r,n,function(t){a.drawClipped?(t.save(),t.beginPath(),t.rect(0,0,n.w,n.h),t.clip(),a.drawElement(t,e,n,!0,!0),t.restore()):a.drawElement(t,e,n,!0,!0),o=!0});if(o){var l=a.getID?a.getID(e):e.id(),u=this._key(t,l);this.typeAndIdToKey.has(u)?this.typeAndIdToKey.get(u).push(r):this.typeAndIdToKey.set(u,[r])}return s}},{key:"getAtlasInfo",value:function(e,t){var n=this,r=this.renderTypes.get(t),a=r.getKey(e);return(Array.isArray(a)?a:[a]).map(function(a){var i=r.getBoundingBox(e,a),o=n.getOrCreateAtlas(e,t,i,a),s=l(o.getOffsets(a),2),u=s[0];return{atlas:o,tex:u,tex1:u,tex2:s[1],bb:i}})}},{key:"getDebugInfo",value:function(){var e,t=[],n=o(this.collections);try{for(n.s();!(e=n.n()).done;){var r=l(e.value,2),a=r[0],i=r[1].getCounts(),s=i.keyCount,u=i.atlasCount;t.push({type:a,keyCount:s,atlasCount:u})}}catch(c){n.e(c)}finally{n.f()}return t}}])}(),dh=function(){return i(function e(t){a(this,e),this.globalOptions=t,this.atlasSize=t.webglTexSize,this.maxAtlasesPerBatch=t.webglTexPerBatch,this.batchAtlases=[]},[{key:"getMaxAtlasesPerBatch",value:function(){return this.maxAtlasesPerBatch}},{key:"getAtlasSize",value:function(){return this.atlasSize}},{key:"getIndexArray",value:function(){return Array.from({length:this.maxAtlasesPerBatch},function(e,t){return t})}},{key:"startBatch",value:function(){this.batchAtlases=[]}},{key:"getAtlasCount",value:function(){return this.batchAtlases.length}},{key:"getAtlases",value:function(){return this.batchAtlases}},{key:"canAddToCurrentBatch",value:function(e){return this.batchAtlases.length!==this.maxAtlasesPerBatch||this.batchAtlases.includes(e)}},{key:"getAtlasIndexForBatch",value:function(e){var t=this.batchAtlases.indexOf(e);if(t<0){if(this.batchAtlases.length===this.maxAtlasesPerBatch)throw new Error("cannot add more atlases to batch");this.batchAtlases.push(e),t=this.batchAtlases.length-1}return t}}])}(),hh={SCREEN:{name:"screen",screen:!0},PICKING:{name:"picking",picking:!0}},fh=1,ph=2,vh=function(){return i(function e(t,n,r){a(this,e),this.r=t,this.gl=n,this.maxInstances=r.webglBatchSize,this.atlasSize=r.webglTexSize,this.bgColor=r.bgColor,this.debug=r.webglDebug,this.batchDebugInfo=[],r.enableWrapping=!0,r.createTextureCanvas=Wd,this.atlasManager=new ch(t,r),this.batchManager=new dh(r),this.simpleShapeOptions=new Map,this.program=this._createShaderProgram(hh.SCREEN),this.pickingProgram=this._createShaderProgram(hh.PICKING),this.vao=this._createVAO()},[{key:"addAtlasCollection",value:function(e,t){this.atlasManager.addAtlasCollection(e,t)}},{key:"addTextureAtlasRenderType",value:function(e,t){this.atlasManager.addRenderType(e,t)}},{key:"addSimpleShapeRenderType",value:function(e,t){this.simpleShapeOptions.set(e,t)}},{key:"invalidate",value:function(e){var t=(arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}).type,n=this.atlasManager;return t?n.invalidate(e,{filterType:function(e){return e===t},forceRedraw:!0}):n.invalidate(e)}},{key:"gc",value:function(){this.atlasManager.gc()}},{key:"_createShaderProgram",value:function(e){var t=this.gl,n="#version 300 es\n precision highp float;\n\n uniform mat3 uPanZoomMatrix;\n uniform int uAtlasSize;\n \n // instanced\n in vec2 aPosition; // a vertex from the unit square\n \n in mat3 aTransform; // used to transform verticies, eg into a bounding box\n in int aVertType; // the type of thing we are rendering\n\n // the z-index that is output when using picking mode\n in vec4 aIndex;\n \n // For textures\n in int aAtlasId; // which shader unit/atlas to use\n in vec4 aTex; // x/y/w/h of texture in atlas\n\n // for edges\n in vec4 aPointAPointB;\n in vec4 aPointCPointD;\n in vec2 aLineWidth; // also used for node border width\n\n // simple shapes\n in vec4 aCornerRadius; // for round-rectangle [top-right, bottom-right, top-left, bottom-left]\n in vec4 aColor; // also used for edges\n in vec4 aBorderColor; // aLineWidth is used for border width\n\n // output values passed to the fragment shader\n out vec2 vTexCoord;\n out vec4 vColor;\n out vec2 vPosition;\n // flat values are not interpolated\n flat out int vAtlasId; \n flat out int vVertType;\n flat out vec2 vTopRight;\n flat out vec2 vBotLeft;\n flat out vec4 vCornerRadius;\n flat out vec4 vBorderColor;\n flat out vec2 vBorderWidth;\n flat out vec4 vIndex;\n \n void main(void) {\n int vid = gl_VertexID;\n vec2 position = aPosition; // TODO make this a vec3, simplifies some code below\n\n if(aVertType == ".concat(0,") {\n float texX = aTex.x; // texture coordinates\n float texY = aTex.y;\n float texW = aTex.z;\n float texH = aTex.w;\n\n if(vid == 1 || vid == 2 || vid == 4) {\n texX += texW;\n }\n if(vid == 2 || vid == 4 || vid == 5) {\n texY += texH;\n }\n\n float d = float(uAtlasSize);\n vTexCoord = vec2(texX / d, texY / d); // tex coords must be between 0 and 1\n\n gl_Position = vec4(uPanZoomMatrix * aTransform * vec3(position, 1.0), 1.0);\n }\n else if(aVertType == ").concat(4," || aVertType == ").concat(7," \n || aVertType == ").concat(5," || aVertType == ").concat(6,") { // simple shapes\n\n // the bounding box is needed by the fragment shader\n vBotLeft = (aTransform * vec3(0, 0, 1)).xy; // flat\n vTopRight = (aTransform * vec3(1, 1, 1)).xy; // flat\n vPosition = (aTransform * vec3(position, 1)).xy; // will be interpolated\n\n // calculations are done in the fragment shader, just pass these along\n vColor = aColor;\n vCornerRadius = aCornerRadius;\n vBorderColor = aBorderColor;\n vBorderWidth = aLineWidth;\n\n gl_Position = vec4(uPanZoomMatrix * aTransform * vec3(position, 1.0), 1.0);\n }\n else if(aVertType == ").concat(1,") {\n vec2 source = aPointAPointB.xy;\n vec2 target = aPointAPointB.zw;\n\n // adjust the geometry so that the line is centered on the edge\n position.y = position.y - 0.5;\n\n // stretch the unit square into a long skinny rectangle\n vec2 xBasis = target - source;\n vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x));\n vec2 point = source + xBasis * position.x + yBasis * aLineWidth[0] * position.y;\n\n gl_Position = vec4(uPanZoomMatrix * vec3(point, 1.0), 1.0);\n vColor = aColor;\n } \n else if(aVertType == ").concat(2,") {\n vec2 pointA = aPointAPointB.xy;\n vec2 pointB = aPointAPointB.zw;\n vec2 pointC = aPointCPointD.xy;\n vec2 pointD = aPointCPointD.zw;\n\n // adjust the geometry so that the line is centered on the edge\n position.y = position.y - 0.5;\n\n vec2 p0, p1, p2, pos;\n if(position.x == 0.0) { // The left side of the unit square\n p0 = pointA;\n p1 = pointB;\n p2 = pointC;\n pos = position;\n } else { // The right side of the unit square, use same approach but flip the geometry upside down\n p0 = pointD;\n p1 = pointC;\n p2 = pointB;\n pos = vec2(0.0, -position.y);\n }\n\n vec2 p01 = p1 - p0;\n vec2 p12 = p2 - p1;\n vec2 p21 = p1 - p2;\n\n // Find the normal vector.\n vec2 tangent = normalize(normalize(p12) + normalize(p01));\n vec2 normal = vec2(-tangent.y, tangent.x);\n\n // Find the vector perpendicular to p0 -> p1.\n vec2 p01Norm = normalize(vec2(-p01.y, p01.x));\n\n // Determine the bend direction.\n float sigma = sign(dot(p01 + p21, normal));\n float width = aLineWidth[0];\n\n if(sign(pos.y) == -sigma) {\n // This is an intersecting vertex. Adjust the position so that there's no overlap.\n vec2 point = 0.5 * width * normal * -sigma / dot(normal, p01Norm);\n gl_Position = vec4(uPanZoomMatrix * vec3(p1 + point, 1.0), 1.0);\n } else {\n // This is a non-intersecting vertex. Treat it like a mitre join.\n vec2 point = 0.5 * width * normal * sigma * dot(normal, p01Norm);\n gl_Position = vec4(uPanZoomMatrix * vec3(p1 + point, 1.0), 1.0);\n }\n\n vColor = aColor;\n } \n else if(aVertType == ").concat(3," && vid < 3) {\n // massage the first triangle into an edge arrow\n if(vid == 0)\n position = vec2(-0.15, -0.3);\n if(vid == 1)\n position = vec2( 0.0, 0.0);\n if(vid == 2)\n position = vec2( 0.15, -0.3);\n\n gl_Position = vec4(uPanZoomMatrix * aTransform * vec3(position, 1.0), 1.0);\n vColor = aColor;\n }\n else {\n gl_Position = vec4(2.0, 0.0, 0.0, 1.0); // discard vertex by putting it outside webgl clip space\n }\n\n vAtlasId = aAtlasId;\n vVertType = aVertType;\n vIndex = aIndex;\n }\n "),r=this.batchManager.getIndexArray(),a="#version 300 es\n precision highp float;\n\n // declare texture unit for each texture atlas in the batch\n ".concat(r.map(function(e){return"uniform sampler2D uTexture".concat(e,";")}).join("\n\t"),"\n\n uniform vec4 uBGColor;\n uniform float uZoom;\n\n in vec2 vTexCoord;\n in vec4 vColor;\n in vec2 vPosition; // model coordinates\n\n flat in int vAtlasId;\n flat in vec4 vIndex;\n flat in int vVertType;\n flat in vec2 vTopRight;\n flat in vec2 vBotLeft;\n flat in vec4 vCornerRadius;\n flat in vec4 vBorderColor;\n flat in vec2 vBorderWidth;\n\n out vec4 outColor;\n\n ").concat("\n float circleSD(vec2 p, float r) {\n return distance(vec2(0), p) - r; // signed distance\n }\n","\n ").concat("\n float rectangleSD(vec2 p, vec2 b) {\n vec2 d = abs(p)-b;\n return distance(vec2(0),max(d,0.0)) + min(max(d.x,d.y),0.0);\n }\n","\n ").concat("\n float roundRectangleSD(vec2 p, vec2 b, vec4 cr) {\n cr.xy = (p.x > 0.0) ? cr.xy : cr.zw;\n cr.x = (p.y > 0.0) ? cr.x : cr.y;\n vec2 q = abs(p) - b + cr.x;\n return min(max(q.x, q.y), 0.0) + distance(vec2(0), max(q, 0.0)) - cr.x;\n }\n","\n ").concat("\n float ellipseSD(vec2 p, vec2 ab) {\n p = abs( p ); // symmetry\n\n // find root with Newton solver\n vec2 q = ab*(p-ab);\n float w = (q.x1.0) ? d : -d;\n }\n","\n\n vec4 blend(vec4 top, vec4 bot) { // blend colors with premultiplied alpha\n return vec4( \n top.rgb + (bot.rgb * (1.0 - top.a)),\n top.a + (bot.a * (1.0 - top.a)) \n );\n }\n\n vec4 distInterp(vec4 cA, vec4 cB, float d) { // interpolate color using Signed Distance\n // scale to the zoom level so that borders don't look blurry when zoomed in\n // note 1.5 is an aribitrary value chosen because it looks good\n return mix(cA, cB, 1.0 - smoothstep(0.0, 1.5 / uZoom, abs(d))); \n }\n\n void main(void) {\n if(vVertType == ").concat(0,") {\n // look up the texel from the texture unit\n ").concat(r.map(function(e){return"if(vAtlasId == ".concat(e,") outColor = texture(uTexture").concat(e,", vTexCoord);")}).join("\n\telse "),"\n } \n else if(vVertType == ").concat(3,") {\n // mimics how canvas renderer uses context.globalCompositeOperation = 'destination-out';\n outColor = blend(vColor, uBGColor);\n outColor.a = 1.0; // make opaque, masks out line under arrow\n }\n else if(vVertType == ").concat(4," && vBorderWidth == vec2(0.0)) { // simple rectangle with no border\n outColor = vColor; // unit square is already transformed to the rectangle, nothing else needs to be done\n }\n else if(vVertType == ").concat(4," || vVertType == ").concat(7," \n || vVertType == ").concat(5," || vVertType == ").concat(6,") { // use SDF\n\n float outerBorder = vBorderWidth[0];\n float innerBorder = vBorderWidth[1];\n float borderPadding = outerBorder * 2.0;\n float w = vTopRight.x - vBotLeft.x - borderPadding;\n float h = vTopRight.y - vBotLeft.y - borderPadding;\n vec2 b = vec2(w/2.0, h/2.0); // half width, half height\n vec2 p = vPosition - vec2(vTopRight.x - b[0] - outerBorder, vTopRight.y - b[1] - outerBorder); // translate to center\n\n float d; // signed distance\n if(vVertType == ").concat(4,") {\n d = rectangleSD(p, b);\n } else if(vVertType == ").concat(7," && w == h) {\n d = circleSD(p, b.x); // faster than ellipse\n } else if(vVertType == ").concat(7,") {\n d = ellipseSD(p, b);\n } else {\n d = roundRectangleSD(p, b, vCornerRadius.wzyx);\n }\n\n // use the distance to interpolate a color to smooth the edges of the shape, doesn't need multisampling\n // we must smooth colors inwards, because we can't change pixels outside the shape's bounding box\n if(d > 0.0) {\n if(d > outerBorder) {\n discard;\n } else {\n outColor = distInterp(vBorderColor, vec4(0), d - outerBorder);\n }\n } else {\n if(d > innerBorder) {\n vec4 outerColor = outerBorder == 0.0 ? vec4(0) : vBorderColor;\n vec4 innerBorderColor = blend(vBorderColor, vColor);\n outColor = distInterp(innerBorderColor, outerColor, d);\n } \n else {\n vec4 outerColor;\n if(innerBorder == 0.0 && outerBorder == 0.0) {\n outerColor = vec4(0);\n } else if(innerBorder == 0.0) {\n outerColor = vBorderColor;\n } else {\n outerColor = blend(vBorderColor, vColor);\n }\n outColor = distInterp(vColor, outerColor, d - innerBorder);\n }\n }\n }\n else {\n outColor = vColor;\n }\n\n ").concat(e.picking?"if(outColor.a == 0.0) discard;\n else outColor = vIndex;":"","\n }\n "),i=function(e,t,n){var r=qd(e,e.VERTEX_SHADER,t),a=qd(e,e.FRAGMENT_SHADER,n),i=e.createProgram();if(e.attachShader(i,r),e.attachShader(i,a),e.linkProgram(i),!e.getProgramParameter(i,e.LINK_STATUS))throw new Error("Could not initialize shaders");return i}(t,n,a);i.aPosition=t.getAttribLocation(i,"aPosition"),i.aIndex=t.getAttribLocation(i,"aIndex"),i.aVertType=t.getAttribLocation(i,"aVertType"),i.aTransform=t.getAttribLocation(i,"aTransform"),i.aAtlasId=t.getAttribLocation(i,"aAtlasId"),i.aTex=t.getAttribLocation(i,"aTex"),i.aPointAPointB=t.getAttribLocation(i,"aPointAPointB"),i.aPointCPointD=t.getAttribLocation(i,"aPointCPointD"),i.aLineWidth=t.getAttribLocation(i,"aLineWidth"),i.aColor=t.getAttribLocation(i,"aColor"),i.aCornerRadius=t.getAttribLocation(i,"aCornerRadius"),i.aBorderColor=t.getAttribLocation(i,"aBorderColor"),i.uPanZoomMatrix=t.getUniformLocation(i,"uPanZoomMatrix"),i.uAtlasSize=t.getUniformLocation(i,"uAtlasSize"),i.uBGColor=t.getUniformLocation(i,"uBGColor"),i.uZoom=t.getUniformLocation(i,"uZoom"),i.uTextures=[];for(var o=0;o1&&void 0!==arguments[1]?arguments[1]:hh.SCREEN;this.panZoomMatrix=e,this.renderTarget=t,this.batchDebugInfo=[],this.wrappedCount=0,this.simpleCount=0,this.startBatch()}},{key:"startBatch",value:function(){this.instanceCount=0,this.batchManager.startBatch()}},{key:"endFrame",value:function(){this.endBatch()}},{key:"_isVisible",value:function(e,t){return!!e.visible()&&(!t||!t.isVisible||t.isVisible(e))}},{key:"drawTexture",value:function(e,t,n){var r=this.atlasManager,a=this.batchManager,i=r.getRenderTypeOpts(n);if(this._isVisible(e,i)&&(!e.isEdge()||this._isValidEdge(e))){if(this.renderTarget.picking&&i.getTexPickingMode){var s=i.getTexPickingMode(e);if(s===fh)return;if(s==ph)return void this.drawPickingRectangle(e,t,n)}var u,c=o(r.getAtlasInfo(e,n));try{for(c.s();!(u=c.n()).done;){var d=u.value,h=d.atlas,f=d.tex1,p=d.tex2;a.canAddToCurrentBatch(h)||this.endBatch();for(var v=a.getAtlasIndexForBatch(h),g=0,y=[[f,!0],[p,!1]];g=this.maxInstances&&this.endBatch()}}}}catch(T){c.e(T)}finally{c.f()}}}},{key:"setTransformMatrix",value:function(e,t,n,r){var a=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],i=0;if(n.shapeProps&&n.shapeProps.padding&&(i=e.pstyle(n.shapeProps.padding).pfValue),r){var o=r.bb,s=r.tex1,l=r.tex2,u=s.w/(s.w+l.w);a||(u=1-u);var c=this._getAdjustedBB(o,i,a,u);this._applyTransformMatrix(t,c,n,e)}else{var d=n.getBoundingBox(e),h=this._getAdjustedBB(d,i,!0,1);this._applyTransformMatrix(t,h,n,e)}}},{key:"_applyTransformMatrix",value:function(e,t,n,r){var a,i;ah(e);var o=n.getRotation?n.getRotation(r):0;if(0!==o){var s=n.getRotationPoint(r);ih(e,e,[s.x,s.y]),oh(e,e,o);var l=n.getRotationOffset(r);a=l.x+(t.xOffset||0),i=l.y+(t.yOffset||0)}else a=t.x1,i=t.y1;ih(e,e,[a,i]),sh(e,e,[t.w,t.h])}},{key:"_getAdjustedBB",value:function(e,t,n,r){var a=e.x1,i=e.y1,o=e.w,s=e.h;t&&(a-=t,i-=t,o+=2*t,s+=2*t);var l=0,u=o*r;return n&&r<1?o=u:!n&&r<1&&(a+=l=o-u,o=u),{x1:a,y1:i,w:o,h:s,xOffset:l,yOffset:e.yOffset}}},{key:"drawPickingRectangle",value:function(e,t,n){var r=this.atlasManager.getRenderTypeOpts(n),a=this.instanceCount;this.vertTypeBuffer.getView(a)[0]=4,Zd(t,this.indexBuffer.getView(a)),Gd([0,0,0],1,this.colorBuffer.getView(a));var i=this.transformBuffer.getMatrixView(a);this.setTransformMatrix(e,i,r),this.simpleCount++,this.instanceCount++,this.instanceCount>=this.maxInstances&&this.endBatch()}},{key:"drawNode",value:function(e,t,n){var r=this.simpleShapeOptions.get(n);if(this._isVisible(e,r)){var a=r.shapeProps,i=this._getVertTypeForShape(e,a.shape);if(void 0===i||r.isSimple&&!r.isSimple(e))this.drawTexture(e,t,n);else{var o=this.instanceCount;if(this.vertTypeBuffer.getView(o)[0]=i,5===i||6===i){var s=r.getBoundingBox(e),l=this._getCornerRadius(e,a.radius,s),u=this.cornerRadiusBuffer.getView(o);u[0]=l,u[1]=l,u[2]=l,u[3]=l,6===i&&(u[0]=0,u[2]=0)}Zd(t,this.indexBuffer.getView(o)),Gd(e.pstyle(a.color).value,e.pstyle(a.opacity).value,this.colorBuffer.getView(o));var c=this.lineWidthBuffer.getView(o);if(c[0]=0,c[1]=0,a.border){var d=e.pstyle("border-width").value;if(d>0){Gd(e.pstyle("border-color").value,e.pstyle("border-opacity").value,this.borderColorBuffer.getView(o));var h=e.pstyle("border-position").value;if("inside"===h)c[0]=0,c[1]=-d;else if("outside"===h)c[0]=d,c[1]=0;else{var f=d/2;c[0]=f,c[1]=-f}}}var p=this.transformBuffer.getMatrixView(o);this.setTransformMatrix(e,p,r),this.simpleCount++,this.instanceCount++,this.instanceCount>=this.maxInstances&&this.endBatch()}}}},{key:"_getVertTypeForShape",value:function(e,t){switch(e.pstyle(t).value){case"rectangle":return 4;case"ellipse":return 7;case"roundrectangle":case"round-rectangle":return 5;case"bottom-round-rectangle":return 6;default:return}}},{key:"_getCornerRadius",value:function(e,t,n){var r=n.w,a=n.h;if("auto"===e.pstyle(t).value)return Rn(r,a);var i=e.pstyle(t).pfValue,o=r/2,s=a/2;return Math.min(i,s,o)}},{key:"drawEdgeArrow",value:function(e,t,n){if(e.visible()){var r,a,i,o=e._private.rscratch;if("source"===n?(r=o.arrowStartX,a=o.arrowStartY,i=o.srcArrowAngle):(r=o.arrowEndX,a=o.arrowEndY,i=o.tgtArrowAngle),!(isNaN(r)||null==r||isNaN(a)||null==a||isNaN(i)||null==i))if("none"!==e.pstyle(n+"-arrow-shape").value){var s=e.pstyle(n+"-arrow-color").value,l=e.pstyle("opacity").value*e.pstyle("line-opacity").value,u=e.pstyle("width").pfValue,c=e.pstyle("arrow-scale").value,d=this.r.getArrowWidth(u,c),h=this.instanceCount,f=this.transformBuffer.getMatrixView(h);ah(f),ih(f,f,[r,a]),sh(f,f,[d,d]),oh(f,f,i),this.vertTypeBuffer.getView(h)[0]=3,Zd(t,this.indexBuffer.getView(h)),Gd(s,l,this.colorBuffer.getView(h)),this.instanceCount++,this.instanceCount>=this.maxInstances&&this.endBatch()}}}},{key:"drawEdgeLine",value:function(e,t){if(e.visible()){var n=this._getEdgePoints(e);if(n){var r=e.pstyle("opacity").value,a=e.pstyle("line-opacity").value,i=e.pstyle("width").pfValue,o=e.pstyle("line-color").value,s=r*a;if(n.length/2+this.instanceCount>this.maxInstances&&this.endBatch(),4==n.length){var l=this.instanceCount;this.vertTypeBuffer.getView(l)[0]=1,Zd(t,this.indexBuffer.getView(l)),Gd(o,s,this.colorBuffer.getView(l)),this.lineWidthBuffer.getView(l)[0]=i;var u=this.pointAPointBBuffer.getView(l);u[0]=n[0],u[1]=n[1],u[2]=n[2],u[3]=n[3],this.instanceCount++,this.instanceCount>=this.maxInstances&&this.endBatch()}else for(var c=0;c=this.maxInstances&&this.endBatch()}}}}},{key:"_isValidEdge",value:function(e){var t=e._private.rscratch;return!t.badLine&&null!=t.allpts&&!isNaN(t.allpts[0])}},{key:"_getEdgePoints",value:function(e){var t=e._private.rscratch;if(this._isValidEdge(e)){var n=t.allpts;if(4==n.length)return n;var r=this._getNumSegments(e);return this._getCurveSegmentPoints(n,r)}}},{key:"_getNumSegments",value:function(e){return Math.min(Math.max(15,5),this.maxInstances)}},{key:"_getCurveSegmentPoints",value:function(e,t){if(4==e.length)return e;for(var n=Array(2*(t+1)),r=0;r<=t;r++)if(0==r)n[0]=e[0],n[1]=e[1];else if(r==t)n[2*r]=e[e.length-2],n[2*r+1]=e[e.length-1];else{var a=r/t;this._setCurvePoint(e,a,n,2*r)}return n}},{key:"_setCurvePoint",value:function(e,t,n,r){if(!(e.length<=2)){for(var a=Array(e.length-2),i=0;i0}},u=function(e){return"yes"===e.pstyle("text-events").strValue?ph:fh},c=function(e){var t=e.position(),n=t.x,r=t.y,a=e.outerWidth(),i=e.outerHeight();return{w:a,h:i,x1:n-a/2,y1:r-i/2}};n.drawing.addAtlasCollection("node",{texRows:e.webglTexRowsNodes}),n.drawing.addAtlasCollection("label",{texRows:e.webglTexRows}),n.drawing.addTextureAtlasRenderType("node-body",{collection:"node",getKey:t.getStyleKey,getBoundingBox:t.getElementBox,drawElement:t.drawElement}),n.drawing.addSimpleShapeRenderType("node-body",{getBoundingBox:c,isSimple:Hd,shapeProps:{shape:"shape",color:"background-color",opacity:"background-opacity",radius:"corner-radius",border:!0}}),n.drawing.addSimpleShapeRenderType("node-overlay",{getBoundingBox:c,isVisible:s("overlay"),shapeProps:{shape:"overlay-shape",color:"overlay-color",opacity:"overlay-opacity",padding:"overlay-padding",radius:"overlay-corner-radius"}}),n.drawing.addSimpleShapeRenderType("node-underlay",{getBoundingBox:c,isVisible:s("underlay"),shapeProps:{shape:"underlay-shape",color:"underlay-color",opacity:"underlay-opacity",padding:"underlay-padding",radius:"underlay-corner-radius"}}),n.drawing.addTextureAtlasRenderType("label",{collection:"label",getTexPickingMode:u,getKey:mh(t.getLabelKey,null),getBoundingBox:bh(t.getLabelBox,null),drawClipped:!0,drawElement:t.drawLabel,getRotation:a(null),getRotationPoint:t.getLabelRotationPoint,getRotationOffset:t.getLabelRotationOffset,isVisible:i("label")}),n.drawing.addTextureAtlasRenderType("edge-source-label",{collection:"label",getTexPickingMode:u,getKey:mh(t.getSourceLabelKey,"source"),getBoundingBox:bh(t.getSourceLabelBox,"source"),drawClipped:!0,drawElement:t.drawSourceLabel,getRotation:a("source"),getRotationPoint:t.getSourceLabelRotationPoint,getRotationOffset:t.getSourceLabelRotationOffset,isVisible:i("source-label")}),n.drawing.addTextureAtlasRenderType("edge-target-label",{collection:"label",getTexPickingMode:u,getKey:mh(t.getTargetLabelKey,"target"),getBoundingBox:bh(t.getTargetLabelBox,"target"),drawClipped:!0,drawElement:t.drawTargetLabel,getRotation:a("target"),getRotationPoint:t.getTargetLabelRotationPoint,getRotationOffset:t.getTargetLabelRotationOffset,isVisible:i("target-label")});var d=Me(function(){console.log("garbage collect flag set"),n.data.gc=!0},1e4);n.onUpdateEleCalcs(function(e,t){var r=!1;t&&t.length>0&&(r|=n.drawing.invalidate(t)),r&&d()}),function(e){var t=e.render;e.render=function(n){n=n||{};var r=e.cy;e.webgl&&(r.zoom()>hd?(!function(e){var t=e.data.contexts[e.WEBGL];t.clear(t.COLOR_BUFFER_BIT|t.DEPTH_BUFFER_BIT)}(e),t.call(e,n)):(!function(e){var t=function(t){t.save(),t.setTransform(1,0,0,1,0,0),t.clearRect(0,0,e.canvasWidth,e.canvasHeight),t.restore()};t(e.data.contexts[e.NODE]),t(e.data.contexts[e.DRAG])}(e),Eh(e,n,hh.SCREEN)))};var n=e.matchCanvasSize;e.matchCanvasSize=function(t){n.call(e,t),e.pickingFrameBuffer.setFramebufferAttachmentSizes(e.canvasWidth,e.canvasHeight),e.pickingFrameBuffer.needsDraw=!0},e.findNearestElements=function(t,n,r,a){return function(e,t,n){var r,a,i,s=function(e,t,n){var r,a,i,o,s=Ud(e),u=s.pan,c=s.zoom,d=function(e,t,n,r,a){var i=r*n+t.x,o=a*n+t.y;return[i,o=Math.round(e.canvasHeight-o)]}(e,u,c,t,n),h=l(d,2),f=h[0],p=h[1],v=6;if(r=f-v/2,a=p-v/2,o=v,0===(i=v)||0===o)return[];var g=e.data.contexts[e.WEBGL];g.bindFramebuffer(g.FRAMEBUFFER,e.pickingFrameBuffer),e.pickingFrameBuffer.needsDraw&&(g.viewport(0,0,g.canvas.width,g.canvas.height),Eh(e,null,hh.PICKING),e.pickingFrameBuffer.needsDraw=!1);var y=i*o,m=new Uint8Array(4*y);g.readPixels(r,a,i,o,g.RGBA,g.UNSIGNED_BYTE,m),g.bindFramebuffer(g.FRAMEBUFFER,null);for(var b=new Set,x=0;x=0&&b.add(w)}return b}(e,t,n),u=e.getCachedZSortedEles(),c=o(s);try{for(c.s();!(i=c.n()).done;){var d=u[i.value];if(!r&&d.isNode()&&(r=d),!a&&d.isEdge()&&(a=d),r&&a)break}}catch(h){c.e(h)}finally{c.f()}return[r,a].filter(Boolean)}(e,t,n)};var r=e.invalidateCachedZSortedEles;e.invalidateCachedZSortedEles=function(){r.call(e),e.pickingFrameBuffer.needsDraw=!0};var a=e.notify;e.notify=function(t,n){a.call(e,t,n),"viewport"===t||"bounds"===t?e.pickingFrameBuffer.needsDraw=!0:"background"===t&&e.drawing.invalidate(n,{type:"node-body"})}}(n)};var mh=function(e,t){return function(n){var r=e(n),a=yh(n,t);return a.length>1?a.map(function(e,t){return"".concat(r,"_").concat(t)}):r}},bh=function(e,t){return function(n,r){var a=e(n);if("string"==typeof r){var i=r.indexOf("_");if(i>0){var o=Number(r.substring(i+1)),s=yh(n,t),l=a.h/s.length,u=l*o,c=a.y1+u;return{x1:a.x1,w:a.w,y1:c,h:l,yOffset:u}}}return a}};function xh(e,t){var n=e.canvasWidth,r=e.canvasHeight,a=Ud(e),i=a.pan,o=a.zoom;t.setTransform(1,0,0,1,0,0),t.clearRect(0,0,n,r),t.translate(i.x,i.y),t.scale(o,o)}function wh(e,t,n){var r=e.drawing;t+=1,n.isNode()?(r.drawNode(n,t,"node-underlay"),r.drawNode(n,t,"node-body"),r.drawTexture(n,t,"label"),r.drawNode(n,t,"node-overlay")):(r.drawEdgeLine(n,t),r.drawEdgeArrow(n,t,"source"),r.drawEdgeArrow(n,t,"target"),r.drawTexture(n,t,"label"),r.drawTexture(n,t,"edge-source-label"),r.drawTexture(n,t,"edge-target-label"))}function Eh(e,t,n){var r;e.webglDebug&&(r=performance.now());var a=e.drawing,i=0;if(n.screen&&e.data.canvasNeedsRedraw[e.SELECT_BOX]&&function(e,t){e.drawSelectionRectangle(t,function(t){return xh(e,t)})}(e,t),e.data.canvasNeedsRedraw[e.NODE]||n.picking){var s=e.data.contexts[e.WEBGL];n.screen?(s.clearColor(0,0,0,0),s.enable(s.BLEND),s.blendFunc(s.ONE,s.ONE_MINUS_SRC_ALPHA)):s.disable(s.BLEND),s.clear(s.COLOR_BUFFER_BIT|s.DEPTH_BUFFER_BIT),s.viewport(0,0,s.canvas.width,s.canvas.height);var l=function(e){var t=e.canvasWidth,n=e.canvasHeight,r=Ud(e),a=r.pan,i=r.zoom,o=rh();ih(o,o,[a.x,a.y]),sh(o,o,[i,i]);var s=rh();!function(e,t,n){e[0]=2/t,e[1]=0,e[2]=0,e[3]=0,e[4]=-2/n,e[5]=0,e[6]=-1,e[7]=1,e[8]=1}(s,t,n);var l,u,c,d,h,f,p,v,g,y,m,b,x,w,E,k,T,C,P,S,B,D=rh();return l=D,c=o,d=(u=s)[0],h=u[1],f=u[2],p=u[3],v=u[4],g=u[5],y=u[6],m=u[7],b=u[8],x=c[0],w=c[1],E=c[2],k=c[3],T=c[4],C=c[5],P=c[6],S=c[7],B=c[8],l[0]=x*d+w*p+E*y,l[1]=x*h+w*v+E*m,l[2]=x*f+w*g+E*b,l[3]=k*d+T*p+C*y,l[4]=k*h+T*v+C*m,l[5]=k*f+T*g+C*b,l[6]=P*d+S*p+B*y,l[7]=P*h+S*v+B*m,l[8]=P*f+S*g+B*b,D}(e),u=e.getCachedZSortedEles();if(i=u.length,a.startFrame(l,n),n.screen){for(var c=0;c0&&i>0){h.clearRect(0,0,a,i),h.globalCompositeOperation="source-over";var f=this.getCachedZSortedEles();if(e.full)h.translate(-n.x1*l,-n.y1*l),h.scale(l,l),this.drawElements(h,f),h.scale(1/l,1/l),h.translate(n.x1*l,n.y1*l);else{var p=t.pan(),v={x:p.x*l,y:p.y*l};l*=t.zoom(),h.translate(v.x,v.y),h.scale(l,l),this.drawElements(h,f),h.scale(1/l,1/l),h.translate(-v.x,-v.y)}e.bg&&(h.globalCompositeOperation="destination-over",h.fillStyle=e.bg,h.rect(0,0,a,i),h.fill())}return d},_h.png=function(e){return Mh(e,this.bufferCanvasImage(e),"image/png")},_h.jpg=function(e){return Mh(e,this.bufferCanvasImage(e),"image/jpeg")};var Rh={nodeShapeImpl:function(e,t,n,r,a,i,o,s){switch(e){case"ellipse":return this.drawEllipsePath(t,n,r,a,i);case"polygon":return this.drawPolygonPath(t,n,r,a,i,o);case"round-polygon":return this.drawRoundPolygonPath(t,n,r,a,i,o,s);case"roundrectangle":case"round-rectangle":return this.drawRoundRectanglePath(t,n,r,a,i,s);case"cutrectangle":case"cut-rectangle":return this.drawCutRectanglePath(t,n,r,a,i,o,s);case"bottomroundrectangle":case"bottom-round-rectangle":return this.drawBottomRoundRectanglePath(t,n,r,a,i,s);case"barrel":return this.drawBarrelPath(t,n,r,a,i)}}},Ih=Lh,Nh=Lh.prototype;function Lh(e){var t=this,n=t.cy.window().document;e.webgl&&(Nh.CANVAS_LAYERS=t.CANVAS_LAYERS=4,console.log("webgl rendering enabled")),t.data={canvases:new Array(Nh.CANVAS_LAYERS),contexts:new Array(Nh.CANVAS_LAYERS),canvasNeedsRedraw:new Array(Nh.CANVAS_LAYERS),bufferCanvases:new Array(Nh.BUFFER_COUNT),bufferContexts:new Array(Nh.CANVAS_LAYERS)};var r="-webkit-tap-highlight-color",a="rgba(0,0,0,0)";t.data.canvasContainer=n.createElement("div");var i=t.data.canvasContainer.style;t.data.canvasContainer.style[r]=a,i.position="relative",i.zIndex="0",i.overflow="hidden";var o=e.cy.container();o.appendChild(t.data.canvasContainer),o.style[r]=a;var s={"-webkit-user-select":"none","-moz-user-select":"-moz-none","user-select":"none","-webkit-tap-highlight-color":"rgba(0,0,0,0)","outline-style":"none"};p&&p.userAgent.match(/msie|trident|edge/i)&&(s["-ms-touch-action"]="none",s["touch-action"]="none");for(var l=0;l{e.d(n,{diagram:()=>ct});var i=e(67633),s=e(40797),r=e(70451);function o(t,n){let e;if(void 0===n)for(const i of t)null!=i&&(e>i||void 0===e&&i>=i)&&(e=i);else{let i=-1;for(let s of t)null!=(s=n(s,++i,t))&&(e>s||void 0===e&&s>=s)&&(e=s)}return e}function c(t){return t.target.depth}function l(t,n){return t.sourceLinks.length?t.depth:n-1}function a(t,n){let e=0;if(void 0===n)for(let i of t)(i=+i)&&(e+=i);else{let i=-1;for(let s of t)(s=+n(s,++i,t))&&(e+=s)}return e}function h(t,n){let e;if(void 0===n)for(const i of t)null!=i&&(e=i)&&(e=i);else{let i=-1;for(let s of t)null!=(s=n(s,++i,t))&&(e=s)&&(e=s)}return e}function u(t){return function(){return t}}function f(t,n){return d(t.source,n.source)||t.index-n.index}function y(t,n){return d(t.target,n.target)||t.index-n.index}function d(t,n){return t.y0-n.y0}function p(t){return t.value}function g(t){return t.index}function _(t){return t.nodes}function k(t){return t.links}function x(t,n){const e=t.get(n);if(!e)throw new Error("missing: "+n);return e}function m({nodes:t}){for(const n of t){let t=n.y0,e=t;for(const i of n.sourceLinks)i.y0=t+i.width/2,t+=i.width;for(const i of n.targetLinks)i.y1=e+i.width/2,e+=i.width}}function v(){let t,n,e,i=0,s=0,r=1,c=1,v=24,b=8,w=g,L=l,S=_,E=k,K=6;function A(){const l={nodes:S.apply(null,arguments),links:E.apply(null,arguments)};return function({nodes:t,links:n}){for(const[e,s]of t.entries())s.index=e,s.sourceLinks=[],s.targetLinks=[];const i=new Map(t.map((n,e)=>[w(n,e,t),n]));for(const[e,s]of n.entries()){s.index=e;let{source:t,target:n}=s;"object"!=typeof t&&(t=s.source=x(i,t)),"object"!=typeof n&&(n=s.target=x(i,n)),t.sourceLinks.push(s),n.targetLinks.push(s)}if(null!=e)for(const{sourceLinks:s,targetLinks:r}of t)s.sort(e),r.sort(e)}(l),function({nodes:t}){for(const n of t)n.value=void 0===n.fixedValue?Math.max(a(n.sourceLinks,p),a(n.targetLinks,p)):n.fixedValue}(l),function({nodes:t}){const n=t.length;let e=new Set(t),i=new Set,s=0;for(;e.size;){for(const t of e){t.depth=s;for(const{target:n}of t.sourceLinks)i.add(n)}if(++s>n)throw new Error("circular link");e=i,i=new Set}}(l),function({nodes:t}){const n=t.length;let e=new Set(t),i=new Set,s=0;for(;e.size;){for(const t of e){t.height=s;for(const{source:n}of t.targetLinks)i.add(n)}if(++s>n)throw new Error("circular link");e=i,i=new Set}}(l),function(e){const l=function({nodes:t}){const e=h(t,t=>t.depth)+1,s=(r-i-v)/(e-1),o=new Array(e);for(const n of t){const t=Math.max(0,Math.min(e-1,Math.floor(L.call(null,n,e))));n.layer=t,n.x0=i+t*s,n.x1=n.x0+v,o[t]?o[t].push(n):o[t]=[n]}if(n)for(const i of o)i.sort(n);return o}(e);t=Math.min(b,(c-s)/(h(l,t=>t.length)-1)),function(n){const e=o(n,n=>(c-s-(n.length-1)*t)/a(n,p));for(const i of n){let n=s;for(const s of i){s.y0=n,s.y1=n+s.value*e,n=s.y1+t;for(const t of s.sourceLinks)t.width=t.value*e}n=(c-n+t)/(i.length+1);for(let t=0;t0))continue;let s=(n/i-t.y0)*e;t.y0+=s,t.y1+=s,P(t)}void 0===n&&r.sort(d),T(r,i)}}function I(t,e,i){for(let s=t.length-2;s>=0;--s){const r=t[s];for(const t of r){let n=0,i=0;for(const{target:e,value:r}of t.sourceLinks){let s=r*(e.layer-t.layer);n+=$(t,e)*s,i+=s}if(!(i>0))continue;let s=(n/i-t.y0)*e;t.y0+=s,t.y1+=s,P(t)}void 0===n&&r.sort(d),T(r,i)}}function T(n,e){const i=n.length>>1,r=n[i];N(n,r.y0-t,i-1,e),D(n,r.y1+t,i+1,e),N(n,c,n.length-1,e),D(n,s,0,e)}function D(n,e,i,s){for(;i1e-6&&(r.y0+=o,r.y1+=o),e=r.y1+t}}function N(n,e,i,s){for(;i>=0;--i){const r=n[i],o=(r.y1-e)*s;o>1e-6&&(r.y0-=o,r.y1-=o),e=r.y0-t}}function P({sourceLinks:t,targetLinks:n}){if(void 0===e){for(const{source:{sourceLinks:t}}of n)t.sort(y);for(const{target:{targetLinks:n}}of t)n.sort(f)}}function C(t){if(void 0===e)for(const{sourceLinks:n,targetLinks:e}of t)n.sort(y),e.sort(f)}function O(n,e){let i=n.y0-(n.sourceLinks.length-1)*t/2;for(const{target:s,width:r}of n.sourceLinks){if(s===e)break;i+=r+t}for(const{source:t,width:s}of e.targetLinks){if(t===n)break;i-=s}return i}function $(n,e){let i=e.y0-(e.targetLinks.length-1)*t/2;for(const{source:s,width:r}of e.targetLinks){if(s===n)break;i+=r+t}for(const{target:t,width:s}of n.sourceLinks){if(t===e)break;i-=s}return i}return A.update=function(t){return m(t),t},A.nodeId=function(t){return arguments.length?(w="function"==typeof t?t:u(t),A):w},A.nodeAlign=function(t){return arguments.length?(L="function"==typeof t?t:u(t),A):L},A.nodeSort=function(t){return arguments.length?(n=t,A):n},A.nodeWidth=function(t){return arguments.length?(v=+t,A):v},A.nodePadding=function(n){return arguments.length?(b=t=+n,A):b},A.nodes=function(t){return arguments.length?(S="function"==typeof t?t:u(t),A):S},A.links=function(t){return arguments.length?(E="function"==typeof t?t:u(t),A):E},A.linkSort=function(t){return arguments.length?(e=t,A):e},A.size=function(t){return arguments.length?(i=s=0,r=+t[0],c=+t[1],A):[r-i,c-s]},A.extent=function(t){return arguments.length?(i=+t[0][0],r=+t[1][0],s=+t[0][1],c=+t[1][1],A):[[i,s],[r,c]]},A.iterations=function(t){return arguments.length?(K=+t,A):K},A}var b=Math.PI,w=2*b,L=1e-6,S=w-L;function E(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function K(){return new E}E.prototype=K.prototype={constructor:E,moveTo:function(t,n){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,n){this._+="L"+(this._x1=+t)+","+(this._y1=+n)},quadraticCurveTo:function(t,n,e,i){this._+="Q"+ +t+","+ +n+","+(this._x1=+e)+","+(this._y1=+i)},bezierCurveTo:function(t,n,e,i,s,r){this._+="C"+ +t+","+ +n+","+ +e+","+ +i+","+(this._x1=+s)+","+(this._y1=+r)},arcTo:function(t,n,e,i,s){t=+t,n=+n,e=+e,i=+i,s=+s;var r=this._x1,o=this._y1,c=e-t,l=i-n,a=r-t,h=o-n,u=a*a+h*h;if(s<0)throw new Error("negative radius: "+s);if(null===this._x1)this._+="M"+(this._x1=t)+","+(this._y1=n);else if(u>L)if(Math.abs(h*c-l*a)>L&&s){var f=e-r,y=i-o,d=c*c+l*l,p=f*f+y*y,g=Math.sqrt(d),_=Math.sqrt(u),k=s*Math.tan((b-Math.acos((d+u-p)/(2*g*_)))/2),x=k/_,m=k/g;Math.abs(x-1)>L&&(this._+="L"+(t+x*a)+","+(n+x*h)),this._+="A"+s+","+s+",0,0,"+ +(h*f>a*y)+","+(this._x1=t+m*c)+","+(this._y1=n+m*l)}else this._+="L"+(this._x1=t)+","+(this._y1=n);else;},arc:function(t,n,e,i,s,r){t=+t,n=+n,r=!!r;var o=(e=+e)*Math.cos(i),c=e*Math.sin(i),l=t+o,a=n+c,h=1^r,u=r?i-s:s-i;if(e<0)throw new Error("negative radius: "+e);null===this._x1?this._+="M"+l+","+a:(Math.abs(this._x1-l)>L||Math.abs(this._y1-a)>L)&&(this._+="L"+l+","+a),e&&(u<0&&(u=u%w+w),u>S?this._+="A"+e+","+e+",0,1,"+h+","+(t-o)+","+(n-c)+"A"+e+","+e+",0,1,"+h+","+(this._x1=l)+","+(this._y1=a):u>L&&(this._+="A"+e+","+e+",0,"+ +(u>=b)+","+h+","+(this._x1=t+e*Math.cos(s))+","+(this._y1=n+e*Math.sin(s))))},rect:function(t,n,e,i){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)+"h"+ +e+"v"+ +i+"h"+-e+"Z"},toString:function(){return this._}};const A=K;var M=Array.prototype.slice;function I(t){return function(){return t}}function T(t){return t[0]}function D(t){return t[1]}function N(t){return t.source}function P(t){return t.target}function C(t){var n=N,e=P,i=T,s=D,r=null;function o(){var o,c=M.call(arguments),l=n.apply(this,c),a=e.apply(this,c);if(r||(r=o=A()),t(r,+i.apply(this,(c[0]=l,c)),+s.apply(this,c),+i.apply(this,(c[0]=a,c)),+s.apply(this,c)),o)return r=null,o+""||null}return o.source=function(t){return arguments.length?(n=t,o):n},o.target=function(t){return arguments.length?(e=t,o):e},o.x=function(t){return arguments.length?(i="function"==typeof t?t:I(+t),o):i},o.y=function(t){return arguments.length?(s="function"==typeof t?t:I(+t),o):s},o.context=function(t){return arguments.length?(r=null==t?null:t,o):r},o}function O(t,n,e,i,s){t.moveTo(n,e),t.bezierCurveTo(n=(n+i)/2,e,n,s,i,s)}function $(t){return[t.source.x1,t.y0]}function j(t){return[t.target.x0,t.y1]}function z(){return C(O).source($).target(j)}var U=function(){var t=(0,s.K2)(function(t,n,e,i){for(e=e||{},i=t.length;i--;e[t[i]]=n);return e},"o"),n=[1,9],e=[1,10],i=[1,5,10,12],r={trace:(0,s.K2)(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SANKEY:4,NEWLINE:5,csv:6,opt_eof:7,record:8,csv_tail:9,EOF:10,"field[source]":11,COMMA:12,"field[target]":13,"field[value]":14,field:15,escaped:16,non_escaped:17,DQUOTE:18,ESCAPED_TEXT:19,NON_ESCAPED_TEXT:20,$accept:0,$end:1},terminals_:{2:"error",4:"SANKEY",5:"NEWLINE",10:"EOF",11:"field[source]",12:"COMMA",13:"field[target]",14:"field[value]",18:"DQUOTE",19:"ESCAPED_TEXT",20:"NON_ESCAPED_TEXT"},productions_:[0,[3,4],[6,2],[9,2],[9,0],[7,1],[7,0],[8,5],[15,1],[15,1],[16,3],[17,1]],performAction:(0,s.K2)(function(t,n,e,i,s,r,o){var c=r.length-1;switch(s){case 7:const t=i.findOrCreateNode(r[c-4].trim().replaceAll('""','"')),n=i.findOrCreateNode(r[c-2].trim().replaceAll('""','"')),e=parseFloat(r[c].trim());i.addLink(t,n,e);break;case 8:case 9:case 11:this.$=r[c];break;case 10:this.$=r[c-1]}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},{5:[1,3]},{6:4,8:5,15:6,16:7,17:8,18:n,20:e},{1:[2,6],7:11,10:[1,12]},t(e,[2,4],{9:13,5:[1,14]}),{12:[1,15]},t(i,[2,8]),t(i,[2,9]),{19:[1,16]},t(i,[2,11]),{1:[2,1]},{1:[2,5]},t(e,[2,2]),{6:17,8:5,15:6,16:7,17:8,18:n,20:e},{15:18,16:7,17:8,18:n,20:e},{18:[1,19]},t(e,[2,3]),{12:[1,20]},t(i,[2,10]),{15:21,16:7,17:8,18:n,20:e},t([1,5,10],[2,7])],defaultActions:{11:[2,1],12:[2,5]},parseError:(0,s.K2)(function(t,n){if(!n.recoverable){var e=new Error(t);throw e.hash=n,e}this.trace(t)},"parseError"),parse:(0,s.K2)(function(t){var n=this,e=[0],i=[],r=[null],o=[],c=this.table,l="",a=0,h=0,u=0,f=o.slice.call(arguments,1),y=Object.create(this.lexer),d={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(d.yy[p]=this.yy[p]);y.setInput(t,d.yy),d.yy.lexer=y,d.yy.parser=this,void 0===y.yylloc&&(y.yylloc={});var g=y.yylloc;o.push(g);var _=y.options&&y.options.ranges;function k(){var t;return"number"!=typeof(t=i.pop()||y.lex()||1)&&(t instanceof Array&&(t=(i=t).pop()),t=n.symbols_[t]||t),t}"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,s.K2)(function(t){e.length=e.length-2*t,r.length=r.length-t,o.length=o.length-t},"popStack"),(0,s.K2)(k,"lex");for(var x,m,v,b,w,L,S,E,K,A={};;){if(v=e[e.length-1],this.defaultActions[v]?b=this.defaultActions[v]:(null==x&&(x=k()),b=c[v]&&c[v][x]),void 0===b||!b.length||!b[0]){var M="";for(L in K=[],c[v])this.terminals_[L]&&L>2&&K.push("'"+this.terminals_[L]+"'");M=y.showPosition?"Parse error on line "+(a+1)+":\n"+y.showPosition()+"\nExpecting "+K.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(a+1)+": Unexpected "+(1==x?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(M,{text:y.match,token:this.terminals_[x]||x,line:y.yylineno,loc:g,expected:K})}if(b[0]instanceof Array&&b.length>1)throw new Error("Parse Error: multiple actions possible at state: "+v+", token: "+x);switch(b[0]){case 1:e.push(x),r.push(y.yytext),o.push(y.yylloc),e.push(b[1]),x=null,m?(x=m,m=null):(h=y.yyleng,l=y.yytext,a=y.yylineno,g=y.yylloc,u>0&&u--);break;case 2:if(S=this.productions_[b[1]][1],A.$=r[r.length-S],A._$={first_line:o[o.length-(S||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(S||1)].first_column,last_column:o[o.length-1].last_column},_&&(A._$.range=[o[o.length-(S||1)].range[0],o[o.length-1].range[1]]),void 0!==(w=this.performAction.apply(A,[l,h,a,d.yy,b[1],r,o].concat(f))))return w;S&&(e=e.slice(0,-1*S*2),r=r.slice(0,-1*S),o=o.slice(0,-1*S)),e.push(this.productions_[b[1]][0]),r.push(A.$),o.push(A._$),E=c[e[e.length-2]][e[e.length-1]],e.push(E);break;case 3:return!0}}return!0},"parse")},o=function(){return{EOF:1,parseError:(0,s.K2)(function(t,n){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,n)},"parseError"),setInput:(0,s.K2)(function(t,n){return this.yy=n||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:(0,s.K2)(function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},"input"),unput:(0,s.K2)(function(t){var n=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===i.length?this.yylloc.first_column:0)+i[i.length-e.length].length-e[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},"unput"),more:(0,s.K2)(function(){return this._more=!0,this},"more"),reject:(0,s.K2)(function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"reject"),less:(0,s.K2)(function(t){this.unput(this.match.slice(t))},"less"),pastInput:(0,s.K2)(function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:(0,s.K2)(function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:(0,s.K2)(function(){var t=this.pastInput(),n=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+n+"^"},"showPosition"),test_match:(0,s.K2)(function(t,n){var e,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,n,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},"test_match"),next:(0,s.K2)(function(){if(this.done)return this.EOF;var t,n,e,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;rn[0].length)){if(n=e,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(e,s[r])))return t;if(this._backtrack){n=!1;continue}return!1}if(!this.options.flex)break}return n?!1!==(t=this.test_match(n,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:(0,s.K2)(function(){var t=this.next();return t||this.lex()},"lex"),begin:(0,s.K2)(function(t){this.conditionStack.push(t)},"begin"),popState:(0,s.K2)(function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:(0,s.K2)(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:(0,s.K2)(function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},"topState"),pushState:(0,s.K2)(function(t){this.begin(t)},"pushState"),stateStackSize:(0,s.K2)(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,s.K2)(function(t,n,e,i){switch(e){case 0:case 1:return this.pushState("csv"),4;case 2:return 10;case 3:return 5;case 4:return 12;case 5:return this.pushState("escaped_text"),18;case 6:return 20;case 7:return this.popState("escaped_text"),18;case 8:return 19}},"anonymous"),rules:[/^(?:sankey-beta\b)/i,/^(?:sankey\b)/i,/^(?:$)/i,/^(?:((\u000D\u000A)|(\u000A)))/i,/^(?:(\u002C))/i,/^(?:(\u0022))/i,/^(?:([\u0020-\u0021\u0023-\u002B\u002D-\u007E])*)/i,/^(?:(\u0022)(?!(\u0022)))/i,/^(?:(([\u0020-\u0021\u0023-\u002B\u002D-\u007E])|(\u002C)|(\u000D)|(\u000A)|(\u0022)(\u0022))*)/i],conditions:{csv:{rules:[2,3,4,5,6,7,8],inclusive:!1},escaped_text:{rules:[7,8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8],inclusive:!0}}}}();function c(){this.yy={}}return r.lexer=o,(0,s.K2)(c,"Parser"),c.prototype=r,r.Parser=c,new c}();U.parser=U;var F=U,W=[],G=[],V=new Map,X=(0,s.K2)(()=>{W=[],G=[],V=new Map,(0,i.IU)()},"clear"),Y=class{constructor(t,n,e=0){this.source=t,this.target=n,this.value=e}static{(0,s.K2)(this,"SankeyLink")}},q=(0,s.K2)((t,n,e)=>{W.push(new Y(t,n,e))},"addLink"),Q=class{constructor(t){this.ID=t}static{(0,s.K2)(this,"SankeyNode")}},R=(0,s.K2)(t=>{t=i.Y2.sanitizeText(t,(0,i.D7)());let n=V.get(t);return void 0===n&&(n=new Q(t),V.set(t,n),G.push(n)),n},"findOrCreateNode"),B=(0,s.K2)(()=>G,"getNodes"),Z=(0,s.K2)(()=>W,"getLinks"),H=(0,s.K2)(()=>({nodes:G.map(t=>({id:t.ID})),links:W.map(t=>({source:t.source.ID,target:t.target.ID,value:t.value}))}),"getGraph"),J={nodesMap:V,getConfig:(0,s.K2)(()=>(0,i.D7)().sankey,"getConfig"),getNodes:B,getLinks:Z,getGraph:H,addLink:q,findOrCreateNode:R,getAccTitle:i.iN,setAccTitle:i.SV,getAccDescription:i.m7,setAccDescription:i.EI,getDiagramTitle:i.ab,setDiagramTitle:i.ke,clear:X},tt=class t{static{(0,s.K2)(this,"Uid")}static{this.count=0}static next(n){return new t(n+ ++t.count)}constructor(t){this.id=t,this.href=`#${t}`}toString(){return"url("+this.href+")"}},nt={left:function(t){return t.depth},right:function(t,n){return n-1-t.height},center:function(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?o(t.sourceLinks,c)-1:0},justify:l},et=(0,s.K2)(function(t,n,e,o){const{securityLevel:c,sankey:l}=(0,i.D7)(),a=i.ME.sankey;let h;"sandbox"===c&&(h=(0,r.Ltv)("#i"+n));const u="sandbox"===c?(0,r.Ltv)(h.nodes()[0].contentDocument.body):(0,r.Ltv)("body"),f="sandbox"===c?u.select(`[id="${n}"]`):(0,r.Ltv)(`[id="${n}"]`),y=l?.width??a.width,d=l?.height??a.width,p=l?.useMaxWidth??a.useMaxWidth,g=l?.nodeAlignment??a.nodeAlignment,_=l?.prefix??a.prefix,k=l?.suffix??a.suffix,x=l?.showValues??a.showValues,m=o.db.getGraph(),b=nt[g];v().nodeId(t=>t.id).nodeWidth(10).nodePadding(10+(x?15:0)).nodeAlign(b).extent([[0,0],[y,d]])(m);const w=(0,r.UMr)(r.zt);f.append("g").attr("class","nodes").selectAll(".node").data(m.nodes).join("g").attr("class","node").attr("id",t=>(t.uid=tt.next("node-")).id).attr("transform",function(t){return"translate("+t.x0+","+t.y0+")"}).attr("x",t=>t.x0).attr("y",t=>t.y0).append("rect").attr("height",t=>t.y1-t.y0).attr("width",t=>t.x1-t.x0).attr("fill",t=>w(t.id));const L=(0,s.K2)(({id:t,value:n})=>x?`${t}\n${_}${Math.round(100*n)/100}${k}`:t,"getText");f.append("g").attr("class","node-labels").attr("font-size",14).selectAll("text").data(m.nodes).join("text").attr("x",t=>t.x0(t.y1+t.y0)/2).attr("dy",(x?"0":"0.35")+"em").attr("text-anchor",t=>t.x0(t.uid=tt.next("linearGradient-")).id).attr("gradientUnits","userSpaceOnUse").attr("x1",t=>t.source.x1).attr("x2",t=>t.target.x0);t.append("stop").attr("offset","0%").attr("stop-color",t=>w(t.source.id)),t.append("stop").attr("offset","100%").attr("stop-color",t=>w(t.target.id))}let K;switch(E){case"gradient":K=(0,s.K2)(t=>t.uid,"coloring");break;case"source":K=(0,s.K2)(t=>w(t.source.id),"coloring");break;case"target":K=(0,s.K2)(t=>w(t.target.id),"coloring");break;default:K=E}S.append("path").attr("d",z()).attr("stroke",K).attr("stroke-width",t=>Math.max(1,t.width)),(0,i.ot)(void 0,f,0,p)},"draw"),it={draw:et},st=(0,s.K2)(t=>t.replaceAll(/^[^\S\n\r]+|[^\S\n\r]+$/g,"").replaceAll(/([\n\r])+/g,"\n").trim(),"prepareTextForParsing"),rt=(0,s.K2)(t=>`.label {\n font-family: ${t.fontFamily};\n }`,"getStyles"),ot=F.parse.bind(F);F.parse=t=>ot(st(t));var ct={styles:rt,parser:F,db:J,renderer:it}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/1746.4ae2d600.js b/pr-preview/pr-4027/assets/js/1746.4ae2d600.js deleted file mode 100644 index ab7a3c34d..000000000 --- a/pr-preview/pr-4027/assets/js/1746.4ae2d600.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1746],{21152:(t,e,s)=>{s.d(e,{P:()=>a});var i=s(67633),n=s(40797),a=(0,n.K2)((t,e,s,a)=>{t.attr("class",s);const{width:l,height:o,x:c,y:h}=r(t,e);(0,i.a$)(t,o,l,a);const d=u(c,h,l,o,e);t.attr("viewBox",d),n.Rm.debug(`viewBox configured: ${d} with padding: ${e}`)},"setupViewPortForSVG"),r=(0,n.K2)((t,e)=>{const s=t.node()?.getBBox()||{width:0,height:0,x:0,y:0};return{width:s.width+2*e,height:s.height+2*e,x:s.x,y:s.y}},"calculateDimensionsWithPadding"),u=(0,n.K2)((t,e,s,i,n)=>`${t-n} ${e-n} ${s} ${i}`,"createViewBox")},52501:(t,e,s)=>{s.d(e,{o:()=>i});var i=(0,s(40797).K2)(()=>"\n /* Font Awesome icon styling - consolidated */\n .label-icon {\n display: inline-block;\n height: 1em;\n overflow: visible;\n vertical-align: -0.125em;\n }\n \n .node .label-icon path {\n fill: currentColor;\n stroke: revert;\n stroke-width: revert;\n }\n","getIconStyles")},71746:(t,e,s)=>{s.d(e,{Lh:()=>T,NM:()=>m,_$:()=>d,tM:()=>b});var i=s(52501),n=s(89625),a=s(21152),r=s(10045),u=s(13226),l=s(67633),o=s(40797),c=s(70451),h=function(){var t=(0,o.K2)(function(t,e,s,i){for(s=s||{},i=t.length;i--;s[t[i]]=e);return s},"o"),e=[1,18],s=[1,19],i=[1,20],n=[1,41],a=[1,42],r=[1,26],u=[1,24],l=[1,25],c=[1,32],h=[1,33],d=[1,34],p=[1,45],A=[1,35],y=[1,36],g=[1,37],C=[1,38],m=[1,27],b=[1,28],E=[1,29],T=[1,30],k=[1,31],f=[1,44],D=[1,46],F=[1,43],B=[1,47],_=[1,9],S=[1,8,9],N=[1,58],L=[1,59],$=[1,60],x=[1,61],v=[1,62],I=[1,63],O=[1,64],w=[1,8,9,41],R=[1,76],P=[1,8,9,12,13,22,39,41,44,68,69,70,71,72,73,74,79,81],K=[1,8,9,12,13,18,20,22,39,41,44,50,60,68,69,70,71,72,73,74,79,81,86,100,102,103],M=[13,60,86,100,102,103],G=[13,60,73,74,86,100,102,103],U=[13,60,68,69,70,71,72,86,100,102,103],Y=[1,100],z=[1,117],Q=[1,113],W=[1,109],X=[1,115],j=[1,110],V=[1,111],q=[1,112],H=[1,114],J=[1,116],Z=[22,48,60,61,82,86,87,88,89,90],tt=[1,8,9,39,41,44],et=[1,8,9,22],st=[1,145],it=[1,8,9,61],nt=[1,8,9,22,48,60,61,82,86,87,88,89,90],at={trace:(0,o.K2)(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mermaidDoc:4,statements:5,graphConfig:6,CLASS_DIAGRAM:7,NEWLINE:8,EOF:9,statement:10,classLabel:11,SQS:12,STR:13,SQE:14,namespaceName:15,alphaNumToken:16,classLiteralName:17,DOT:18,className:19,GENERICTYPE:20,relationStatement:21,LABEL:22,namespaceStatement:23,classStatement:24,memberStatement:25,annotationStatement:26,clickStatement:27,styleStatement:28,cssClassStatement:29,noteStatement:30,classDefStatement:31,direction:32,acc_title:33,acc_title_value:34,acc_descr:35,acc_descr_value:36,acc_descr_multiline_value:37,namespaceIdentifier:38,STRUCT_START:39,classStatements:40,STRUCT_STOP:41,NAMESPACE:42,classIdentifier:43,STYLE_SEPARATOR:44,members:45,CLASS:46,emptyBody:47,SPACE:48,ANNOTATION_START:49,ANNOTATION_END:50,MEMBER:51,SEPARATOR:52,relation:53,NOTE_FOR:54,noteText:55,NOTE:56,CLASSDEF:57,classList:58,stylesOpt:59,ALPHA:60,COMMA:61,direction_tb:62,direction_bt:63,direction_rl:64,direction_lr:65,relationType:66,lineType:67,AGGREGATION:68,EXTENSION:69,COMPOSITION:70,DEPENDENCY:71,LOLLIPOP:72,LINE:73,DOTTED_LINE:74,CALLBACK:75,LINK:76,LINK_TARGET:77,CLICK:78,CALLBACK_NAME:79,CALLBACK_ARGS:80,HREF:81,STYLE:82,CSSCLASS:83,style:84,styleComponent:85,NUM:86,COLON:87,UNIT:88,BRKT:89,PCT:90,commentToken:91,textToken:92,graphCodeTokens:93,textNoTagsToken:94,TAGSTART:95,TAGEND:96,"==":97,"--":98,DEFAULT:99,MINUS:100,keywords:101,UNICODE_TEXT:102,BQUOTE_STR:103,$accept:0,$end:1},terminals_:{2:"error",7:"CLASS_DIAGRAM",8:"NEWLINE",9:"EOF",12:"SQS",13:"STR",14:"SQE",18:"DOT",20:"GENERICTYPE",22:"LABEL",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",39:"STRUCT_START",41:"STRUCT_STOP",42:"NAMESPACE",44:"STYLE_SEPARATOR",46:"CLASS",48:"SPACE",49:"ANNOTATION_START",50:"ANNOTATION_END",51:"MEMBER",52:"SEPARATOR",54:"NOTE_FOR",56:"NOTE",57:"CLASSDEF",60:"ALPHA",61:"COMMA",62:"direction_tb",63:"direction_bt",64:"direction_rl",65:"direction_lr",68:"AGGREGATION",69:"EXTENSION",70:"COMPOSITION",71:"DEPENDENCY",72:"LOLLIPOP",73:"LINE",74:"DOTTED_LINE",75:"CALLBACK",76:"LINK",77:"LINK_TARGET",78:"CLICK",79:"CALLBACK_NAME",80:"CALLBACK_ARGS",81:"HREF",82:"STYLE",83:"CSSCLASS",86:"NUM",87:"COLON",88:"UNIT",89:"BRKT",90:"PCT",93:"graphCodeTokens",95:"TAGSTART",96:"TAGEND",97:"==",98:"--",99:"DEFAULT",100:"MINUS",101:"keywords",102:"UNICODE_TEXT",103:"BQUOTE_STR"},productions_:[0,[3,1],[3,1],[4,1],[6,4],[5,1],[5,2],[5,3],[11,3],[15,1],[15,1],[15,3],[15,2],[19,1],[19,3],[19,1],[19,2],[19,2],[19,2],[10,1],[10,2],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,2],[10,2],[10,1],[23,4],[23,5],[38,2],[40,1],[40,2],[40,3],[24,1],[24,3],[24,4],[24,3],[24,6],[43,2],[43,3],[47,0],[47,2],[47,2],[26,4],[45,1],[45,2],[25,1],[25,2],[25,1],[25,1],[21,3],[21,4],[21,4],[21,5],[30,3],[30,2],[31,3],[58,1],[58,3],[32,1],[32,1],[32,1],[32,1],[53,3],[53,2],[53,2],[53,1],[66,1],[66,1],[66,1],[66,1],[66,1],[67,1],[67,1],[27,3],[27,4],[27,3],[27,4],[27,4],[27,5],[27,3],[27,4],[27,4],[27,5],[27,4],[27,5],[27,5],[27,6],[28,3],[29,3],[59,1],[59,3],[84,1],[84,2],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[91,1],[91,1],[92,1],[92,1],[92,1],[92,1],[92,1],[92,1],[92,1],[94,1],[94,1],[94,1],[94,1],[16,1],[16,1],[16,1],[16,1],[17,1],[55,1]],performAction:(0,o.K2)(function(t,e,s,i,n,a,r){var u=a.length-1;switch(n){case 8:this.$=a[u-1];break;case 9:case 10:case 13:case 15:this.$=a[u];break;case 11:case 14:this.$=a[u-2]+"."+a[u];break;case 12:case 16:case 100:this.$=a[u-1]+a[u];break;case 17:case 18:this.$=a[u-1]+"~"+a[u]+"~";break;case 19:i.addRelation(a[u]);break;case 20:a[u-1].title=i.cleanupLabel(a[u]),i.addRelation(a[u-1]);break;case 31:this.$=a[u].trim(),i.setAccTitle(this.$);break;case 32:case 33:this.$=a[u].trim(),i.setAccDescription(this.$);break;case 34:i.addClassesToNamespace(a[u-3],a[u-1]);break;case 35:i.addClassesToNamespace(a[u-4],a[u-1]);break;case 36:this.$=a[u],i.addNamespace(a[u]);break;case 37:case 51:case 64:case 97:this.$=[a[u]];break;case 38:this.$=[a[u-1]];break;case 39:a[u].unshift(a[u-2]),this.$=a[u];break;case 41:i.setCssClass(a[u-2],a[u]);break;case 42:i.addMembers(a[u-3],a[u-1]);break;case 44:i.setCssClass(a[u-5],a[u-3]),i.addMembers(a[u-5],a[u-1]);break;case 45:this.$=a[u],i.addClass(a[u]);break;case 46:this.$=a[u-1],i.addClass(a[u-1]),i.setClassLabel(a[u-1],a[u]);break;case 50:i.addAnnotation(a[u],a[u-2]);break;case 52:a[u].push(a[u-1]),this.$=a[u];break;case 53:case 55:case 56:break;case 54:i.addMember(a[u-1],i.cleanupLabel(a[u]));break;case 57:this.$={id1:a[u-2],id2:a[u],relation:a[u-1],relationTitle1:"none",relationTitle2:"none"};break;case 58:this.$={id1:a[u-3],id2:a[u],relation:a[u-1],relationTitle1:a[u-2],relationTitle2:"none"};break;case 59:this.$={id1:a[u-3],id2:a[u],relation:a[u-2],relationTitle1:"none",relationTitle2:a[u-1]};break;case 60:this.$={id1:a[u-4],id2:a[u],relation:a[u-2],relationTitle1:a[u-3],relationTitle2:a[u-1]};break;case 61:i.addNote(a[u],a[u-1]);break;case 62:i.addNote(a[u]);break;case 63:this.$=a[u-2],i.defineClass(a[u-1],a[u]);break;case 65:this.$=a[u-2].concat([a[u]]);break;case 66:i.setDirection("TB");break;case 67:i.setDirection("BT");break;case 68:i.setDirection("RL");break;case 69:i.setDirection("LR");break;case 70:this.$={type1:a[u-2],type2:a[u],lineType:a[u-1]};break;case 71:this.$={type1:"none",type2:a[u],lineType:a[u-1]};break;case 72:this.$={type1:a[u-1],type2:"none",lineType:a[u]};break;case 73:this.$={type1:"none",type2:"none",lineType:a[u]};break;case 74:this.$=i.relationType.AGGREGATION;break;case 75:this.$=i.relationType.EXTENSION;break;case 76:this.$=i.relationType.COMPOSITION;break;case 77:this.$=i.relationType.DEPENDENCY;break;case 78:this.$=i.relationType.LOLLIPOP;break;case 79:this.$=i.lineType.LINE;break;case 80:this.$=i.lineType.DOTTED_LINE;break;case 81:case 87:this.$=a[u-2],i.setClickEvent(a[u-1],a[u]);break;case 82:case 88:this.$=a[u-3],i.setClickEvent(a[u-2],a[u-1]),i.setTooltip(a[u-2],a[u]);break;case 83:this.$=a[u-2],i.setLink(a[u-1],a[u]);break;case 84:this.$=a[u-3],i.setLink(a[u-2],a[u-1],a[u]);break;case 85:this.$=a[u-3],i.setLink(a[u-2],a[u-1]),i.setTooltip(a[u-2],a[u]);break;case 86:this.$=a[u-4],i.setLink(a[u-3],a[u-2],a[u]),i.setTooltip(a[u-3],a[u-1]);break;case 89:this.$=a[u-3],i.setClickEvent(a[u-2],a[u-1],a[u]);break;case 90:this.$=a[u-4],i.setClickEvent(a[u-3],a[u-2],a[u-1]),i.setTooltip(a[u-3],a[u]);break;case 91:this.$=a[u-3],i.setLink(a[u-2],a[u]);break;case 92:this.$=a[u-4],i.setLink(a[u-3],a[u-1],a[u]);break;case 93:this.$=a[u-4],i.setLink(a[u-3],a[u-1]),i.setTooltip(a[u-3],a[u]);break;case 94:this.$=a[u-5],i.setLink(a[u-4],a[u-2],a[u]),i.setTooltip(a[u-4],a[u-1]);break;case 95:this.$=a[u-2],i.setCssStyle(a[u-1],a[u]);break;case 96:i.setCssClass(a[u-1],a[u]);break;case 98:a[u-2].push(a[u]),this.$=a[u-2]}},"anonymous"),table:[{3:1,4:2,5:3,6:4,7:[1,6],10:5,16:39,17:40,19:21,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,33:e,35:s,37:i,38:22,42:n,43:23,46:a,49:r,51:u,52:l,54:c,56:h,57:d,60:p,62:A,63:y,64:g,65:C,75:m,76:b,78:E,82:T,83:k,86:f,100:D,102:F,103:B},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,3]},t(_,[2,5],{8:[1,48]}),{8:[1,49]},t(S,[2,19],{22:[1,50]}),t(S,[2,21]),t(S,[2,22]),t(S,[2,23]),t(S,[2,24]),t(S,[2,25]),t(S,[2,26]),t(S,[2,27]),t(S,[2,28]),t(S,[2,29]),t(S,[2,30]),{34:[1,51]},{36:[1,52]},t(S,[2,33]),t(S,[2,53],{53:53,66:56,67:57,13:[1,54],22:[1,55],68:N,69:L,70:$,71:x,72:v,73:I,74:O}),{39:[1,65]},t(w,[2,40],{39:[1,67],44:[1,66]}),t(S,[2,55]),t(S,[2,56]),{16:68,60:p,86:f,100:D,102:F},{16:39,17:40,19:69,60:p,86:f,100:D,102:F,103:B},{16:39,17:40,19:70,60:p,86:f,100:D,102:F,103:B},{16:39,17:40,19:71,60:p,86:f,100:D,102:F,103:B},{60:[1,72]},{13:[1,73]},{16:39,17:40,19:74,60:p,86:f,100:D,102:F,103:B},{13:R,55:75},{58:77,60:[1,78]},t(S,[2,66]),t(S,[2,67]),t(S,[2,68]),t(S,[2,69]),t(P,[2,13],{16:39,17:40,19:80,18:[1,79],20:[1,81],60:p,86:f,100:D,102:F,103:B}),t(P,[2,15],{20:[1,82]}),{15:83,16:84,17:85,60:p,86:f,100:D,102:F,103:B},{16:39,17:40,19:86,60:p,86:f,100:D,102:F,103:B},t(K,[2,123]),t(K,[2,124]),t(K,[2,125]),t(K,[2,126]),t([1,8,9,12,13,20,22,39,41,44,68,69,70,71,72,73,74,79,81],[2,127]),t(_,[2,6],{10:5,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,19:21,38:22,43:23,16:39,17:40,5:87,33:e,35:s,37:i,42:n,46:a,49:r,51:u,52:l,54:c,56:h,57:d,60:p,62:A,63:y,64:g,65:C,75:m,76:b,78:E,82:T,83:k,86:f,100:D,102:F,103:B}),{5:88,10:5,16:39,17:40,19:21,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,33:e,35:s,37:i,38:22,42:n,43:23,46:a,49:r,51:u,52:l,54:c,56:h,57:d,60:p,62:A,63:y,64:g,65:C,75:m,76:b,78:E,82:T,83:k,86:f,100:D,102:F,103:B},t(S,[2,20]),t(S,[2,31]),t(S,[2,32]),{13:[1,90],16:39,17:40,19:89,60:p,86:f,100:D,102:F,103:B},{53:91,66:56,67:57,68:N,69:L,70:$,71:x,72:v,73:I,74:O},t(S,[2,54]),{67:92,73:I,74:O},t(M,[2,73],{66:93,68:N,69:L,70:$,71:x,72:v}),t(G,[2,74]),t(G,[2,75]),t(G,[2,76]),t(G,[2,77]),t(G,[2,78]),t(U,[2,79]),t(U,[2,80]),{8:[1,95],24:96,40:94,43:23,46:a},{16:97,60:p,86:f,100:D,102:F},{41:[1,99],45:98,51:Y},{50:[1,101]},{13:[1,102]},{13:[1,103]},{79:[1,104],81:[1,105]},{22:z,48:Q,59:106,60:W,82:X,84:107,85:108,86:j,87:V,88:q,89:H,90:J},{60:[1,118]},{13:R,55:119},t(S,[2,62]),t(S,[2,128]),{22:z,48:Q,59:120,60:W,61:[1,121],82:X,84:107,85:108,86:j,87:V,88:q,89:H,90:J},t(Z,[2,64]),{16:39,17:40,19:122,60:p,86:f,100:D,102:F,103:B},t(P,[2,16]),t(P,[2,17]),t(P,[2,18]),{39:[2,36]},{15:124,16:84,17:85,18:[1,123],39:[2,9],60:p,86:f,100:D,102:F,103:B},{39:[2,10]},t(tt,[2,45],{11:125,12:[1,126]}),t(_,[2,7]),{9:[1,127]},t(et,[2,57]),{16:39,17:40,19:128,60:p,86:f,100:D,102:F,103:B},{13:[1,130],16:39,17:40,19:129,60:p,86:f,100:D,102:F,103:B},t(M,[2,72],{66:131,68:N,69:L,70:$,71:x,72:v}),t(M,[2,71]),{41:[1,132]},{24:96,40:133,43:23,46:a},{8:[1,134],41:[2,37]},t(w,[2,41],{39:[1,135]}),{41:[1,136]},t(w,[2,43]),{41:[2,51],45:137,51:Y},{16:39,17:40,19:138,60:p,86:f,100:D,102:F,103:B},t(S,[2,81],{13:[1,139]}),t(S,[2,83],{13:[1,141],77:[1,140]}),t(S,[2,87],{13:[1,142],80:[1,143]}),{13:[1,144]},t(S,[2,95],{61:st}),t(it,[2,97],{85:146,22:z,48:Q,60:W,82:X,86:j,87:V,88:q,89:H,90:J}),t(nt,[2,99]),t(nt,[2,101]),t(nt,[2,102]),t(nt,[2,103]),t(nt,[2,104]),t(nt,[2,105]),t(nt,[2,106]),t(nt,[2,107]),t(nt,[2,108]),t(nt,[2,109]),t(S,[2,96]),t(S,[2,61]),t(S,[2,63],{61:st}),{60:[1,147]},t(P,[2,14]),{15:148,16:84,17:85,60:p,86:f,100:D,102:F,103:B},{39:[2,12]},t(tt,[2,46]),{13:[1,149]},{1:[2,4]},t(et,[2,59]),t(et,[2,58]),{16:39,17:40,19:150,60:p,86:f,100:D,102:F,103:B},t(M,[2,70]),t(S,[2,34]),{41:[1,151]},{24:96,40:152,41:[2,38],43:23,46:a},{45:153,51:Y},t(w,[2,42]),{41:[2,52]},t(S,[2,50]),t(S,[2,82]),t(S,[2,84]),t(S,[2,85],{77:[1,154]}),t(S,[2,88]),t(S,[2,89],{13:[1,155]}),t(S,[2,91],{13:[1,157],77:[1,156]}),{22:z,48:Q,60:W,82:X,84:158,85:108,86:j,87:V,88:q,89:H,90:J},t(nt,[2,100]),t(Z,[2,65]),{39:[2,11]},{14:[1,159]},t(et,[2,60]),t(S,[2,35]),{41:[2,39]},{41:[1,160]},t(S,[2,86]),t(S,[2,90]),t(S,[2,92]),t(S,[2,93],{77:[1,161]}),t(it,[2,98],{85:146,22:z,48:Q,60:W,82:X,86:j,87:V,88:q,89:H,90:J}),t(tt,[2,8]),t(w,[2,44]),t(S,[2,94])],defaultActions:{2:[2,1],3:[2,2],4:[2,3],83:[2,36],85:[2,10],124:[2,12],127:[2,4],137:[2,52],148:[2,11],152:[2,39]},parseError:(0,o.K2)(function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)},"parseError"),parse:(0,o.K2)(function(t){var e=this,s=[0],i=[],n=[null],a=[],r=this.table,u="",l=0,c=0,h=0,d=a.slice.call(arguments,1),p=Object.create(this.lexer),A={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(A.yy[y]=this.yy[y]);p.setInput(t,A.yy),A.yy.lexer=p,A.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var g=p.yylloc;a.push(g);var C=p.options&&p.options.ranges;function m(){var t;return"number"!=typeof(t=i.pop()||p.lex()||1)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof A.yy.parseError?this.parseError=A.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,o.K2)(function(t){s.length=s.length-2*t,n.length=n.length-t,a.length=a.length-t},"popStack"),(0,o.K2)(m,"lex");for(var b,E,T,k,f,D,F,B,_,S={};;){if(T=s[s.length-1],this.defaultActions[T]?k=this.defaultActions[T]:(null==b&&(b=m()),k=r[T]&&r[T][b]),void 0===k||!k.length||!k[0]){var N="";for(D in _=[],r[T])this.terminals_[D]&&D>2&&_.push("'"+this.terminals_[D]+"'");N=p.showPosition?"Parse error on line "+(l+1)+":\n"+p.showPosition()+"\nExpecting "+_.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(N,{text:p.match,token:this.terminals_[b]||b,line:p.yylineno,loc:g,expected:_})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+T+", token: "+b);switch(k[0]){case 1:s.push(b),n.push(p.yytext),a.push(p.yylloc),s.push(k[1]),b=null,E?(b=E,E=null):(c=p.yyleng,u=p.yytext,l=p.yylineno,g=p.yylloc,h>0&&h--);break;case 2:if(F=this.productions_[k[1]][1],S.$=n[n.length-F],S._$={first_line:a[a.length-(F||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(F||1)].first_column,last_column:a[a.length-1].last_column},C&&(S._$.range=[a[a.length-(F||1)].range[0],a[a.length-1].range[1]]),void 0!==(f=this.performAction.apply(S,[u,c,l,A.yy,k[1],n,a].concat(d))))return f;F&&(s=s.slice(0,-1*F*2),n=n.slice(0,-1*F),a=a.slice(0,-1*F)),s.push(this.productions_[k[1]][0]),n.push(S.$),a.push(S._$),B=r[s[s.length-2]][s[s.length-1]],s.push(B);break;case 3:return!0}}return!0},"parse")},rt=function(){return{EOF:1,parseError:(0,o.K2)(function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},"parseError"),setInput:(0,o.K2)(function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:(0,o.K2)(function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},"input"),unput:(0,o.K2)(function(t){var e=t.length,s=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),s.length-1&&(this.yylineno-=s.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:s?(s.length===i.length?this.yylloc.first_column:0)+i[i.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},"unput"),more:(0,o.K2)(function(){return this._more=!0,this},"more"),reject:(0,o.K2)(function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"reject"),less:(0,o.K2)(function(t){this.unput(this.match.slice(t))},"less"),pastInput:(0,o.K2)(function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:(0,o.K2)(function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:(0,o.K2)(function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},"showPosition"),test_match:(0,o.K2)(function(t,e){var s,i,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var a in n)this[a]=n[a];return!1}return!1},"test_match"),next:(0,o.K2)(function(){if(this.done)return this.EOF;var t,e,s,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),a=0;ae[0].length)){if(e=s,i=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,n[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,n[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:(0,o.K2)(function(){var t=this.next();return t||this.lex()},"lex"),begin:(0,o.K2)(function(t){this.conditionStack.push(t)},"begin"),popState:(0,o.K2)(function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:(0,o.K2)(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:(0,o.K2)(function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},"topState"),pushState:(0,o.K2)(function(t){this.begin(t)},"pushState"),stateStackSize:(0,o.K2)(function(){return this.conditionStack.length},"stateStackSize"),options:{},performAction:(0,o.K2)(function(t,e,s,i){switch(s){case 0:return 62;case 1:return 63;case 2:return 64;case 3:return 65;case 4:case 5:case 14:case 31:case 36:case 40:case 47:break;case 6:return this.begin("acc_title"),33;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),35;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 19:case 22:case 24:case 58:case 61:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:case 35:return 8;case 15:case 16:return 7;case 17:case 37:case 45:return"EDGE_STATE";case 18:this.begin("callback_name");break;case 20:this.popState(),this.begin("callback_args");break;case 21:return 79;case 23:return 80;case 25:return"STR";case 26:this.begin("string");break;case 27:return 82;case 28:return 57;case 29:return this.begin("namespace"),42;case 30:case 39:return this.popState(),8;case 32:return this.begin("namespace-body"),39;case 33:case 43:return this.popState(),41;case 34:case 44:return"EOF_IN_STRUCT";case 38:return this.begin("class"),46;case 41:return this.popState(),this.popState(),41;case 42:return this.begin("class-body"),39;case 46:return"OPEN_IN_STRUCT";case 48:return"MEMBER";case 49:return 83;case 50:return 75;case 51:return 76;case 52:return 78;case 53:return 54;case 54:return 56;case 55:return 49;case 56:return 50;case 57:return 81;case 59:return"GENERICTYPE";case 60:this.begin("generic");break;case 62:return"BQUOTE_STR";case 63:this.begin("bqstring");break;case 64:case 65:case 66:case 67:return 77;case 68:case 69:return 69;case 70:case 71:return 71;case 72:return 70;case 73:return 68;case 74:return 72;case 75:return 73;case 76:return 74;case 77:return 22;case 78:return 44;case 79:return 100;case 80:return 18;case 81:return"PLUS";case 82:return 87;case 83:return 61;case 84:case 85:return 89;case 86:return 90;case 87:case 88:return"EQUALS";case 89:return 60;case 90:return 12;case 91:return 14;case 92:return"PUNCTUATION";case 93:return 86;case 94:return 102;case 95:case 96:return 48;case 97:return 9}},"anonymous"),rules:[/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:classDiagram-v2\b)/,/^(?:classDiagram\b)/,/^(?:\[\*\])/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:["])/,/^(?:[^"]*)/,/^(?:["])/,/^(?:style\b)/,/^(?:classDef\b)/,/^(?:namespace\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:\[\*\])/,/^(?:class\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[}])/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\[\*\])/,/^(?:[{])/,/^(?:[\n])/,/^(?:[^{}\n]*)/,/^(?:cssClass\b)/,/^(?:callback\b)/,/^(?:link\b)/,/^(?:click\b)/,/^(?:note for\b)/,/^(?:note\b)/,/^(?:<<)/,/^(?:>>)/,/^(?:href\b)/,/^(?:[~])/,/^(?:[^~]*)/,/^(?:~)/,/^(?:[`])/,/^(?:[^`]+)/,/^(?:[`])/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:\s*<\|)/,/^(?:\s*\|>)/,/^(?:\s*>)/,/^(?:\s*<)/,/^(?:\s*\*)/,/^(?:\s*o\b)/,/^(?:\s*\(\))/,/^(?:--)/,/^(?:\.\.)/,/^(?::{1}[^:\n;]+)/,/^(?::{3})/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?::)/,/^(?:,)/,/^(?:#)/,/^(?:#)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:\w+)/,/^(?:\[)/,/^(?:\])/,/^(?:[!"#$%&'*+,-.`?\\/])/,/^(?:[0-9]+)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\s)/,/^(?:\s)/,/^(?:$)/],conditions:{"namespace-body":{rules:[26,33,34,35,36,37,38,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},namespace:{rules:[26,29,30,31,32,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},"class-body":{rules:[26,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},class:{rules:[26,39,40,41,42,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},acc_descr_multiline:{rules:[11,12,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},acc_descr:{rules:[9,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},acc_title:{rules:[7,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},callback_args:{rules:[22,23,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},callback_name:{rules:[19,20,21,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},href:{rules:[26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},struct:{rules:[26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},generic:{rules:[26,49,50,51,52,53,54,55,56,57,58,59,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},bqstring:{rules:[26,49,50,51,52,53,54,55,56,57,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},string:{rules:[24,25,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,8,10,13,14,15,16,17,18,26,27,28,29,38,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!0}}}}();function ut(){this.yy={}}return at.lexer=rt,(0,o.K2)(ut,"Parser"),ut.prototype=at,at.Parser=ut,new ut}();h.parser=h;var d=h,p=["#","+","~","-",""],A=class{static{(0,o.K2)(this,"ClassMember")}constructor(t,e){this.memberType=e,this.visibility="",this.classifier="",this.text="";const s=(0,l.jZ)(t,(0,l.D7)());this.parseMember(s)}getDisplayDetails(){let t=this.visibility+(0,l.QO)(this.id);"method"===this.memberType&&(t+=`(${(0,l.QO)(this.parameters.trim())})`,this.returnType&&(t+=" : "+(0,l.QO)(this.returnType))),t=t.trim();return{displayText:t,cssStyle:this.parseClassifier()}}parseMember(t){let e="";if("method"===this.memberType){const s=/([#+~-])?(.+)\((.*)\)([\s$*])?(.*)([$*])?/.exec(t);if(s){const t=s[1]?s[1].trim():"";if(p.includes(t)&&(this.visibility=t),this.id=s[2],this.parameters=s[3]?s[3].trim():"",e=s[4]?s[4].trim():"",this.returnType=s[5]?s[5].trim():"",""===e){const t=this.returnType.substring(this.returnType.length-1);/[$*]/.exec(t)&&(e=t,this.returnType=this.returnType.substring(0,this.returnType.length-1))}}}else{const s=t.length,i=t.substring(0,1),n=t.substring(s-1);p.includes(i)&&(this.visibility=i),/[$*]/.exec(n)&&(e=n),this.id=t.substring(""===this.visibility?0:1,""===e?s:s-1)}this.classifier=e,this.id=this.id.startsWith(" ")?" "+this.id.trim():this.id.trim();const s=`${this.visibility?"\\"+this.visibility:""}${(0,l.QO)(this.id)}${"method"===this.memberType?`(${(0,l.QO)(this.parameters)})${this.returnType?" : "+(0,l.QO)(this.returnType):""}`:""}`;this.text=s.replaceAll("<","<").replaceAll(">",">"),this.text.startsWith("\\<")&&(this.text=this.text.replace("\\<","~"))}parseClassifier(){switch(this.classifier){case"*":return"font-style:italic;";case"$":return"text-decoration:underline;";default:return""}}},y="classId-",g=0,C=(0,o.K2)(t=>l.Y2.sanitizeText(t,(0,l.D7)()),"sanitizeText"),m=class{constructor(){this.relations=[],this.classes=new Map,this.styleClasses=new Map,this.notes=[],this.interfaces=[],this.namespaces=new Map,this.namespaceCounter=0,this.functions=[],this.lineType={LINE:0,DOTTED_LINE:1},this.relationType={AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3,LOLLIPOP:4},this.setupToolTips=(0,o.K2)(t=>{let e=(0,c.Ltv)(".mermaidTooltip");null===(e._groups||e)[0][0]&&(e=(0,c.Ltv)("body").append("div").attr("class","mermaidTooltip").style("opacity",0));(0,c.Ltv)(t).select("svg").selectAll("g.node").on("mouseover",t=>{const s=(0,c.Ltv)(t.currentTarget);if(null===s.attr("title"))return;const i=this.getBoundingClientRect();e.transition().duration(200).style("opacity",".9"),e.text(s.attr("title")).style("left",window.scrollX+i.left+(i.right-i.left)/2+"px").style("top",window.scrollY+i.top-14+document.body.scrollTop+"px"),e.html(e.html().replace(/<br\/>/g,"
    ")),s.classed("hover",!0)}).on("mouseout",t=>{e.transition().duration(500).style("opacity",0);(0,c.Ltv)(t.currentTarget).classed("hover",!1)})},"setupToolTips"),this.direction="TB",this.setAccTitle=l.SV,this.getAccTitle=l.iN,this.setAccDescription=l.EI,this.getAccDescription=l.m7,this.setDiagramTitle=l.ke,this.getDiagramTitle=l.ab,this.getConfig=(0,o.K2)(()=>(0,l.D7)().class,"getConfig"),this.functions.push(this.setupToolTips.bind(this)),this.clear(),this.addRelation=this.addRelation.bind(this),this.addClassesToNamespace=this.addClassesToNamespace.bind(this),this.addNamespace=this.addNamespace.bind(this),this.setCssClass=this.setCssClass.bind(this),this.addMembers=this.addMembers.bind(this),this.addClass=this.addClass.bind(this),this.setClassLabel=this.setClassLabel.bind(this),this.addAnnotation=this.addAnnotation.bind(this),this.addMember=this.addMember.bind(this),this.cleanupLabel=this.cleanupLabel.bind(this),this.addNote=this.addNote.bind(this),this.defineClass=this.defineClass.bind(this),this.setDirection=this.setDirection.bind(this),this.setLink=this.setLink.bind(this),this.bindFunctions=this.bindFunctions.bind(this),this.clear=this.clear.bind(this),this.setTooltip=this.setTooltip.bind(this),this.setClickEvent=this.setClickEvent.bind(this),this.setCssStyle=this.setCssStyle.bind(this)}static{(0,o.K2)(this,"ClassDB")}splitClassNameAndType(t){const e=l.Y2.sanitizeText(t,(0,l.D7)());let s="",i=e;if(e.indexOf("~")>0){const t=e.split("~");i=C(t[0]),s=C(t[1])}return{className:i,type:s}}setClassLabel(t,e){const s=l.Y2.sanitizeText(t,(0,l.D7)());e&&(e=C(e));const{className:i}=this.splitClassNameAndType(s);this.classes.get(i).label=e,this.classes.get(i).text=`${e}${this.classes.get(i).type?`<${this.classes.get(i).type}>`:""}`}addClass(t){const e=l.Y2.sanitizeText(t,(0,l.D7)()),{className:s,type:i}=this.splitClassNameAndType(e);if(this.classes.has(s))return;const n=l.Y2.sanitizeText(s,(0,l.D7)());this.classes.set(n,{id:n,type:i,label:n,text:`${n}${i?`<${i}>`:""}`,shape:"classBox",cssClasses:"default",methods:[],members:[],annotations:[],styles:[],domId:y+n+"-"+g}),g++}addInterface(t,e){const s={id:`interface${this.interfaces.length}`,label:t,classId:e};this.interfaces.push(s)}lookUpDomId(t){const e=l.Y2.sanitizeText(t,(0,l.D7)());if(this.classes.has(e))return this.classes.get(e).domId;throw new Error("Class not found: "+e)}clear(){this.relations=[],this.classes=new Map,this.notes=[],this.interfaces=[],this.functions=[],this.functions.push(this.setupToolTips.bind(this)),this.namespaces=new Map,this.namespaceCounter=0,this.direction="TB",(0,l.IU)()}getClass(t){return this.classes.get(t)}getClasses(){return this.classes}getRelations(){return this.relations}getNotes(){return this.notes}addRelation(t){o.Rm.debug("Adding relation: "+JSON.stringify(t));const e=[this.relationType.LOLLIPOP,this.relationType.AGGREGATION,this.relationType.COMPOSITION,this.relationType.DEPENDENCY,this.relationType.EXTENSION];t.relation.type1!==this.relationType.LOLLIPOP||e.includes(t.relation.type2)?t.relation.type2!==this.relationType.LOLLIPOP||e.includes(t.relation.type1)?(this.addClass(t.id1),this.addClass(t.id2)):(this.addClass(t.id1),this.addInterface(t.id2,t.id1),t.id2="interface"+(this.interfaces.length-1)):(this.addClass(t.id2),this.addInterface(t.id1,t.id2),t.id1="interface"+(this.interfaces.length-1)),t.id1=this.splitClassNameAndType(t.id1).className,t.id2=this.splitClassNameAndType(t.id2).className,t.relationTitle1=l.Y2.sanitizeText(t.relationTitle1.trim(),(0,l.D7)()),t.relationTitle2=l.Y2.sanitizeText(t.relationTitle2.trim(),(0,l.D7)()),this.relations.push(t)}addAnnotation(t,e){const s=this.splitClassNameAndType(t).className;this.classes.get(s).annotations.push(e)}addMember(t,e){this.addClass(t);const s=this.splitClassNameAndType(t).className,i=this.classes.get(s);if("string"==typeof e){const t=e.trim();t.startsWith("<<")&&t.endsWith(">>")?i.annotations.push(C(t.substring(2,t.length-2))):t.indexOf(")")>0?i.methods.push(new A(t,"method")):t&&i.members.push(new A(t,"attribute"))}}addMembers(t,e){Array.isArray(e)&&(e.reverse(),e.forEach(e=>this.addMember(t,e)))}addNote(t,e){const s={id:`note${this.notes.length}`,class:e,text:t};this.notes.push(s)}cleanupLabel(t){return t.startsWith(":")&&(t=t.substring(1)),C(t.trim())}setCssClass(t,e){t.split(",").forEach(t=>{let s=t;/\d/.exec(t[0])&&(s=y+s);const i=this.classes.get(s);i&&(i.cssClasses+=" "+e)})}defineClass(t,e){for(const s of t){let t=this.styleClasses.get(s);void 0===t&&(t={id:s,styles:[],textStyles:[]},this.styleClasses.set(s,t)),e&&e.forEach(e=>{if(/color/.exec(e)){const s=e.replace("fill","bgFill");t.textStyles.push(s)}t.styles.push(e)}),this.classes.forEach(t=>{t.cssClasses.includes(s)&&t.styles.push(...e.flatMap(t=>t.split(",")))})}}setTooltip(t,e){t.split(",").forEach(t=>{void 0!==e&&(this.classes.get(t).tooltip=C(e))})}getTooltip(t,e){return e&&this.namespaces.has(e)?this.namespaces.get(e).classes.get(t).tooltip:this.classes.get(t).tooltip}setLink(t,e,s){const i=(0,l.D7)();t.split(",").forEach(t=>{let n=t;/\d/.exec(t[0])&&(n=y+n);const a=this.classes.get(n);a&&(a.link=u._K.formatUrl(e,i),"sandbox"===i.securityLevel?a.linkTarget="_top":a.linkTarget="string"==typeof s?C(s):"_blank")}),this.setCssClass(t,"clickable")}setClickEvent(t,e,s){t.split(",").forEach(t=>{this.setClickFunc(t,e,s),this.classes.get(t).haveCallback=!0}),this.setCssClass(t,"clickable")}setClickFunc(t,e,s){const i=l.Y2.sanitizeText(t,(0,l.D7)());if("loose"!==(0,l.D7)().securityLevel)return;if(void 0===e)return;const n=i;if(this.classes.has(n)){const t=this.lookUpDomId(n);let i=[];if("string"==typeof s){i=s.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t{const s=document.querySelector(`[id="${t}"]`);null!==s&&s.addEventListener("click",()=>{u._K.runFunc(e,...i)},!1)})}}bindFunctions(t){this.functions.forEach(e=>{e(t)})}getDirection(){return this.direction}setDirection(t){this.direction=t}addNamespace(t){this.namespaces.has(t)||(this.namespaces.set(t,{id:t,classes:new Map,children:{},domId:y+t+"-"+this.namespaceCounter}),this.namespaceCounter++)}getNamespace(t){return this.namespaces.get(t)}getNamespaces(){return this.namespaces}addClassesToNamespace(t,e){if(this.namespaces.has(t))for(const s of e){const{className:e}=this.splitClassNameAndType(s);this.classes.get(e).parent=t,this.namespaces.get(t).classes.set(e,this.classes.get(e))}}setCssStyle(t,e){const s=this.classes.get(t);if(e&&s)for(const i of e)i.includes(",")?s.styles.push(...i.split(",")):s.styles.push(i)}getArrowMarker(t){let e;switch(t){case 0:e="aggregation";break;case 1:e="extension";break;case 2:e="composition";break;case 3:e="dependency";break;case 4:e="lollipop";break;default:e="none"}return e}getData(){const t=[],e=[],s=(0,l.D7)();for(const n of this.namespaces.keys()){const e=this.namespaces.get(n);if(e){const i={id:e.id,label:e.id,isGroup:!0,padding:s.class.padding??16,shape:"rect",cssStyles:["fill: none","stroke: black"],look:s.look};t.push(i)}}for(const n of this.classes.keys()){const e=this.classes.get(n);if(e){const i=e;i.parentId=e.parent,i.look=s.look,t.push(i)}}let i=0;for(const n of this.notes){i++;const a={id:n.id,label:n.text,isGroup:!1,shape:"note",padding:s.class.padding??6,cssStyles:["text-align: left","white-space: nowrap",`fill: ${s.themeVariables.noteBkgColor}`,`stroke: ${s.themeVariables.noteBorderColor}`],look:s.look};t.push(a);const r=this.classes.get(n.class)?.id??"";if(r){const t={id:`edgeNote${i}`,start:n.id,end:r,type:"normal",thickness:"normal",classes:"relation",arrowTypeStart:"none",arrowTypeEnd:"none",arrowheadStyle:"",labelStyle:[""],style:["fill: none"],pattern:"dotted",look:s.look};e.push(t)}}for(const n of this.interfaces){const e={id:n.id,label:n.label,isGroup:!1,shape:"rect",cssStyles:["opacity: 0;"],look:s.look};t.push(e)}i=0;for(const n of this.relations){i++;const t={id:(0,u.rY)(n.id1,n.id2,{prefix:"id",counter:i}),start:n.id1,end:n.id2,type:"normal",label:n.title,labelpos:"c",thickness:"normal",classes:"relation",arrowTypeStart:this.getArrowMarker(n.relation.type1),arrowTypeEnd:this.getArrowMarker(n.relation.type2),startLabelRight:"none"===n.relationTitle1?"":n.relationTitle1,endLabelLeft:"none"===n.relationTitle2?"":n.relationTitle2,arrowheadStyle:"",labelStyle:["display: inline-block"],style:n.style||"",pattern:1==n.relation.lineType?"dashed":"solid",look:s.look};e.push(t)}return{nodes:t,edges:e,other:{},config:s,direction:this.getDirection()}}},b=(0,o.K2)(t=>`g.classGroup text {\n fill: ${t.nodeBorder||t.classText};\n stroke: none;\n font-family: ${t.fontFamily};\n font-size: 10px;\n\n .title {\n font-weight: bolder;\n }\n\n}\n\n.nodeLabel, .edgeLabel {\n color: ${t.classText};\n}\n.edgeLabel .label rect {\n fill: ${t.mainBkg};\n}\n.label text {\n fill: ${t.classText};\n}\n\n.labelBkg {\n background: ${t.mainBkg};\n}\n.edgeLabel .label span {\n background: ${t.mainBkg};\n}\n\n.classTitle {\n font-weight: bolder;\n}\n.node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n\n.divider {\n stroke: ${t.nodeBorder};\n stroke-width: 1;\n}\n\ng.clickable {\n cursor: pointer;\n}\n\ng.classGroup rect {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n}\n\ng.classGroup line {\n stroke: ${t.nodeBorder};\n stroke-width: 1;\n}\n\n.classLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${t.mainBkg};\n opacity: 0.5;\n}\n\n.classLabel .label {\n fill: ${t.nodeBorder};\n font-size: 10px;\n}\n\n.relation {\n stroke: ${t.lineColor};\n stroke-width: 1;\n fill: none;\n}\n\n.dashed-line{\n stroke-dasharray: 3;\n}\n\n.dotted-line{\n stroke-dasharray: 1 2;\n}\n\n#compositionStart, .composition {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#compositionEnd, .composition {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionStart, .extension {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionEnd, .extension {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationStart, .aggregation {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationEnd, .aggregation {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopStart, .lollipop {\n fill: ${t.mainBkg} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopEnd, .lollipop {\n fill: ${t.mainBkg} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n.edgeTerminals {\n font-size: 11px;\n line-height: initial;\n}\n\n.classTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n}\n ${(0,i.o)()}\n`,"getStyles"),E=(0,o.K2)((t,e="TB")=>{if(!t.doc)return e;let s=e;for(const i of t.doc)"dir"===i.stmt&&(s=i.value);return s},"getDir"),T={getClasses:(0,o.K2)(function(t,e){return e.db.getClasses()},"getClasses"),draw:(0,o.K2)(async function(t,e,s,i){o.Rm.info("REF0:"),o.Rm.info("Drawing class diagram (v3)",e);const{securityLevel:c,state:h,layout:d}=(0,l.D7)(),p=i.db.getData(),A=(0,n.A)(e,c);p.type=i.type,p.layoutAlgorithm=(0,r.q7)(d),p.nodeSpacing=h?.nodeSpacing||50,p.rankSpacing=h?.rankSpacing||50,p.markers=["aggregation","extension","composition","dependency","lollipop"],p.diagramId=e,await(0,r.XX)(p,A);u._K.insertTitle(A,"classDiagramTitleText",h?.titleTopMargin??25,i.db.getDiagramTitle()),(0,a.P)(A,8,"classDiagram",h?.useMaxWidth??!0)},"draw"),getDir:E}},89625:(t,e,s)=>{s.d(e,{A:()=>a});var i=s(40797),n=s(70451),a=(0,i.K2)((t,e)=>{let s;"sandbox"===e&&(s=(0,n.Ltv)("#i"+t));return("sandbox"===e?(0,n.Ltv)(s.nodes()[0].contentDocument.body):(0,n.Ltv)("body")).select(`[id="${t}"]`)},"getDiagramElement")}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/17896441.bf9de707.js b/pr-preview/pr-4027/assets/js/17896441.bf9de707.js deleted file mode 100644 index 9587ef169..000000000 --- a/pr-preview/pr-4027/assets/js/17896441.bf9de707.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8401],{67569:(s,e,c)=>{c.d(e,{A:()=>d});var a=c(96540),n=c(18073),i=c(49489),t=c(7227),l=c(29813),o=c(74848);const r=({src:s,...e})=>(0,o.jsx)(l.A,{fallback:(0,o.jsx)("div",{children:"Loading asciinema cast..."}),children:()=>{const n=c(30459),i=(0,a.useRef)(null);return(0,a.useEffect)(()=>{n.create(s,i.current,e)},[s]),(0,o.jsx)("div",{ref:i})}}),d={...n.A,Tabs:i.A,TabItem:t.A,AsciinemaWidget:r}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/179.98ad7c3b.js b/pr-preview/pr-4027/assets/js/179.98ad7c3b.js deleted file mode 100644 index 1f68195d9..000000000 --- a/pr-preview/pr-4027/assets/js/179.98ad7c3b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[179],{72560:(e,t,n)=>{n.r(t),n.d(t,{default:()=>r});n(96540);var o=n(23230),i=n(17153),s=n(86185),a=n(83510),l=n(74848);function r(){const e=(0,o.T)({id:"theme.NotFound.title",message:"Page Not Found"});return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(i.be,{title:e}),(0,l.jsx)(s.A,{children:(0,l.jsx)(a.A,{})})]})}},83510:(e,t,n)=>{n.d(t,{A:()=>l});n(96540);var o=n(34164),i=n(23230),s=n(85225),a=n(74848);function l({className:e}){return(0,a.jsx)("main",{className:(0,o.A)("container margin-vert--xl",e),children:(0,a.jsx)("div",{className:"row",children:(0,a.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,a.jsx)(s.A,{as:"h1",className:"hero__title",children:(0,a.jsx)(i.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,a.jsx)("p",{children:(0,a.jsx)(i.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,a.jsx)("p",{children:(0,a.jsx)(i.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/1890268c.ccf2c28e.js b/pr-preview/pr-4027/assets/js/1890268c.ccf2c28e.js deleted file mode 100644 index 96e8c4a11..000000000 --- a/pr-preview/pr-4027/assets/js/1890268c.ccf2c28e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8488],{28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>a});var n=r(96540);const s={},i=n.createContext(s);function o(e){const t=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),n.createElement(i.Provider,{value:t},e.children)}},89691:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"architecture/orchestration","title":"Orchestrating Constellation clusters","description":"You can use the CLI to create a cluster on the supported cloud platforms.","source":"@site/versioned_docs/version-2.24/architecture/orchestration.md","sourceDirName":"architecture","slug":"/architecture/orchestration","permalink":"/constellation/pr-preview/pr-4027/architecture/orchestration","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/architecture/orchestration.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/constellation/pr-preview/pr-4027/architecture/overview"},"next":{"title":"Versions and support","permalink":"/constellation/pr-preview/pr-4027/architecture/versions"}}');var s=r(74848),i=r(28453);const o={},a="Orchestrating Constellation clusters",c={},l=[{value:"Workspaces",id:"workspaces",level:2},{value:"Cluster creation process",id:"cluster-creation-process",level:2},{value:"Creation process details",id:"creation-process-details",level:3},{value:"Post-installation configuration",id:"post-installation-configuration",level:2},{value:"Upgrades",id:"upgrades",level:2},{value:"Attestation of upgrades",id:"attestation-of-upgrades",level:3}];function h(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"orchestrating-constellation-clusters",children:"Orchestrating Constellation clusters"})}),"\n",(0,s.jsx)(t.p,{children:"You can use the CLI to create a cluster on the supported cloud platforms.\nThe CLI provisions the resources in your cloud environment and initiates the initialization of your cluster.\nIt uses a set of parameters and an optional configuration file to manage your cluster installation.\nThe CLI is also used for updating your cluster."}),"\n",(0,s.jsx)(t.h2,{id:"workspaces",children:"Workspaces"}),"\n",(0,s.jsxs)(t.p,{children:["Each Constellation cluster has an associated ",(0,s.jsx)(t.em,{children:"workspace"}),".\nThe workspace is where data such as the Constellation state and config files are stored.\nEach workspace is associated with a single cluster and configuration.\nThe CLI stores state in the local filesystem making the current directory the active workspace.\nMultiple clusters require multiple workspaces, hence, multiple directories.\nNote that every operation on a cluster always has to be performed from the directory associated with its workspace."]}),"\n",(0,s.jsx)(t.p,{children:"You may copy files from the workspace to other locations,\nbut you shouldn't move or delete them while the cluster is still being used.\nThe Constellation CLI takes care of managing the workspace.\nOnly when a cluster was terminated, and you are sure the files aren't needed anymore, should you remove a workspace."}),"\n",(0,s.jsx)(t.h2,{id:"cluster-creation-process",children:"Cluster creation process"}),"\n",(0,s.jsxs)(t.p,{children:["To allow for fine-grained configuration of your cluster and cloud environment, Constellation supports an extensive configuration file with strong defaults. ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/config",children:"Generating the configuration file"})," is typically the first thing you do in the workspace."]}),"\n",(0,s.jsx)(t.p,{children:"Altogether, the following files are generated during the creation of a Constellation cluster and stored in the current workspace:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"a configuration file"}),"\n",(0,s.jsx)(t.li,{children:"a state file"}),"\n",(0,s.jsx)(t.li,{children:"a Base64-encoded master secret"}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/reference/terraform",children:"Terraform artifacts"}),", stored in subdirectories"]}),"\n",(0,s.jsxs)(t.li,{children:["a Kubernetes ",(0,s.jsx)(t.code,{children:"kubeconfig"})," file."]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["After the initialization of your cluster, the CLI will provide you with a Kubernetes ",(0,s.jsx)(t.code,{children:"kubeconfig"})," file.\nThis file grants you access to your Kubernetes cluster and configures the ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/",children:"kubectl"})," tool.\nIn addition, the cluster's ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/orchestration#post-installation-configuration",children:"identifier"})," is returned and stored in the state file."]}),"\n",(0,s.jsx)(t.h3,{id:"creation-process-details",children:"Creation process details"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["The CLI ",(0,s.jsx)(t.code,{children:"apply"})," command first creates the confidential VM (CVM) resources in your cloud environment and configures the network"]}),"\n",(0,s.jsx)(t.li,{children:"Each CVM boots the Constellation node image and measures every component in the boot chain"}),"\n",(0,s.jsxs)(t.li,{children:["The first microservice launched in each node is the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#bootstrapper",children:(0,s.jsx)(t.em,{children:"Bootstrapper"})})]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"Bootstrapper"})," waits until it either receives an initialization request or discovers an initialized cluster"]}),"\n",(0,s.jsxs)(t.li,{children:["The CLI then connects to the ",(0,s.jsx)(t.em,{children:"Bootstrapper"})," of a selected node, sends the configuration, and initiates the initialization of the cluster"]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"Bootstrapper"})," of ",(0,s.jsx)(t.strong,{children:"that"})," node ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#bootstrapper",children:"initializes the Kubernetes cluster"})," and deploys the other Constellation ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices",children:"microservices"})," including the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#joinservice",children:(0,s.jsx)(t.em,{children:"JoinService"})})]}),"\n",(0,s.jsxs)(t.li,{children:["Subsequently, the ",(0,s.jsx)(t.em,{children:"Bootstrappers"})," of the other nodes discover the initialized cluster and send join requests to the ",(0,s.jsx)(t.em,{children:"JoinService"})]}),"\n",(0,s.jsx)(t.li,{children:"As part of the join request each node includes an attestation statement of its boot measurements as authentication"}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"JoinService"})," verifies the attestation statements and joins the nodes to the Kubernetes cluster"]}),"\n",(0,s.jsx)(t.li,{children:"This process is repeated for every node joining the cluster later (e.g., through autoscaling)"}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"post-installation-configuration",children:"Post-installation configuration"}),"\n",(0,s.jsxs)(t.p,{children:["Post-installation the CLI provides a configuration for ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-api/",children:"accessing the cluster using the Kubernetes API"}),".\nThe ",(0,s.jsx)(t.code,{children:"kubeconfig"})," file provides the credentials and configuration for connecting and authenticating to the API server.\nOnce configured, orchestrate the Kubernetes cluster via ",(0,s.jsx)(t.code,{children:"kubectl"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"After the initialization, the CLI will present you with a couple of tokens:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys#master-secret",children:(0,s.jsx)(t.em,{children:"master secret"})})," (stored in the ",(0,s.jsx)(t.code,{children:"constellation-mastersecret.json"})," file by default)"]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys#cluster-identity",children:(0,s.jsx)(t.em,{children:"clusterID"})})," of your cluster in Base64 encoding"]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["You can read more about these values and their meaning in the guide on ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys#cluster-identity",children:"cluster identity"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.em,{children:"master secret"})," must be kept secret and can be used to ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/recovery",children:"recover your cluster"}),".\nInstead of managing this secret manually, you can ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys#user-managed-key-management",children:"use your key management solution of choice"})," with Constellation."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.em,{children:"clusterID"})," uniquely identifies a cluster and can be used to ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/verify-cluster",children:"verify your cluster"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"upgrades",children:"Upgrades"}),"\n",(0,s.jsxs)(t.p,{children:["Constellation images and microservices may need to be upgraded to new versions during the lifetime of a cluster.\nConstellation implements a rolling update mechanism ensuring no downtime of the control or data plane.\nYou can upgrade a Constellation cluster with a single operation by using the CLI.\nFor step-by-step instructions on how to do this, refer to ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/upgrade",children:"Upgrade your cluster"}),"."]}),"\n",(0,s.jsx)(t.h3,{id:"attestation-of-upgrades",children:"Attestation of upgrades"}),"\n",(0,s.jsxs)(t.p,{children:["With every new image, corresponding measurements are released.\nDuring an update procedure, the CLI provides new measurements to the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#joinservice",children:"JoinService"})," securely.\nNew measurements for an updated image are automatically pulled and verified by the CLI following the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/attestation#chain-of-trust",children:"supply chain security concept"})," of Constellation.\nThe ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/attestation#cluster-facing-attestation",children:"attestation section"})," describes in detail how these measurements are then used by the JoinService for the attestation of nodes."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/1b80620b.8be59223.js b/pr-preview/pr-4027/assets/js/1b80620b.8be59223.js deleted file mode 100644 index a56d262f2..000000000 --- a/pr-preview/pr-4027/assets/js/1b80620b.8be59223.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3452],{20895:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"workflows/troubleshooting","title":"Troubleshooting","description":"This section aids you in finding problems when working with Constellation.","source":"@site/docs/workflows/troubleshooting.md","sourceDirName":"workflows","slug":"/workflows/troubleshooting","permalink":"/constellation/pr-preview/pr-4027/next/workflows/troubleshooting","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/workflows/troubleshooting.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Reproduce release artifacts","permalink":"/constellation/pr-preview/pr-4027/next/workflows/reproducible-builds"},"next":{"title":"Architecture","permalink":"/constellation/pr-preview/pr-4027/next/category/architecture"}}');var o=s(74848),i=s(28453);const r={},a="Troubleshooting",l={},c=[{value:"Common issues",id:"common-issues",level:2},{value:"Issues with creating new clusters",id:"issues-with-creating-new-clusters",level:3},{value:"Azure: Resource Providers can't be registered",id:"azure-resource-providers-cant-be-registered",level:3},{value:"Azure: Can't update attestation policy",id:"azure-cant-update-attestation-policy",level:3},{value:"Nodes fail to join with error untrusted measurement value",id:"nodes-fail-to-join-with-error-untrusted-measurement-value",level:3},{value:"Upgrading Kubernetes resources fails",id:"upgrading-kubernetes-resources-fails",level:3},{value:"Diagnosing issues",id:"diagnosing-issues",level:2},{value:"Logs",id:"logs",level:3},{value:"Node shell access",id:"node-shell-access",level:3},{value:"Emergency SSH access",id:"emergency-ssh-access",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"troubleshooting",children:"Troubleshooting"})}),"\n",(0,o.jsx)(n.p,{children:"This section aids you in finding problems when working with Constellation."}),"\n",(0,o.jsx)(n.h2,{id:"common-issues",children:"Common issues"}),"\n",(0,o.jsx)(n.h3,{id:"issues-with-creating-new-clusters",children:"Issues with creating new clusters"}),"\n",(0,o.jsxs)(n.p,{children:["When you create a new cluster, you should always use the ",(0,o.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/releases/latest",children:"latest release"}),".\nIf something doesn't work, check out the ",(0,o.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"known issues"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"azure-resource-providers-cant-be-registered",children:"Azure: Resource Providers can't be registered"}),"\n",(0,o.jsxs)(n.p,{children:["On Azure, you may receive the following error when running ",(0,o.jsx)(n.code,{children:"apply"})," or ",(0,o.jsx)(n.code,{children:"terminate"})," with limited IAM permissions:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-shell-session",children:"Error: Error ensuring Resource Providers are registered.\n\nTerraform automatically attempts to register the Resource Providers it supports to\nensure it's able to provision resources.\n\nIf you don't have permission to register Resource Providers you may wish to use the\n\"skip_provider_registration\" flag in the Provider block to disable this functionality.\n\n[...]\n"})}),"\n",(0,o.jsxs)(n.p,{children:["To continue, please ensure that the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/install#required-permissions",children:"required resource providers"})," have been registered in your subscription by your administrator."]}),"\n",(0,o.jsxs)(n.p,{children:["Afterward, set ",(0,o.jsx)(n.code,{children:"ARM_SKIP_PROVIDER_REGISTRATION=true"})," as an environment variable and either run ",(0,o.jsx)(n.code,{children:"apply"})," or ",(0,o.jsx)(n.code,{children:"terminate"})," again.\nFor example:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"ARM_SKIP_PROVIDER_REGISTRATION=true constellation apply\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Or alternatively, for ",(0,o.jsx)(n.code,{children:"terminate"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"ARM_SKIP_PROVIDER_REGISTRATION=true constellation terminate\n"})}),"\n",(0,o.jsx)(n.h3,{id:"azure-cant-update-attestation-policy",children:"Azure: Can't update attestation policy"}),"\n",(0,o.jsxs)(n.p,{children:["On Azure, you may receive the following error when running ",(0,o.jsx)(n.code,{children:"apply"})," from within an Azure environment, e.g., an Azure VM:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-shell-session",children:"An error occurred: patching policies: updating attestation policy: unexpected status code: 403 Forbidden\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The problem occurs because the Azure SDK we use internally attempts to ",(0,o.jsx)(n.a,{href:"https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#DefaultAzureCredential",children:"authenticate towards the Azure API with the managed identity of your current environment instead of the Azure CLI token"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"We decided not to deviate from this behavior and comply with the ordering of credentials."}),"\n",(0,o.jsxs)(n.p,{children:["A solution is to add the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/install#required-permissions",children:"required permissions"})," to the managed identity of your environment. For example, the managed identity of your Azure VM, instead of the account that you've authenticated with in the Azure CLI."]}),"\n",(0,o.jsx)(n.p,{children:"If your setup requires a change in the ordering of credentials, please open an issue and explain your desired behavior."}),"\n",(0,o.jsxs)(n.h3,{id:"nodes-fail-to-join-with-error-untrusted-measurement-value",children:["Nodes fail to join with error ",(0,o.jsx)(n.code,{children:"untrusted measurement value"})]}),"\n",(0,o.jsxs)(n.p,{children:["This error indicates that a node's ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/attestation",children:"attestation statement"})," contains measurements that don't match the trusted values expected by the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#joinservice",children:"JoinService"}),".\nThis may for example happen if the cloud provider updates the VM's firmware such that it influences the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/attestation#runtime-measurements",children:"runtime measurements"})," in an unforeseen way.\nA failed upgrade due to an erroneous attestation config can also cause this error.\nYou can change the expected measurements to resolve the failure."]}),"\n",(0,o.jsx)(n.admonition,{type:"caution",children:(0,o.jsxs)(n.p,{children:["Attestation and trusted measurements are crucial for the security of your cluster.\nBe extra careful when manually changing these settings.\nWhen in doubt, check if the encountered ",(0,o.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"issue is known"})," or ",(0,o.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation#support",children:"contact support"}),"."]})}),"\n",(0,o.jsxs)(n.admonition,{type:"tip",children:[(0,o.jsxs)(n.p,{children:["During an upgrade with modified attestation config, a backup of the current configuration is stored in the ",(0,o.jsx)(n.code,{children:"join-config"})," config map in the ",(0,o.jsx)(n.code,{children:"kube-system"})," namespace under the ",(0,o.jsx)(n.code,{children:"attestationConfig_backup"})," key. To restore the old attestation config after a failed upgrade, replace the value of ",(0,o.jsx)(n.code,{children:"attestationConfig"})," with the value from ",(0,o.jsx)(n.code,{children:"attestationConfig_backup"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'kubectl patch configmaps -n kube-system join-config -p "{\\"data\\":{\\"attestationConfig\\":\\"$(kubectl get configmaps -n kube-system join-config -o "jsonpath={.data.attestationConfig_backup}")\\"}}"\n'})})]}),"\n",(0,o.jsxs)(n.p,{children:["You can use the ",(0,o.jsx)(n.code,{children:"apply"})," command to change measurements of a running cluster:"]}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["Modify the ",(0,o.jsx)(n.code,{children:"measurements"})," key in your local ",(0,o.jsx)(n.code,{children:"constellation-conf.yaml"})," to the expected values."]}),"\n",(0,o.jsxs)(n.li,{children:["Run ",(0,o.jsx)(n.code,{children:"constellation apply"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Keep in mind that running ",(0,o.jsx)(n.code,{children:"apply"})," also applies any version changes from your config to the cluster."]}),"\n",(0,o.jsx)(n.p,{children:"You can run these commands to learn about the versions currently configured in the cluster:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Kubernetes API server version: ",(0,o.jsx)(n.code,{children:"kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.kubernetesClusterVersion"})]}),"\n",(0,o.jsxs)(n.li,{children:["image version: ",(0,o.jsx)(n.code,{children:"kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.imageVersion"})]}),"\n",(0,o.jsxs)(n.li,{children:["microservices versions: ",(0,o.jsx)(n.code,{children:"helm list --filter 'constellation-services' -n kube-system"})]}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"upgrading-kubernetes-resources-fails",children:"Upgrading Kubernetes resources fails"}),"\n",(0,o.jsxs)(n.p,{children:["Constellation manages its Kubernetes resources using Helm.\nWhen applying an upgrade, the charts that are about to be installed, and a values override file ",(0,o.jsx)(n.code,{children:"overrides.yaml"}),",\nare saved to disk in your current workspace under ",(0,o.jsx)(n.code,{children:"constellation-upgrade/upgrade-/helm-charts/"}),".\nIf upgrading the charts using the Constellation CLI fails, you can review these charts and try to manually apply the upgrade."]}),"\n",(0,o.jsx)(n.admonition,{type:"caution",children:(0,o.jsxs)(n.p,{children:["Changing and manually applying the charts may destroy cluster resources and can lead to broken Constellation deployments.\nProceed with caution and when in doubt,\ncheck if the encountered ",(0,o.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"issue is known"})," or ",(0,o.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation#support",children:"contact support"}),"."]})}),"\n",(0,o.jsx)(n.h2,{id:"diagnosing-issues",children:"Diagnosing issues"}),"\n",(0,o.jsx)(n.h3,{id:"logs",children:"Logs"}),"\n",(0,o.jsxs)(n.p,{children:["To get started on diagnosing issues with Constellation, it's often helpful to collect logs from nodes, pods, or other resources in the cluster. Most logs are available through Kubernetes' standard\n",(0,o.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/logging/",children:"logging interfaces"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"To debug issues occurring at boot time of the nodes, you can use the serial console interface of the CSP while the machine boots to get a read-only view of the boot logs."}),"\n",(0,o.jsxs)(n.p,{children:["Apart from that, Constellation also offers further ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/observability",children:"observability integrations"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"node-shell-access",children:"Node shell access"}),"\n",(0,o.jsxs)(n.p,{children:["Debugging via a shell on a node is ",(0,o.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/debug/debug-application/debug-running-pod/#node-shell-session",children:"directly supported by Kubernetes"}),"."]}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Figure out which node to connect to:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"kubectl get nodes\n# or to see more information, such as IPs:\nkubectl get nodes -o wide\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Connect to the node:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"kubectl debug node/constell-worker-xksa0-000000 -it --image=busybox\n"})}),"\n",(0,o.jsx)(n.p,{children:"You will be presented with a prompt."}),"\n",(0,o.jsxs)(n.p,{children:["The nodes file system is mounted at ",(0,o.jsx)(n.code,{children:"/host"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Once finished, clean up the debug pod:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"kubectl delete pod node-debugger-constell-worker-xksa0-000000-bjthj\n"})}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"emergency-ssh-access",children:"Emergency SSH access"}),"\n",(0,o.jsx)(n.p,{children:"Emergency SSH access to nodes can be useful to diagnose issues or download important data even if the Kubernetes API isn't reachable anymore."}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Enter the ",(0,o.jsx)(n.code,{children:"constellation-terraform"})," directory in your Constellation workspace and enable emergency SSH access to the cluster:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:' cd constellation-terraform\n echo "emergency_ssh = true" >> ./terraform.tfvars\n terraform apply\n'})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Sign an existing SSH key with your master secret:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"cd ../ # go back to your Constellation workspace\nconstellation ssh --key your_public_key.pub\n"})}),"\n",(0,o.jsxs)(n.p,{children:["A certificate is written to ",(0,o.jsx)(n.code,{children:"constellation_cert.pub"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["The certificate is valid for 24 hours and enables you to access your Constellation nodes using\n",(0,o.jsx)(n.a,{href:"https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Certificate-based_Authentication",children:"certificate based authentication"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Now you can connect to any Constellation node using your certificate and your private key."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"ssh -o CertificateFile=constellation_cert.pub -o UserKnownHostsFile=./known_hosts -i root@\n"})}),"\n",(0,o.jsx)(n.p,{children:"Normally, you don't have access to the Constellation nodes since they reside in a private network.\nTo access those nodes anyways, you can use your Constellation load balancer as a proxy jump host.\nFor this, use something along the following SSH client configuration:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-text",children:"Host \n ProxyJump none\n\nHost *\n IdentityFile \n PreferredAuthentications publickey\n CertificateFile=constellation_cert.pub\n UserKnownHostsFile=./known_hosts\n User root\n ProxyJump \n"})}),"\n",(0,o.jsxs)(n.p,{children:["With this configuration you can connect to a Constellation node using ",(0,o.jsx)(n.code,{children:"ssh -F "}),".\nYou can obtain the private node IP and the public IP of the load balancer using your CSP's web UI. Note that if\nyou use the load balancers domain name, ssh host certificate verification doesn't work, so using the public IP is recommended."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>a});var t=s(96540);const o={},i=t.createContext(o);function r(e){const n=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/1c0e8ae3.89100639.js b/pr-preview/pr-4027/assets/js/1c0e8ae3.89100639.js deleted file mode 100644 index de20c7140..000000000 --- a/pr-preview/pr-4027/assets/js/1c0e8ae3.89100639.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[663],{28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>r});var t=s(96540);const l={},i=t.createContext(l);function o(e){const n=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:o(e.components),t.createElement(i.Provider,{value:n},e.children)}},87187:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"getting-started/first-steps-local","title":"First steps with a local cluster","description":"A local cluster lets you deploy and test Constellation without a cloud subscription.","source":"@site/versioned_docs/version-2.24/getting-started/first-steps-local.md","sourceDirName":"getting-started","slug":"/getting-started/first-steps-local","permalink":"/constellation/pr-preview/pr-4027/getting-started/first-steps-local","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/getting-started/first-steps-local.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"First steps (cloud)","permalink":"/constellation/pr-preview/pr-4027/getting-started/first-steps"},"next":{"title":"Cloud Marketplaces","permalink":"/constellation/pr-preview/pr-4027/getting-started/marketplaces"}}');var l=s(74848),i=s(28453);const o={},r="First steps with a local cluster",a={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Software installation on Ubuntu",id:"software-installation-on-ubuntu",level:3},{value:"Create a cluster",id:"create-a-cluster",level:2},{value:"Connect to the cluster",id:"connect-to-the-cluster",level:2},{value:"Deploy a sample application",id:"deploy-a-sample-application",level:2},{value:"Terminate your cluster",id:"terminate-your-cluster",level:2},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"VMs have no internet access / CLI remains in "Initializing cluster" state",id:"vms-have-no-internet-access--cli-remains-in-initializing-cluster-state",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components},{TabItem:s,Tabs:t}=n;return s||h("TabItem",!0),t||h("Tabs",!0),(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"first-steps-with-a-local-cluster",children:"First steps with a local cluster"})}),"\n",(0,l.jsx)(n.p,{children:"A local cluster lets you deploy and test Constellation without a cloud subscription.\nYou have two options:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Use MiniConstellation to automatically deploy a two-node cluster."}),"\n",(0,l.jsx)(n.li,{children:"For more fine-grained control, create the cluster using the QEMU provider."}),"\n"]}),"\n",(0,l.jsxs)(n.p,{children:["Both options use virtualization to create a local cluster with control-plane nodes and worker nodes. They ",(0,l.jsx)(n.strong,{children:"don't"})," require hardware with Confidential VM (CVM) support. For attestation, they currently use a software-based vTPM provided by KVM/QEMU."]}),"\n",(0,l.jsx)(n.p,{children:"You need an x64 machine with a Linux OS.\nYou can use a VM, but it needs nested virtualization."}),"\n",(0,l.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Machine requirements:","\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"An x86-64 CPU with at least 4 cores (6 cores are recommended)"}),"\n",(0,l.jsx)(n.li,{children:"At least 4 GB RAM (6 GB are recommended)"}),"\n",(0,l.jsx)(n.li,{children:"20 GB of free disk space"}),"\n",(0,l.jsx)(n.li,{children:"Hardware virtualization enabled in the BIOS/UEFI (often referred to as Intel VT-x or AMD-V/SVM) / nested-virtualization support when using a VM"}),"\n"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["Software requirements:","\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Linux OS with ",(0,l.jsx)(n.a,{href:"https://www.linux-kvm.org/page/Main_Page",children:"KVM kernel module"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Recommended: Ubuntu 22.04 LTS"}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://docs.docker.com/engine/install/",children:"Docker"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://gitlab.gnome.org/GNOME/libxslt/-/wikis/home",children:"xsltproc"})}),"\n",(0,l.jsxs)(n.li,{children:["(Optional) ",(0,l.jsx)(n.a,{href:"https://www.libvirt.org/manpages/virsh.html",children:"virsh"})," to observe and access your nodes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"software-installation-on-ubuntu",children:"Software installation on Ubuntu"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:'# install Docker\ncurl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg\necho "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null\nsudo apt update\nsudo apt install docker-ce\n# install other dependencies\nsudo apt install xsltproc\nsudo snap install kubectl --classic\n# install Constellation CLI\ncurl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-amd64\nsudo install constellation-linux-amd64 /usr/local/bin/constellation\n# do not drop forwarded packages\nsudo iptables -P FORWARD ACCEPT\n'})}),"\n",(0,l.jsx)(n.h2,{id:"create-a-cluster",children:"Create a cluster"}),"\n",(0,l.jsxs)(t,{groupId:"csp",children:[(0,l.jsxs)(s,{value:"mini",label:"MiniConstellation",children:[(0,l.jsxs)(n.p,{children:["With the ",(0,l.jsx)(n.code,{children:"constellation mini"})," command, you can deploy and test Constellation locally. This mode is called MiniConstellation. Conceptually, MiniConstellation is similar to ",(0,l.jsx)(n.a,{href:"https://microk8s.io/",children:"MicroK8s"}),", ",(0,l.jsx)(n.a,{href:"https://k3s.io/",children:"K3s"}),", and ",(0,l.jsx)(n.a,{href:"https://minikube.sigs.k8s.io/docs/",children:"minikube"}),"."]}),(0,l.jsx)(n.admonition,{type:"caution",children:(0,l.jsxs)(n.p,{children:["MiniConstellation has specific soft- and hardware requirements such as a Linux OS running on an x86-64 CPU. Pay attention to all ",(0,l.jsx)(n.a,{href:"#prerequisites",children:"prerequisites"})," when setting up."]})}),(0,l.jsx)(n.admonition,{type:"note",children:(0,l.jsx)(n.p,{children:"Since MiniConstellation runs on your local system, cloud features such as load balancing,\nattaching persistent storage, or autoscaling aren't available."})}),(0,l.jsx)(n.p,{children:"The following creates your MiniConstellation cluster (may take up to 10 minutes to complete):"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation mini up\n"})}),(0,l.jsxs)(n.p,{children:["This will configure your current directory as the ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/orchestration#workspaces",children:"workspace"})," for this cluster.\nAll ",(0,l.jsx)(n.code,{children:"constellation"})," commands concerning this cluster need to be issued from this directory."]})]}),(0,l.jsxs)(s,{value:"qemu",label:"QEMU",children:[(0,l.jsxs)(n.p,{children:["With the QEMU provider, you can create a local Constellation cluster as if it were in the cloud. The provider uses ",(0,l.jsx)(n.a,{href:"https://www.qemu.org/",children:"QEMU"})," to create multiple VMs for the cluster nodes, which interact with each other."]}),(0,l.jsx)(n.admonition,{type:"caution",children:(0,l.jsxs)(n.p,{children:["Constellation on QEMU has specific soft- and hardware requirements such as a Linux OS running on an x86-64 CPU. Pay attention to all ",(0,l.jsx)(n.a,{href:"#prerequisites",children:"prerequisites"})," when setting up."]})}),(0,l.jsx)(n.admonition,{type:"note",children:(0,l.jsx)(n.p,{children:"Since Constellation on QEMU runs on your local system, cloud features such as load balancing,\nattaching persistent storage, or autoscaling aren't available."})}),(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"To set up your local cluster, you need to create a configuration file for Constellation first."}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation config generate qemu\n"})}),(0,l.jsxs)(n.p,{children:["This creates a ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/config",children:"configuration file"})," for QEMU called ",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"}),". After that, your current folder also becomes your ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/orchestration#workspaces",children:"workspace"}),". All ",(0,l.jsx)(n.code,{children:"constellation"})," commands for your cluster need to be executed from this directory."]}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["Now you can create your cluster and its nodes. ",(0,l.jsx)(n.code,{children:"constellation apply"})," uses the options set in ",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"}),"."]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation apply -y\n"})}),(0,l.jsx)(n.p,{children:"The Output should look like the following:"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:'$ constellation apply -y\nChecking for infrastructure changes\nThe following Constellation cluster will be created:\n 3 control-plane nodes of type 2-vCPUs will be created.\n 1 worker node of type 2-vCPUs will be created.\nCreating\nCloud infrastructure created successfully.\nYour Constellation master secret was successfully written to ./constellation-mastersecret.json\nConnecting\nInitializing cluster\nInstalling Kubernetes components\nYour Constellation cluster was successfully initialized.\n\nConstellation cluster identifier g6iMP5wRU1b7mpOz2WEISlIYSfdAhB0oNaOg6XEwKFY=\nKubernetes configuration constellation-admin.conf\n\nYou can now connect to your cluster by executing:\n export KUBECONFIG="$PWD/constellation-admin.conf"\n'})}),(0,l.jsxs)(n.p,{children:["The cluster's identifier will be different in your output.\nKeep ",(0,l.jsx)(n.code,{children:"constellation-mastersecret.json"})," somewhere safe.\nThis will allow you to ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/recovery",children:"recover your cluster"})," in case of a disaster."]}),(0,l.jsx)(n.admonition,{type:"info",children:(0,l.jsxs)(n.p,{children:["Depending on your setup, ",(0,l.jsx)(n.code,{children:"constellation apply"})," may take 10+ minutes to complete."]})}),(0,l.jsxs)(n.ol,{start:"3",children:["\n",(0,l.jsx)(n.li,{children:"Configure kubectl"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:'export KUBECONFIG="$PWD/constellation-admin.conf"\n'})})]})]}),"\n",(0,l.jsx)(n.h2,{id:"connect-to-the-cluster",children:"Connect to the cluster"}),"\n",(0,l.jsx)(n.p,{children:"Your cluster initially consists of a single control-plane node:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"$ kubectl get nodes\nNAME STATUS ROLES AGE VERSION\ncontrol-plane-0 Ready control-plane 66s v1.24.6\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Additional nodes will request to join the cluster shortly. Before each additional node is allowed to join the cluster, its state is verified using remote attestation by the ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#joinservice",children:"JoinService"}),".\nIf verification passes successfully, the new node receives keys and certificates to join the cluster."]}),"\n",(0,l.jsx)(n.p,{children:"You can follow this process by viewing the logs of the JoinService:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:'$ kubectl logs -n kube-system daemonsets/join-service -f\n{"level":"INFO","ts":"2022-10-14T09:32:20Z","caller":"cmd/main.go:48","msg":"Constellation Node Join Service","version":"2.1.0","cloudProvider":"qemu"}\n{"level":"INFO","ts":"2022-10-14T09:32:20Z","logger":"validator","caller":"watcher/validator.go:96","msg":"Updating expected measurements"}\n...\n'})}),"\n",(0,l.jsx)(n.p,{children:"Once all nodes have joined your cluster, it may take a couple of minutes for all resources to become available.\nYou can check on the state of your cluster by running the following:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"$ kubectl get nodes\nNAME STATUS ROLES AGE VERSION\ncontrol-plane-0 Ready control-plane 2m59s v1.24.6\nworker-0 Ready 32s v1.24.6\n"})}),"\n",(0,l.jsx)(n.h2,{id:"deploy-a-sample-application",children:"Deploy a sample application"}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["Deploy the ",(0,l.jsx)(n.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"emojivoto app"})]}),"\n"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment\n"})}),"\n",(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsx)(n.li,{children:"Expose the frontend service locally"}),"\n"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments\nkubectl -n emojivoto port-forward svc/web-svc 8080:80 &\ncurl http://localhost:8080\nkill %1\n"})}),"\n",(0,l.jsx)(n.h2,{id:"terminate-your-cluster",children:"Terminate your cluster"}),"\n",(0,l.jsxs)(t,{groupId:"csp",children:[(0,l.jsxs)(s,{value:"mini",label:"MiniConstellation",children:[(0,l.jsx)(n.p,{children:"Once you are done, you can clean up the created resources using the following command:"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation mini down\n"})}),(0,l.jsxs)(n.p,{children:["This will destroy your cluster and clean up your workspace.\nThe VM image and cluster configuration file (",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"}),") will be kept and may be reused to create new clusters."]})]}),(0,l.jsxs)(s,{value:"qemu",label:"QEMU",children:[(0,l.jsx)(n.p,{children:"Once you are done, you can clean up the created resources using the following command:"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation terminate\n"})}),(0,l.jsx)(n.p,{children:"This should give the following output:"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"$ constellation terminate\nYou are about to terminate a Constellation cluster.\nAll of its associated resources will be DESTROYED.\nThis action is irreversible and ALL DATA WILL BE LOST.\nDo you want to continue? [y/n]:\n"})}),(0,l.jsxs)(n.p,{children:["Confirm with ",(0,l.jsx)(n.code,{children:"y"})," to terminate the cluster:"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"Terminating ...\nYour Constellation cluster was terminated successfully.\n"})}),(0,l.jsxs)(n.p,{children:["This will destroy your cluster and clean up your workspace.\nThe VM image and cluster configuration file (",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"}),") will be kept and may be reused to create new clusters."]})]})]}),"\n",(0,l.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,l.jsxs)(n.p,{children:["Make sure to use the ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/releases/latest",children:"latest release"})," and check out the ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"known issues"}),"."]}),"\n",(0,l.jsx)(n.h3,{id:"vms-have-no-internet-access--cli-remains-in-initializing-cluster-state",children:'VMs have no internet access / CLI remains in "Initializing cluster" state'}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:"iptables"})," rules may prevent your VMs from accessing the internet.\nMake sure your rules aren't dropping forwarded packages."]}),"\n",(0,l.jsx)(n.p,{children:"List your rules:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo iptables -S\n"})}),"\n",(0,l.jsx)(n.p,{children:"The output may look similar to the following:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"-P INPUT ACCEPT\n-P FORWARD DROP\n-P OUTPUT ACCEPT\n-N DOCKER\n-N DOCKER-ISOLATION-STAGE-1\n-N DOCKER-ISOLATION-STAGE-2\n-N DOCKER-USER\n"})}),"\n",(0,l.jsxs)(n.p,{children:["If your ",(0,l.jsx)(n.code,{children:"FORWARD"})," chain is set to ",(0,l.jsx)(n.code,{children:"DROP"}),", you need to update your rules:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo iptables -P FORWARD ACCEPT\n"})})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}function h(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/1c53691b.0108663e.js b/pr-preview/pr-4027/assets/js/1c53691b.0108663e.js deleted file mode 100644 index 1b2d0431e..000000000 --- a/pr-preview/pr-4027/assets/js/1c53691b.0108663e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5845],{6110:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"workflows/verify-cli","title":"Verify the CLI","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","source":"@site/docs/workflows/verify-cli.md","sourceDirName":"workflows","slug":"/workflows/verify-cli","permalink":"/constellation/pr-preview/pr-4027/next/workflows/verify-cli","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/workflows/verify-cli.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Workflows","permalink":"/constellation/pr-preview/pr-4027/next/category/workflows"},"next":{"title":"Configure your cluster","permalink":"/constellation/pr-preview/pr-4027/next/workflows/config"}}');var i=n(74848),o=n(28453);const r={},a="Verify the CLI",l={},c=[{value:"Verify the signature",id:"verify-the-signature",level:2},{value:"Optional: Manually inspect the transparency log",id:"optional-manually-inspect-the-transparency-log",level:3},{value:"Verify the provenance",id:"verify-the-provenance",level:2}];function d(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",...(0,o.R)(),...e.components},{AsciinemaWidget:n}=s;return n||function(e,s){throw new Error("Expected "+(s?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("AsciinemaWidget",!0),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.header,{children:(0,i.jsx)(s.h1,{id:"verify-the-cli",children:"Verify the CLI"})}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details."})}),"\n",(0,i.jsx)(n,{src:"/constellation/assets/verify-cli.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsxs)(s.p,{children:["Edgeless Systems uses ",(0,i.jsx)(s.a,{href:"https://www.sigstore.dev/",children:"sigstore"})," and ",(0,i.jsx)(s.a,{href:"https://slsa.dev",children:"SLSA"}),' to ensure supply-chain security for the Constellation CLI and node images ("artifacts"). sigstore consists of three components: ',(0,i.jsx)(s.a,{href:"https://docs.sigstore.dev/cosign/signing/overview/",children:"Cosign"}),", ",(0,i.jsx)(s.a,{href:"https://docs.sigstore.dev/logging/overview",children:"Rekor"}),", and Fulcio. Edgeless Systems uses Cosign to sign artifacts. All signatures are uploaded to the public Rekor transparency log, which resides at ",(0,i.jsx)(s.code,{children:"https://rekor.sigstore.dev"}),"."]}),"\n",(0,i.jsxs)(s.admonition,{type:"note",children:[(0,i.jsx)(s.p,{children:"The public key for Edgeless Systems' long-term code-signing key is:"}),(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT\nJmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==\n-----END PUBLIC KEY-----\n"})}),(0,i.jsxs)(s.p,{children:["The public key is also available for download at ",(0,i.jsx)(s.a,{href:"https://edgeless.systems/es.pub",children:"https://edgeless.systems/es.pub"})," and in the Twitter profile ",(0,i.jsx)(s.a,{href:"https://twitter.com/EdgelessSystems",children:"@EdgelessSystems"}),"."]})]}),"\n",(0,i.jsx)(s.p,{children:"The Rekor transparency log is a public append-only ledger that verifies and records signatures and associated metadata. The Rekor transparency log enables everyone to observe the sequence of (software) signatures issued by Edgeless Systems and many other parties. The transparency log allows for the public identification of dubious or malicious signatures."}),"\n",(0,i.jsx)(s.p,{children:"You should always ensure that (1) your CLI executable was signed with the private key corresponding to the above public key and that (2) there is a corresponding entry in the Rekor transparency log. Both can be done as described in the following."}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"You don't need to verify the Constellation node images. This is done automatically by your CLI and the rest of Constellation."})}),"\n",(0,i.jsx)(s.h2,{id:"verify-the-signature",children:"Verify the signature"}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"This guide assumes Linux on an amd64 processor. The exact steps for other platforms differ slightly."})}),"\n",(0,i.jsxs)(s.p,{children:["First, ",(0,i.jsx)(s.a,{href:"https://docs.sigstore.dev/cosign/system_config/installation/",children:"install the Cosign CLI"}),". Next, ",(0,i.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"download"})," and verify the signature that accompanies your CLI executable, for example:"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:"$ cosign verify-blob --key https://edgeless.systems/es.pub --signature constellation-linux-amd64.sig constellation-linux-amd64\n\nVerified OK\n"})}),"\n",(0,i.jsxs)(s.p,{children:["The above performs an offline verification of the provided public key, signature, and executable. To also verify that a corresponding entry exists in the public Rekor transparency log, add the variable ",(0,i.jsx)(s.code,{children:"COSIGN_EXPERIMENTAL=1"}),":"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:"$ COSIGN_EXPERIMENTAL=1 cosign verify-blob --key https://edgeless.systems/es.pub --signature constellation-linux-amd64.sig constellation-linux-amd64\n\ntlog entry verified with uuid: afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13 index: 3477047\nVerified OK\n"})}),"\n",(0,i.jsx)(s.p,{children:"\ud83c\udfc1 You now know that your CLI executable was officially released and signed by Edgeless Systems."}),"\n",(0,i.jsx)(s.h3,{id:"optional-manually-inspect-the-transparency-log",children:"Optional: Manually inspect the transparency log"}),"\n",(0,i.jsxs)(s.p,{children:["To further inspect the public Rekor transparency log, ",(0,i.jsx)(s.a,{href:"https://docs.sigstore.dev/logging/installation",children:"install the Rekor CLI"}),". A search for the CLI executable should give a single UUID. (Note that this UUID contains the UUID from the previous ",(0,i.jsx)(s.code,{children:"cosign"})," command.)"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:"$ rekor-cli search --artifact constellation-linux-amd64\n\nFound matching entries (listed by UUID):\n362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13\n"})}),"\n",(0,i.jsx)(s.p,{children:"With this UUID you can get the full entry from the transparency log:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:'$ rekor-cli get --uuid=362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13\n\nLogID: c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d\nIndex: 3477047\nIntegratedTime: 2022-09-12T22:28:16Z\nUUID: afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13\nBody: {\n "HashedRekordObj": {\n "data": {\n "hash": {\n "algorithm": "sha256",\n "value": "40e137b9b9b8204d672642fd1e181c6d5ccb50cfc5cc7fcbb06a8c2c78f44aff"\n }\n },\n "signature": {\n "content": "MEUCIQCSER3mGj+j5Pr2kOXTlCIHQC3gT30I7qkLr9Awt6eUUQIgcLUKRIlY50UN8JGwVeNgkBZyYD8HMxwC/LFRWoMn180=",\n "publicKey": {\n "content": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFZjhGMWhwbXdFK1lDRlh6akd0YVFjckw2WFpWVApKbUVlNWlTTHZHMVN5UVNBZXc3V2RNS0Y2bzl0OGUyVEZ1Q2t6bE9oaGx3czJPSFdiaUZabkZXQ0Z3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=="\n }\n }\n }\n}\n'})}),"\n",(0,i.jsxs)(s.p,{children:["The field ",(0,i.jsx)(s.code,{children:"publicKey"})," should contain Edgeless Systems' public key in Base64 encoding."]}),"\n",(0,i.jsx)(s.p,{children:"You can get an exhaustive list of artifact signatures issued by Edgeless Systems via the following command:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-bash",children:"rekor-cli search --public-key https://edgeless.systems/es.pub --pki-format x509\n"})}),"\n",(0,i.jsx)(s.p,{children:"Edgeless Systems monitors this list to detect potential unauthorized use of its private key."}),"\n",(0,i.jsx)(s.h2,{id:"verify-the-provenance",children:"Verify the provenance"}),"\n",(0,i.jsxs)(s.p,{children:["Provenance attests that a software artifact was produced by a specific repository and build system invocation. For more information on provenance visit ",(0,i.jsx)(s.a,{href:"https://slsa.dev/provenance/v0.2",children:"slsa.dev"})," and learn about the ",(0,i.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/next/reference/slsa",children:"adoption of SLSA for Constellation"}),"."]}),"\n",(0,i.jsx)(s.p,{children:"Just as checking its signature proves that the CLI hasn't been manipulated, checking the provenance proves that the artifact was produced by the expected build process and hasn't been tampered with."}),"\n",(0,i.jsxs)(s.p,{children:["To verify the provenance, first install the ",(0,i.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-verifier",children:"slsa-verifier"}),". Then make sure you have the provenance file (",(0,i.jsx)(s.code,{children:"constellation.intoto.jsonl"}),") and Constellation CLI downloaded. Both are available on the ",(0,i.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub release page"}),"."]}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"The same provenance file is valid for all Constellation CLI executables of a given version independent of the target platform."})}),"\n",(0,i.jsx)(s.p,{children:"Use the verifier to perform the check:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:"$ slsa-verifier verify-artifact constellation-linux-amd64 \\\n --provenance-path constellation.intoto.jsonl \\\n --source-uri github.com/edgelesssys/constellation\n\nVerified signature against tlog entry index 7771317 at URL: https://rekor.sigstore.dev/api/v1/log/entries/24296fb24b8ad77af2c04c8b4ae0d5bc5...\nVerified build using builder https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v1.2.2 at commit 18e9924b416323c37b9cdfd6cc728de8a947424a\nPASSED: Verified SLSA provenance\n"})})]})}function h(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>r,x:()=>a});var t=n(96540);const i={},o=t.createContext(i);function r(e){const s=t.useContext(o);return t.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),t.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/1e04dd29.b8b7e365.js b/pr-preview/pr-4027/assets/js/1e04dd29.b8b7e365.js deleted file mode 100644 index 16cd5b4cf..000000000 --- a/pr-preview/pr-4027/assets/js/1e04dd29.b8b7e365.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4318],{2702:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"intro","title":"Introduction","description":"Welcome to the documentation of Constellation! Constellation is a Kubernetes engine that aims to provide the best possible data security.","source":"@site/versioned_docs/version-2.23/intro.md","sourceDirName":".","slug":"/","permalink":"/constellation/pr-preview/pr-4027/2.23/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/intro.md","tags":[],"version":"2.23","frontMatter":{"slug":"/","id":"intro"},"sidebar":"docs","next":{"title":"Basics","permalink":"/constellation/pr-preview/pr-4027/2.23/category/basics"}}');var i=n(74848),o=n(28453);const r={slug:"/",id:"intro"},a="Introduction",l={},c=[{value:"Goals",id:"goals",level:2},{value:"Use cases",id:"use-cases",level:2},{value:"Next steps",id:"next-steps",level:2}];function d(e){const t={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"introduction",children:"Introduction"})}),"\n",(0,i.jsx)(t.p,{children:"Welcome to the documentation of Constellation! Constellation is a Kubernetes engine that aims to provide the best possible data security."}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Constellation concept",src:n(60420).A+"",width:"1776",height:"746"})}),"\n",(0,i.jsxs)(t.p,{children:["Constellation shields your entire Kubernetes cluster from the underlying cloud infrastructure. Everything inside is always encrypted, including at runtime in memory. For this, Constellation leverages a technology called ",(0,i.jsx)(t.em,{children:"confidential computing"})," and more specifically Confidential VMs."]}),"\n",(0,i.jsx)(t.admonition,{type:"tip",children:(0,i.jsxs)(t.p,{children:["See the \ud83d\udcc4",(0,i.jsx)(t.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"})," for more information on confidential computing."]})}),"\n",(0,i.jsx)(t.h2,{id:"goals",children:"Goals"}),"\n",(0,i.jsx)(t.p,{children:"From a security perspective, Constellation is designed to keep all data always encrypted and to prevent any access from the underlying (cloud) infrastructure. This includes access from datacenter employees, privileged cloud admins, and attackers coming through the infrastructure. Such attackers could be malicious co-tenants escalating their privileges or hackers who managed to compromise a cloud server."}),"\n",(0,i.jsx)(t.p,{children:"From a DevOps perspective, Constellation is designed to work just like what you would expect from a modern Kubernetes engine."}),"\n",(0,i.jsx)(t.h2,{id:"use-cases",children:"Use cases"}),"\n",(0,i.jsxs)(t.p,{children:["Constellation provides unique security ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/overview/confidential-kubernetes",children:"features"})," and ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/overview/security-benefits",children:"benefits"}),". The core use cases are:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Increasing the overall security of your clusters"}),"\n",(0,i.jsx)(t.li,{children:"Increasing the trustworthiness of your SaaS offerings"}),"\n",(0,i.jsx)(t.li,{children:"Moving sensitive workloads from on-prem to the cloud"}),"\n",(0,i.jsx)(t.li,{children:"Meeting regulatory requirements"}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,i.jsxs)(t.p,{children:["You can learn more about the concept of Confidential Kubernetes, features, security benefits, and performance of Constellation in the ",(0,i.jsx)(t.em,{children:"Basics"})," section. To jump right into the action head to ",(0,i.jsx)(t.em,{children:"Getting started"}),"."]})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var s=n(96540);const i={},o=s.createContext(i);function r(e){const t=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:t},e.children)}},60420:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/concept-d3a09a16a8e7ca14a7bdf274ea7bce40.svg"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/2093.f4a3364b.js b/pr-preview/pr-4027/assets/js/2093.f4a3364b.js deleted file mode 100644 index de45cf7e7..000000000 --- a/pr-preview/pr-4027/assets/js/2093.f4a3364b.js +++ /dev/null @@ -1 +0,0 @@ -(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2093],{7227:(A,e,t)=>{"use strict";t.d(e,{A:()=>o});t(96540);var n=t(34164);const g={tabItem:"tabItem_Ymn6"};var V=t(74848);function o({children:A,hidden:e,className:t}){return(0,V.jsx)("div",{role:"tabpanel",className:(0,n.A)(g.tabItem,t),hidden:e,children:A})}},18073:(A,e,t)=>{"use strict";t.d(e,{A:()=>YA});var n=t(96540),g=t(21141),V=t(11062),o=t(34164),i=t(7710),s=t(86957);function r(){const{prism:A}=(0,s.p)(),{colorMode:e}=(0,i.G)(),t=A.theme,n=A.darkTheme||t;return"dark"===e?n:t}var I=t(18630),B=t(18426),a=t.n(B),C=t(4799),Q=t(74848);const E=/title=(?["'])(?.*?)\1/,c=/\{(?<range>[\d,-]+)\}/,l={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}},u={...l,lua:{start:"--",end:""},wasm:{start:"\\;\\;",end:""},tex:{start:"%",end:""},vb:{start:"['\u2018\u2019]",end:""},vbnet:{start:"(?:_\\s*)?['\u2018\u2019]",end:""},rem:{start:"[Rr][Ee][Mm]\\b",end:""},f90:{start:"!",end:""},ml:{start:"\\(\\*",end:"\\*\\)"},cobol:{start:"\\*>",end:""}},d=Object.keys(l);function h(A,e){const t=A.map(A=>{const{start:t,end:n}=u[A];return`(?:${t}\\s*(${e.flatMap(A=>[A.line,A.block?.start,A.block?.end].filter(Boolean)).join("|")})\\s*${n})`}).join("|");return new RegExp(`^\\s*(?:${t})\\s*$`)}function f({showLineNumbers:A,metastring:e}){return"boolean"==typeof A?A?1:void 0:"number"==typeof A?A:function(A){const e=A?.split(" ").find(A=>A.startsWith("showLineNumbers"));if(e){if(e.startsWith("showLineNumbers=")){const A=e.replace("showLineNumbers=","");return parseInt(A,10)}return 1}}(e)}function w(A,e){const{language:t,magicComments:n}=e;if(void 0===t)return{lineClassNames:{},code:A};const g=function(A,e){switch(A){case"js":case"javascript":case"ts":case"typescript":return h(["js","jsBlock"],e);case"jsx":case"tsx":return h(["js","jsBlock","jsx"],e);case"html":return h(["js","jsBlock","html"],e);case"python":case"py":case"bash":return h(["bash"],e);case"markdown":case"md":return h(["html","jsx","bash"],e);case"tex":case"latex":case"matlab":return h(["tex"],e);case"lua":case"haskell":return h(["lua"],e);case"sql":return h(["lua","jsBlock"],e);case"wasm":return h(["wasm"],e);case"vb":case"vba":case"visual-basic":return h(["vb","rem"],e);case"vbnet":return h(["vbnet","rem"],e);case"batch":return h(["rem"],e);case"basic":return h(["rem","f90"],e);case"fsharp":return h(["js","ml"],e);case"ocaml":case"sml":return h(["ml"],e);case"fortran":return h(["f90"],e);case"cobol":return h(["cobol"],e);default:return h(d,e)}}(t,n),V=A.split(/\r?\n/),o=Object.fromEntries(n.map(A=>[A.className,{start:0,range:""}])),i=Object.fromEntries(n.filter(A=>A.line).map(({className:A,line:e})=>[e,A])),s=Object.fromEntries(n.filter(A=>A.block).map(({className:A,block:e})=>[e.start,A])),r=Object.fromEntries(n.filter(A=>A.block).map(({className:A,block:e})=>[e.end,A]));for(let B=0;B<V.length;){const A=V[B].match(g);if(!A){B+=1;continue}const e=A.slice(1).find(A=>void 0!==A);i[e]?o[i[e]].range+=`${B},`:s[e]?o[s[e]].start=B:r[e]&&(o[r[e]].range+=`${o[r[e]].start}-${B-1},`),V.splice(B,1)}const I={};return Object.entries(o).forEach(([A,{range:e}])=>{a()(e).forEach(e=>{I[e]??=[],I[e].push(A)})}),{code:V.join("\n"),lineClassNames:I}}function m(A,e){const t=A.replace(/\r?\n$/,"");return function(A,{metastring:e,magicComments:t}){if(e&&c.test(e)){const n=e.match(c).groups.range;if(0===t.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${e}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const g=t[0].className,V=a()(n).filter(A=>A>0).map(A=>[A-1,[g]]);return{lineClassNames:Object.fromEntries(V),code:A}}return null}(t,{...e})??w(t,{...e})}function y(A){const e=function(A){return e=A.language??function(A){if(!A)return;const e=A.split(" ").find(A=>A.startsWith("language-"));return e?.replace(/language-/,"")}(A.className)??A.defaultLanguage,e?.toLowerCase()??"text";var e}({language:A.language,defaultLanguage:A.defaultLanguage,className:A.className}),{lineClassNames:t,code:n}=m(A.code,{metastring:A.metastring,magicComments:A.magicComments,language:e}),g=function({className:A,language:e}){return(0,o.A)(A,e&&!A?.includes(`language-${e}`)&&`language-${e}`)}({className:A.className,language:e}),V=(i=A.metastring,(i?.match(E)?.groups.title??"")||A.title);var i;const s=f({showLineNumbers:A.showLineNumbers,metastring:A.metastring});return{codeInput:A.code,code:n,className:g,language:e,title:V,lineNumbersStart:s,lineClassNames:t}}const D=(0,n.createContext)(null);function p({metadata:A,wordWrap:e,children:t}){const g=(0,n.useMemo)(()=>({metadata:A,wordWrap:e}),[A,e]);return(0,Q.jsx)(D.Provider,{value:g,children:t})}function k(){const A=(0,n.useContext)(D);if(null===A)throw new C.dV("CodeBlockContextProvider");return A}const q="codeBlockContainer_Ckt0";function N({as:A,...e}){const t=function(A){const e={color:"--prism-color",backgroundColor:"--prism-background-color"},t={};return Object.entries(A.plain).forEach(([A,n])=>{const g=e[A];g&&"string"==typeof n&&(t[g]=n)}),t}(r());return(0,Q.jsx)(A,{...e,style:t,className:(0,o.A)(e.className,q,I.G.common.codeBlock)})}const F="codeBlock_bY9V",v="codeBlockStandalone_MEMb",M="codeBlockLines_e6Vv",b="codeBlockLinesWithNumbering_o6Pm";function G({children:A,className:e}){return(0,Q.jsx)(N,{as:"pre",tabIndex:0,className:(0,o.A)(v,"thin-scrollbar",e),children:(0,Q.jsx)("code",{className:M,children:A})})}const R={attributes:!0,characterData:!0,childList:!0,subtree:!0};function L(A,e){const[t,g]=(0,n.useState)(),V=(0,n.useCallback)(()=>{g(A.current?.closest("[role=tabpanel][hidden]"))},[A,g]);(0,n.useEffect)(()=>{V()},[V]),function(A,e,t=R){const g=(0,C._q)(e),V=(0,C.Be)(t);(0,n.useEffect)(()=>{const e=new MutationObserver(g);return A&&e.observe(A,V),()=>e.disconnect()},[A,g,V])}(t,A=>{A.forEach(A=>{"attributes"===A.type&&"hidden"===A.attributeName&&(e(),V())})},{attributes:!0,characterData:!1,childList:!1,subtree:!1})}function S({children:A}){return A}var J=t(71765);function U({line:A,token:e,...t}){return(0,Q.jsx)("span",{...t})}const x="codeLine_lJS_",Y="codeLineNumber_Tfdd",K="codeLineContent_feaV";function T({line:A,classNames:e,showLineNumbers:t,getLineProps:n,getTokenProps:g}){const V=function(A){const e=1===A.length&&"\n"===A[0].content?A[0]:void 0;return e?[{...e,content:""}]:A}(A),i=n({line:V,className:(0,o.A)(e,t&&x)}),s=V.map((A,e)=>{const t=g({token:A});return(0,Q.jsx)(U,{...t,line:V,token:A,children:t.children},e)});return(0,Q.jsxs)("span",{...i,children:[t?(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)("span",{className:Y}),(0,Q.jsx)("span",{className:K,children:s})]}):s,(0,Q.jsx)("br",{})]})}const j=n.forwardRef((A,e)=>(0,Q.jsx)("pre",{ref:e,tabIndex:0,...A,className:(0,o.A)(A.className,F,"thin-scrollbar")}));function H(A){const{metadata:e}=k();return(0,Q.jsx)("code",{...A,className:(0,o.A)(A.className,M,void 0!==e.lineNumbersStart&&b),style:{...A.style,counterReset:void 0===e.lineNumbersStart?void 0:"line-count "+(e.lineNumbersStart-1)}})}function O({className:A}){const{metadata:e,wordWrap:t}=k(),n=r(),{code:g,language:V,lineNumbersStart:i,lineClassNames:s}=e;return(0,Q.jsx)(J.f4,{theme:n,code:g,language:V,children:({className:e,style:n,tokens:g,getLineProps:V,getTokenProps:r})=>(0,Q.jsx)(j,{ref:t.codeBlockRef,className:(0,o.A)(A,e),style:n,children:(0,Q.jsx)(H,{children:g.map((A,e)=>(0,Q.jsx)(T,{line:A,getLineProps:V,getTokenProps:r,classNames:s[e],showLineNumbers:void 0!==i},e))})})})}var W=t(29813),_=t(23230);function Z({className:A,...e}){return(0,Q.jsx)("button",{type:"button",...e,className:(0,o.A)("clean-btn",A)})}function z(A){return(0,Q.jsx)("svg",{viewBox:"0 0 24 24",...A,children:(0,Q.jsx)("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"})})}function X(A){return(0,Q.jsx)("svg",{viewBox:"0 0 24 24",...A,children:(0,Q.jsx)("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"})})}const P={copyButtonCopied:"copyButtonCopied_Vdqa",copyButtonIcons:"copyButtonIcons_IEyt",copyButtonIcon:"copyButtonIcon_TrPX",copyButtonSuccessIcon:"copyButtonSuccessIcon_cVMy"};function $(A){return A?(0,_.T)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,_.T)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"})}function AA({className:A}){const{copyCode:e,isCopied:t}=function(){const{metadata:{code:A}}=k(),[e,t]=(0,n.useState)(!1),g=(0,n.useRef)(void 0),V=(0,n.useCallback)(()=>{navigator.clipboard.writeText(A).then(()=>{t(!0),g.current=window.setTimeout(()=>{t(!1)},1e3)})},[A]);return(0,n.useEffect)(()=>()=>window.clearTimeout(g.current),[]),{copyCode:V,isCopied:e}}();return(0,Q.jsx)(Z,{"aria-label":$(t),title:(0,_.T)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,o.A)(A,P.copyButton,t&&P.copyButtonCopied),onClick:e,children:(0,Q.jsxs)("span",{className:P.copyButtonIcons,"aria-hidden":"true",children:[(0,Q.jsx)(z,{className:P.copyButtonIcon}),(0,Q.jsx)(X,{className:P.copyButtonSuccessIcon})]})})}function eA(A){return(0,Q.jsx)("svg",{viewBox:"0 0 24 24",...A,children:(0,Q.jsx)("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"})})}const tA="wordWrapButtonIcon_b1P5",nA="wordWrapButtonEnabled_uzNF";function gA({className:A}){const{wordWrap:e}=k();if(!(e.isEnabled||e.isCodeScrollable))return!1;const t=(0,_.T)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return(0,Q.jsx)(Z,{onClick:()=>e.toggle(),className:(0,o.A)(A,e.isEnabled&&nA),"aria-label":t,title:t,children:(0,Q.jsx)(eA,{className:tA,"aria-hidden":"true"})})}const VA="buttonGroup_M5ko";function oA({className:A}){return(0,Q.jsx)(W.A,{children:()=>(0,Q.jsxs)("div",{className:(0,o.A)(A,VA),children:[(0,Q.jsx)(gA,{}),(0,Q.jsx)(AA,{})]})})}const iA="codeBlockContent_QJqH",sA="codeBlockTitle_OeMC";function rA({className:A}){const{metadata:e}=k();return(0,Q.jsxs)(N,{as:"div",className:(0,o.A)(A,e.className),children:[e.title&&(0,Q.jsx)("div",{className:sA,children:(0,Q.jsx)(S,{children:e.title})}),(0,Q.jsxs)("div",{className:iA,children:[(0,Q.jsx)(O,{}),(0,Q.jsx)(oA,{})]})]})}function IA(A){const e=function(A){const{prism:e}=(0,s.p)();return y({code:A.children,className:A.className,metastring:A.metastring,magicComments:e.magicComments,defaultLanguage:e.defaultLanguage,language:A.language,title:A.title,showLineNumbers:A.showLineNumbers})}(A),t=function(){const[A,e]=(0,n.useState)(!1),[t,g]=(0,n.useState)(!1),V=(0,n.useRef)(null),o=(0,n.useCallback)(()=>{const t=V.current.querySelector("code");A?t.removeAttribute("style"):(t.style.whiteSpace="pre-wrap",t.style.overflowWrap="anywhere"),e(A=>!A)},[V,A]),i=(0,n.useCallback)(()=>{const{scrollWidth:A,clientWidth:e}=V.current,t=A>e||V.current.querySelector("code").hasAttribute("style");g(t)},[V]);return L(V,i),(0,n.useEffect)(()=>{i()},[A,i]),(0,n.useEffect)(()=>(window.addEventListener("resize",i,{passive:!0}),()=>{window.removeEventListener("resize",i)}),[i]),{codeBlockRef:V,isEnabled:A,isCodeScrollable:t,toggle:o}}();return(0,Q.jsx)(p,{metadata:e,wordWrap:t,children:(0,Q.jsx)(rA,{})})}function BA({children:A,...e}){const t=(0,V.A)(),g=function(A){return n.Children.toArray(A).some(A=>(0,n.isValidElement)(A))?A:Array.isArray(A)?A.join(""):A}(A),o="string"==typeof g?IA:G;return(0,Q.jsx)(o,{...e,children:g},String(t))}function aA(A){return(0,Q.jsx)("code",{...A})}var CA=t(14783),QA=t(19819);var EA=t(37344),cA=t(94549);const lA="details_lb9f",uA="isBrowser_bmU9",dA="collapsibleContent_i85q";function hA(A){return!!A&&("SUMMARY"===A.tagName||hA(A.parentElement))}function fA(A,e){return!!A&&(A===e||fA(A.parentElement,e))}function wA({summary:A,children:e,...t}){(0,EA.A)().collectAnchor(t.id);const g=(0,V.A)(),i=(0,n.useRef)(null),{collapsed:s,setCollapsed:r}=(0,cA.u)({initialState:!t.open}),[I,B]=(0,n.useState)(t.open),a=n.isValidElement(A)?A:(0,Q.jsx)("summary",{children:A??"Details"});return(0,Q.jsxs)("details",{...t,ref:i,open:I,"data-collapsed":s,className:(0,o.A)(lA,g&&uA,t.className),onMouseDown:A=>{hA(A.target)&&A.detail>1&&A.preventDefault()},onClick:A=>{A.stopPropagation();const e=A.target;hA(e)&&fA(e,i.current)&&(A.preventDefault(),s?(r(!1),B(!0)):r(!0))},children:[a,(0,Q.jsx)(cA.N,{lazy:!1,collapsed:s,onCollapseTransitionEnd:A=>{r(A),B(!A)},children:(0,Q.jsx)("div",{className:dA,children:e})})]})}const mA="details_b_Ee";function yA({...A}){return(0,Q.jsx)(wA,{...A,className:(0,o.A)("alert alert--info",mA,A.className)})}function DA(A){const e=n.Children.toArray(A.children),t=e.find(A=>n.isValidElement(A)&&"summary"===A.type),g=(0,Q.jsx)(Q.Fragment,{children:e.filter(A=>A!==t)});return(0,Q.jsx)(yA,{...A,summary:t,children:g})}var pA=t(85225);function kA(A){return(0,Q.jsx)(pA.A,{...A})}const qA="containsTaskList_mC6p";function NA(A){if(void 0!==A)return(0,o.A)(A,A?.includes("contains-task-list")&&qA)}const FA="img_ev3q";var vA=t(54182),MA=t(33832),bA=t(34176);let GA=null;async function RA(){return GA||(GA=async function(){return(await t.e(2279).then(t.bind(t,22279))).default}()),GA}function LA(){const{colorMode:A}=(0,i.G)(),e=(0,s.p)().mermaid,t=e.theme[A],{options:g}=e;return(0,n.useMemo)(()=>({startOnLoad:!1,...g,theme:t}),[t,g])}function SA({text:A,config:e}){const[t,g]=(0,n.useState)(null),V=(0,n.useState)(`mermaid-svg-${Math.round(1e7*Math.random())}`)[0],o=LA(),i=e??o;return(0,n.useEffect)(()=>{(async function({id:A,text:e,config:t}){const n=await RA();n.initialize(t);try{return await n.render(A,e)}catch(g){throw document.querySelector(`#d${A}`)?.remove(),g}})({id:V,text:A,config:i}).then(g).catch(A=>{g(()=>{throw A})})},[V,A,i]),t}const JA="container_lyt7";function UA({renderResult:A}){const e=(0,n.useRef)(null);return(0,n.useEffect)(()=>{const t=e.current;A.bindFunctions?.(t)},[A]),(0,Q.jsx)("div",{ref:e,className:`docusaurus-mermaid-container ${JA}`,dangerouslySetInnerHTML:{__html:A.svg}})}function xA({value:A}){const e=SA({text:A});return null===e?null:(0,Q.jsx)(UA,{renderResult:e})}const YA={Head:g.A,details:DA,Details:DA,code:function(A){return function(A){return void 0!==A.children&&n.Children.toArray(A.children).every(A=>"string"==typeof A&&!A.includes("\n"))}(A)?(0,Q.jsx)(aA,{...A}):(0,Q.jsx)(BA,{...A})},a:function(A){const e=(0,QA.v)(A.id);return(0,Q.jsx)(CA.A,{...A,className:(0,o.A)(e,A.className)})},pre:function(A){return(0,Q.jsx)(Q.Fragment,{children:A.children})},ul:function(A){return(0,Q.jsx)("ul",{...A,className:NA(A.className)})},li:function(A){(0,EA.A)().collectAnchor(A.id);const e=(0,QA.v)(A.id);return(0,Q.jsx)("li",{className:(0,o.A)(e,A.className),...A})},img:function(A){return(0,Q.jsx)("img",{decoding:"async",loading:"lazy",...A,className:(e=A.className,(0,o.A)(e,FA))});var e},h1:A=>(0,Q.jsx)(kA,{as:"h1",...A}),h2:A=>(0,Q.jsx)(kA,{as:"h2",...A}),h3:A=>(0,Q.jsx)(kA,{as:"h3",...A}),h4:A=>(0,Q.jsx)(kA,{as:"h4",...A}),h5:A=>(0,Q.jsx)(kA,{as:"h5",...A}),h6:A=>(0,Q.jsx)(kA,{as:"h6",...A}),admonition:vA.A,mermaid:function(A){return(0,Q.jsx)(MA.A,{fallback:A=>(0,Q.jsx)(bA.MN,{...A}),children:(0,Q.jsx)(xA,{...A})})}}},18426:(A,e)=>{function t(A){let e,t=[];for(let n of A.split(",").map(A=>A.trim()))if(/^-?\d+$/.test(n))t.push(parseInt(n,10));else if(e=n.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[A,n,g,V]=e;if(n&&V){n=parseInt(n),V=parseInt(V);const A=n<V?1:-1;"-"!==g&&".."!==g&&"\u2025"!==g||(V+=A);for(let e=n;e!==V;e+=A)t.push(e)}}return t}e.default=t,A.exports=t},28453:(A,e,t)=>{"use strict";t.d(e,{R:()=>o,x:()=>i});var n=t(96540);const g={},V=n.createContext(g);function o(A){const e=n.useContext(V);return n.useMemo(function(){return"function"==typeof A?A(e):{...e,...A}},[e,A])}function i(A){let e;return e=A.disableParentContext?"function"==typeof A.components?A.components(g):A.components||g:o(A.components),n.createElement(V.Provider,{value:e},A.children)}},29813:(A,e,t)=>{"use strict";t.d(e,{A:()=>V});t(96540);var n=t(11062),g=t(74848);function V({children:A,fallback:e}){return(0,n.A)()?(0,g.jsx)(g.Fragment,{children:A?.()}):e??null}},30459:(A,e,t)=>{"use strict";function n(A){return"number"==typeof A?A:"string"==typeof A?A.split(":").reverse().map(parseFloat).reduce((A,e,t)=>A+e*Math.pow(60,t)):void 0}t.r(e),t.d(e,{create:()=>tn});class g{log(){}debug(){}info(){}warn(){}error(){}}class V{constructor(A,e){this.logger=A,this.prefix=e}log(A){for(var e=arguments.length,t=new Array(e>1?e-1:0),n=1;n<e;n++)t[n-1]=arguments[n];this.logger.log(`${this.prefix}${A}`,...t)}debug(A){for(var e=arguments.length,t=new Array(e>1?e-1:0),n=1;n<e;n++)t[n-1]=arguments[n];this.logger.debug(`${this.prefix}${A}`,...t)}info(A){for(var e=arguments.length,t=new Array(e>1?e-1:0),n=1;n<e;n++)t[n-1]=arguments[n];this.logger.info(`${this.prefix}${A}`,...t)}warn(A){for(var e=arguments.length,t=new Array(e>1?e-1:0),n=1;n<e;n++)t[n-1]=arguments[n];this.logger.warn(`${this.prefix}${A}`,...t)}error(A){for(var e=arguments.length,t=new Array(e>1?e-1:0),n=1;n<e;n++)t[n-1]=arguments[n];this.logger.error(`${this.prefix}${A}`,...t)}}let o;const i=new Array(128).fill(void 0);function s(A){return i[A]}function r(A){const e=typeof A;if("number"==e||"boolean"==e||null==A)return`${A}`;if("string"==e)return`"${A}"`;if("symbol"==e){const e=A.description;return null==e?"Symbol":`Symbol(${e})`}if("function"==e){const e=A.name;return"string"==typeof e&&e.length>0?`Function(${e})`:"Function"}if(Array.isArray(A)){const e=A.length;let t="[";e>0&&(t+=r(A[0]));for(let n=1;n<e;n++)t+=", "+r(A[n]);return t+="]",t}const t=/\[object ([^\]]+)\]/.exec(toString.call(A));let n;if(!(t.length>1))return toString.call(A);if(n=t[1],"Object"==n)try{return"Object("+JSON.stringify(A)+")"}catch(g){return"Object"}return A instanceof Error?`${A.name}: ${A.message}\n${A.stack}`:n}i.push(void 0,null,!0,!1);let I=0,B=null;function a(){return null!==B&&0!==B.byteLength||(B=new Uint8Array(o.memory.buffer)),B}const C="undefined"!=typeof TextEncoder?new TextEncoder("utf-8"):{encode:()=>{throw Error("TextEncoder not available")}},Q="function"==typeof C.encodeInto?function(A,e){return C.encodeInto(A,e)}:function(A,e){const t=C.encode(A);return e.set(t),{read:A.length,written:t.length}};function E(A,e,t){if(void 0===t){const t=C.encode(A),n=e(t.length,1)>>>0;return a().subarray(n,n+t.length).set(t),I=t.length,n}let n=A.length,g=e(n,1)>>>0;const V=a();let o=0;for(;o<n;o++){const e=A.charCodeAt(o);if(e>127)break;V[g+o]=e}if(o!==n){0!==o&&(A=A.slice(o)),g=t(g,n,n=o+3*A.length,1)>>>0;const e=a().subarray(g+o,g+n);o+=Q(A,e).written,g=t(g,n,o,1)>>>0}return I=o,g}let c=null;function l(){return null!==c&&0!==c.byteLength||(c=new Int32Array(o.memory.buffer)),c}let u=i.length;function d(A){const e=s(A);return function(A){A<132||(i[A]=u,u=A)}(A),e}function h(A){u===i.length&&i.push(i.length+1);const e=u;return u=i[e],i[e]=A,e}const f="undefined"!=typeof TextDecoder?new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0}):{decode:()=>{throw Error("TextDecoder not available")}};function w(A,e){return A>>>=0,f.decode(a().subarray(A,A+e))}"undefined"!=typeof TextDecoder&&f.decode();let m=null;function y(A,e){return A>>>=0,(null!==m&&0!==m.byteLength||(m=new Uint32Array(o.memory.buffer)),m).subarray(A/4,A/4+e)}const D="undefined"==typeof FinalizationRegistry?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(A=>o.__wbg_vt_free(A>>>0));class p{static __wrap(A){A>>>=0;const e=Object.create(p.prototype);return e.__wbg_ptr=A,D.register(e,e.__wbg_ptr,e),e}__destroy_into_raw(){const A=this.__wbg_ptr;return this.__wbg_ptr=0,D.unregister(this),A}free(){const A=this.__destroy_into_raw();o.__wbg_vt_free(A)}feed(A){const e=E(A,o.__wbindgen_export_0,o.__wbindgen_export_1),t=I;return d(o.vt_feed(this.__wbg_ptr,e,t))}resize(A,e){return d(o.vt_resize(this.__wbg_ptr,A,e))}getSize(){try{const n=o.__wbindgen_add_to_stack_pointer(-16);o.vt_getSize(n,this.__wbg_ptr);var A=l()[n/4+0],e=l()[n/4+1],t=y(A,e).slice();return o.__wbindgen_export_2(A,4*e,4),t}finally{o.__wbindgen_add_to_stack_pointer(16)}}getLine(A){return d(o.vt_getLine(this.__wbg_ptr,A))}getCursor(){return d(o.vt_getCursor(this.__wbg_ptr))}}function k(){const A={wbg:{}};return A.wbg.__wbindgen_is_string=function(A){return"string"==typeof s(A)},A.wbg.__wbg_new_b525de17f44a8943=function(){return h(new Array)},A.wbg.__wbg_set_17224bc548dd1d7b=function(A,e,t){s(A)[e>>>0]=d(t)},A.wbg.__wbindgen_debug_string=function(A,e){const t=E(r(s(e)),o.__wbindgen_export_0,o.__wbindgen_export_1),n=I;l()[A/4+1]=n,l()[A/4+0]=t},A.wbg.__wbindgen_object_drop_ref=function(A){d(A)},A.wbg.__wbindgen_number_new=function(A){return h(A)},A.wbg.__wbindgen_bigint_from_u64=function(A){return h(BigInt.asUintN(64,A))},A.wbg.__wbindgen_error_new=function(A,e){return h(new Error(w(A,e)))},A.wbg.__wbg_new_f9876326328f45ed=function(){return h(new Object)},A.wbg.__wbg_set_f975102236d3c502=function(A,e,t){s(A)[d(e)]=d(t)},A.wbg.__wbg_new_f841cc6f2098f4b5=function(){return h(new Map)},A.wbg.__wbg_set_388c4c6422704173=function(A,e,t){return h(s(A).set(s(e),s(t)))},A.wbg.__wbindgen_string_new=function(A,e){return h(w(A,e))},A.wbg.__wbindgen_object_clone_ref=function(A){return h(s(A))},A.wbg.__wbindgen_throw=function(A,e){throw new Error(w(A,e))},A}function q(A,e){return o=A.exports,N.__wbindgen_wasm_module=e,c=null,m=null,B=null,o}async function N(A){if(void 0!==o)return o;const e=k();("string"==typeof A||"function"==typeof Request&&A instanceof Request||"function"==typeof URL&&A instanceof URL)&&(A=fetch(A));const{instance:t,module:n}=await async function(A,e){if("function"==typeof Response&&A instanceof Response){if("function"==typeof WebAssembly.instantiateStreaming)try{return await WebAssembly.instantiateStreaming(A,e)}catch(t){if("application/wasm"==A.headers.get("Content-Type"))throw t;console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",t)}const n=await A.arrayBuffer();return await WebAssembly.instantiate(n,e)}{const t=await WebAssembly.instantiate(A,e);return t instanceof WebAssembly.Instance?{instance:t,module:A}:t}}(await A,e);return q(t,n)}var F=Object.freeze({__proto__:null,Vt:p,create:function(A,e,t){const n=o.create(A,e,t);return p.__wrap(n)},default:N,initSync:function(A){if(void 0!==o)return o;const e=k();return A instanceof WebAssembly.Module||(A=new WebAssembly.Module(A)),q(new WebAssembly.Instance(A,e),A)}});const v=[62,0,0,0,63,52,53,54,55,56,57,58,59,60,61,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,0,0,0,0,0,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51];function M(A){return v[A-43]}const b=function(A){let e,t=A.endsWith("==")?2:A.endsWith("=")?1:0,n=A.length,g=new Uint8Array(n/4*3);for(let V=0,o=0;V<n;V+=4,o+=3)e=M(A.charCodeAt(V))<<18|M(A.charCodeAt(V+1))<<12|M(A.charCodeAt(V+2))<<6|M(A.charCodeAt(V+3)),g[o]=e>>16,g[o+1]=e>>8&255,g[o+2]=255&e;return g.subarray(0,g.length-t)}("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QAJAAkACQAJAAkACQAJAAkAgAy8BACIDDh4AAQIDBAUOBg4HDg4ODg4ODg4ODg4ICAkKCw4MDg0OCyACQagBakEBIAEoAgAgASgCBEHQnMAAEI4BIAEgAikDqAE3AgAgAEEAOgAADBgLIAJBsAFqQQEgASgCACABKAIEQeCcwAAQjgEgASACKQOwATcCACAAQQE6AAAMFwsgAkG4AWpBASABKAIAIAEoAgRB8JzAABCOASABIAIpA7gBNwIAIABBAjoAAAwWCyACQcABakEBIAEoAgAgASgCBEGAncAAEI4BIAEgAikDwAE3AgAgAEEDOgAADBULIAJByAFqQQEgASgCACABKAIEQZCdwAAQjgEgASACKQPIATcCACAAQQQ6AAAMFAsgAkHQAWpBASABKAIAIAEoAgRBoJ3AABCOASABIAIpA9ABNwIAIABBBToAAAwTCyACQdgBakEBIAEoAgAgASgCBEGwncAAEI4BIAEgAikD2AE3AgAgAEEGOgAADBILIAJB4AFqQQEgASgCACABKAIEQcCdwAAQjgEgASACKQPgATcCACAAQQc6AAAMEQsgAkHoAWpBASABKAIAIAEoAgRB0J3AABCOASABIAIpA+gBNwIAIABBCDoAAAwQCyACQfABakEBIAEoAgAgASgCBEHgncAAEI4BIAEgAikD8AE3AgAgAEEJOgAADA8LIAJB+AFqQQEgASgCACABKAIEQfCdwAAQjgEgASACKQP4ATcCACAAQQo6AAAMDgsgAkGAAmpBASABKAIAIAEoAgRBgJ7AABCOASABIAIpA4ACNwIAIABBCzoAAAwNCyACQYgCakEBIAEoAgAgASgCBEGQnsAAEI4BIAEgAikDiAI3AgAgAEEMOgAADAwLIAJBkAJqQQEgASgCACABKAIEQaCewAAQjgEgASACKQOQAjcCACAAQQ06AAAMCwsCQAJAIANBHmtB//8DcUEITwRAIANBJmsOAgEIAgsgAkEIakEBIAEoAgAgASgCBEHAoMAAEI4BIAEgAikDCDcCACAAIANBHms6AAIgAEEOOwAADAwLAkAgASgCBCIDQQJPBEAgAkGYAWogASgCAEEQahByIAIoApgBIgMNASABKAIEIQMLIAJB6ABqQQEgASgCACADQbCewAAQjgEgAigCbCEDIAIoAmghBAwNCwJAAkACQCACKAKc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IAEvARg7AQQgACABLwEIOwECDC4LIABBAzoAACAAIAEvAQg7AQIMLQsgAS8BCA4EFxgZGhYLIAEvAQgOAxscHRoLIABBHjoAACAAIAEvAQg7AQIMKgsgAEEVOgAAIAAgAS8BCDsBAgwpCyAAQQ06AAAgACABLwEIOwECDCgLIABBLToAACAAIAEvAQg7AQIMJwsgAEEoOgAAIAAgAS8BCDsBAgwmCyABLwEIDgYZGBoYGBsYCyAAQRY6AAAgACABLwEIOwECDCQLIABBAToAACAAIAEvAQg7AQIMIwsgAEECOgAAIAAgAS8BCDsBAgwiCyAAQQo6AAAgACABLwEIOwECDCELIABBIjoAACAAIAEvAQg7AQIMIAsgAEEvOgAAIAAgAS8BCDsBAgwfCyAAQTA6AAAgACABLwEIOwECDB4LIABBCzoAACAAIAEvARg7AQQgACABLwEIOwECDB0LIAEvAQgOBBQTExUTCyADIAQgASgChARBgJzAABCBASADQUBrIgEgAygCACICIAIgAygCBEEEdGoQLyADQTtqIAFBCGooAgA2AAAgAyADKQJANwAzIABBKzoAACAAIAMpADA3AAEgAEEIaiADQTdqKQAANwAADBsLIANBCGogBCABKAKEBEGQnMAAEIEBIANBQGsiASADKAIIIgIgAiADKAIMQQR0ahAvIANBO2ogAUEIaigCADYAACADIAMpAkA3ADMgAEElOgAAIAAgAykAMDcAASAAQQhqIANBN2opAAA3AAAMGgsgA0EYaiAEIAEoAoQEQaCcwAAQgQEgAyADKQMYNwJMIANB1gBqIANBzABqEBACfyADLQBWQRJGBEBBACEBQQAhBEEBDAELIANBEGpBBEEBQQVBlInAABBrIANB2gBqLQAAIQEgAygCECECIAMoAhQiBCADKABWNgAAIARBBGogAToAACADQQE2AjggAyAENgI0IAMgAjYCMCADIAMpAkw3AkBBBSECQQEhAQNAIANB2wBqIANBQGsQECADLQBbQRJGRQRAIAMoAjAgAUYEQCADQTBqIAFBAUEBQQUQdyADKAI0IQQLIAIgBGoiBSADKABbNgAAIAVBBGogA0HfAGotAAA6AAAgAyABQQFqIgE2AjggAkEFaiECDAELCyADKAIwIQQgAygCNAshAiAAIAE2AgwgACACNgIIIAAgBDYC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IAdBAWsiBw0ACwtBB0kNAANAIAMgBC0AADoAACADQQFqIARBAWotAAA6AAAgA0ECaiAEQQJqLQAAOgAAIANBA2ogBEEDai0AADoAACADQQRqIARBBGotAAA6AAAgA0EFaiAEQQVqLQAAOgAAIANBBmogBEEGai0AADoAACADQQdqIARBB2otAAA6AAAgBEEIaiEEIAUgA0EIaiIDRw0ACwsgAiAGayIHQXxxIgggBWohAwJAIAEgBmoiBEEDcUUEQCADIAVNDQEgBCEBA0AgBSABKAIANgIAIAFBBGohASAFQQRqIgUgA0kNAAsMAQsgAyAFTQ0AIARBA3QiAkEYcSEGIARBfHEiCUEEaiEBQQAgAmtBGHEhCiAJKAIAIQIDQCACIAZ2IQkgBSAJIAEoAgAiAiAKdHI2AgAgAUEEaiEBIAVBBGoiBSADSQ0ACwsgB0EDcSECIAQgCGohAQsCQCACIANqIgYgA00NACACQQFrIAJBB3EiBARAA0AgAyABLQAAOgAAIAFBAWohASADQQFqIQMgBEEBayIEDQALC0EHSQ0AA0AgAyABLQAAOgAAIANBAWogAUEBai0AADoAACADQQJqIAFBAmotAAA6AAAgA0EDaiABQQNqLQAAOgAAIANBBGogAUEEai0AADoAACADQQVqIAFBBWotAAA6AAAgA0EGaiABQQZqLQAAOgAAIANBB2ogAUEHai0AADoAACABQQhqIQEgBiADQQhqIgNHDQALCyAAC+oEAQp/IwBBMGsiAyQAIAMgATYCLCADIAA2AiggA0EDOgAkIANCIDcCHCADQQA2AhQgA0EANgIMAn8CQAJAAkAgAigCECIKRQRAIAIoAgwiAEUNASACKAIIIgEgAEEDdGohBCAAQQFrQf////8BcUEBaiEHIAIoAgAhAANAIABBBGooAgAiBQRAIAMoAiggACgCACAFIAMoAiwoAgwRAwANBAsgASgCACADQQxqIAFBBGooAgARAgANAyAAQQhqIQAgBCABQQhqIgFHDQALDAELIAIoAhQiAEUNACAAQQV0IQsgAEEBa0H///8/cUEBaiEHIAIoAgghBSACKAIAIQADQCAAQQRqKAIAIgEEQCADKAIoIAAoAgAgASADKAIsKAIMEQMADQMLIAMgCCAKaiIBQRBqKAIANgIcIAMgAUEcai0AADoAJCADIAFB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QRBqIARBCGovAAA7AAALIAIgA0sNASABIANJDQIgA0EUbCIGIAJBFGwiAmshBSAAIAJqIQIgBEEIaiEHA0AgBQRAIAJCoICAgBA3AgAgAiAEKQAANwAIIAJBEGogBy8AADsAACAFQRRrIQUgAkEUaiECDAELCyABIANNDQAgACAGaiIAKAIEDQAgAEKggICAEDcCACAAIAQpAAA3AAggAEEQaiAEQQhqLwAAOwAACw8LIAIgA0G8lcAAEMoBAAsgAyABQbyVwAAQyAEAC4sCAQN/IwBBMGsiAyQAIAMgAjYCGCADIAE2AhQCQCADQRRqEGYiAUH//wNxQQNGBEAgAEEANgIIIABCgICAgCA3AgAMAQsgA0EIakEEQQJBAkGUicAAEGsgAygCCCECIAMoAgwiBCABOwEAIANBATYCJCADIAQ2AiAgAyACNgIcIAMgAykCFDcCKEECIQFBASECA0AgA0EoahBmIgVB//8DcUEDRkUEQCADKAIcIAJGBEAgA0EcaiACQQFBAkECEHcgAygCICEECyABIARqIAU7AQAgAyACQQFqIgI2AiQgAUECaiEBDAELCyAAIAMpAhw3AgAgAEEIaiADQSRqKAIANgIACyADQTBqJAALhQIBA38jAEEwayIDJAAgAyACNgIYIAMgATYCFAJAIANBFGoQW0H//wNxIgFFBEAgAEEANgIIIABCgICAgCA3AgAMAQsgA0EIakEEQQJBAkGUicAAEGsgAygCCCECIAMoAgwiBCABOwEAIANBATYCJCADIAQ2AiAgAyACNgIcIAMgAykCFDcCKEECIQFBASECA0AgA0EoahBbQf//A3EiBQRAIAMoAhwgAkYEQCADQRxqIAJBAUECQQIQdyADKAIgIQQLIAEgBGogBTsBACADIAJBAWoiAjYCJCABQQJqIQEMAQsLIAAgAykCHDcCACAAQQhqIANBJGooAgA2AgALIANBMGokAAuDAgECfyMAQTBrIgQkACAEQRBqIAAoAhggAxAyIARBCGogABB9IAQgASACIAQoAgggBCgCDEHcj8AAEHUCQCAEKAIEIgBFBEAgBCgCECAEKAIUQQRBFBCvAQwBCyAAQQR0IgFBEGshAyABIAQoAgAiAGoiAkEQayEBA0AgAwRAIARBIGoiBSAEQRBqEGEgACgCACAAQQRqKAIAQQRBFBCvASAA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ACIBBEAgAiABEQQACyAAKAIEIgEEQCACIAAoAgggARBDCwtCAQF/IwBBEGsiAyQAIANBCGogASACELUBIAMoAgwhASAAKAIIIAAoAgwQwgEgACABNgIMIABBATYCCCADQRBqJAALQgAgAC0AvAFBAUYEQCAAQQA6ALwBIABB9ABqIABBiAFqEH8gACAAQSRqEIABIAAoAmAgACgCZEEAIAAoAqABEGALC0EBA38gASgCFCICIAEoAhwiA2shBCACIANJBEAgBCACQbyPwAAQyQEACyAAIAM2AgQgACABKAIQIARBBHRqNgIAC0IBAX8jAEEgayIDJAAgA0EANgIQIANBATYCBCADQgQ3AgggAyABNgIcIAMgADYCGCADIANBGGo2AgAgAyACEJcBAAtBAQN/IAEoAhQiAiABKAIcIgNrIQQgAiADSQRAIAQgAkHMj8AAEMkBAAsgACADNgIEIAAgASgCECAEQQR0ajYCAAtEAQF/IAEoAgAiAiABKAIERgRAIABBgICAgHg2AgAPCyABIAJBEGo2AgAgACACKQIANwIAIABBCGogAkEIaikCADcCAAs7AQN/A0AgAkEURkUEQCAAIAJqIgMoAgAhBCADIAEgAmoiAygCADYCACADIAQ2AgAgAkEEaiECDAELCws7AQN/A0AgAkEkRkUEQCAAIAJqIgMoAgAhBCADIAEgAmoiAygCADYCACADIAQ2AgAgAkEEaiECDAELCws7AQF/AkAgAkF/RwRAIAJBAWohBCACQSBJDQEgBEEgIAMQyAEACyADEIoBAAsgACAENgIEIAAgATYCAAs4AAJAIAFpQQFHDQBBgICAgHggAWsgAEkNACAABEBBqfLAAC0AABogASAAED8iAUUNAQsgAQ8LAAs7AQF/IwBBEGsiAiQAIAEQvAEgAkEIaiABEJkBIAIoAgwhASAAIAIoAgg2AgAgACABNgIEIAJBEGokAAs4AAJAIAJBgIDEAEYNACAAIAIgASgCEBECAEUNAEEBDwsgA0UEQEEADwsgACADIAQgASgCDBEDAAstAQF/IAEgACgCAE8EfyAAKAIEIQIgAC0ACEUEQCABIAJNDwsgASACSQVBAAsLRAEBf0EBIQICQCABQQFLDQBByIHAACAAEIUBDQBB1IHAACAAEIUBDQBB4IHAACAAEIUBDQBB7IHAACAAEIUBIQILIAILNQEBfyABELwBIAEoAgAiAkF/RgRAEM0BAAsgASACQQFqNgIAIAAgATYCBCAAIAFBBGo2AgALNAEBfyAAKAIIIgMgACgCAEYEQCAAIAIQdAsgACADQQFqNgIIIAAoAgQgA0ECdGogATYCAAsuAQF/IwBBEGsiAiQAIAJBCGogASAAEJoBIAIoAggiAARAIAJBEGokACAADwsACzcBAX8jAEEgayIBJAAgAUEANgIYIAFBATYCDCABQYipwAA2AgggAUIENwIQIAFBCGogABCXAQALKgEBfyACIAMQPyIEBEAgBCAAIAEgAyABIANJGxAZGiAAIAIgARBDCyAECysAIAIgA0kEQCADIAIgBBDJAQALIAAgAiADazYCBCAAIAEgA0EUbGo2AgALLwEBfyAAIAIQnQEgACgCBCAAKAIIIgNBFGxqIAEgAkEUbBAZGiAAIAIgA2o2AggLKwAgASADSwRAIAEgAyAEEMkBAAsgACADIAFrNgIEIAAgAiABQQR0ajYCAAswAAJAAkAgA2lBAUcNAEGAgICAeCADayABSQ0AIAAgASADIAIQiwEiAA0BCwALIAALLgADQCABBEAgACgCACAAQQRqKAIAQQRBFBCvASABQQFrIQEgAEEQaiEADAELCwsyAQF/IAAoAgghAiABIAAoAgBBAmotAAAQqwEhASAAKAIEIAIgARACIAAgAkEBajYCCAsqACAAIAAoAmggAWoiASAAKAKcASIAQQFrIAAgAUsbQQAgAUEAThs2AmgLMwECfyAAIAAoAqgBIgIgACgCrAFBAWoiAyABIABBsgFqEEEgACgCYCAAKAJkIAIgAxBgCzMBAn8gACAAKAKoASICIAAoAqwBQQFqIgMgASAAQbIBahAgIAAoAmAgACgCZCACIAMQYAsqACABIAJJBEBBpInAAEEjQZSKwAAQfAALIAIgACACQRRsaiABIAJrEB0LNQAgACAAKQJ0NwJoIAAgACkBfDcBsgEgACAALwGGATsBvgEgAEG6AWogAEGEAWovAQA7AQAL7AECAn8BfiMAQRBrIgIkACACQQE7AQwgAiABNgIIIAIgADYCBCMAQRBrIgEkACACQQRqIgApAgAhBCABIAA2AgwgASAENwIEIwBBEGsiACQAIAFBBGoiASgCACICKAIMIQMCQAJAAkACQCACKAIEDgIAAQILIAMNAUEBIQJBACEDDAILIAMNACACKAIAIgIoAgQhAyACKAIAIQIMAQsgAEGAgICAeDYCACAAIAE2AgwgASgCCCIBLQAJGiAAQRkgAS0ACBBXAAsgACADNgIEIAAgAjYCACABKAIIIgEtAAkaIABBGiABLQAIEFcACysBAn8CQCAAKAIEIAAoAggiARA+IgJFDQAgASACSQ0AIAAgASACazYCCAsLKAAgASgCAEUEQCABQX82AgAgACABNgIEIAAgAUEEajYCAA8LEM0BAAsmACACBEBBqfLAAC0AABogASACED8hAQsgACACNgIEIAAgATYCAAsjAQF/IAEgACgCACAAKAIIIgJrSwRAIAAgAiABQQFBARB3CwsjAQF/IAEgACgCACAAKAIIIgJrSwRAIAAgAiABQQRBEBB3CwsjAQF/IAEgACgCACAAKAIIIgJrSwRAIAAgAiABQQRBFBB3CwslACAAQQE2AgQgACABKAIEIAEoAgBrQQR2IgE2AgggACABNgIACxsAIAEgAk0EQCACIAEgAxBYAAsgACACQRRsagsgACABIAJNBEAgAiABQeCjwAAQWAALIAAgAmpBAToAAAsbACABIAJNBEAgAiABIAMQWAALIAAgAkEEdGoLAwAACwMAAAsDAAALAwAACwMAAAsDAAALGgBBqfLAAC0AABpBBCAAED8iAARAIAAPCwALHQAgBCAAQQJqLQAAEKsBIQAgASACIAMQIyAAEAkLIQAgAEUEQEGYq8AAQTIQzAEACyAAIAIgAyABKAIQEQEACxYAIAFBAXFFBEAgALgQBQ8LIACtEAYLHwAgAEUEQEGYq8AAQTIQzAEACyAAIAIgASgCEBECAAsbAQF/IAEQACECIAAgATYCBCAAIAJBAUc2AgALGQEBfyAAKAIAIgEEQCAAKAIEQQEgARBDCwsSACAABEAgASACIAAgA2wQQwsLIQEBfyAAKAIQIgEgACgCFBCQASAAKAIMIAFBBEEQEK8BCyEBAX8gACgCBCIBIAAoAggQkAEgACgCACABQQRBEBCvAQsWACAAQQFxRQRAQYCAwABBFRDMAQALCxMAIAFFBEBBAEEAIAIQWAALIAALFgAgAEEQahBlIAAoAgAgACgCBBC3AQsUACAAIAEgAhAMNgIEIABBADYCAAsZACABKAIcQd+DwABBBSABKAIgKAIMEQMACxkAIABBgICAgHhHBEAgACABQQRBFBCvAQsLFAAgAQRAQYCAgIB4IAEQtwELIAELGQAgASgCHEHEpcAAQQ4gASgCICgCDBEDAAsPACACBEAgACABIAIQQwsLDwAgAQRAIAAgAiABEEMLCxMAIAAEQA8LQajowABBGxDMAQALDwAgAEGEAU8EQCAAEAQLCxMAIAAoAgggACgCAEECQQIQrwELFQAgAiACELgBGiAAQYCAgIB4NgIACxQAIAAoAgAgASAAKAIEKAIMEQIACxAAIAEgACgCBCAAKAIIEBMLDAAgAARAIAEQvQELCzwAIABFBEAjAEEgayIAJAAgAEEANgIYIABBATYCDCAAQZCEwAA2AgggAEIENwIQIABBCGogARCXAQALAAsUACAAQQA2AgggAEKAgICAEDcCAAsSACAAIAFBjI3AABBtQQE6AAwLEAAgASAAKAIAIAAoAgQQEwsOAEHspcAAQSsgABB8AAtrAQF/IwBBMGsiAyQAIAMgATYCBCADIAA2AgAgA0ECNgIMIANB5KnAADYCCCADQgI3AhQgAyADQQRqrUKAgICAsAGENwMoIAMgA61CgICAgLABhDcDICADIANBIGo2AhAgA0EIaiACEJcBAAtrAQF/IwBBMGsiAyQAIAMgATYCBCADIAA2AgAgA0ECNgIMIANBxKnAADYCCCADQgI3AhQgAyADQQRqrUKAgICAsAGENwMoIAMgA61CgICAgLABhDcDICADIANBIGo2AhAgA0EIaiACEJcBAAtrAQF/IwBBMGsiAyQAIAMgATYCBCADIAA2AgAgA0ECNgIMIANBmKrAADYCCCADQgI3AhQgAyADQQRqrUKAgICAsAGENwMoIAMgA61CgICAgLABhDcDICADIANBIGo2AhAgA0EIaiACEJcBAAsLACAAIwBqJAAjAAsJACAAIAEQDgALDgBBw+jAAEHPABDMAQALDQAgAEHkg8AAIAEQGgsNACAAQfCmwAAgARAaCwwAIAAgASkCADcDAAsKACAAKAIAEL0BCw0AIABBgICAgHg2AgALCQAgAEEANgIACwYAIAAQZQsFAEGABAsEAEEBCwQAIAELBABBAAsLi2gRAEGAgMAAC98EYHVud3JhcF90aHJvd2AgZmFpbGVkAAAAGwAAAAQAAAAEAAAAHAAAAGNhbGxlZCBgUmVzdWx0Ojp1bndyYXAoKWAgb24gYW4gYEVycmAgdmFsdWVNYXAga2V5IGlzIG5vdCBhIHN0cmluZyBhbmQgY2Fubm90IGJlIGFuIG9iamVjdCBrZXkAADQKEABYAAAAfQEAADMAAAA0ChAAWAAAAIIBAAAcAAAANAoQAFgAAAB/AQAAHAAAADQKEABYAAAAeQEAABwAAAAAJQAAfyUAAAAAAAAAKAAA/ygAAAAAAACAJQAAnyUAAAAAAACw4AAAs+AAAAAAAABmZ3NyYy9saWIucnNiZ2ZhaW50Ym9sZGl0YWxpY3VuZGVybGluZXN0cmlrZXRocm91Z2hibGlua2ludmVyc2UjNwEQAAEAAAABAAAAAAAAAAEAAAAAAAAA+gAQAAoAAAAlAAAANgAAAPoAEAAKAAAAKgAAADYAAAD6ABAACgAAAEwAAAAxAAAA+gAQAAoAAABDAAAAIAAAAPoAEAAKAAAARgAAACIAAAD6ABAACgAAAEEAAAAWAAAA+gAQAAoAAABTAAAALwAAAHRleHRwZW5vZmZzZXRjZWxsQ291bnRjaGFyV2lkdGhFcnJvch0AAAAMAAAABAAAAB4AAAAfAAAAIAAAAGNhcGFjaXR5IG92ZXJmbG93AAAA/AEQABEAAABsaWJyYXJ5L2FsbG9jL3NyYy9yYXdfdmVjLnJzGAIQABwAAAAoAgAAEQAAAGxpYnJhcnkvYWxsb2Mvc3JjL3N0cmluZy5ycwBB6ITAAAuVHwEAAAAhAAAAYSBmb3JtYXR0aW5nIHRyYWl0IGltcGxlbWVudGF0aW9uIHJldHVybmVkIGFuIGVycm9yIHdoZW4gdGhlIHVuZGVybHlpbmcgc3RyZWFtIGRpZCBub3RsaWJyYXJ5L2FsbG9jL3NyYy9mbXQucnMAAMYCEAAYAAAAigIAAA4AAABEAhAAGwAAAI0FAAAbAAAAKSBzaG91bGQgYmUgPCBsZW4gKGlzIGluc2VydGlvbiBpbmRleCAoaXMgKSBzaG91bGQgYmUgPD0gbGVuIChpcyAAAAAWAxAAFAAAACoDEAAXAAAAFDQQAAEAAAByZW1vdmFsIGluZGV4IChpcyAAAFwDEAASAAAAAAMQABYAAAAUNBAAAQAAAGBhdGAgc3BsaXQgaW5kZXggKGlzIAAAAIgDEAAVAAAAKgMQABcAAAAUNBAAAQAAAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3VuaWNvZGUtd2lkdGgtMC4xLjE0L3NyYy90YWJsZXMucnO4AxAAZAAAAJEAAAAVAAAAuAMQAGQAAACXAAAAGQAAAC9ydXN0Yy80ZDkxZGU0ZTQ4MTk4ZGEyZTMzNDEzZWZkY2Q5Y2QyY2MwYzQ2Njg4L2xpYnJhcnkvY29yZS9zcmMvaXRlci90cmFpdHMvaXRlcmF0b3IucnM8BBAAWAAAALMHAAAJAAAAYXNzZXJ0aW9uIGZhaWxlZDogbWlkIDw9IHNlbGYubGVuKCkvcnVzdGMvNGQ5MWRlNGU0ODE5OGRhMmUzMzQxM2VmZGNkOWNkMmNjMGM0NjY4OC9saWJyYXJ5L2NvcmUvc3JjL3NsaWNlL21vZC5yc8cEEABNAAAAoA0AAAkAAABhc3NlcnRpb24gZmFpbGVkOiBrIDw9IHNlbGYubGVuKCkAAADHBBAATQAAAM0NAAAJAAAAL3J1c3RjLzRkOTFkZTRlNDgxOThkYTJlMzM0MTNlZmRjZDljZDJjYzBjNDY2ODgvbGlicmFyeS9hbGxvYy9zcmMvc2xpY2UucnMAAFgFEABKAAAAoQAAABkAAAAvcnVzdGMvNGQ5MWRlNGU0ODE5OGRhMmUzMzQxM2VmZGNkOWNkMmNjMGM0NjY4OC9saWJyYXJ5L2FsbG9jL3NyYy92ZWMvbW9kLnJztAUQAEwAAAA/CgAAJAAAAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2F2dC0wLjE2LjAvc3JjL2J1ZmZlci5ycwAAEAYQAFoAAAAtAAAAGQAAABAGEABaAAAAWgAAAA0AAAAQBhAAWgAAAF4AAAANAAAAEAYQAFoAAABjAAAADQAAABAGEABaAAAAaAAAAB0AAAAQBhAAWgAAAHUAAAAlAAAAEAYQAFoAAAB/AAAAJQAAABAGEABaAAAAhwAAABUAAAAQBhAAWgAAAJEAAAAlAAAAEAYQAFoAAACYAAAAFQAAABAGEABaAAAAnQAAACUAAAAQBhAAWgAAAKgAAAARAAAAEAYQAFoAAACzAAAA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cnR5X2xpbmVzLnJzaBEQAGgAAAAIAAAAFAAAAGgREABoAAAADAAAAA8AAABoERAAaAAAABAAAAAPAEGIpMAAC9MHAQAAACIAAAAjAAAAJAAAACUAAAAmAAAAFAAAAAQAAAAnAAAAKAAAACkAAAAqAAAAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvYXZ0LTAuMTYuMC9zcmMvdGVybWluYWwucnM4EhAAXAAAAHUCAAAVAAAAOBIQAFwAAACxAgAADgAAADgSEABcAAAABQQAACMAAABCb3Jyb3dNdXRFcnJvcmFscmVhZHkgYm9ycm93ZWQ6INISEAASAAAAY2FsbGVkIGBPcHRpb246OnVud3JhcCgpYCBvbiBhIGBOb25lYCB2YWx1ZWluZGV4IG91dCBvZiBib3VuZHM6IHRoZSBsZW4gaXMgIGJ1dCB0aGUgaW5kZXggaXMgAAAAFxMQACAAAAA3ExAAEgAAADogAAABAAAAAAAAAFwTEAACAAAAAAAAAAwAAAAEAAAAKwAAACwAAAAtAAAAICAgICwKKCgKMHgwMDAxMDIwMzA0MDUwNjA3MDgwOTEwMTExMjEzMTQxNTE2MTcxODE5MjAyMTIyMjMyNDI1MjYyNzI4MjkzMDMxMzIzMzM0MzUzNjM3MzgzOTQwNDE0MjQzNDQ0NTQ2NDc0ODQ5NTA1MTUyNTM1NDU1NTY1NzU4NTk2MDYxNjI2MzY0NjU2NjY3Njg2OTcwNzE3MjczNzQ3NTc2Nzc3ODc5ODA4MTgyODM4NDg1ODY4Nzg4ODk5MDkxOTI5Mzk0OTU5Njk3OTg5OWF0dGVtcHRlZCB0byBpbmRleCBzbGljZSB1cCB0byBtYXhpbXVtIHVzaXplAFsUEAAsAAAAcmFuZ2Ugc3RhcnQgaW5kZXggIG91dCBvZiByYW5nZSBmb3Igc2xpY2Ugb2YgbGVuZ3RoIJAUEAASAAAAohQQACIAAAByYW5nZSBlbmQgaW5kZXgg1BQQABAAAACiFBAAIgAAAHNsaWNlIGluZGV4IHN0YXJ0cyBhdCAgYnV0IGVuZHMgYXQgAPQUEAAWAAAAChUQAA0AAABIYXNoIHRhYmxlIGNhcGFjaXR5IG92ZXJmbG93KBUQABwAAAAvcnVzdC9kZXBzL2hhc2hicm93bi0wLjE1LjIvc3JjL3Jhdy9tb2QucnMAAEwVEAAqAAAAIwAAACgAAACSNBAAawAAABkBAAASAAAAY2xvc3VyZSBpbnZva2VkIHJlY3Vyc2l2ZWx5IG9yIGFmdGVyIGJlaW5nIGRyb3BwZWQAAAAAAAD//////////9AVEABB6KvAAAvhAS9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3NlcmRlLXdhc20tYmluZGdlbi0wLjYuNS9zcmMvbGliLnJzAAAA6BUQAGUAAAA1AAAADgAAAC9ydXN0Yy80ZDkxZGU0ZTQ4MTk4ZGEyZTMzNDEzZWZkY2Q5Y2QyY2MwYzQ2Njg4L2xpYnJhcnkvYWxsb2Mvc3JjL3N0cmluZy5ycwBgFhAASwAAAI0FAAAbAAAAwDMQAEwAAAAoAgAAEQBBga7AAAuHAQECAwMEBQYHCAkKCwwNDgMDAwMDAwMPAwMDAwMDAw8JCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCRAJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQBBgbDAAAufCwECAgICAwICBAIFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdAgIeAgICAgICAh8gISIjAiQlJicoKQIqAgICAissAgICAi0uAgICLzAxMjMCAgICAgI0AgI1NjcCODk6Ozw9Pj85OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTlAOTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OUECAkJDAgJERUZHSEkCSjk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OUsCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI5OTk5TAICAgICTU5PUAICAlECUlMCAgICAgICAgICAgICVFUCAlYCVwICWFlaW1xdXl9gYQJiYwJkZWZnAmgCaWprbAICbW5vcAJxcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnR1AgICAgICAnZ3OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTl4OTk5OTk5OTk5eXoCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAns5OXw5OX0CAgICAgICAgICAgICAgICAgICfgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAn8CAgKAgYICAgICAgICAgICAgICAgKDhAICAgICAgICAgKFhnUCAocCAgKIAgICAgICAomKAgICAgICAgICAgICAouMAo2OAo+QkZKTlJWWApcCApiZmpsCAgICAgICAgICOTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5nB0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAnQICAgKenwIEAgUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0CAh4CAgICAgICHyAhIiMCJCUmJygpAioCAgICoKGio6Slpi6nqKmqq6ytMwICAgICAq4CAjU2NwI4OTo7PD0+rzk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OUwCAgICArBOT7GFhnUCAocCAgKIAgICAgICAomKAgICAgICAgICAgICAouMsrOOAo+QkZKTlJWWApcCApiZmpsCAgICAgICAgICVVV1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAEG8u8AACylVVVVVFQBQVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAQBB77vAAAvEARBBEFVVVVVVV1VVVVVVVVVVVVFVVQAAQFT13VVVVVVVVVVVFQAAAAAAVVVVVfxdVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUFABQAFARQVVVVVVVVVRVRVVVVVVVVVQAAAAAAAEBVVVVVVVVVVVXVV1VVVVVVVVVVVVVVBQAAVFVVVVVVVVVVVVVVVVUVAABVVVFVVVVVVQUQAAABAVBVVVVVVVVVVVVVAVVVVVVV/////39VVVVQVQAAVVVVVVVVVVVVVQUAQcC9wAALmARAVVVVVVVVVVVVVVVVVUVUAQBUUQEAVVUFVVVVVVVVVVFVVVVVVVVVVVVVVVVVVUQBVFVRVRVVVQVVVVVVVVVFQVVVVVVVVVVVVVVVVVVVVEEVFFBRVVVVVVVVVVBRVVVBVVVVVVVVVVVVVVVVVVVUARBUUVVVVVUFVVVVVVUFAFFVVVVVVVVVVVVVVVVVVQQBVFVRVQFVVQVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVRVRVVVFVFVVVVVVVVVVVVVVUVFVVVVVVVVVVVVVVVVUEVAUEUFVBVVUFVVVVVVVVVVFVVVVVVVVVVVVVVVVVVRREBQRQVUFVVQVVVVVVVVVVUFVVVVVVVVVVVVVVVVUVRAFUVUFVFVVVBVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVVVVVFFQVEVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVEAQFVVFQBAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUQAAVFVVAEBVVVVVVVVVVVVVVVVVVVVVVVVQVVVVVVVVEVFVVVVVVVVVVVVVVVVVAQAAQAAEVQEAAAEAAAAAAAAAAFRVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUBBABBQVVVVVVVVVAFVFVVVQFUVVVFQVVRVVVVUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqgBBgMLAAAuQA1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAVVVVVVVVVVVVVVVVQVUVVVVVVVVBVVVVVVVVVUFVVVVVVVVVQVVVVV///33//3XX3fW1ddVEABQVUUBAABVV1FVVVVVVVVVVVVVFQBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUFVVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAVVFVFVQFVVVVVVVVVVVVVVVVVVVVVVVVVVVVXFRRVVVVVVVVVVVVVVVVVVUUAQEQBAFQVAAAUVVVVVVVVVVVVVVVVAAAAAAAAAEBVVVVVVVVVVVVVVVUAVVVVVVVVVVVVVVVVAABQBVVVVVVVVVVVVRUAAFVVVVBVVVVVVVVVBVAQUFVVVVVVVVVVVVVVVVVFUBFQVVVVVVVVVVVVVVVVVVUAAAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAAAAAEAFRRVVRQVVVVVVVVVVVVVVVVVVVVVVUAQaDFwAALkwhVVRUAVVVVVVVVBUBVVVVVVVVVVVVVVVUAAAAAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAAAAAAAAAABUVVVVVVVVVVVV9VVVVWlVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf1X11VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV9VVVVVVVfVVVVVVVVVVVVVVVV////VVVVVVVVVVVVVdVVVVVV1VVVVV1V9VVVVVV9VV9VdVVXVVVVVXVV9V11XVVd9VVVVVVVVVVXVVVVVVVVVVV31d9VVVVVVVVVVVVVVVVVVVX9VVVVVVVVV1VV1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVXVV1VVVVVVVVVVVVVVVVddVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVQVVVVVVVVVVVVVVVVVVVV/f///////////////19V1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAAAAAAAAAAKqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqVVVVqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpaVVVVVVVVqqqqqqqqqqqqqqqqqqoKAKqqqmqpqqqqqqqqqqqqqqqqqqqqqqqqqqpqgaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpVqaqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqKqqqqqqqqqqqmqqqqqqqqqqqqqqqqqqqqqqqqqqqqpVVZWqqqqqqqqqqqqqqmqqqqqqqqqqqqqqVVWqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqVVVVVVVVVVVVVVVVVVVVVaqqqlaqqqqqqqqqqqqqqqqqalVVVVVVVVVVVVVVVVVfVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFUAAAFBVVVVVVVVVBVVVVVVVVVVVVVVVVVVVVVVVVVVVUFVVVUVFFVVVVVVVVUFVVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQVVVVVVVVAAAAAFBVRRVVVVVVVVVVVVUFAFBVVVVVVRUAAFBVVVWqqqqqqqqqVkBVVVVVVVVVVVVVVRUFUFBVVVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVVVQFAQUFVVRVVVVRVVVVVVVVVVVVVVVRVVVVVVVVVVVVVVVUEFFQFUVVVVVVVVVVVVVVQVUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVFFVVVVVqqqqqqqqqqqqVVVVAAAAAABAFQBBv83AAAvhDFVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQAAAPCqqlpVAAAAAKqqqqqqqqqqaqqqqqpqqlVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRWpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpWVVVVVVVVVVVVVVVVVVUFVFVVVVVVVVVVVVVVVVVVVapqVVUAAFRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVBUBVAUFVAFVVVVVVVVVVVVVAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQVVVVVVVVdVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVRVVVVVVVVVVVVVVVVVVVVVVVVVAVVVVVVVVVVVVVVVVVVVVVVVBQAAVFVVVVVVVVVVVVVVBVBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVVVVVVVVVVVVVVVVVQAAAEBVVVVVVVVVVVVVFFRVFVBVVVVVVVVVVVVVVRVAQVVFVVVVVVVVVVVVVVVVVVVVQFVVVVVVVVVVFQABAFRVVVVVVVVVVVVVVVVVVRVVVVVQVVVVVVVVVVVVVVVVBQBABVUBFFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVAEVUVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVFQBAVVVVVVVQVVVVVVVVVVVVVVVVVRVEVFVVVVUVVVVVBQBUAFRVVVVVVVVVVVVVVVVVVVVVAAAFRFVVVVVVRVVVVVVVVVVVVVVVVVVVVVVVVVVVFABEEQRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRUFUFUQVFVVVVVVVVBVVVVVVVVVVVVVVVVVVVVVVVVVVRUAQBFUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVRABBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAQUQAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFQAAQVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFUVBBFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUABVVUVVVVVVVVVQEAQFVVVVVVVVVVVRUABEBVFVVVAUABVVVVVVVVVVVVVQAAAABAUFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAQAAQVVVVVVVVVVVVVVVVVVVVVVVVVVUFAAAAAAAFAARBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAUBFEAAAVVVVVVVVVVVVVVVVVVVVVVVVUBFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVVFVVQFVVVVVVVVVVVVVVVQVAVURVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVBUAAABQVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAVFVVVVVVVVVVVVVVVVVVAEBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVVRVAVVVVVVVVVVVVVVVVVVVVVVVVVapUVVVaVVVVqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqVVWqqqqqqqqqqqqqqqqqqqqqqqqqqqpaVVVVVVVVVVVVVaqqVlVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVaqpqmmqqqqqqqqqqmpVVVVlVVVVVVVVVWpZVVVVqlVVqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpVVVVVVVVVVUEAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAQavawAALdVAAAAAAAEBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVURUAUAAAAAQAEAVVVVVVVVVQVQVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVBVRVVVVVVVVVVVVVVVVVVQBBrdvAAAsCQBUAQbvbwAALxQZUVVFVVVVUVVVVVRUAAQAAAFVVVVVVVVVVVVVVVVVVVVVVVVVVAEAAAAAAFAAQBEBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVVQBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQBAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAEBVVVVVVVVVVVVVVVVVVVdVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV1VVVVVVVVVVVVVVVVVVVVXX9/39VVVVVVVVVVVVVVVVVVVVVVVX1////////blVVVaqquqqqqqrq+r+/VaqqVlVfVVVVqlpVVVVVVVX//////////1dVVf3/3///////////////////////9///////VVVV/////////////3/V/1VVVf////9XV///////////////////////f/f/////////////////////////////////////////////////////////////1////////////////////19VVdV/////////VVVVVXVVVVVVVVV9VVVVV1VVVVVVVVVVVVVVVVVVVVVVVVVV1f///////////////////////////1VVVVVVVVVVVVVVVf//////////////////////X1VXf/1V/1VV1VdV//9XVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV////VVdVVVVVVVX//////////////3///9//////////////////////////////////////////////////////////////VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf///1f//1dV///////////////f/19V9f///1X//1dV//9XVaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpaVVVVVVVVVVVZllVhqqVZqlVVVVVVlVVVVVVVVVWVVVUAQY7iwAALAQMAQZziwAAL4QdVVVVVVZVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRUAlmpaWmqqBUCmWZVlVVVVVVVVVVUAAAAAVVZVValWVVVVVVVVVVVVVlVVVVVVVVVVAAAAAAAAAABUVVVVlVlZVVVlVVVpVVVVVVVVVVVVVVWVVpVqqqqqVaqqWlVVVVlVqqqqVVVVVWVVVVpVVVVVpWVWVVVVlVVVVVVVVaaWmpZZWWWplqqqZlWqVVpZVVpWZVVVVWqqpaVaVVVVpapaVVVZWVVVWVVVVVVVlVVVVVVVVVVVVVVVVVVVVVVVVVVVZVX1VVVVaVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqVaqqqqqqqqqqqlVVVaqqqqqlWlVVmqpaVaWlVVpapZalWlVVVaVaVZVVVVV9VWlZpVVfVWZVVVVVVVVVVWZV////VVVVmppqmlVVVdVVVVVV1VVVpV1V9VVVVVW9Va+quqqrqqqaVbqq+q66rlVd9VVVVVVVVVVXVVVVVVlVVVV31d9VVVVVVVVVpaqqVVVVVVVV1VdVVVVVVVVVVVVVVVVXrVpVVVVVVVVVVVWqqqqqqqqqaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqgAAAMCqqlpVAAAAAKqqqqqqqqqqaqqqqqpqqlVVVVVVVVVVVVVVVQVUVVVVVVVVVVVVVVVVVVVVqmpVVQAAVFmqqmpVqqqqqqqqqlqqqqqqqqqqqqqqqqqqqlpVqqqqqqqqqrr+/7+qqqqqVlVVVVVVVVVVVVVVVVX1////////L3J1c3RjLzRkOTFkZTRlNDgxOThkYTJlMzM0MTNlZmRjZDljZDJjYzBjNDY2ODgvbGlicmFyeS9hbGxvYy9zcmMvcmF3X3ZlYy5yc0pzVmFsdWUoKQAAAAw0EAAIAAAAFDQQAAEAAABudWxsIHBvaW50ZXIgcGFzc2VkIHRvIHJ1c3RyZWN1cnNpdmUgdXNlIG9mIGFuIG9iamVjdCBkZXRlY3RlZCB3aGljaCB3b3VsZCBsZWFkIHRvIHVuc2FmZSBhbGlhc2luZyBpbiBydXN0L2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvd2FzbS1iaW5kZ2VuLTAuMi45Mi9zcmMvY29udmVydC9zbGljZXMucnMARwlwcm9kdWNlcnMBDHByb2Nlc3NlZC1ieQIGd2FscnVzBjAuMjAuMwx3YXNtLWJpbmRnZW4SMC4yLjkyICgyYTRhNDkzNjIp");class G{constructor(){let A=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;this.speed=A,this.startTime=performance.now()}getTime(){return this.speed*(performance.now()-this.startTime)/1e3}setTime(A){this.startTime=performance.now()-A/this.speed*1e3}}class R{constructor(){}getTime(A){}setTime(A){}}class L{constructor(A,e){this.input="function"==typeof A.next?A:A[Symbol.iterator](),this.xfs=e??[]}map(A){return this.transform(function(A){return e=>t=>{e(A(t))}}(A))}flatMap(A){return this.transform(function(A){return e=>t=>{A(t).forEach(e)}}(A))}filter(A){return this.transform(function(A){return e=>t=>{A(t)&&e(t)}}(A))}take(A){return this.transform(function(A){let e=0;return t=>n=>{e<A&&t(n),e+=1}}(A))}drop(A){return this.transform(function(A){let e=0;return t=>n=>{e+=1,e>A&&t(n)}}(A))}transform(A){return new L(this.input,this.xfs.concat([A]))}multiplex(A,e){return new L(new J(this[Symbol.iterator](),A[Symbol.iterator](),e))}toArray(){return Array.from(this)}[Symbol.iterator](){let A=0,e=[],t=!1;const n=(g=this.xfs,V=A=>e.push(A),g.reverse().reduce((A,e)=>{const t=S(e(A.step));return{step:t.step,flush:()=>{t.flush(),A.flush()}}},S(V)));var g,V;return{next:()=>{for(A===e.length&&(e=[],A=0);0===e.length;){const A=this.input.next();if(A.done)break;n.step(A.value)}return 0!==e.length||t||(n.flush(),t=!0),e.length>0?{done:!1,value:e[A++]}:{done:!0}}}}}function S(A){return"function"==typeof A?{step:A,flush:()=>{}}:A}class J{constructor(A,e,t){this.left=A,this.right=e,this.comparator=t}[Symbol.iterator](){let A,e;return{next:()=>{if(void 0===A&&void 0!==this.left){const e=this.left.next();e.done?this.left=void 0:A=e.value}if(void 0===e&&void 0!==this.right){const A=this.right.next();A.done?this.right=void 0:e=A.value}if(void 0===A&&void 0===e)return{done:!0};if(void 0===A){const A=e;return e=void 0,{done:!1,value:A}}if(void 0===e){const e=A;return A=void 0,{done:!1,value:e}}if(this.comparator(A,e)){const e=A;return A=void 0,{done:!1,value:e}}{const A=e;return e=void 0,{done:!1,value:A}}}}}}async function U(A){if(A instanceof Response){const e=await A.text(),t=function(A){const e=A.split("\n");let t;try{t=JSON.parse(e[0])}catch(g){return}const n=new L(e).drop(1).filter(A=>"["===A[0]).map(JSON.parse);return{header:t,events:n}}(e);if(void 0!==t){const{header:A,events:e}=t;if(2===A.version)return Y(A,e);if(3===A.version)return K(A,e);throw`asciicast v${A.version} format not supported`}{const A=JSON.parse(e);if(1===A.version)return x(A)}}else{if("object"==typeof A&&1===A.version)return x(A);if(Array.isArray(A)){const e=A[0];if(2===e.version){return Y(e,A.slice(1,A.length))}if(3===e.version){return K(e,A.slice(1,A.length))}throw`asciicast v${e.version} format not supported`}}throw"invalid data"}function x(A){let e=0;const t=new L(A.stdout).map(A=>(e+=A[0],[e,"o",A[1]]));return{cols:A.width,rows:A.height,events:t}}function Y(A,e){return{cols:A.width,rows:A.height,theme:T(A.theme),events:e,idleTimeLimit:A.idle_time_limit}}function K(A,e){e instanceof L||(e=new L(e));let t=0;return e=e.map(A=>(t+=A[0],[t,A[1],A[2]])),{cols:A.term.cols,rows:A.term.rows,theme:T(A.term?.theme),events:e,idleTimeLimit:A.idle_time_limit}}function T(A){if(void 0===A)return;const e=/^#[0-9A-Fa-f]{6}$/,t=A?.fg,n=A?.bg,g=A?.palette;return e.test(t)&&e.test(n)&&/^(#[0-9A-Fa-f]{6}:){7,}#[0-9A-Fa-f]{6}$/.test(g)?{foreground:t,background:n,palette:g.split(":")}:void 0}function j(A){return"number"==typeof A?[A,"m",""]:[A[0],"m",A[1]]}function H(){let A=0;return function(e){return"m"===e[1]?[e[0],e[1],{index:A++,time:e[0],label:e[2]}]:e}}class O{constructor(){this.items=[],this.onPush=void 0}push(A){this.items.push(A),void 0!==this.onPush&&(this.onPush(this.popAll()),this.onPush=void 0)}popAll(){if(this.items.length>0){const A=this.items;return this.items=[],A}{const A=this;return new Promise(e=>{A.onPush=e})}}}function W(A,e,t,n,g,V,o,i,s){const r=function(A,e,t,n){return function(g,V){"o"===g?A(V):"i"===g?t(V):"r"===g?e(V.cols,V.rows):"m"===g&&n(V)}}(e,t,n,g);if(0===A)return s.debug("using no buffer"),function(A){return{pushEvent(e){A(e[1],e[2])},pushText(e){A("o",e)},stop(){}}}(r);{let e;return"number"==typeof(A=A??{})?(s.debug(`using fixed time buffer (${A} ms)`),e=e=>A):"function"==typeof A?(s.debug("using custom dynamic buffer"),e=A({logger:s})):(s.debug("using adaptive buffer",A),e=function(){let{logger:A}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{minBufferTime:e=50,bufferLevelStep:t=100,maxBufferLevel:n=50,transitionDuration:g=500,peakHalfLifeUp:V=100,peakHalfLifeDown:o=1e4,floorHalfLifeUp:i=5e3,floorHalfLifeDown:s=100,idealHalfLifeUp:r=1e3,idealHalfLifeDown:I=5e3,safetyMultiplier:B=1.2,minImprovementDuration:a=3e3}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};function C(A){return 0===A?e:t*A}let Q=1,E=C(Q),c=performance.now(),l=null,u=null,d=null,h=null,f=null,w=null;return function(m){const y=performance.now(),D=Math.max(0,y-c);if(c=y,null===l)l=m;else if(m>l){const A=1-Math.pow(2,-D/V);l+=A*(m-l)}else{const A=1-Math.pow(2,-D/o);l+=A*(m-l)}if(l=Math.max(l,0),null===u)u=m;else if(m>u){const A=1-Math.pow(2,-D/i);u+=A*(m-u)}else{const A=1-Math.pow(2,-D/s);u+=A*(m-u)}u=Math.max(u,0);const p=B*(l+(l-u));if(null===d)d=p;else if(p>d){const A=1-Math.pow(2,-D/r);d+=+A*(p-d)}else{const A=1-Math.pow(2,-D/I);d+=+A*(p-d)}let k;var q,N,F;return d<=e?k=0:(q=Math.ceil(d/t),N=1,F=n,k=Math.min(F,Math.max(N,q))),m>E&&A.debug("buffer underrun",{latency:m,bufferTime:E}),k>Q?(m>E?Q=Math.min(k,Q+3):Q+=1,f=C(Q),w=(f-E)/g,h=null,A.debug("raising buffer",{latency:m,bufferTime:E,targetBufferTime:f})):k<Q?(null==h&&(h=y),y-h>=a&&(Q-=1,f=C(Q),w=(f-E)/g,h=y,A.debug("lowering buffer",{latency:m,bufferTime:E,targetBufferTime:f}))):h=null,null!==f&&(E+=w*D,(w>=0&&E>f||w<0&&E<f)&&(E=f,f=null)),E}}({logger:s},A)),function(A,e,t,n,g){let V=arguments.length>5&&void 0!==arguments[5]?arguments[5]:1/60,o=performance.now()-1e3*g,i=A(0);const s=new O;V*=1e3;let r=-V,I=!1;function B(){return performance.now()-o}return setTimeout(async()=>{for(;!I;){const A=await s.popAll();if(I)return;for(const n of A){const A=1e3*n[0]+i;if(A-r<V){e(n[1],n[2]);continue}const g=A-B();if(g>0&&(await _(g),I))return;t(n[0]),e(n[1],n[2]),r=A}}},0),{pushEvent(e){let t=B()-1e3*e[0];t<0&&(n.debug(`correcting epoch by ${t} ms`),o+=t,t=0),i=A(t),s.push(e)},pushText(A){s.push([B()/1e3,"o",A])},stop(){I=!0,s.push(void 0)}}}(e,r,V,s,o??0,i)}}function _(A){return new Promise(e=>{setTimeout(e,A)})}const Z=1e6;function z(A){const e=new TextDecoder,t=new TextDecoder;let n,g=function(A){const e=(new TextDecoder).decode(A);if("ALiS\x01"!==e)throw"not an ALiS v1 live stream";g=o},V=0;function o(A){const e=new AA(new DataView(A)),t=e.getUint8();if(1!==t)throw`expected reset (0x01) frame, got ${t}`;return i(e,A)}function i(A,t){A.decodeVarUint();let o=A.decodeVarUint();n=o,o/=Z,V=0;const i=A.decodeVarUint(),r=A.decodeVarUint(),I=A.getUint8();let B;if(8===I){const e=30;B=X(new Uint8Array(t,A.offset,e)),A.forward(e)}else if(16===I){const e=54;B=X(new Uint8Array(t,A.offset,e)),A.forward(e)}else if(0!==I)throw`alis: invalid theme format (${I})`;const a=A.decodeVarUint();let C;return a>0&&(C=e.decode(new Uint8Array(t,A.offset,a))),g=s,{time:o,term:{size:{cols:i,rows:r},theme:B,init:C}}}function s(s){const r=new AA(new DataView(s)),I=r.getUint8();return 1===I?i(r,s):111===I?function(A,t){A.decodeVarUint();const g=A.decodeVarUint();n+=g;const V=A.decodeVarUint(),o=e.decode(new Uint8Array(t,A.offset,V));return[n/Z,"o",o]}(r,s):105===I?function(A,e){A.decodeVarUint();const g=A.decodeVarUint();n+=g;const V=A.decodeVarUint(),o=t.decode(new Uint8Array(e,A.offset,V));return[n/Z,"i",o]}(r,s):114===I?function(A){A.decodeVarUint();const e=A.decodeVarUint();n+=e;const t=A.decodeVarUint(),g=A.decodeVarUint();return[n/Z,"r",{cols:t,rows:g}]}(r):109===I?function(A,e){A.decodeVarUint();const t=A.decodeVarUint();n+=t;const g=A.decodeVarUint(),o=new TextDecoder,i=V++,s=n/Z,r=o.decode(new Uint8Array(e,A.offset,g));return[s,"m",{index:i,time:s,label:r}]}(r,s):4===I?(g=o,!1):void A.debug(`alis: unknown frame type: ${I}`)}return function(A){return g(A)}}function X(A){const e=A.length/3,t=P(A[0],A[1],A[2]),n=P(A[3],A[4],A[5]),g=[];for(let V=2;V<e;V++)g.push(P(A[3*V],A[3*V+1],A[3*V+2]));return{foreground:t,background:n,palette:g}}function P(A,e,t){return`#${$(A)}${$(e)}${$(t)}`}function $(A){return A.toString(16).padStart(2,"0")}class AA{constructor(A){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;this.inner=A,this.offset=e}forward(A){this.offset+=A}getUint8(){const A=this.inner.getUint8(this.offset);return this.offset+=1,A}decodeVarUint(){let A=BigInt(0),e=BigInt(0),t=this.getUint8();for(;t>127;)t&=127,A+=BigInt(t)<<e,e+=BigInt(7),t=this.getUint8();return A+=BigInt(t)<<e,Number(A)}}function eA(){const A=new TextDecoder;let e=function(n){const g=A.decode(n,{stream:!0}),[V,o]=function(A){const e=A.match(/\x1b\[8;(\d+);(\d+)t/);if(null!==e)return[parseInt(e[2],10),parseInt(e[1],10)]}(g)??function(A){const e=A.match(/\[.*COLUMNS="(\d{1,3})" LINES="(\d{1,3})".*\]/);if(null!==e)return[parseInt(e[1],10),parseInt(e[2],10)]}(g)??[80,24];return e=t,{time:0,term:{size:{cols:V,rows:o},init:g}}};function t(e){return A.decode(e,{stream:!0})}return function(A){return e(A)}}function tA(A){const e=Math.min(500*Math.pow(2,A),1e4);return Math.random()*e}function nA(A){if(A.length<13)return;const e=function(A){const e=gA(A.subarray(0,4)),t=gA(A.subarray(4,8));return e+t/1e6}(A.subarray(0,8)),t=gA(A.subarray(8,12));return{time:e,data:A.subarray(12,12+t),len:t+12}}function gA(A){return A[0]+256*A[1]+256*A[2]*256+256*A[3]*256*256}const VA=(async(A={})=>{let{initializeHook:e}=A;return null!=e?await e(N,b):await N(b),F})();class oA{constructor(A){this.core=A,this.driver=A.driver}onEnter(A){}init(){}play(){}pause(){}togglePlay(){}mute(){this.driver&&this.driver.mute()&&this.core._dispatchEvent("muted",!0)}unmute(){this.driver&&this.driver.unmute()&&this.core._dispatchEvent("muted",!1)}seek(A){return!1}step(A){}stop(){this.driver.stop()}}class iA extends oA{async init(){try{return await this.core._initializeDriver(),this.core._setState("idle")}catch(A){throw this.core._setState("errored"),A}}async play(){this.core._dispatchEvent("play");const A=await this.init();await A.doPlay()}async togglePlay(){await this.play()}async seek(A){const e=await this.init();return await e.seek(A)}async step(A){const e=await this.init();await e.step(A)}stop(){}}class sA extends oA{onEnter(A){let{reason:e,message:t}=A;this.core._dispatchEvent("idle",{message:t}),"paused"===e&&this.core._dispatchEvent("pause")}async play(){this.core._dispatchEvent("play"),await this.doPlay()}async doPlay(){const A=await this.driver.play();!0===A?this.core._setState("playing"):"function"==typeof A&&(this.core._setState("playing"),this.driver.stop=A)}async togglePlay(){await this.play()}seek(A){return this.driver.seek(A)}step(A){this.driver.step(A)}}class rA extends oA{onEnter(){this.core._dispatchEvent("playing")}pause(){!0===this.driver.pause()&&this.core._setState("idle",{reason:"paused"})}togglePlay(){this.pause()}seek(A){return this.driver.seek(A)}}class IA extends oA{onEnter(){this.core._dispatchEvent("loading")}}class BA extends oA{onEnter(A){let{message:e}=A;this.core._dispatchEvent("offline",{message:e})}}class aA extends oA{onEnter(A){let{message:e}=A;this.core._dispatchEvent("ended",{message:e})}async play(){this.core._dispatchEvent("play"),await this.driver.restart()&&this.core._setState("playing")}async togglePlay(){await this.play()}async seek(A){return!0===await this.driver.seek(A)&&(this.core._setState("idle"),!0)}}class CA extends oA{onEnter(){this.core._dispatchEvent("errored")}}class QA{constructor(A,e){this.logger=e.logger,this.state=new iA(this),this.stateName="uninitialized",this.driver=function(A){if("function"==typeof A)return A;"string"==typeof A&&(A="ws://"==A.substring(0,5)||"wss://"==A.substring(0,6)?{driver:"websocket",url:A}:"clock:"==A.substring(0,6)?{driver:"clock"}:"random:"==A.substring(0,7)?{driver:"random"}:"benchmark:"==A.substring(0,10)?{driver:"benchmark",url:A.substring(10)}:{driver:"recording",url:A});void 0===A.driver&&(A.driver="recording");if("recording"==A.driver&&(void 0===A.parser&&(A.parser="asciicast"),"string"==typeof A.parser)){if(!cA.has(A.parser))throw`unknown parser: ${A.parser}`;A.parser=cA.get(A.parser)}if(EA.has(A.driver)){const e=EA.get(A.driver);return(t,n)=>e(A,t,n)}throw`unsupported driver: ${JSON.stringify(A)}`}(A),this.changedLines=new Set,this.cursor=void 0,this.duration=void 0,this.cols=e.cols,this.rows=e.rows,this.speed=e.speed,this.loop=e.loop,this.autoPlay=e.autoPlay,this.idleTimeLimit=e.idleTimeLimit,this.preload=e.preload,this.startAt=n(e.startAt),this.poster=this._parsePoster(e.poster),this.markers=this._normalizeMarkers(e.markers),this.pauseOnMarkers=e.pauseOnMarkers,this.audioUrl=e.audioUrl,this.commandQueue=Promise.resolve(),this.eventHandlers=new Map([["ended",[]],["errored",[]],["idle",[]],["input",[]],["loading",[]],["marker",[]],["metadata",[]],["muted",[]],["offline",[]],["pause",[]],["play",[]],["playing",[]],["ready",[]],["reset",[]],["resize",[]],["seeked",[]],["terminalUpdate",[]]])}async init(){this.wasm=await VA;const A=this._feed.bind(this),e=this._resetVt.bind(this),t=this._resizeVt.bind(this),n=this._setState.bind(this),g="npt"===this.poster.type?this.poster.value:void 0;this.driver=this.driver({feed:A,onInput:A=>{this._dispatchEvent("input",{data:A})},onMarker:A=>{let{index:e,time:t,label:n}=A;this._dispatchEvent("marker",{index:e,time:t,label:n})},reset:e,resize:t,setState:n,logger:this.logger},{cols:this.cols,rows:this.rows,speed:this.speed,idleTimeLimit:this.idleTimeLimit,startAt:this.startAt,loop:this.loop,posterTime:g,markers:this.markers,pauseOnMarkers:this.pauseOnMarkers,audioUrl:this.audioUrl}),"function"==typeof this.driver&&(this.driver={play:this.driver}),(this.preload||void 0!==g)&&this._withState(A=>A.init());const V="text"===this.poster.type?this._renderPoster(this.poster.value):null,o={isPausable:!!this.driver.pause,isSeekable:!!this.driver.seek,poster:V};if(void 0===this.driver.init&&(this.driver.init=()=>({})),void 0===this.driver.pause&&(this.driver.pause=()=>{}),void 0===this.driver.seek&&(this.driver.seek=A=>!1),void 0===this.driver.step&&(this.driver.step=A=>{}),void 0===this.driver.stop&&(this.driver.stop=()=>{}),void 0===this.driver.restart&&(this.driver.restart=()=>{}),void 0===this.driver.mute&&(this.driver.mute=()=>{}),void 0===this.driver.unmute&&(this.driver.unmute=()=>{}),void 0===this.driver.getCurrentTime){const A=this.driver.play;let e=new R;this.driver.play=()=>(e=new G(this.speed),A()),this.driver.getCurrentTime=()=>e.getTime()}this._dispatchEvent("ready",o),this.autoPlay&&this.play()}play(){return this._withState(A=>A.play())}pause(){return this._withState(A=>A.pause())}togglePlay(){return this._withState(A=>A.togglePlay())}seek(A){return this._withState(async e=>{await e.seek(A)&&this._dispatchEvent("seeked")})}step(A){return this._withState(e=>e.step(A))}stop(){return this._withState(A=>A.stop())}mute(){return this._withState(A=>A.mute())}unmute(){return this._withState(A=>A.unmute())}getChanges(){const A={};if(this.changedLines.size>0){const e=new Map,t=this.vt.rows;for(const A of this.changedLines)A<t&&e.set(A,{id:A,segments:this.vt.getLine(A)});this.changedLines.clear(),A.lines=e}return void 0===this.cursor&&this.vt&&(this.cursor=this.vt.getCursor()??!1,A.cursor=this.cursor),A}getCurrentTime(){return this.driver.getCurrentTime()}getRemainingTime(){if("number"==typeof this.duration)return this.duration-Math.min(this.getCurrentTime(),this.duration)}getProgress(){if("number"==typeof this.duration)return Math.min(this.getCurrentTime(),this.duration)/this.duration}getDuration(){return this.duration}addEventListener(A,e){this.eventHandlers.get(A).push(e)}_dispatchEvent(A){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};for(const t of this.eventHandlers.get(A))t(e)}_withState(A){return this._enqueueCommand(()=>A(this.state))}_enqueueCommand(A){return this.commandQueue=this.commandQueue.then(A),this.commandQueue}_setState(A){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(this.stateName===A)return this.state;if(this.stateName=A,"playing"===A)this.state=new rA(this);else if("idle"===A)this.state=new sA(this);else if("loading"===A)this.state=new IA(this);else if("ended"===A)this.state=new aA(this);else if("offline"===A)this.state=new BA(this);else{if("errored"!==A)throw`invalid state: ${A}`;this.state=new CA(this)}return this.state.onEnter(e),this.state}_feed(A){this._doFeed(A),this._dispatchEvent("terminalUpdate")}_doFeed(A){this.vt.feed(A).forEach(A=>this.changedLines.add(A)),this.cursor=void 0}async _initializeDriver(){const A=await this.driver.init();this.cols=this.cols??A.cols??80,this.rows=this.rows??A.rows??24,this.duration=this.duration??A.duration,this.markers=this._normalizeMarkers(A.markers)??this.markers??[],0===this.cols&&(this.cols=80),0===this.rows&&(this.rows=24),this._initializeVt(this.cols,this.rows);const e=void 0!==A.poster?this._renderPoster(A.poster):null;this._dispatchEvent("metadata",{cols:this.cols,rows:this.rows,duration:this.duration,markers:this.markers,theme:A.theme,hasAudio:A.hasAudio,poster:e})}_resetVt(A,e){let t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:void 0;this.logger.debug(`core: vt reset (${A}x${e})`),this.cols=A,this.rows=e,this.cursor=void 0,this._initializeVt(A,e),void 0!==t&&""!==t&&this._doFeed(t),this._dispatchEvent("reset",{cols:A,rows:e,theme:n})}_resizeVt(A,e){if(A===this.vt.cols&&e===this.vt.rows)return;this.vt.resize(A,e).forEach(A=>this.changedLines.add(A)),this.cursor=void 0,this.vt.cols=A,this.vt.rows=e,this.logger.debug(`core: vt resize (${A}x${e})`),this._dispatchEvent("resize",{cols:A,rows:e})}_initializeVt(A,e){this.vt=this.wasm.create(A,e,!0,100),this.vt.cols=A,this.vt.rows=e,this.changedLines.clear();for(let t=0;t<e;t++)this.changedLines.add(t)}_parsePoster(A){return"string"!=typeof A?{}:"data:text/plain,"==A.substring(0,16)?{type:"text",value:[A.substring(16)]}:"npt:"==A.substring(0,4)?{type:"npt",value:n(A.substring(4))}:{}}_renderPoster(A){const e=this.cols??80,t=this.rows??24;this.logger.debug(`core: poster init (${e}x${t})`);const n=this.wasm.create(e,t,!1,0);A.forEach(A=>n.feed(A));const g=n.getCursor()??!1,V=[];for(let o=0;o<t;o++)V.push({id:o,segments:n.getLine(o)});return{cursor:g,lines:V}}_normalizeMarkers(A){if(Array.isArray(A))return A.map(A=>"number"==typeof A?[A,""]:A)}}const EA=new Map([["benchmark",function(A,e){let t,{url:n,iterations:g=10}=A,{feed:V,setState:o}=e,i=0;return{async init(){const A=await U(await fetch(n)),{cols:e,rows:g,events:V}=A;t=Array.from(V).filter(A=>{let[e,t,n]=A;return"o"===t}).map(A=>{let[e,t,n]=A;return[e,n]});const o=t[t.length-1][0];for(const[n,s]of t)i+=new Blob([s]).size;return{cols:e,rows:g,duration:o}},play(){const A=performance.now();for(let o=0;o<g;o++){for(const[A,e]of t)V(e);V("\x1bc")}const e=(performance.now()-A)/1e3,n=i*g/e,s=i/1048576*g/e;return console.info("benchmark: result",{byteCount:i,iterations:g,duration:e,throughput:n,throughputMbs:s}),setTimeout(()=>{o("stopped",{reason:"ended"})},0),!0}}}],["clock",function(A,e,t){let{hourColor:n=3,minuteColor:g=4,separatorColor:V=9}=A,{feed:o}=e,{cols:i=5,rows:s=1}=t;const r=Math.floor(s/2),I=Math.floor(i/2)-2,B=`\x1b[?25l\x1b[1m\x1b[${r}B`;let a;const C=()=>{const A=new Date,e=A.getHours(),t=A.getMinutes(),o=[];o.push("\r");for(let n=0;n<I;n++)o.push(" ");return o.push(`\x1b[3${n}m`),e<10&&o.push("0"),o.push(`${e}`),o.push(`\x1b[3${V};5m:\x1b[25m`),o.push(`\x1b[3${g}m`),t<10&&o.push("0"),o.push(`${t}`),o},Q=()=>{C().forEach(o)};return{init:()=>{const A=[B].concat(C());return{cols:i,rows:s,duration:1440,poster:A}},play:()=>(o(B),Q(),a=setInterval(Q,1e3),!0),stop:()=>{clearInterval(a)},getCurrentTime:()=>{const A=new Date;return 60*A.getHours()+A.getMinutes()}}}],["eventsource",function(A,e){let t,n,{url:g,bufferTime:o,minFrameTime:i}=A,{feed:s,reset:r,resize:I,onInput:B,onMarker:a,setState:C,logger:Q}=e;Q=new V(Q,"eventsource: ");let E=new R;function c(A){void 0!==n&&n.stop(),n=W(o,s,I,B,a,A=>E.setTime(A),A,i,Q)}return{play:()=>{t=new EventSource(g),t.addEventListener("open",()=>{Q.info("opened"),c()}),t.addEventListener("error",A=>{Q.info("errored"),Q.debug({e:A}),C("loading")}),t.addEventListener("message",A=>{const e=JSON.parse(A.data);if(Array.isArray(e))n.pushEvent(e);else if(void 0!==e.cols||void 0!==e.width){const A=e.cols??e.width,t=e.rows??e.height;Q.debug(`vt reset (${A}x${t})`),C("playing"),c(e.time),r(A,t,e.init??void 0),E=new G,"number"==typeof e.time&&E.setTime(e.time)}else"offline"===e.state&&(Q.info("stream offline"),C("offline",{message:"Stream offline"}),E=new R)}),t.addEventListener("done",()=>{Q.info("closed"),t.close(),C("ended",{message:"Stream ended"})})},stop:()=>{void 0!==n&&n.stop(),void 0!==t&&t.close()},getCurrentTime:()=>E.getTime()}}],["random",function(A,e,t){let{feed:n}=e,{speed:g}=t;const V=" ".charCodeAt(0),o="~".charCodeAt(0)-V;let i;const s=()=>{const A=Math.pow(5,4*Math.random());i=setTimeout(r,A/g)},r=()=>{s();const A=String.fromCharCode(V+Math.floor(Math.random()*o));n(A)};return()=>(s(),()=>clearInterval(i))}],["recording",function(A,e,t){let n,g,V,o,i,s,r,I,B,a,C,Q,{feed:E,resize:c,onInput:l,onMarker:u,setState:d,logger:h}=e,{speed:f,idleTimeLimit:w,startAt:m,loop:y,posterTime:D,markers:p,pauseOnMarkers:k,cols:q,rows:N,audioUrl:F}=t,v=0,M=0,b=0,G=!1,R=!1,S=()=>performance.now()*f,J=!1;async function U(A,e){const t=await fetch(A,e);if(!t.ok)throw`failed fetching recording from ${A}: ${t.status} ${t.statusText}`;return t}function x(){const A=V[v];A?r=function(A,e){let t=(1e3*e-(S()-I))/f;t<0&&(t=0);return setTimeout(A,t)}(Y,A[0]):O()}function Y(){let A,e=V[v];do{M=e[0],v++;if(T(e))return;e=V[v],A=S()-I}while(e&&A>1e3*e[0]);x()}function K(){clearTimeout(r),r=null}function T(A){const[e,t,n]=A;if("o"===t)E(n);else if("i"===t)l(n);else if("r"===t){const[A,e]=n.split("x");c(A,e)}else if("m"===t&&(u(n),k))return W(),B=1e3*e,d("idle",{reason:"paused"}),!0;return!1}function O(){K(),b++,!0===y||"number"==typeof y&&b<y?(v=0,I=S(),E("\x1bc"),X(),x(),Q&&(Q.currentTime=0)):(B=1e3*i,d("ended"),Q&&Q.pause())}function W(){return R=!1,Q&&Q.pause(),!r||(K(),B=S()-I,!0)}async function _(){Q&&!C&&function(){C=new AudioContext({latencyHint:"interactive"});const A=C.createMediaElementSource(Q);A.connect(C.destination),S=P}(),I=S()-B,B=null,x(),Q&&await Q.play()}async function Z(A){if(G)return!1;const e=!!r;W(),Q&&Q.pause();const t=(B??0)/1e3;if("string"==typeof A)"<<"===A?A=t-5:">>"===A?A=t+5:"<<<"===A?A=t-.1*i:">>>"===A?A=t+.1*i:"%"===A[A.length-1]&&(A=parseFloat(A.substring(0,A.length-1))/100*i);else if("object"==typeof A)if("prev"===A.marker)A=z(t)??0,e&&t-A<1&&(A=z(A)??0);else if("next"===A.marker)A=function(A){if(0==o.length)return;let e,t=o.length-1,n=o[t];for(;n&&n[0]>A;)e=n[0],n=o[--t];return e}(t)??i;else if("number"==typeof A.marker){const e=o[A.marker];if(void 0===e)throw`invalid marker index: ${A.marker}`;A=e[0]}const n=Math.min(Math.max(A,0),i);if(1e3*n===B)return!1;n<M&&(E("\x1bc"),X(),v=0,M=0);let g=V[v];for(;g&&g[0]<=n;)"o"!==g[1]&&"r"!==g[1]||T(g),M=g[0],g=V[++v];return B=1e3*n,s=null,Q&&J&&(Q.currentTime=n/f),e?await _():void 0===V[v]&&O(),!0}function z(A){if(0==o.length)return;let e,t=0,n=o[t];for(;n&&n[0]<A;)e=n[0],n=o[++t];return e}function X(){c(q,N)}function P(){if(!C)throw"audio context not started - can't tell time!";const{contextTime:A,performanceTime:e}=C.getOutputTimestamp();return 0===e?1e3*A:1e3*A+(performance.now()-e)}function $(){if(h.debug("audio buffering"),G=!0,R=!!r,a=setTimeout(()=>d("loading"),1e3),!r)return!0;h.debug("pausing session playback"),K(),B=S()-I}function AA(){h.debug("audio resumed"),clearTimeout(a),d("playing"),G&&(G=!1,R&&(h.debug("resuming session playback"),I=S()-B,B=null,x()))}return{init:async function(){const e=setTimeout(()=>{d("loading")},3e3);try{let e=async function(A,e,t){const{parser:r,minFrameTime:I,inputOffset:B,dumpFilename:a,encoding:C="utf-8"}=A,Q=await async function(A){let{url:e,data:t,fetchOpts:n={}}=A;if("string"==typeof e)return await U(e,n);if(Array.isArray(e))return await Promise.all(e.map(A=>U(A,n)));if(void 0!==t){"function"==typeof t&&(t=t()),t instanceof Promise||(t=Promise.resolve(t));const A=await t;return"string"==typeof A||A instanceof ArrayBuffer?new Response(A):A}throw"failed fetching recording file: url/data missing in src"}(A),E=function(A,e,t){let{startAt:n=0,idleTimeLimit:g,minFrameTime:V,inputOffset:o,markers_:i}=t,{events:s}=A;s instanceof L||(s=new L(s));g=g??A.idleTimeLimit??1/0;const r={offset:0};s=s.transform(function(A){let e,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1/60;return n=>{let g=0,V=0;return{step:A=>{g++,void 0!==e?"o"===A[1]&&"o"===e[1]&&A[0]-e[0]<t?e[2]+=A[2]:(n(e),e=A,V++):e=A},flush:()=>{void 0!==e&&(n(e),V++),A.debug(`batched ${g} frames to ${V} frames`)}}}}(e,V)).map(function(A,e,t){let n=0,g=0;return function(V){const o=V[0]-n-A;return n=V[0],o>0&&(g+=o,V[0]<e&&(t.offset+=o)),[V[0]-g,V[1],V[2]]}}(g,n,r)).map(H()),void 0!==i&&(i=new L(i).map(j),s=s.filter(A=>"m"!==A[1]).multiplex(i,(A,e)=>A[0]<e[0]).map(H()));s=s.toArray(),void 0!==o&&(s=s.map(A=>"i"===A[1]?[A[0]+o,A[1],A[2]]:A),s.sort((A,e)=>A[0]-e[0]));const I=s[s.length-1][0],B=n-r.offset;return{...A,events:s,duration:I,effectiveStartAt:B}}(await r(Q,{encoding:C}),e,{...t,minFrameTime:I,inputOffset:B});if(({cols:n,rows:g,events:V,duration:i,effectiveStartAt:s}=E),q=q??n,N=N??g,0===V.length)throw"recording is missing events";void 0!==a&&function(A,e){const t=document.createElement("a"),n=A.events.map(A=>"m"===A[1]?[A[0],A[1],A[2].label]:A),g=function(A){return`${JSON.stringify({version:2,width:A.cols,height:A.rows})}\n${A.events.map(JSON.stringify).join("\n")}\n`}({...A,events:n});t.href=URL.createObjectURL(new Blob([g],{type:"text/plain"})),t.download=e,t.click()}(E,a);const c=void 0!==D?(l=D,V.filter(A=>A[0]<l&&"o"===A[1]).map(A=>A[2])):void 0;var l;return o=V.filter(A=>"m"===A[1]).map(A=>[A[0],A[2].label]),{cols:n,rows:g,duration:i,theme:E.theme,poster:c,markers:o}}(A,h,{idleTimeLimit:w,startAt:m,markers_:p});const t=await async function(A){if(!A)return!1;Q=await async function(A){const e=new Audio;let t;e.preload="metadata",e.loop=!1,e.crossOrigin="anonymous";const n=new Promise(A=>{t=A});function g(){t(),e.removeEventListener("canplay",g)}return e.addEventListener("canplay",g),e.src=A,e.load(),await n,e}(A),J=NaN!==Q.duration&&Q.duration!==1/0&&Q.seekable.length>0&&Q.seekable.end(Q.seekable.length-1)===Q.duration,J?(Q.addEventListener("playing",AA),Q.addEventListener("waiting",$)):h.warn(`audio is not seekable - you must enable range request support on the server providing ${Q.src} for audio seeking to work`);return!0}(F);return e=await e,{...e,hasAudio:t}}finally{clearTimeout(e)}},play:async function(){if(r)throw"already playing";if(void 0===V[v])throw"already ended";return null!==s&&Z(s),await _(),!0},pause:W,seek:Z,step:function(A){let e,t;if(void 0===A&&(A=1),A>0){let n=v;e=V[n];for(let g=0;g<A;g++){for(;void 0!==e&&"o"!==e[1];)e=V[++n];void 0!==e&&"o"===e[1]&&(t=n)}}else{let n=Math.max(v-2,0);e=V[n];for(let g=A;g<0;g++){for(;void 0!==e&&"o"!==e[1];)e=V[--n];void 0!==e&&"o"===e[1]&&(t=n)}void 0!==t&&(E("\x1bc"),X(),v=0)}if(void 0!==t){for(;v<=t;)e=V[v++],"o"!==e[1]&&"r"!==e[1]||T(e);M=e[0],B=1e3*M,s=null,Q&&J&&(Q.currentTime=M/f),void 0===V[t+1]&&O()}},restart:async function(){if(r)throw"still playing";if(void 0!==V[v])throw"not ended";return Z(0),await _(),!0},stop:W,mute:function(){if(Q)return Q.muted=!0,!0},unmute:function(){if(Q)return Q.muted=!1,!0},getCurrentTime:function(){return r?(S()-I)/1e3:(B??0)/1e3}}}],["websocket",function(A,e,t){let n,g,{url:o,bufferTime:i,reconnectDelay:s=tA,minFrameTime:r}=A,{feed:I,reset:B,resize:a,onInput:C,onMarker:Q,setState:E,logger:c}=e,{audioUrl:l}=t;c=new V(c,"websocket: ");let u,d,h,f=new R,w=0,m=!1,y=!1;function D(){n=new WebSocket(o,["v1.alis","v2.asciicast","v3.asciicast","raw"]),n.binaryType="arraybuffer",n.onopen=()=>{const A=n.protocol||"raw";c.info("opened"),c.info(`activating ${A} protocol handler`),"v1.alis"===A?n.onmessage=p(z(c)):"v2.asciicast"===A?n.onmessage=p(function(){let A=function(t){const n=JSON.parse(t);if(2!==n.version)throw"not an asciicast v2 stream";return A=e,{time:0,term:{size:{cols:n.width,rows:n.height}}}};function e(A){const e=JSON.parse(A);if("r"===e[1]){const[A,t]=e[2].split("x");return[e[0],"r",{cols:parseInt(A,10),rows:parseInt(t,10)}]}return e}return function(e){return A(e)}}()):"v3.asciicast"===A?n.onmessage=p(function(){let A=function(e){const n=JSON.parse(e);if(3!==n.version)throw"not an asciicast v3 stream";A=t;const g={size:{cols:n.term.cols,rows:n.term.rows}};return n.term.theme&&(g.theme={foreground:n.term.theme.fg,background:n.term.theme.bg,palette:n.term.theme.palette.split(":")}),{time:0,term:g}},e=0;function t(A){const t=JSON.parse(A),[n,g,V]=t;if(e+=n,"r"===g){const[A,t]=V.split("x");return[e,"r",{cols:parseInt(A,10),rows:parseInt(t,10)}]}return[e,g,V]}return function(e){return A(e)}}()):"raw"===A&&(n.onmessage=p(eA())),u=setTimeout(()=>{w=0},1e3)},n.onclose=A=>{if(clearTimeout(d),N(),m||1e3===A.code||1005===A.code)c.info("closed"),E("ended",{message:"Stream ended"});else if(1002===A.code)c.debug(`close reason: ${A.reason}`),E("ended",{message:"Err: Player not compatible with the server"});else{clearTimeout(u);const A=s(w++);c.info(`unclean close, reconnecting in ${A}...`),E("loading"),setTimeout(D,A)}},y=!1}function p(A){return d=setTimeout(q,5e3),function(e){try{const t=A(e.data);if(g)if(Array.isArray(t))g.pushEvent(t);else if("string"==typeof t)g.pushText(t);else if("object"!=typeof t||Array.isArray(t)){if(!1===t)q();else if(void 0!==t)throw`unexpected value from protocol handler: ${t}`}else k(t);else if("object"!=typeof t||Array.isArray(t)){if(void 0!==t)throw clearTimeout(d),`unexpected value from protocol handler: ${t}`;clearTimeout(d),d=setTimeout(q,1e3)}else k(t),clearTimeout(d)}catch(t){throw n.close(),t}}}function k(A){let{time:e,term:t}=A;const{size:n,init:V,theme:o}=t,{cols:s,rows:l}=n;c.info(`stream reset (${s}x${l} @${e})`),E("playing"),N(),g=W(i,I,a,C,Q,A=>f.setTime(A),e,r,c),B(s,l,V,o),f=new G,y=!0,"number"==typeof e&&f.setTime(e)}function q(){N(),y?(c.info("stream ended"),E("offline",{message:"Stream ended"})):(c.info("stream offline"),E("offline",{message:"Stream offline"})),f=new R}function N(){g&&g.stop(),g=null}return{init:()=>({hasAudio:!!l}),play:()=>{D(),l&&(h=new Audio,h.preload="auto",h.crossOrigin="anonymous",h.src=l,h.play())},stop:()=>{m=!0,N(),void 0!==n&&n.close(),h&&h.pause()},mute:function(){if(h)return h.muted=!0,!0},unmute:function(){if(h)return h.muted=!1,!0},getCurrentTime:()=>f.getTime()}}]]),cA=new Map([["asciicast",U],["typescript",async function(A,e){let{encoding:t}=e;const n=new TextDecoder(t);let g,V,o=(await A[0].text()).split("\n").filter(A=>A.length>0).map(A=>A.split(" "));o[0].length<3&&(o=o.map(A=>["O",A[0],A[1]]));const i=await A[1].arrayBuffer(),s=new Uint8Array(i),r=s.findIndex(A=>10==A)+1,I=n.decode(s.subarray(0,r)).match(/COLUMNS="(\d+)" LINES="(\d+)"/);null!==I&&(g=parseInt(I[1],10),V=parseInt(I[2],10));const B={array:s,cursor:r};let a=B;if(void 0!==A[2]){const e=await A[2].arrayBuffer();a={array:new Uint8Array(e),cursor:r}}const C=[];let Q=0;for(const E of o)if(Q+=parseFloat(E[1]),"O"===E[0]){const A=parseInt(E[2],10),e=B.array.subarray(B.cursor,B.cursor+A),t=n.decode(e);C.push([Q,"o",t]),B.cursor+=A}else if("I"===E[0]){const A=parseInt(E[2],10),e=a.array.subarray(a.cursor,a.cursor+A),t=n.decode(e);C.push([Q,"i",t]),a.cursor+=A}else if("S"===E[0]&&"SIGWINCH"===E[2]){const A=parseInt(E[4].slice(5),10),e=parseInt(E[3].slice(5),10);C.push([Q,"r",`${A}x${e}`])}else"H"===E[0]&&"COLUMNS"===E[2]?g=parseInt(E[3],10):"H"===E[0]&&"LINES"===E[2]&&(V=parseInt(E[3],10));return g=g??80,V=V??24,{cols:g,rows:V,events:C}}],["ttyrec",async function(A,e){let{encoding:t}=e;const n=new TextDecoder(t),g=await A.arrayBuffer(),V=new Uint8Array(g),o=nA(V),i=o.time,s=n.decode(o.data).match(/\x1b\[8;(\d+);(\d+)t/),r=[];let I=80,B=24;null!==s&&(I=parseInt(s[2],10),B=parseInt(s[1],10));let a=0,C=nA(V);for(;void 0!==C;){const A=C.time-i,e=n.decode(C.data);r.push([A,"o",e]),a+=C.len,C=nA(V.subarray(a))}return{cols:I,rows:B,events:r}}]]);const lA=Symbol("solid-proxy"),uA="function"==typeof Proxy,dA=Symbol("solid-track"),hA={equals:(A,e)=>A===e};let fA=zA;const wA=1,mA=2,yA={owned:null,cleanups:null,context:null,owner:null};var DA=null;let pA=null,kA=null,qA=null,NA=null,FA=0;function vA(A,e){const t=kA,n=DA,g=0===A.length,V=void 0===e?n:e,o=g?yA:{owned:null,cleanups:null,context:V?V.context:null,owner:V},i=g?A:()=>A(()=>LA(()=>Ae(o)));DA=o,kA=null;try{return ZA(i,!0)}finally{kA=t,DA=n}}function MA(A,e){const t={value:A,observers:null,observerSlots:null,comparator:(e=e?Object.assign({},hA,e):hA).equals||void 0};return[jA.bind(t),A=>("function"==typeof A&&(A=A(t.value)),HA(t,A))]}function bA(A,e,t){OA(WA(A,e,!1,wA))}function GA(A,e,t){t=t?Object.assign({},hA,t):hA;const n=WA(A,e,!0,0);return n.observers=null,n.observerSlots=null,n.comparator=t.equals||void 0,OA(n),jA.bind(n)}function RA(A){return ZA(A,!1)}function LA(A){if(null===kA)return A();const e=kA;kA=null;try{return A()}finally{kA=e}}function SA(A){!function(A,e){fA=XA;const t=WA(A,e,!1,wA);t.user=!0,NA?NA.push(t):OA(t)}(()=>LA(A))}function JA(A){return null===DA||(null===DA.cleanups?DA.cleanups=[A]:DA.cleanups.push(A)),A}function UA(){return kA}function xA(A){const e=kA,t=DA;return Promise.resolve().then(()=>{kA=e,DA=t,ZA(A,!1),kA=DA=null})}const[YA,KA]=MA(!1);function TA(A){const e=GA(A),t=GA(()=>te(e()));return t.toArray=()=>{const A=t();return Array.isArray(A)?A:null!=A?[A]:[]},t}function jA(){if(this.sources&&this.state)if(this.state===wA)OA(this);else{const A=qA;qA=null,ZA(()=>PA(this),!1),qA=A}if(kA){const A=this.observers?this.observers.length:0;kA.sources?(kA.sources.push(this),kA.sourceSlots.push(A)):(kA.sources=[this],kA.sourceSlots=[A]),this.observers?(this.observers.push(kA),this.observerSlots.push(kA.sources.length-1)):(this.observers=[kA],this.observerSlots=[kA.sources.length-1])}return this.value}function HA(A,e,t){let n=A.value;return A.comparator&&A.comparator(n,e)||(A.value=e,A.observers&&A.observers.length&&ZA(()=>{for(let e=0;e<A.observers.length;e+=1){const t=A.observers[e],n=pA&&pA.running;n&&pA.disposed.has(t),(n?t.tState:t.state)||(t.pure?qA.push(t):NA.push(t),t.observers&&$A(t)),n||(t.state=wA)}if(qA.length>1e6)throw qA=[],new Error},!1)),e}function OA(A){if(!A.fn)return;Ae(A);const e=FA;!function(A,e,t){let n;const g=DA,V=kA;kA=DA=A;try{n=A.fn(e)}catch(o){return A.pure&&(A.state=wA,A.owned&&A.owned.forEach(Ae),A.owned=null),A.updatedAt=t+1,ee(o)}finally{kA=V,DA=g}(!A.updatedAt||A.updatedAt<=t)&&(null!=A.updatedAt&&"observers"in A?HA(A,n):A.value=n,A.updatedAt=t)}(A,A.value,e)}function WA(A,e,t,n=wA,g){const V={fn:A,state:n,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:e,owner:DA,context:DA?DA.context:null,pure:t};return null===DA||DA!==yA&&(DA.owned?DA.owned.push(V):DA.owned=[V]),V}function _A(A){if(0===A.state)return;if(A.state===mA)return PA(A);if(A.suspense&&LA(A.suspense.inFallback))return A.suspense.effects.push(A);const e=[A];for(;(A=A.owner)&&(!A.updatedAt||A.updatedAt<FA);)A.state&&e.push(A);for(let t=e.length-1;t>=0;t--)if((A=e[t]).state===wA)OA(A);else if(A.state===mA){const t=qA;qA=null,ZA(()=>PA(A,e[0]),!1),qA=t}}function ZA(A,e){if(qA)return A();let t=!1;e||(qA=[]),NA?t=!0:NA=[],FA++;try{const e=A();return function(A){qA&&(zA(qA),qA=null);if(A)return;const e=NA;NA=null,e.length&&ZA(()=>fA(e),!1)}(t),e}catch(n){t||(NA=null),qA=null,ee(n)}}function zA(A){for(let e=0;e<A.length;e++)_A(A[e])}function XA(A){let e,t=0;for(e=0;e<A.length;e++){const n=A[e];n.user?A[t++]=n:_A(n)}for(e=0;e<t;e++)_A(A[e])}function PA(A,e){A.state=0;for(let t=0;t<A.sources.length;t+=1){const n=A.sources[t];if(n.sources){const A=n.state;A===wA?n!==e&&(!n.updatedAt||n.updatedAt<FA)&&_A(n):A===mA&&PA(n,e)}}}function $A(A){for(let e=0;e<A.observers.length;e+=1){const t=A.observers[e];t.state||(t.state=mA,t.pure?qA.push(t):NA.push(t),t.observers&&$A(t))}}function Ae(A){let e;if(A.sources)for(;A.sources.length;){const e=A.sources.pop(),t=A.sourceSlots.pop(),n=e.observers;if(n&&n.length){const A=n.pop(),g=e.observerSlots.pop();t<n.length&&(A.sourceSlots[g]=t,n[t]=A,e.observerSlots[t]=g)}}if(A.tOwned){for(e=A.tOwned.length-1;e>=0;e--)Ae(A.tOwned[e]);delete A.tOwned}if(A.owned){for(e=A.owned.length-1;e>=0;e--)Ae(A.owned[e]);A.owned=null}if(A.cleanups){for(e=A.cleanups.length-1;e>=0;e--)A.cleanups[e]();A.cleanups=null}A.state=0}function ee(A,e=DA){const t=function(A){return A instanceof Error?A:new Error("string"==typeof A?A:"Unknown error",{cause:A})}(A);throw t}function te(A){if("function"==typeof A&&!A.length)return te(A());if(Array.isArray(A)){const e=[];for(let t=0;t<A.length;t++){const n=te(A[t]);Array.isArray(n)?e.push.apply(e,n):e.push(n)}return e}return A}const ne=Symbol("fallback");function ge(A){for(let e=0;e<A.length;e++)A[e]()}function Ve(A,e){return LA(()=>A(e||{}))}function oe(){return!0}const ie={get:(A,e,t)=>e===lA?t:A.get(e),has:(A,e)=>e===lA||A.has(e),set:oe,deleteProperty:oe,getOwnPropertyDescriptor:(A,e)=>({configurable:!0,enumerable:!0,get:()=>A.get(e),set:oe,deleteProperty:oe}),ownKeys:A=>A.keys()};function se(A){return(A="function"==typeof A?A():A)?A:{}}function re(){for(let A=0,e=this.length;A<e;++A){const e=this[A]();if(void 0!==e)return e}}const Ie=A=>`Stale read from <${A}>.`;function Be(A){const e="fallback"in A&&{fallback:()=>A.fallback};return GA(function(A,e,t={}){let n=[],g=[],V=[],o=0,i=e.length>1?[]:null;return JA(()=>ge(V)),()=>{let s,r,I=A()||[],B=I.length;return I[dA],LA(()=>{let A,e,C,Q,E,c,l,u,d;if(0===B)0!==o&&(ge(V),V=[],n=[],g=[],o=0,i&&(i=[])),t.fallback&&(n=[ne],g[0]=vA(A=>(V[0]=A,t.fallback())),o=1);else if(0===o){for(g=new Array(B),r=0;r<B;r++)n[r]=I[r],g[r]=vA(a);o=B}else{for(C=new Array(B),Q=new Array(B),i&&(E=new Array(B)),c=0,l=Math.min(o,B);c<l&&n[c]===I[c];c++);for(l=o-1,u=B-1;l>=c&&u>=c&&n[l]===I[u];l--,u--)C[u]=g[l],Q[u]=V[l],i&&(E[u]=i[l]);for(A=new Map,e=new Array(u+1),r=u;r>=c;r--)d=I[r],s=A.get(d),e[r]=void 0===s?-1:s,A.set(d,r);for(s=c;s<=l;s++)d=n[s],r=A.get(d),void 0!==r&&-1!==r?(C[r]=g[s],Q[r]=V[s],i&&(E[r]=i[s]),r=e[r],A.set(d,r)):V[s]();for(r=c;r<B;r++)r in C?(g[r]=C[r],V[r]=Q[r],i&&(i[r]=E[r],i[r](r))):g[r]=vA(a);g=g.slice(0,o=B),n=I.slice(0)}return g});function a(A){if(V[r]=A,i){const[A,t]=MA(r);return i[r]=t,e(I[r],A)}return e(I[r])}}}(()=>A.each,A.children,e||void 0))}function ae(A){const e="fallback"in A&&{fallback:()=>A.fallback};return GA(function(A,e,t={}){let n,g=[],V=[],o=[],i=[],s=0;return JA(()=>ge(o)),()=>{const r=A()||[],I=r.length;return r[dA],LA(()=>{if(0===I)return 0!==s&&(ge(o),o=[],g=[],V=[],s=0,i=[]),t.fallback&&(g=[ne],V[0]=vA(A=>(o[0]=A,t.fallback())),s=1),V;for(g[0]===ne&&(o[0](),o=[],g=[],V=[],s=0),n=0;n<I;n++)n<g.length&&g[n]!==r[n]?i[n](()=>r[n]):n>=g.length&&(V[n]=vA(B));for(;n<g.length;n++)o[n]();return s=i.length=o.length=I,g=r.slice(0),V=V.slice(0,s)});function B(A){o[n]=A;const[t,g]=MA(r[n]);return i[n]=g,e(t,n)}}}(()=>A.each,A.children,e||void 0))}function Ce(A){const e=A.keyed,t=GA(()=>A.when,void 0,void 0),n=e?t:GA(t,void 0,{equals:(A,e)=>!A==!e});return GA(()=>{const g=n();if(g){const V=A.children;return"function"==typeof V&&V.length>0?LA(()=>V(e?g:()=>{if(!LA(n))throw Ie("Show");return t()})):V}return A.fallback},void 0,void 0)}function Qe(A){const e=TA(()=>A.children),t=GA(()=>{const A=e(),t=Array.isArray(A)?A:[A];let n=()=>{};for(let e=0;e<t.length;e++){const A=e,g=t[e],V=n,o=GA(()=>V()?void 0:g.when,void 0,void 0),i=g.keyed?o:GA(o,void 0,{equals:(A,e)=>!A==!e});n=()=>V()||(i()?[A,o,g]:void 0)}return n});return GA(()=>{const e=t()();if(!e)return A.fallback;const[n,g,V]=e,o=V.children;return"function"==typeof o&&o.length>0?LA(()=>o(V.keyed?g():()=>{if(LA(t)()?.[0]!==n)throw Ie("Match");return g()})):o},void 0,void 0)}function Ee(A){return A}const ce="_$DX_DELEGATE";function le(A,e,t,n={}){let g;return vA(n=>{g=n,e===document?A():ye(e,A(),e.firstChild?null:void 0,t)},n.owner),()=>{g(),e.textContent=""}}function ue(A,e,t,n){let g;const V=()=>{const e=document.createElement("template");return e.innerHTML=A,e.content.firstChild},o=e?()=>LA(()=>document.importNode(g||(g=V()),!0)):()=>(g||(g=V())).cloneNode(!0);return o.cloneNode=o,o}function de(A,e=window.document){const t=e[ce]||(e[ce]=new Set);for(let n=0,g=A.length;n<g;n++){const g=A[n];t.has(g)||(t.add(g),e.addEventListener(g,De))}}function he(A,e){null==e?A.removeAttribute("class"):A.className=e}function fe(A,e,t,n){Array.isArray(t)?(A[`$$${e}`]=t[0],A[`$$${e}Data`]=t[1]):A[`$$${e}`]=t}function we(A,e,t){if(!e)return t?function(A,e){A.removeAttribute(e)}(A,"style"):e;const n=A.style;if("string"==typeof e)return n.cssText=e;let g,V;for(V in"string"==typeof t&&(n.cssText=t=void 0),t||(t={}),e||(e={}),t)null==e[V]&&n.removeProperty(V),delete t[V];for(V in e)g=e[V],g!==t[V]&&(n.setProperty(V,g),t[V]=g);return t}function me(A,e,t){return LA(()=>A(e,t))}function ye(A,e,t,n){if(void 0===t||n||(n=[]),"function"!=typeof e)return pe(A,e,n,t);bA(n=>pe(A,e(),n,t),n)}function De(A){let e=A.target;const t=`$$${A.type}`,n=A.target,g=A.currentTarget,V=e=>Object.defineProperty(A,"target",{configurable:!0,value:e}),o=()=>{const n=e[t];if(n&&!e.disabled){const g=e[`${t}Data`];if(void 0!==g?n.call(e,g,A):n.call(e,A),A.cancelBubble)return}return e.host&&"string"!=typeof e.host&&!e.host._$host&&e.contains(A.target)&&V(e.host),!0},i=()=>{for(;o()&&(e=e._$host||e.parentNode||e.host););};if(Object.defineProperty(A,"currentTarget",{configurable:!0,get:()=>e||document}),A.composedPath){const t=A.composedPath();V(t[0]);for(let A=0;A<t.length-2&&(e=t[A],o());A++){if(e._$host){e=e._$host,i();break}if(e.parentNode===g)break}}else i();V(n)}function pe(A,e,t,n,g){for(;"function"==typeof t;)t=t();if(e===t)return t;const V=typeof e,o=void 0!==n;if(A=o&&t[0]&&t[0].parentNode||A,"string"===V||"number"===V){if("number"===V&&(e=e.toString())===t)return t;if(o){let g=t[0];g&&3===g.nodeType?g.data!==e&&(g.data=e):g=document.createTextNode(e),t=Ne(A,t,n,g)}else t=""!==t&&"string"==typeof t?A.firstChild.data=e:A.textContent=e}else if(null==e||"boolean"===V)t=Ne(A,t,n);else{if("function"===V)return bA(()=>{let g=e();for(;"function"==typeof g;)g=g();t=pe(A,g,t,n)}),()=>t;if(Array.isArray(e)){const V=[],i=t&&Array.isArray(t);if(ke(V,e,t,g))return bA(()=>t=pe(A,V,t,n,!0)),()=>t;if(0===V.length){if(t=Ne(A,t,n),o)return t}else i?0===t.length?qe(A,V,n):function(A,e,t){let n=t.length,g=e.length,V=n,o=0,i=0,s=e[g-1].nextSibling,r=null;for(;o<g||i<V;)if(e[o]!==t[i]){for(;e[g-1]===t[V-1];)g--,V--;if(g===o){const e=V<n?i?t[i-1].nextSibling:t[V-i]:s;for(;i<V;)A.insertBefore(t[i++],e)}else if(V===i)for(;o<g;)r&&r.has(e[o])||e[o].remove(),o++;else if(e[o]===t[V-1]&&t[i]===e[g-1]){const n=e[--g].nextSibling;A.insertBefore(t[i++],e[o++].nextSibling),A.insertBefore(t[--V],n),e[g]=t[V]}else{if(!r){r=new Map;let A=i;for(;A<V;)r.set(t[A],A++)}const n=r.get(e[o]);if(null!=n)if(i<n&&n<V){let s,I=o,B=1;for(;++I<g&&I<V&&null!=(s=r.get(e[I]))&&s===n+B;)B++;if(B>n-i){const g=e[o];for(;i<n;)A.insertBefore(t[i++],g)}else A.replaceChild(t[i++],e[o++])}else o++;else e[o++].remove()}}else o++,i++}(A,t,V):(t&&Ne(A),qe(A,V));t=V}else if(e.nodeType){if(Array.isArray(t)){if(o)return t=Ne(A,t,n,e);Ne(A,t,null,e)}else null!=t&&""!==t&&A.firstChild?A.replaceChild(e,A.firstChild):A.appendChild(e);t=e}}return t}function ke(A,e,t,n){let g=!1;for(let V=0,o=e.length;V<o;V++){let o,i=e[V],s=t&&t[A.length];if(null==i||!0===i||!1===i);else if("object"==(o=typeof i)&&i.nodeType)A.push(i);else if(Array.isArray(i))g=ke(A,i,s)||g;else if("function"===o)if(n){for(;"function"==typeof i;)i=i();g=ke(A,Array.isArray(i)?i:[i],Array.isArray(s)?s:[s])||g}else A.push(i),g=!0;else{const e=String(i);s&&3===s.nodeType&&s.data===e?A.push(s):A.push(document.createTextNode(e))}}return g}function qe(A,e,t=null){for(let n=0,g=e.length;n<g;n++)A.insertBefore(e[n],t)}function Ne(A,e,t,n){if(void 0===t)return A.textContent="";const g=n||document.createTextNode("");if(e.length){let n=!1;for(let V=e.length-1;V>=0;V--){const o=e[V];if(g!==o){const e=o.parentNode===A;n||V?e&&o.remove():e?A.replaceChild(g,o):A.insertBefore(g,t)}else n=!0}}else A.insertBefore(g,t);return[g]}const Fe=Symbol("store-raw"),ve=Symbol("store-node"),Me=Symbol("store-has"),be=Symbol("store-self");function Ge(A){let e=A[lA];if(!e&&(Object.defineProperty(A,lA,{value:e=new Proxy(A,xe)}),!Array.isArray(A))){const t=Object.keys(A),n=Object.getOwnPropertyDescriptors(A);for(let g=0,V=t.length;g<V;g++){const V=t[g];n[V].get&&Object.defineProperty(A,V,{enumerable:n[V].enumerable,get:n[V].get.bind(e)})}}return e}function Re(A){let e;return null!=A&&"object"==typeof A&&(A[lA]||!(e=Object.getPrototypeOf(A))||e===Object.prototype||Array.isArray(A))}function Le(A,e=new Set){let t,n,g,V;if(t=null!=A&&A[Fe])return t;if(!Re(A)||e.has(A))return A;if(Array.isArray(A)){Object.isFrozen(A)?A=A.slice(0):e.add(A);for(let t=0,V=A.length;t<V;t++)g=A[t],(n=Le(g,e))!==g&&(A[t]=n)}else{Object.isFrozen(A)?A=Object.assign({},A):e.add(A);const t=Object.keys(A),o=Object.getOwnPropertyDescriptors(A);for(let i=0,s=t.length;i<s;i++)V=t[i],o[V].get||(g=A[V],(n=Le(g,e))!==g&&(A[V]=n))}return A}function Se(A,e){let t=A[e];return t||Object.defineProperty(A,e,{value:t=Object.create(null)}),t}function Je(A,e,t){if(A[e])return A[e];const[n,g]=MA(t,{equals:!1,internal:!0});return n.$=g,A[e]=n}function Ue(A){UA()&&Je(Se(A,ve),be)()}const xe={get(A,e,t){if(e===Fe)return A;if(e===lA)return t;if(e===dA)return Ue(A),t;const n=Se(A,ve),g=n[e];let V=g?g():A[e];if(e===ve||e===Me||"__proto__"===e)return V;if(!g){const t=Object.getOwnPropertyDescriptor(A,e);!UA()||"function"==typeof V&&!A.hasOwnProperty(e)||t&&t.get||(V=Je(n,e,V)())}return Re(V)?Ge(V):V},has:(A,e)=>e===Fe||e===lA||e===dA||e===ve||e===Me||"__proto__"===e||(UA()&&Je(Se(A,Me),e)(),e in A),set:()=>!0,deleteProperty:()=>!0,ownKeys:function(A){return Ue(A),Reflect.ownKeys(A)},getOwnPropertyDescriptor:function(A,e){const t=Reflect.getOwnPropertyDescriptor(A,e);return t&&!t.get&&t.configurable&&e!==lA&&e!==ve?(delete t.value,delete t.writable,t.get=()=>A[lA][e],t):t}};function Ye(A,e,t,n=!1){if(!n&&A[e]===t)return;const g=A[e],V=A.length;void 0===t?(delete A[e],A[Me]&&A[Me][e]&&void 0!==g&&A[Me][e].$()):(A[e]=t,A[Me]&&A[Me][e]&&void 0===g&&A[Me][e].$());let o,i=Se(A,ve);if((o=Je(i,e,g))&&o.$(()=>t),Array.isArray(A)&&A.length!==V){for(let e=A.length;e<V;e++)(o=i[e])&&o.$();(o=Je(i,"length",V))&&o.$(A.length)}(o=i[be])&&o.$()}function Ke(A,e){const t=Object.keys(e);for(let n=0;n<t.length;n+=1){const g=t[n];Ye(A,g,e[g])}}function Te(A,e,t=[]){let n,g=A;if(e.length>1){n=e.shift();const V=typeof n,o=Array.isArray(A);if(Array.isArray(n)){for(let g=0;g<n.length;g++)Te(A,[n[g]].concat(e),t);return}if(o&&"function"===V){for(let g=0;g<A.length;g++)n(A[g],g)&&Te(A,[g].concat(e),t);return}if(o&&"object"===V){const{from:g=0,to:V=A.length-1,by:o=1}=n;for(let n=g;n<=V;n+=o)Te(A,[n].concat(e),t);return}if(e.length>1)return void Te(A[n],e,[n].concat(t));g=A[n],t=[n].concat(t)}let V=e[0];"function"==typeof V&&(V=V(g,t),V===g)||void 0===n&&null==V||(V=Le(V),void 0===n||Re(g)&&Re(V)&&!Array.isArray(V)?Ke(g,V):Ye(A,n,V))}function je(...[A,e]){const t=Le(A||{}),n=Array.isArray(t);return[Ge(t),function(...A){RA(()=>{n&&1===A.length?function(A,e){if("function"==typeof e&&(e=e(A)),e=Le(e),Array.isArray(e)){if(A===e)return;let t=0,n=e.length;for(;t<n;t++){const n=e[t];A[t]!==n&&Ye(A,t,n)}Ye(A,"length",n)}else Ke(A,e)}(t,A[0]):Te(t,A)})}]}const He=Symbol("store-root");function Oe(A,e,t,n,g){const V=e[t];if(A===V)return;const o=Array.isArray(A);if(t!==He&&(!Re(A)||!Re(V)||o!==Array.isArray(V)||g&&A[g]!==V[g]))return void Ye(e,t,A);if(o){if(A.length&&V.length&&(!n||g&&A[0]&&null!=A[0][g])){let e,t,o,i,s,r,I,B;for(o=0,i=Math.min(V.length,A.length);o<i&&(V[o]===A[o]||g&&V[o]&&A[o]&&V[o][g]===A[o][g]);o++)Oe(A[o],V,o,n,g);const a=new Array(A.length),C=new Map;for(i=V.length-1,s=A.length-1;i>=o&&s>=o&&(V[i]===A[s]||g&&V[i]&&A[s]&&V[i][g]===A[s][g]);i--,s--)a[s]=V[i];if(o>s||o>i){for(t=o;t<=s;t++)Ye(V,t,A[t]);for(;t<A.length;t++)Ye(V,t,a[t]),Oe(A[t],V,t,n,g);return void(V.length>A.length&&Ye(V,"length",A.length))}for(I=new Array(s+1),t=s;t>=o;t--)r=A[t],B=g&&r?r[g]:r,e=C.get(B),I[t]=void 0===e?-1:e,C.set(B,t);for(e=o;e<=i;e++)r=V[e],B=g&&r?r[g]:r,t=C.get(B),void 0!==t&&-1!==t&&(a[t]=V[e],t=I[t],C.set(B,t));for(t=o;t<A.length;t++)t in a?(Ye(V,t,a[t]),Oe(A[t],V,t,n,g)):Ye(V,t,A[t])}else for(let e=0,t=A.length;e<t;e++)Oe(A[e],V,e,n,g);return void(V.length>A.length&&Ye(V,"length",A.length))}const i=Object.keys(A);for(let r=0,I=i.length;r<I;r++)Oe(A[i[r]],V,i[r],n,g);const s=Object.keys(V);for(let r=0,I=s.length;r<I;r++)void 0===A[s[r]]&&Ye(V,s[r],void 0)}function We(A,e={}){const{merge:t,key:n="id"}=e,g=Le(A);return A=>{if(!Re(A)||!Re(g))return g;const e=Oe(g,{[He]:A},He,t,n);return void 0===e?A:e}}const _e=()=>{},Ze=(A,e)=>e();function ze(A,e){const t=LA(A),n=t?[t]:[],{onEnter:g=Ze,onExit:V=Ze}=e,[o,i]=MA(e.appear?[]:n),[s]=[YA,xA];let r,I=!1;function B(A,e){if(!A)return e&&e();I=!0,V(A,()=>{RA(()=>{I=!1,i(e=>e.filter(e=>e!==A)),e&&e()})})}function a(A){const e=r;if(!e)return A&&A();r=void 0,i(A=>[e,...A]),g(e,A??_e)}const C="out-in"===e.mode?A=>I||B(A,a):"in-out"===e.mode?A=>a(()=>B(A)):A=>{B(A),a()};var Q,E;return Q=e=>{const t=A();return LA(s)?(s(),e):(t!==e&&(r=t,RA(()=>LA(()=>C(e)))),t)},E=e.appear?void 0:t,OA(WA(Q,E,!0,wA)),o}const Xe=A=>A instanceof Element;function Pe(A,e){if(e(A))return A;if("function"==typeof A&&!A.length)return Pe(A(),e);if(Array.isArray(A))for(const t of A){const A=Pe(t,e);if(A)return A}return null}function $e(A,e=Xe,t=Xe){const n=GA(A);return GA(()=>Pe(n(),e))}function At(A){requestAnimationFrame(()=>requestAnimationFrame(A))}var et={inout:"in-out",outin:"out-in"},tt=A=>{const e=function(A){return GA(()=>{const e=A.name||"s";return{enterActive:(A.enterActiveClass||e+"-enter-active").split(" "),enter:(A.enterClass||e+"-enter").split(" "),enterTo:(A.enterToClass||e+"-enter-to").split(" "),exitActive:(A.exitActiveClass||e+"-exit-active").split(" "),exit:(A.exitClass||e+"-exit").split(" "),exitTo:(A.exitToClass||e+"-exit-to").split(" "),move:(A.moveClass||e+"-move").split(" ")}})}(A);return ze($e(()=>A.children),{mode:et[A.mode],appear:A.appear,onEnter(t,n){!function(A,e,t,n){const{onBeforeEnter:g,onEnter:V,onAfterEnter:o}=e;function i(e){e&&e.target!==t||(n?.(),t.removeEventListener("transitionend",i),t.removeEventListener("animationend",i),t.classList.remove(...A.enterActive),t.classList.remove(...A.enterTo),o?.(t))}g?.(t),t.classList.add(...A.enter),t.classList.add(...A.enterActive),queueMicrotask(()=>{if(!t.parentNode)return n?.();V?.(t,()=>i())}),At(()=>{t.classList.remove(...A.enter),t.classList.add(...A.enterTo),(!V||V.length<2)&&(t.addEventListener("transitionend",i),t.addEventListener("animationend",i))})}(e(),A,t,n)},onExit(t,n){!function(A,e,t,n){const{onBeforeExit:g,onExit:V,onAfterExit:o}=e;if(!t.parentNode)return n?.();function i(e){e&&e.target!==t||(n?.(),t.removeEventListener("transitionend",i),t.removeEventListener("animationend",i),t.classList.remove(...A.exitActive),t.classList.remove(...A.exitTo),o?.(t))}g?.(t),t.classList.add(...A.exit),t.classList.add(...A.exitActive),V?.(t,()=>i()),At(()=>{t.classList.remove(...A.exit),t.classList.add(...A.exitTo),(!V||V.length<2)&&(t.addEventListener("transitionend",i),t.addEventListener("animationend",i))})}(e(),A,t,n)}})};const nt=ue("<span></span>",2);var gt=A=>{const e=GA(()=>{if(1==A.text.length){const e=A.text.codePointAt(0);if(e>=9600&&e<=9631||57520==e||57522==e)return e}}),t=GA(()=>e()?" ":A.text),n=GA(()=>function(A,e,t){const n=A.get("fg"),g=A.get("bg");let V={"--offset":e,width:`${t+.01}ch`};"string"==typeof n&&(V["--fg"]=n);"string"==typeof g&&(V["--bg"]=g);return V}(A.pen,A.offset,A.cellCount)),g=GA(()=>function(A,e,t){const n=Vt(A.get("fg"),A.get("bold"),"fg-"),g=Vt(A.get("bg"),!1,"bg-");let V=t??"";void 0!==e&&(V+=` cp-${e.toString(16)}`);n&&(V+=" "+n);g&&(V+=" "+g);A.has("bold")&&(V+=" ap-bright");A.has("faint")&&(V+=" ap-faint");A.has("italic")&&(V+=" ap-italic");A.has("underline")&&(V+=" ap-underline");A.has("blink")&&(V+=" ap-blink");A.get("inverse")&&(V+=" ap-inverse");return V}(A.pen,e(),A.extraClass));return(()=>{const A=nt.cloneNode(!0);return ye(A,t),bA(e=>{const t=g(),V=n();return t!==e._v$&&he(A,e._v$=t),e._v$2=we(A,V,e._v$2),e},{_v$:void 0,_v$2:void 0}),A})()};function Vt(A,e,t){if("number"==typeof A)return e&&A<8&&(A+=8),`${t}${A}`}const ot=ue('<span class="ap-line" role="paragraph"></span>',2);var it=A=>(()=>{const e=ot.cloneNode(!0);return ye(e,Ve(ae,{get each(){return(()=>{if("number"==typeof A.cursor){const e=[];let t=0,n=0;for(;n<A.segments.length&&t+A.segments[n].cellCount-1<A.cursor;){const g=A.segments[n];e.push(g),t+=g.cellCount,n++}if(n<A.segments.length){const g=A.segments[n],V=g.charWidth;let o=A.cursor-t;const i=Math.floor(o/V);o=i*V;const s=Array.from(g.text);for(i>0&&e.push({...g,text:s.slice(0,i).join("")}),e.push({...g,text:s[i],offset:t+o,cellCount:V,extraClass:"ap-cursor"}),i<s.length-1&&e.push({...g,text:s.slice(i+1).join(""),offset:t+o+1,cellCount:g.cellCount-V}),n++;n<A.segments.length;){const t=A.segments[n];e.push(t),n++}}return e}return A.segments})()},children:A=>Ve(gt,function(...A){let e=!1;for(let o=0;o<A.length;o++){const t=A[o];e=e||!!t&&lA in t,A[o]="function"==typeof t?(e=!0,GA(t)):t}if(uA&&e)return new Proxy({get(e){for(let t=A.length-1;t>=0;t--){const n=se(A[t])[e];if(void 0!==n)return n}},has(e){for(let t=A.length-1;t>=0;t--)if(e in se(A[t]))return!0;return!1},keys(){const e=[];for(let t=0;t<A.length;t++)e.push(...Object.keys(se(A[t])));return[...new Set(e)]}},ie);const t={},n=Object.create(null);for(let o=A.length-1;o>=0;o--){const e=A[o];if(!e)continue;const g=Object.getOwnPropertyNames(e);for(let A=g.length-1;A>=0;A--){const V=g[A];if("__proto__"===V||"constructor"===V)continue;const o=Object.getOwnPropertyDescriptor(e,V);if(n[V]){const A=t[V];A&&(o.get?A.push(o.get.bind(e)):void 0!==o.value&&A.push(()=>o.value))}else n[V]=o.get?{enumerable:!0,configurable:!0,get:re.bind(t[V]=[o.get.bind(e)])}:void 0!==o.value?o:void 0}}const g={},V=Object.keys(n);for(let o=V.length-1;o>=0;o--){const A=V[o],e=n[A];e&&e.get?Object.defineProperty(g,A,e):g[A]=e?e.value:void 0}return g}(A))})),e})();const st=ue('<pre class="ap-terminal" aria-live="off" tabindex="0"></pre>',2);var rt=A=>{const e=()=>A.lineHeight??1.3333333333,t=GA(()=>({width:`${A.cols}ch`,height:e()*A.rows+"em","font-size":100*(A.scale||1)+"%","font-family":A.fontFamily,"--term-line-height":`${e()}em`,"--term-cols":A.cols})),n=GA(()=>A.cursor?.[0]),g=GA(()=>A.cursor?.[1]);return(()=>{const e=st.cloneNode(!0),V=A.ref;return"function"==typeof V?me(V,e):A.ref=e,ye(e,Ve(Be,{get each(){return A.lines},children:(A,e)=>Ve(it,{get segments(){return A.segments},get cursor(){return(A=()=>e()===g(),GA(()=>A()))()?n():null;var A}})})),bA(n=>{const g=!(!A.blink&&!A.cursorHold),V=!!A.blink,o=t();return g!==n._v$&&e.classList.toggle("ap-cursor-on",n._v$=g),V!==n._v$2&&e.classList.toggle("ap-blink",n._v$2=V),n._v$3=we(e,o,n._v$3),n},{_v$:void 0,_v$2:void 0,_v$3:void 0}),e})()};const It=ue('<svg version="1.1" viewBox="0 0 12 12" class="ap-icon ap-icon-fullscreen-off"><path d="M7,5 L7,0 L9,2 L11,0 L12,1 L10,3 L12,5 Z"></path><path d="M5,7 L0,7 L2,9 L0,11 L1,12 L3,10 L5,12 Z"></path></svg>',6);var Bt=A=>It.cloneNode(!0);const at=ue('<svg version="1.1" viewBox="6 8 14 16" class="ap-icon"><path d="M0.938 8.313h22.125c0.5 0 0.938 0.438 0.938 0.938v13.5c0 0.5-0.438 0.938-0.938 0.938h-22.125c-0.5 0-0.938-0.438-0.938-0.938v-13.5c0-0.5 0.438-0.938 0.938-0.938zM1.594 22.063h20.813v-12.156h-20.813v12.156zM3.844 11.188h1.906v1.938h-1.906v-1.938zM7.469 11.188h1.906v1.938h-1.906v-1.938zM11.031 11.188h1.938v1.938h-1.938v-1.938zM14.656 11.188h1.875v1.938h-1.875v-1.938zM18.25 11.188h1.906v1.938h-1.906v-1.938zM5.656 15.031h1.938v1.938h-1.938v-1.938zM9.281 16.969v-1.938h1.906v1.938h-1.906zM12.875 16.969v-1.938h1.906v1.938h-1.906zM18.406 16.969h-1.938v-1.938h1.938v1.938zM16.531 20.781h-9.063v-1.906h9.063v1.906z"></path></svg>',4);var Ct=A=>at.cloneNode(!0);const Qt=ue('<svg version="1.1" viewBox="0 0 12 12" class="ap-icon" aria-label="Pause" role="button"><path d="M1,0 L4,0 L4,12 L1,12 Z"></path><path d="M8,0 L11,0 L11,12 L8,12 Z"></path></svg>',6);var Et=A=>Qt.cloneNode(!0);const ct=ue('<svg version="1.1" viewBox="0 0 12 12" class="ap-icon" aria-label="Play" role="button"><path d="M1,0 L11,6 L1,12 Z"></path></svg>',4);var lt=A=>ct.cloneNode(!0);const ut=ue('<svg version="1.1" viewBox="0 0 12 12" class="ap-icon ap-icon-fullscreen-on"><path d="M12,0 L7,0 L9,2 L7,4 L8,5 L10,3 L12,5 Z"></path><path d="M0,12 L0,7 L2,9 L4,7 L5,8 L3,10 L5,12 Z"></path></svg>',6);var dt=A=>ut.cloneNode(!0);const ht=ue('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"><path d="M10.5 3.75a.75.75 0 0 0-1.264-.546L5.203 7H2.667a.75.75 0 0 0-.7.48A6.985 6.985 0 0 0 1.5 10c0 .887.165 1.737.468 2.52.111.29.39.48.7.48h2.535l4.033 3.796a.75.75 0 0 0 1.264-.546V3.75ZM16.45 5.05a.75.75 0 0 0-1.06 1.061 5.5 5.5 0 0 1 0 7.778.75.75 0 0 0 1.06 1.06 7 7 0 0 0 0-9.899Z"></path><path d="M14.329 7.172a.75.75 0 0 0-1.061 1.06 2.5 2.5 0 0 1 0 3.536.75.75 0 0 0 1.06 1.06 4 4 0 0 0 0-5.656Z"></path></svg>',6);var ft=A=>ht.cloneNode(!0);const wt=ue('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-5"><path d="M10.047 3.062a.75.75 0 0 1 .453.688v12.5a.75.75 0 0 1-1.264.546L5.203 13H2.667a.75.75 0 0 1-.7-.48A6.985 6.985 0 0 1 1.5 10c0-.887.165-1.737.468-2.52a.75.75 0 0 1 .7-.48h2.535l4.033-3.796a.75.75 0 0 1 .811-.142ZM13.78 7.22a.75.75 0 1 0-1.06 1.06L14.44 10l-1.72 1.72a.75.75 0 0 0 1.06 1.06l1.72-1.72 1.72 1.72a.75.75 0 1 0 1.06-1.06L16.56 10l1.72-1.72a.75.75 0 0 0-1.06-1.06L15.5 8.94l-1.72-1.72Z"></path></svg>',4);var mt=A=>wt.cloneNode(!0);const yt=ue('<span class="ap-button ap-playback-button" tabindex="0"></span>',2),Dt=ue('<span class="ap-bar"><span class="ap-gutter ap-gutter-empty"></span><span class="ap-gutter ap-gutter-full"></span></span>',6),pt=ue('<span class="ap-tooltip">Unmute (m)</span>',2),kt=ue('<span class="ap-tooltip">Mute (m)</span>',2),qt=ue('<span class="ap-button ap-speaker-button ap-tooltip-container" aria-label="Mute / unmute" role="button" tabindex="0"></span>',2),Nt=ue('<div class="ap-control-bar"><span class="ap-timer" aria-readonly="true" role="textbox" tabindex="0"><span class="ap-time-elapsed"></span><span class="ap-time-remaining"></span></span><span class="ap-progressbar"></span><span class="ap-button ap-kbd-button ap-tooltip-container" aria-label="Show keyboard shortcuts" role="button" tabindex="0"><span class="ap-tooltip">Keyboard shortcuts (?)</span></span><span class="ap-button ap-fullscreen-button ap-tooltip-container" aria-label="Toggle fullscreen mode" role="button" tabindex="0"><span class="ap-tooltip">Fullscreen (f)</span></span></div>',18),Ft=ue('<span class="ap-marker-container ap-tooltip-container"><span class="ap-marker"></span><span class="ap-tooltip"></span></span>',6);function vt(A){let e=Math.floor(A);const t=Math.floor(e/86400);e%=86400;const n=Math.floor(e/3600);e%=3600;const g=Math.floor(e/60);return e%=60,t>0?`${Mt(t)}:${Mt(n)}:${Mt(g)}:${Mt(e)}`:n>0?`${Mt(n)}:${Mt(g)}:${Mt(e)}`:`${Mt(g)}:${Mt(e)}`}function Mt(A){return A<10?`0${A}`:A.toString()}var bt=A=>{const e=A=>e=>{e.preventDefault(),A(e)},t=()=>"number"==typeof A.currentTime?vt(A.currentTime):"--:--",n=()=>"number"==typeof A.remainingTime?"-"+vt(A.remainingTime):t(),g=GA(()=>"number"==typeof A.duration?A.markers.filter(e=>e[0]<A.duration):[]),V=A=>{const e=A.currentTarget.offsetWidth,t=A.currentTarget.getBoundingClientRect(),n=A.clientX-t.left;return 100*Math.max(0,n/e)+"%"},[o,i]=MA(!1),s=function(A,e){let t=!0;return function(){if(t){t=!1;for(var n=arguments.length,g=new Array(n),V=0;V<n;V++)g[V]=arguments[V];A.apply(this,g),setTimeout(()=>t=!0,e)}}}(A.onSeekClick,50),r=e=>{e._marker||e.altKey||e.shiftKey||e.metaKey||e.ctrlKey||0!==e.button||(i(!0),A.onSeekClick(V(e)))},I=A=>{A.altKey||A.shiftKey||A.metaKey||A.ctrlKey||o()&&s(V(A))},B=()=>{i(!1)};return document.addEventListener("mouseup",B),JA(()=>{document.removeEventListener("mouseup",B)}),(()=>{const V=Nt.cloneNode(!0),o=V.firstChild,i=o.firstChild,s=i.nextSibling,B=o.nextSibling,a=B.nextSibling,C=a.firstChild,Q=a.nextSibling,E=Q.firstChild,c=A.ref;return"function"==typeof c?me(c,V):A.ref=V,ye(V,Ve(Ce,{get when(){return A.isPausable},get children(){const t=yt.cloneNode(!0);return fe(t,"click",e(A.onPlayClick)),ye(t,Ve(Qe,{get children(){return[Ve(Ee,{get when(){return A.isPlaying},get children(){return Ve(Et,{})}}),Ve(Ee,{when:!0,get children(){return Ve(lt,{})}})]}})),t}}),o),ye(i,t),ye(s,n),ye(B,Ve(Ce,{get when(){return"number"==typeof A.progress||A.isSeekable},get children(){const t=Dt.cloneNode(!0),n=t.firstChild.nextSibling;return t.$$mousemove=I,t.$$mousedown=r,ye(t,Ve(Be,{get each(){return g()},children:(t,n)=>(()=>{const g=Ft.cloneNode(!0),V=g.firstChild,o=V.nextSibling;var i;return g.$$mousedown=A=>{A._marker=!0},fe(g,"click",(i=n(),e(()=>{A.onSeekClick({marker:i})}))),ye(o,()=>(A=>""===A[1]?vt(A[0]):`${vt(A[0])} - ${A[1]}`)(t)),bA(e=>{const n=(e=>e[0]/A.duration*100+"%")(t),o=!!(e=>"number"==typeof A.currentTime&&e[0]<=A.currentTime)(t);return n!==e._v$&&g.style.setProperty("left",e._v$=n),o!==e._v$2&&V.classList.toggle("ap-marker-past",e._v$2=o),e},{_v$:void 0,_v$2:void 0}),g})()}),null),bA(e=>we(n,{transform:`scaleX(${A.progress||0}`},e)),t}})),ye(V,Ve(Ce,{get when(){return void 0!==A.isMuted},get children(){const t=qt.cloneNode(!0);return fe(t,"click",e(A.onMuteClick)),ye(t,Ve(Qe,{get children(){return[Ve(Ee,{get when(){return!0===A.isMuted},get children(){return[Ve(mt,{}),pt.cloneNode(!0)]}}),Ve(Ee,{get when(){return!1===A.isMuted},get children(){return[Ve(ft,{}),kt.cloneNode(!0)]}})]}})),t}}),a),fe(a,"click",e(A.onHelpClick)),ye(a,Ve(Ct,{}),C),fe(Q,"click",e(A.onFullscreenClick)),ye(Q,Ve(dt,{}),E),ye(Q,Ve(Bt,{}),E),bA(()=>V.classList.toggle("ap-seekable",!!A.isSeekable)),V})()};de(["click","mousedown","mousemove"]);const Gt=ue('<div class="ap-overlay ap-overlay-error"><span>\ud83d\udca5</span></div>',4);var Rt=A=>Gt.cloneNode(!0);const Lt=ue('<div class="ap-overlay ap-overlay-loading"><span class="ap-loader"></span></div>',4);var St=A=>Lt.cloneNode(!0);const Jt=ue('<div class="ap-overlay ap-overlay-info"><span></span></div>',4);var Ut=A=>(()=>{const e=Jt.cloneNode(!0),t=e.firstChild;return ye(t,()=>A.message),bA(n=>{const g=!!A.wasPlaying,V={"font-family":A.fontFamily};return g!==n._v$&&e.classList.toggle("ap-was-playing",n._v$=g),n._v$2=we(t,V,n._v$2),n},{_v$:void 0,_v$2:void 0}),e})();const xt=ue('<div class="ap-overlay ap-overlay-start"><div class="ap-play-button"><div><span><svg version="1.1" viewBox="0 0 1000.0 1000.0" class="ap-icon"><defs><mask id="small-triangle-mask"><rect width="100%" height="100%" fill="white"></rect><polygon points="700.0 500.0, 400.00000000000006 326.7949192431122, 399.9999999999999 673.2050807568877" fill="black"></polygon></mask></defs><polygon points="1000.0 500.0, 250.0000000000001 66.98729810778059, 249.99999999999977 933.0127018922192" mask="url(#small-triangle-mask)" fill="white" class="ap-play-btn-fill"></polygon><polyline points="673.2050807568878 400.0, 326.7949192431123 600.0" stroke="white" stroke-width="90" class="ap-play-btn-stroke"></polyline></svg></span></div></div></div>',22);var Yt=A=>(()=>{const e=xt.cloneNode(!0);var t;return fe(e,"click",(t=A.onClick,A=>{A.preventDefault(),t(A)})),e})();de(["click"]);const Kt=ue("<li><kbd>space</kbd> - pause / resume</li>",4),Tt=ue("<li><kbd>\u2190</kbd> / <kbd>\u2192</kbd> - rewind / fast-forward by 5 seconds</li>",6),jt=ue("<li><kbd>Shift</kbd> + <kbd>\u2190</kbd> / <kbd>\u2192</kbd> - rewind / fast-forward by 10%</li>",8),Ht=ue("<li><kbd>[</kbd> / <kbd>]</kbd> - jump to the previous / next marker</li>",6),Ot=ue("<li><kbd>0</kbd>, <kbd>1</kbd>, <kbd>2</kbd> ... <kbd>9</kbd> - jump to 0%, 10%, 20% ... 90%</li>",10),Wt=ue("<li><kbd>,</kbd> / <kbd>.</kbd> - step back / forward, a frame at a time (when paused)</li>",6),_t=ue("<li><kbd>m</kbd> - mute / unmute audio</li>",4),Zt=ue('<div class="ap-overlay ap-overlay-help"><div><div><p>Keyboard shortcuts</p><ul><li><kbd>f</kbd> - toggle fullscreen mode</li><li><kbd>?</kbd> - show this help popup</li></ul></div></div></div>',18);var zt=A=>(()=>{const e=Zt.cloneNode(!0),t=e.firstChild,n=t.firstChild.firstChild.nextSibling,g=n.firstChild,V=g.nextSibling;var o;return fe(e,"click",(o=A.onClose,A=>{A.preventDefault(),o(A)})),t.$$click=A=>{A.stopPropagation()},ye(n,Ve(Ce,{get when(){return A.isPausable},get children(){return Kt.cloneNode(!0)}}),g),ye(n,Ve(Ce,{get when(){return A.isSeekable},get children(){return[Tt.cloneNode(!0),jt.cloneNode(!0),Ht.cloneNode(!0),Ot.cloneNode(!0),Wt.cloneNode(!0)]}}),g),ye(n,Ve(Ce,{get when(){return A.hasAudio},get children(){return _t.cloneNode(!0)}}),V),bA(t=>we(e,{"font-family":A.fontFamily},t)),e})();de(["click"]);const Xt=ue('<div class="ap-wrapper" tabindex="-1"><div></div></div>',4);var Pt=A=>{const e=A.logger,t=A.core,n=A.autoPlay,[g,V]=je({lines:[],cursor:void 0,charW:A.charW,charH:A.charH,bordersW:A.bordersW,bordersH:A.bordersH,containerW:0,containerH:0,isPausable:!0,isSeekable:!0,isFullscreen:!1,currentTime:null,remainingTime:null,progress:null,blink:!0,cursorHold:!1}),[o,i]=MA(!1),[s,r]=MA(void 0),[I,B]=MA(!1),[a,C]=MA(n?null:"start"),[Q,E]=MA(null),[c,l]=MA({cols:A.cols,rows:A.rows},{equals:(A,e)=>A.cols===e.cols&&A.rows===e.rows}),[u,d]=MA(void 0),[h,f]=je([]),[w,m]=MA(!1),[y,D]=MA(!1),[p,k]=MA(void 0),q=GA(()=>c().cols||80),N=GA(()=>c().rows||24),F=()=>!1===A.controls?0:32;let v,M,b,G,R,L,S,J,U,x;function Y(){VA(),tA(),nA()}function K(A){RA(()=>{A.rows<c().rows&&V("lines",g.lines.slice(0,A.rows)),l(A)})}function T(A){null===A||n||V({lines:A.lines,cursor:A.cursor})}const j=new Promise(A=>{x=A});t.addEventListener("ready",A=>{let{isPausable:e,isSeekable:t,poster:n}=A;V({isPausable:e,isSeekable:t}),T(n),x()}),t.addEventListener("metadata",A=>{let{cols:e,rows:t,duration:n,theme:g,poster:V,markers:o,hasAudio:i}=A;RA(()=>{K({cols:e,rows:t}),d(n),k(g),f(o),T(V),r(!i&&void 0)})}),t.addEventListener("play",()=>{C(null)}),t.addEventListener("playing",()=>{RA(()=>{i(!0),B(!0),C(null),W(),gA(),eA()})}),t.addEventListener("idle",()=>{RA(()=>{i(!1),Y()})}),t.addEventListener("loading",()=>{RA(()=>{i(!1),Y(),C("loader")})}),t.addEventListener("offline",A=>{let{message:e}=A;RA(()=>{i(!1),Y(),void 0!==e&&(E(e),C("info"))})}),t.addEventListener("muted",A=>{r(A)});let H=0;t.addEventListener("ended",A=>{let{message:t}=A;RA(()=>{i(!1),Y(),void 0!==t&&(E(t),C("info"))}),e.debug(`view: render count: ${H}`)}),t.addEventListener("errored",()=>{C("error")}),t.addEventListener("resize",K),t.addEventListener("reset",A=>{let{cols:e,rows:t,theme:n}=A;RA(()=>{K({cols:e,rows:t}),k(n),W()})}),t.addEventListener("seeked",()=>{nA()}),t.addEventListener("terminalUpdate",()=>{void 0===v&&(v=requestAnimationFrame(W))});const O=()=>{U=new ResizeObserver(function(A,e){let t;return function(){for(var n=arguments.length,g=new Array(n),V=0;V<n;V++)g[V]=arguments[V];clearTimeout(t),t=setTimeout(()=>A.apply(this,g),e)}}(A=>{V({containerW:R.offsetWidth,containerH:R.offsetHeight}),R.dispatchEvent(new CustomEvent("resize",{detail:{el:L}}))},10)),U.observe(R)};SA(async()=>{e.info("view: mounted"),e.debug("view: font measurements",{charW:g.charW,charH:g.charH}),O(),V({containerW:R.offsetWidth,containerH:R.offsetHeight})}),JA(()=>{t.stop(),VA(),tA(),U.disconnect()});const W=async()=>{const A=await t.getChanges();RA(()=>{void 0!==A.lines&&A.lines.forEach((A,e)=>{V("lines",e,We(A))}),void 0!==A.cursor&&V("cursor",We(A.cursor)),V("cursorHold",!0)}),v=void 0,H+=1},_=GA(()=>{const e=g.charW*q()+g.bordersW,t=g.charH*N()+g.bordersH;let n=A.fit??"width";if("both"===n||g.isFullscreen){n=g.containerW/(g.containerH-F())>e/t?"height":"width"}if(!1===n||"none"===n)return{};if("width"===n){const A=g.containerW/e;return{scale:A,width:g.containerW,height:t*A+F()}}if("height"===n){const A=(g.containerH-F())/t;return{scale:A,width:e*A,height:g.containerH}}throw`unsupported fit mode: ${n}`}),Z=()=>{V("isFullscreen",document.fullscreenElement??document.webkitFullscreenElement)},z=()=>{g.isFullscreen?(document.exitFullscreen??document.webkitExitFullscreen??(()=>{})).apply(document):(R.requestFullscreen??R.webkitRequestFullscreen??(()=>{})).apply(R)},X=()=>{y()?D(!1):(t.pause(),D(!0))},P=A=>{if(!(A.altKey||A.metaKey||A.ctrlKey)){if(" "==A.key)t.togglePlay();else if(","==A.key)t.step(-1).then(nA);else if("."==A.key)t.step().then(nA);else if("f"==A.key)z();else if("m"==A.key)IA();else if("["==A.key)t.seek({marker:"prev"});else if("]"==A.key)t.seek({marker:"next"});else if(A.key.charCodeAt(0)>=48&&A.key.charCodeAt(0)<=57){const e=(A.key.charCodeAt(0)-48)/10;t.seek(100*e+"%")}else if("?"==A.key)X();else if("ArrowLeft"==A.key)A.shiftKey?t.seek("<<<"):t.seek("<<");else if("ArrowRight"==A.key)A.shiftKey?t.seek(">>>"):t.seek(">>");else{if("Escape"!=A.key)return;D(!1)}A.stopPropagation(),A.preventDefault()}},$=()=>{g.isFullscreen&&oA(!0)},AA=()=>{g.isFullscreen||oA(!1)},eA=()=>{b=setInterval(nA,100)},tA=()=>{clearInterval(b)},nA=async()=>{const A=await t.getCurrentTime(),e=await t.getRemainingTime(),n=await t.getProgress();V({currentTime:A,remainingTime:e,progress:n})},gA=()=>{G=setInterval(()=>{V(A=>{const e={blink:!A.blink};return e.blink&&(e.cursorHold=!1),e})},600)},VA=()=>{clearInterval(G),V("blink",!0)},oA=A=>{clearTimeout(M),A&&(M=setTimeout(()=>oA(!1),2e3)),m(A)},iA=GA(()=>{const e=A.theme||"auto/asciinema";return"auto/"===e.slice(0,5)?{name:e.slice(5),colors:p()}:{name:e}}),sA=()=>{j.then(()=>t.play())},rA=()=>{j.then(()=>t.togglePlay())},IA=()=>{j.then(()=>{!0===s()?t.unmute():t.mute()})},BA=A=>{j.then(()=>t.seek(A))},aA=(()=>{const e=Xt.cloneNode(!0),t=e.firstChild;"function"==typeof R?me(R,e):R=e,e.addEventListener("webkitfullscreenchange",Z),e.addEventListener("fullscreenchange",Z),e.$$mousemove=$,e.$$keydown=P;return"function"==typeof L?me(L,t):L=t,t.$$mousemove=()=>oA(!0),t.addEventListener("mouseleave",AA),ye(t,Ve(rt,{get cols(){return q()},get rows(){return N()},get scale(){return _()?.scale},get blink(){return g.blink},get lines(){return g.lines},get cursor(){return g.cursor},get cursorHold(){return g.cursorHold},get fontFamily(){return A.terminalFontFamily},get lineHeight(){return A.terminalLineHeight},ref(A){"function"==typeof S?S(A):S=A}}),null),ye(t,Ve(Ce,{get when(){return!1!==A.controls},get children(){return Ve(bt,{get duration(){return u()},get currentTime(){return g.currentTime},get remainingTime(){return g.remainingTime},get progress(){return g.progress},markers:h,get isPlaying(){return o()||"loader"==a()},get isPausable(){return g.isPausable},get isSeekable(){return g.isSeekable},get isMuted(){return s()},onPlayClick:rA,onFullscreenClick:z,onHelpClick:X,onSeekClick:BA,onMuteClick:IA,ref(A){"function"==typeof J?J(A):J=A}})}}),null),ye(t,Ve(Qe,{get children(){return[Ve(Ee,{get when(){return"start"==a()},get children(){return Ve(Yt,{onClick:sA})}}),Ve(Ee,{get when(){return"loader"==a()},get children(){return Ve(St,{})}}),Ve(Ee,{get when(){return"error"==a()},get children(){return Ve(Rt,{})}})]}}),null),ye(t,Ve(tt,{name:"slide",get children(){return Ve(Ce,{get when(){return"info"==a()},get children(){return Ve(Ut,{get message(){return Q()},get fontFamily(){return A.terminalFontFamily},get wasPlaying(){return I()}})}})}}),null),ye(t,Ve(Ce,{get when(){return y()},get children(){return Ve(zt,{get fontFamily(){return A.terminalFontFamily},onClose:()=>D(!1),get isPausable(){return g.isPausable},get isSeekable(){return g.isSeekable},get hasAudio(){return void 0!==s()}})}}),null),bA(n=>{const g=!!(!0===A.controls||"auto"===A.controls&&w()),V=`ap-player asciinema-player-theme-${iA().name}`,o=(()=>{const e={};!1!==A.fit&&"none"!==A.fit||void 0===A.terminalFontSize||("small"===A.terminalFontSize?e["font-size"]="12px":"medium"===A.terminalFontSize?e["font-size"]="18px":"big"===A.terminalFontSize?e["font-size"]="24px":e["font-size"]=A.terminalFontSize);const t=_();void 0!==t.width&&(e.width=`${t.width}px`,e.height=`${t.height}px`);const n=iA().colors;return n&&(e["--term-color-foreground"]=n.foreground,e["--term-color-background"]=n.background,n.palette.forEach((A,t)=>{e[`--term-color-${t}`]=A})),e})();return g!==n._v$&&e.classList.toggle("ap-hud",n._v$=g),V!==n._v$2&&he(t,n._v$2=V),n._v$3=we(t,o,n._v$3),n},{_v$:void 0,_v$2:void 0,_v$3:void 0}),e})();return aA};function $t(A,e){let t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const n=function(A,e){const t=80,n=24,g=document.createElement("div");let V;g.style.height="0px",g.style.overflow="hidden",g.style.fontSize="15px",document.body.appendChild(g);const o=le(()=>(V=Ve(rt,{cols:t,rows:n,lineHeight:e,fontFamily:A,lines:[]}),V),g),i={charW:V.clientWidth/t,charH:V.clientHeight/n,bordersW:V.offsetWidth-V.clientWidth,bordersH:V.offsetHeight-V.clientHeight};return o(),document.body.removeChild(g),i}(t.terminalFontFamily,t.terminalLineHeight),g={core:A,logger:t.logger,cols:t.cols,rows:t.rows,fit:t.fit,controls:t.controls,autoPlay:t.autoPlay,terminalFontSize:t.terminalFontSize,terminalFontFamily:t.terminalFontFamily,terminalLineHeight:t.terminalLineHeight,theme:t.theme,...n};let V;const o=le(()=>(V=Ve(Pt,g),V),e);return{el:V,dispose:o}}de(["keydown","mousemove"]);const An=["autoPlay","autoplay","cols","idleTimeLimit","loop","markers","pauseOnMarkers","poster","preload","rows","speed","startAt","audioUrl"],en=["autoPlay","autoplay","cols","controls","fit","rows","terminalFontFamily","terminalFontSize","terminalLineHeight","theme"];function tn(A,e){let t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const n=t.logger??new g,V=new QA(A,function(A){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const t=Object.fromEntries(Object.entries(A).filter(A=>{let[e]=A;return An.includes(e)}));return t.autoPlay??=t.autoplay,t.speed??=1,{...t,...e}}(t,{logger:n})),{el:o,dispose:i}=$t(V,e,function(A){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const t=Object.fromEntries(Object.entries(A).filter(A=>{let[e]=A;return en.includes(e)}));return t.autoPlay??=t.autoplay,t.controls??="auto",{...t,...e}}(t,{logger:n})),s=V.init(),r={el:o,dispose:i,getCurrentTime:()=>s.then(V.getCurrentTime.bind(V)),getDuration:()=>s.then(V.getDuration.bind(V)),play:()=>s.then(V.play.bind(V)),pause:()=>s.then(V.pause.bind(V)),seek:A=>s.then(()=>V.seek(A)),addEventListener:(A,e)=>V.addEventListener(A,e.bind(r))};return r}},49489:(A,e,t)=>{"use strict";t.d(e,{A:()=>m});var n=t(96540),g=t(34164),V=t(18630),o=t(24245),i=t(56347),s=t(36494),r=t(62814),I=t(45167),B=t(69900);function a(A){return n.Children.toArray(A).filter(A=>"\n"!==A).map(A=>{if(!A||(0,n.isValidElement)(A)&&function(A){const{props:e}=A;return!!e&&"object"==typeof e&&"value"in e}(A))return A;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof A.type?A.type:A.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)})?.filter(Boolean)??[]}function C(A){const{values:e,children:t}=A;return(0,n.useMemo)(()=>{const A=e??function(A){return a(A).map(({props:{value:A,label:e,attributes:t,default:n}})=>({value:A,label:e,attributes:t,default:n}))}(t);return function(A){const e=(0,I.XI)(A,(A,e)=>A.value===e.value);if(e.length>0)throw new Error(`Docusaurus error: Duplicate values "${e.map(A=>A.value).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(A),A},[e,t])}function Q({value:A,tabValues:e}){return e.some(e=>e.value===A)}function E({queryString:A=!1,groupId:e}){const t=(0,i.W6)(),g=function({queryString:A=!1,groupId:e}){if("string"==typeof A)return A;if(!1===A)return null;if(!0===A&&!e)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return e??null}({queryString:A,groupId:e});return[(0,r.aZ)(g),(0,n.useCallback)(A=>{if(!g)return;const e=new URLSearchParams(t.location.search);e.set(g,A),t.replace({...t.location,search:e.toString()})},[g,t])]}function c(A){const{defaultValue:e,queryString:t=!1,groupId:g}=A,V=C(A),[o,i]=(0,n.useState)(()=>function({defaultValue:A,tabValues:e}){if(0===e.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(A){if(!Q({value:A,tabValues:e}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${A}" but none of its children has the corresponding value. Available values are: ${e.map(A=>A.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return A}const t=e.find(A=>A.default)??e[0];if(!t)throw new Error("Unexpected error: 0 tabValues");return t.value}({defaultValue:e,tabValues:V})),[r,I]=E({queryString:t,groupId:g}),[a,c]=function({groupId:A}){const e=function(A){return A?`docusaurus.tab.${A}`:null}(A),[t,g]=(0,B.Dv)(e);return[t,(0,n.useCallback)(A=>{e&&g.set(A)},[e,g])]}({groupId:g}),l=(()=>{const A=r??a;return Q({value:A,tabValues:V})?A:null})();(0,s.A)(()=>{l&&i(l)},[l]);return{selectedValue:o,selectValue:(0,n.useCallback)(A=>{if(!Q({value:A,tabValues:V}))throw new Error(`Can't select invalid tab value=${A}`);i(A),I(A),c(A)},[I,c,V]),tabValues:V}}var l=t(11062);const u={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var d=t(74848);function h({className:A,block:e,selectedValue:t,selectValue:n,tabValues:V}){const i=[],{blockElementScrollPositionUntilNextRender:s}=(0,o.a_)(),r=A=>{const e=A.currentTarget,g=i.indexOf(e),o=V[g].value;o!==t&&(s(e),n(o))},I=A=>{let e=null;switch(A.key){case"Enter":r(A);break;case"ArrowRight":{const t=i.indexOf(A.currentTarget)+1;e=i[t]??i[0];break}case"ArrowLeft":{const t=i.indexOf(A.currentTarget)-1;e=i[t]??i[i.length-1];break}}e?.focus()};return(0,d.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,g.A)("tabs",{"tabs--block":e},A),children:V.map(({value:A,label:e,attributes:n})=>(0,d.jsx)("li",{role:"tab",tabIndex:t===A?0:-1,"aria-selected":t===A,ref:A=>{i.push(A)},onKeyDown:I,onClick:r,...n,className:(0,g.A)("tabs__item",u.tabItem,n?.className,{"tabs__item--active":t===A}),children:e??A},A))})}function f({lazy:A,children:e,selectedValue:t}){const V=(Array.isArray(e)?e:[e]).filter(Boolean);if(A){const A=V.find(A=>A.props.value===t);return A?(0,n.cloneElement)(A,{className:(0,g.A)("margin-top--md",A.props.className)}):null}return(0,d.jsx)("div",{className:"margin-top--md",children:V.map((A,e)=>(0,n.cloneElement)(A,{key:e,hidden:A.props.value!==t}))})}function w(A){const e=c(A);return(0,d.jsxs)("div",{className:(0,g.A)(V.G.tabs.container,"tabs-container",u.tabList),children:[(0,d.jsx)(h,{...e,...A}),(0,d.jsx)(f,{...e,...A})]})}function m(A){const e=(0,l.A)();return(0,d.jsx)(w,{...A,children:a(A.children)},String(e))}},54182:(A,e,t)=>{"use strict";t.d(e,{A:()=>M});var n=t(96540),g=t(74848);function V(A){const{mdxAdmonitionTitle:e,rest:t}=function(A){const e=n.Children.toArray(A),t=e.find(A=>n.isValidElement(A)&&"mdxAdmonitionTitle"===A.type),V=e.filter(A=>A!==t),o=t?.props.children;return{mdxAdmonitionTitle:o,rest:V.length>0?(0,g.jsx)(g.Fragment,{children:V}):null}}(A.children),V=A.title??e;return{...A,...V&&{title:V},children:t}}var o=t(34164),i=t(23230),s=t(18630);const r="admonition_xJq3",I="admonitionHeading_Gvgb",B="admonitionIcon_Rf37",a="admonitionContent_BuS1";function C({type:A,className:e,children:t}){return(0,g.jsx)("div",{className:(0,o.A)(s.G.common.admonition,s.G.common.admonitionType(A),r,e),children:t})}function Q({icon:A,title:e}){return(0,g.jsxs)("div",{className:I,children:[(0,g.jsx)("span",{className:B,children:A}),e]})}function E({children:A}){return A?(0,g.jsx)("div",{className:a,children:A}):null}function c(A){const{type:e,icon:t,title:n,children:V,className:o}=A;return(0,g.jsxs)(C,{type:e,className:o,children:[n||t?(0,g.jsx)(Q,{title:n,icon:t}):null,(0,g.jsx)(E,{children:V})]})}function l(A){return(0,g.jsx)("svg",{viewBox:"0 0 14 16",...A,children:(0,g.jsx)("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})})}const u={icon:(0,g.jsx)(l,{}),title:(0,g.jsx)(i.A,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)",children:"note"})};function d(A){return(0,g.jsx)(c,{...u,...A,className:(0,o.A)("alert alert--secondary",A.className),children:A.children})}function h(A){return(0,g.jsx)("svg",{viewBox:"0 0 12 16",...A,children:(0,g.jsx)("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})})}const f={icon:(0,g.jsx)(h,{}),title:(0,g.jsx)(i.A,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)",children:"tip"})};function w(A){return(0,g.jsx)(c,{...f,...A,className:(0,o.A)("alert alert--success",A.className),children:A.children})}function m(A){return(0,g.jsx)("svg",{viewBox:"0 0 14 16",...A,children:(0,g.jsx)("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})})}const y={icon:(0,g.jsx)(m,{}),title:(0,g.jsx)(i.A,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)",children:"info"})};function D(A){return(0,g.jsx)(c,{...y,...A,className:(0,o.A)("alert alert--info",A.className),children:A.children})}function p(A){return(0,g.jsx)("svg",{viewBox:"0 0 16 16",...A,children:(0,g.jsx)("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})})}const k={icon:(0,g.jsx)(p,{}),title:(0,g.jsx)(i.A,{id:"theme.admonition.warning",description:"The default label used for the Warning admonition (:::warning)",children:"warning"})};function q(A){return(0,g.jsx)("svg",{viewBox:"0 0 12 16",...A,children:(0,g.jsx)("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})})}const N={icon:(0,g.jsx)(q,{}),title:(0,g.jsx)(i.A,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)",children:"danger"})};const F={icon:(0,g.jsx)(p,{}),title:(0,g.jsx)(i.A,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)",children:"caution"})};const v={...{note:d,tip:w,info:D,warning:function(A){return(0,g.jsx)(c,{...k,...A,className:(0,o.A)("alert alert--warning",A.className),children:A.children})},danger:function(A){return(0,g.jsx)(c,{...N,...A,className:(0,o.A)("alert alert--danger",A.className),children:A.children})}},...{secondary:A=>(0,g.jsx)(d,{title:"secondary",...A}),important:A=>(0,g.jsx)(D,{title:"important",...A}),success:A=>(0,g.jsx)(w,{title:"success",...A}),caution:function(A){return(0,g.jsx)(c,{...F,...A,className:(0,o.A)("alert alert--warning",A.className),children:A.children})}}};function M(A){const e=V(A),t=(n=e.type,v[n]||(console.warn(`No admonition component found for admonition type "${n}". Using Info as fallback.`),v.info));var n;return(0,g.jsx)(t,{...e})}},62400:(A,e,t)=>{"use strict";t.d(e,{A:()=>s});t(96540);var n=t(34164),g=t(23230),V=t(14783),o=t(74848);function i(A){const{permalink:e,title:t,subLabel:g,isNext:i}=A;return(0,o.jsxs)(V.A,{className:(0,n.A)("pagination-nav__link",i?"pagination-nav__link--next":"pagination-nav__link--prev"),to:e,children:[g&&(0,o.jsx)("div",{className:"pagination-nav__sublabel",children:g}),(0,o.jsx)("div",{className:"pagination-nav__label",children:t})]})}function s(A){const{className:e,previous:t,next:V}=A;return(0,o.jsxs)("nav",{className:(0,n.A)(e,"pagination-nav"),"aria-label":(0,g.T)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[t&&(0,o.jsx)(i,{...t,subLabel:(0,o.jsx)(g.A,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),V&&(0,o.jsx)(i,{...V,subLabel:(0,o.jsx)(g.A,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}},62529:(A,e,t)=>{"use strict";t.d(e,{A:()=>h});t(96540);var n=t(34164),g=t(18630),V=t(45357),o=t(80260),i=t(14783),s=t(23230),r=t(98180),I=t(74848);function B(A){return(0,I.jsx)("svg",{viewBox:"0 0 24 24",...A,children:(0,I.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const a={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function C(){const A=(0,r.Ay)("/");return(0,I.jsx)("li",{className:"breadcrumbs__item",children:(0,I.jsx)(i.A,{"aria-label":(0,s.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:A,children:(0,I.jsx)(B,{className:a.breadcrumbHomeIcon})})})}var Q=t(21141),E=t(97639);function c(A){const e=function({breadcrumbs:A}){const{siteConfig:e}=(0,E.A)();return{"@context":"https://schema.org","@type":"BreadcrumbList",itemListElement:A.filter(A=>A.href).map((A,t)=>({"@type":"ListItem",position:t+1,name:A.label,item:`${e.url}${A.href}`}))}}({breadcrumbs:A.breadcrumbs});return(0,I.jsx)(Q.A,{children:(0,I.jsx)("script",{type:"application/ld+json",children:JSON.stringify(e)})})}const l={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function u({children:A,href:e,isLast:t}){const n="breadcrumbs__link";return t?(0,I.jsx)("span",{className:n,children:A}):e?(0,I.jsx)(i.A,{className:n,href:e,children:(0,I.jsx)("span",{children:A})}):(0,I.jsx)("span",{className:n,children:A})}function d({children:A,active:e}){return(0,I.jsx)("li",{className:(0,n.A)("breadcrumbs__item",{"breadcrumbs__item--active":e}),children:A})}function h(){const A=(0,V.OF)(),e=(0,o.Dt)();return A?(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(c,{breadcrumbs:A}),(0,I.jsx)("nav",{className:(0,n.A)(g.G.docs.docBreadcrumbs,l.breadcrumbsContainer),"aria-label":(0,s.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,I.jsxs)("ul",{className:"breadcrumbs",children:[e&&(0,I.jsx)(C,{}),A.map((e,t)=>{const n=t===A.length-1,g="category"===e.type&&e.linkUnlisted?void 0:e.href;return(0,I.jsx)(d,{active:n,children:(0,I.jsx)(u,{href:g,isLast:n,children:e.label})},t)})]})})]}):null}},79436:(A,e,t)=>{"use strict";t.d(e,{A:()=>s});t(96540);var n=t(34164),g=t(23230),V=t(18630),o=t(91704),i=t(74848);function s({className:A}){const e=(0,o.r)();return e.badge?(0,i.jsx)("span",{className:(0,n.A)(A,V.G.docs.docVersionBadge,"badge badge--secondary"),children:(0,i.jsx)(g.A,{id:"theme.docs.versionBadge.label",values:{versionLabel:e.label},children:"Version: {versionLabel}"})}):null}},84799:(A,e,t)=>{"use strict";t.d(e,{A:()=>c});t(96540);var n=t(34164),g=t(97639),V=t(14783),o=t(23230),i=t(19802),s=t(18630),r=t(86457),I=t(91704),B=t(74848);const a={unreleased:function({siteTitle:A,versionMetadata:e}){return(0,B.jsx)(o.A,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:A,versionLabel:(0,B.jsx)("b",{children:e.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function({siteTitle:A,versionMetadata:e}){return(0,B.jsx)(o.A,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:A,versionLabel:(0,B.jsx)("b",{children:e.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function C(A){const e=a[A.versionMetadata.banner];return(0,B.jsx)(e,{...A})}function Q({versionLabel:A,to:e,onClick:t}){return(0,B.jsx)(o.A,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:A,latestVersionLink:(0,B.jsx)("b",{children:(0,B.jsx)(V.A,{to:e,onClick:t,children:(0,B.jsx)(o.A,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function E({className:A,versionMetadata:e}){const{siteConfig:{title:t}}=(0,g.A)(),{pluginId:V}=(0,i.vT)({failfast:!0}),{savePreferredVersionName:o}=(0,r.g1)(V),{latestDocSuggestion:I,latestVersionSuggestion:a}=(0,i.HW)(V),E=I??(c=a).docs.find(A=>A.id===c.mainDocId);var c;return(0,B.jsxs)("div",{className:(0,n.A)(A,s.G.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,B.jsx)("div",{children:(0,B.jsx)(C,{siteTitle:t,versionMetadata:e})}),(0,B.jsx)("div",{className:"margin-top--md",children:(0,B.jsx)(Q,{versionLabel:a.label,to:E.path,onClick:()=>o(a.name)})})]})}function c({className:A}){const e=(0,I.r)();return e.banner?(0,B.jsx)(E,{className:A,versionMetadata:e}):null}},86829:(A,e,t)=>{"use strict";t.r(e),t.d(e,{default:()=>wA});var n=t(96540),g=t(17153),V=t(4799),o=t(74848);const i=n.createContext(null);function s({children:A,content:e}){const t=function(A){return(0,n.useMemo)(()=>({metadata:A.metadata,frontMatter:A.frontMatter,assets:A.assets,contentTitle:A.contentTitle,toc:A.toc}),[A])}(e);return(0,o.jsx)(i.Provider,{value:t,children:A})}function r(){const A=(0,n.useContext)(i);if(null===A)throw new V.dV("DocProvider");return A}function I(){const{metadata:A,frontMatter:e,assets:t}=r();return(0,o.jsx)(g.be,{title:A.title,description:A.description,keywords:e.keywords,image:t.image??e.image})}var B=t(34164),a=t(82216),C=t(62400);function Q(){const{metadata:A}=r();return(0,o.jsx)(C.A,{className:"docusaurus-mt-lg",previous:A.previous,next:A.next})}var E=t(84799),c=t(79436),l=t(18630),u=t(23230),d=t(14783);const h={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};function f({permalink:A,label:e,count:t,description:n}){return(0,o.jsxs)(d.A,{rel:"tag",href:A,title:n,className:(0,B.A)(h.tag,t?h.tagWithCount:h.tagRegular),children:[e,t&&(0,o.jsx)("span",{children:t})]})}const w={tags:"tags_jXut",tag:"tag_QGVx"};function m({tags:A}){return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("b",{children:(0,o.jsx)(u.A,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,o.jsx)("ul",{className:(0,B.A)(w.tags,"padding--none","margin-left--sm"),children:A.map(A=>(0,o.jsx)("li",{className:w.tag,children:(0,o.jsx)(f,{...A})},A.permalink))})]})}const y={iconEdit:"iconEdit_Z9Sw"};function D({className:A,...e}){return(0,o.jsx)("svg",{fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,B.A)(y.iconEdit,A),"aria-hidden":"true",...e,children:(0,o.jsx)("g",{children:(0,o.jsx)("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})})})}function p({editUrl:A}){return(0,o.jsxs)(d.A,{to:A,className:l.G.common.editThisPage,children:[(0,o.jsx)(D,{}),(0,o.jsx)(u.A,{id:"theme.common.editThisPage",description:"The link label to edit the current page",children:"Edit this page"})]})}var k=t(97639);function q(A={}){const{i18n:{currentLocale:e}}=(0,k.A)(),t=function(){const{i18n:{currentLocale:A,localeConfigs:e}}=(0,k.A)();return e[A].calendar}();return new Intl.DateTimeFormat(e,{calendar:t,...A})}function N({lastUpdatedAt:A}){const e=new Date(A),t=q({day:"numeric",month:"short",year:"numeric",timeZone:"UTC"}).format(e);return(0,o.jsx)(u.A,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:(0,o.jsx)("b",{children:(0,o.jsx)("time",{dateTime:e.toISOString(),itemProp:"dateModified",children:t})})},children:" on {date}"})}function F({lastUpdatedBy:A}){return(0,o.jsx)(u.A,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:(0,o.jsx)("b",{children:A})},children:" by {user}"})}function v({lastUpdatedAt:A,lastUpdatedBy:e}){return(0,o.jsxs)("span",{className:l.G.common.lastUpdated,children:[(0,o.jsx)(u.A,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:A?(0,o.jsx)(N,{lastUpdatedAt:A}):"",byUser:e?(0,o.jsx)(F,{lastUpdatedBy:e}):""},children:"Last updated{atDate}{byUser}"}),!1]})}const M={lastUpdated:"lastUpdated_JAkA",noPrint:"noPrint_WFHX"};function b({className:A,editUrl:e,lastUpdatedAt:t,lastUpdatedBy:n}){return(0,o.jsxs)("div",{className:(0,B.A)("row",A),children:[(0,o.jsx)("div",{className:(0,B.A)("col",M.noPrint),children:e&&(0,o.jsx)(p,{editUrl:e})}),(0,o.jsx)("div",{className:(0,B.A)("col",M.lastUpdated),children:(t||n)&&(0,o.jsx)(v,{lastUpdatedAt:t,lastUpdatedBy:n})})]})}function G(){const{metadata:A}=r(),{editUrl:e,lastUpdatedAt:t,lastUpdatedBy:n,tags:g}=A,V=g.length>0,i=!!(e||t||n);return V||i?(0,o.jsxs)("footer",{className:(0,B.A)(l.G.docs.docFooter,"docusaurus-mt-lg"),children:[V&&(0,o.jsx)("div",{className:(0,B.A)("row margin-top--sm",l.G.docs.docFooterTagsRow),children:(0,o.jsx)("div",{className:"col",children:(0,o.jsx)(m,{tags:g})})}),i&&(0,o.jsx)(b,{className:(0,B.A)("margin-top--sm",l.G.docs.docFooterEditMetaRow),editUrl:e,lastUpdatedAt:t,lastUpdatedBy:n})]}):null}var R=t(94549),L=t(86957);function S(A){const e=A.map(A=>({...A,parentIndex:-1,children:[]})),t=Array(7).fill(-1);e.forEach((A,e)=>{const n=t.slice(2,A.level);A.parentIndex=Math.max(...n),t[A.level]=e});const n=[];return e.forEach(A=>{const{parentIndex:t,...g}=A;t>=0?e[t].children.push(g):n.push(g)}),n}function J({toc:A,minHeadingLevel:e,maxHeadingLevel:t}){return A.flatMap(A=>{const n=J({toc:A.children,minHeadingLevel:e,maxHeadingLevel:t});return function(A){return A.level>=e&&A.level<=t}(A)?[{...A,children:n}]:n})}function U(A){const e=A.getBoundingClientRect();return e.top===e.bottom?U(A.parentNode):e}function x(A,{anchorTopOffset:e}){const t=A.find(A=>U(A).top>=e);if(t){return function(A){return A.top>0&&A.bottom<window.innerHeight/2}(U(t))?t:A[A.indexOf(t)-1]??null}return A[A.length-1]??null}function Y(){const A=(0,n.useRef)(0),{navbar:{hideOnScroll:e}}=(0,L.p)();return(0,n.useEffect)(()=>{A.current=e?0:document.querySelector(".navbar").clientHeight},[e]),A}function K(A){const e=(0,n.useRef)(void 0),t=Y();(0,n.useEffect)(()=>{if(!A)return()=>{};const{linkClassName:n,linkActiveClassName:g,minHeadingLevel:V,maxHeadingLevel:o}=A;function i(){const A=function(A){return Array.from(document.getElementsByClassName(A))}(n),i=function({minHeadingLevel:A,maxHeadingLevel:e}){const t=[];for(let n=A;n<=e;n+=1)t.push(`h${n}.anchor`);return Array.from(document.querySelectorAll(t.join()))}({minHeadingLevel:V,maxHeadingLevel:o}),s=x(i,{anchorTopOffset:t.current}),r=A.find(A=>s&&s.id===function(A){return decodeURIComponent(A.href.substring(A.href.indexOf("#")+1))}(A));A.forEach(A=>{!function(A,t){t?(e.current&&e.current!==A&&e.current.classList.remove(g),A.classList.add(g),e.current=A):A.classList.remove(g)}(A,A===r)})}return document.addEventListener("scroll",i),document.addEventListener("resize",i),i(),()=>{document.removeEventListener("scroll",i),document.removeEventListener("resize",i)}},[A,t])}function T({toc:A,className:e,linkClassName:t,isChild:n}){return A.length?(0,o.jsx)("ul",{className:n?void 0:e,children:A.map(A=>(0,o.jsxs)("li",{children:[(0,o.jsx)(d.A,{to:`#${A.id}`,className:t??void 0,dangerouslySetInnerHTML:{__html:A.value}}),(0,o.jsx)(T,{isChild:!0,toc:A.children,className:e,linkClassName:t})]},A.id))}):null}const j=n.memo(T);function H({toc:A,className:e="table-of-contents table-of-contents__left-border",linkClassName:t="table-of-contents__link",linkActiveClassName:g,minHeadingLevel:V,maxHeadingLevel:i,...s}){const r=(0,L.p)(),I=V??r.tableOfContents.minHeadingLevel,B=i??r.tableOfContents.maxHeadingLevel,a=function({toc:A,minHeadingLevel:e,maxHeadingLevel:t}){return(0,n.useMemo)(()=>J({toc:S(A),minHeadingLevel:e,maxHeadingLevel:t}),[A,e,t])}({toc:A,minHeadingLevel:I,maxHeadingLevel:B});return K((0,n.useMemo)(()=>{if(t&&g)return{linkClassName:t,linkActiveClassName:g,minHeadingLevel:I,maxHeadingLevel:B}},[t,g,I,B])),(0,o.jsx)(j,{toc:a,className:e,linkClassName:t,...s})}const O={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function W({collapsed:A,...e}){return(0,o.jsx)("button",{type:"button",...e,className:(0,B.A)("clean-btn",O.tocCollapsibleButton,!A&&O.tocCollapsibleButtonExpanded,e.className),children:(0,o.jsx)(u.A,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component",children:"On this page"})})}const _={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function Z({toc:A,className:e,minHeadingLevel:t,maxHeadingLevel:n}){const{collapsed:g,toggleCollapsed:V}=(0,R.u)({initialState:!0});return(0,o.jsxs)("div",{className:(0,B.A)(_.tocCollapsible,!g&&_.tocCollapsibleExpanded,e),children:[(0,o.jsx)(W,{collapsed:g,onClick:V}),(0,o.jsx)(R.N,{lazy:!0,className:_.tocCollapsibleContent,collapsed:g,children:(0,o.jsx)(H,{toc:A,minHeadingLevel:t,maxHeadingLevel:n})})]})}const z={tocMobile:"tocMobile_ITEo"};function X(){const{toc:A,frontMatter:e}=r();return(0,o.jsx)(Z,{toc:A,minHeadingLevel:e.toc_min_heading_level,maxHeadingLevel:e.toc_max_heading_level,className:(0,B.A)(l.G.docs.docTocMobile,z.tocMobile)})}const P={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"},$="table-of-contents__link toc-highlight",AA="table-of-contents__link--active";function eA({className:A,...e}){return(0,o.jsx)("div",{className:(0,B.A)(P.tableOfContents,"thin-scrollbar",A),children:(0,o.jsx)(H,{...e,linkClassName:$,linkActiveClassName:AA})})}function tA(){const{toc:A,frontMatter:e}=r();return(0,o.jsx)(eA,{toc:A,minHeadingLevel:e.toc_min_heading_level,maxHeadingLevel:e.toc_max_heading_level,className:l.G.docs.docTocDesktop})}var nA=t(85225),gA=t(28453),VA=t(67569);function oA({children:A}){return(0,o.jsx)(gA.x,{components:VA.A,children:A})}function iA({children:A}){const e=function(){const{metadata:A,frontMatter:e,contentTitle:t}=r();return e.hide_title||void 0!==t?null:A.title}();return(0,o.jsxs)("div",{className:(0,B.A)(l.G.docs.docMarkdown,"markdown"),children:[e&&(0,o.jsx)("header",{children:(0,o.jsx)(nA.A,{as:"h1",children:e})}),(0,o.jsx)(oA,{children:A})]})}var sA=t(62529),rA=t(21141);function IA(){return(0,o.jsx)(u.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function BA(){return(0,o.jsx)(u.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function aA(){return(0,o.jsx)(rA.A,{children:(0,o.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function CA(){return(0,o.jsx)(u.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function QA(){return(0,o.jsx)(u.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}var EA=t(54182);function cA({className:A}){return(0,o.jsx)(EA.A,{type:"caution",title:(0,o.jsx)(CA,{}),className:(0,B.A)(A,l.G.common.draftBanner),children:(0,o.jsx)(QA,{})})}function lA({className:A}){return(0,o.jsx)(EA.A,{type:"caution",title:(0,o.jsx)(IA,{}),className:(0,B.A)(A,l.G.common.unlistedBanner),children:(0,o.jsx)(BA,{})})}function uA(A){return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(aA,{}),(0,o.jsx)(lA,{...A})]})}function dA({metadata:A}){const{unlisted:e,frontMatter:t}=A;return(0,o.jsxs)(o.Fragment,{children:[(e||t.unlisted)&&(0,o.jsx)(uA,{}),t.draft&&(0,o.jsx)(cA,{})]})}const hA={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function fA({children:A}){const e=function(){const{frontMatter:A,toc:e}=r(),t=(0,a.l)(),n=A.hide_table_of_contents,g=!n&&e.length>0;return{hidden:n,mobile:g?(0,o.jsx)(X,{}):void 0,desktop:!g||"desktop"!==t&&"ssr"!==t?void 0:(0,o.jsx)(tA,{})}}(),{metadata:t}=r();return(0,o.jsxs)("div",{className:"row",children:[(0,o.jsxs)("div",{className:(0,B.A)("col",!e.hidden&&hA.docItemCol),children:[(0,o.jsx)(dA,{metadata:t}),(0,o.jsx)(E.A,{}),(0,o.jsxs)("div",{className:hA.docItemContainer,children:[(0,o.jsxs)("article",{children:[(0,o.jsx)(sA.A,{}),(0,o.jsx)(c.A,{}),e.mobile,(0,o.jsx)(iA,{children:A}),(0,o.jsx)(G,{})]}),(0,o.jsx)(Q,{})]})]}),e.desktop&&(0,o.jsx)("div",{className:"col col--3",children:e.desktop})]})}function wA(A){const e=`docs-doc-id-${A.content.metadata.id}`,t=A.content;return(0,o.jsx)(s,{content:A.content,children:(0,o.jsxs)(g.e3,{className:e,children:[(0,o.jsx)(I,{}),(0,o.jsx)(fA,{children:(0,o.jsx)(t,{})})]})})}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/20a029f4.19707c04.js b/pr-preview/pr-4027/assets/js/20a029f4.19707c04.js deleted file mode 100644 index d5e4f35a2..000000000 --- a/pr-preview/pr-4027/assets/js/20a029f4.19707c04.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5343],{28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>s});var t=r(96540);const o={},l=t.createContext(o);function i(e){const n=t.useContext(l);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),t.createElement(l.Provider,{value:n},e.children)}},57710:(e,n,r)=>{r.d(n,{A:()=>t});const t=r.p+"assets/images/recovery-gcp-serial-console-link-d31487c5a5e88fbcde9dcc33e876838d.png"},80438:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>t,toc:()=>a});const t=JSON.parse('{"id":"workflows/recovery","title":"Recover your cluster","description":"Recovery of a Constellation cluster means getting it back into a healthy state after too many concurrent node failures in the control plane.","source":"@site/versioned_docs/version-2.22/workflows/recovery.md","sourceDirName":"workflows","slug":"/workflows/recovery","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/recovery","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/workflows/recovery.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Terminate your cluster","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/terminate"},"next":{"title":"Verify your cluster","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cluster"}}');var o=r(74848),l=r(28453);const i={},s="Recover your cluster",c={},a=[{value:"Identify unhealthy clusters",id:"identify-unhealthy-clusters",level:2},{value:"Recover a cluster",id:"recover-a-cluster",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,l.R)(),...e.components},{TabItem:t,Tabs:i}=n;return t||g("TabItem",!0),i||g("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"recover-your-cluster",children:"Recover your cluster"})}),"\n",(0,o.jsxs)(n.p,{children:["Recovery of a Constellation cluster means getting it back into a healthy state after too many concurrent node failures in the control plane.\nReasons for an unhealthy cluster can vary from a power outage, or planned reboot, to migration of nodes and regions.\nRecovery events are rare, because Constellation is built for high availability and automatically and securely replaces failed nodes. When a node is replaced, Constellation's control plane first verifies the new node before it sends the node the cryptographic keys required to decrypt its ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/images#state-disk",children:"state disk"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Constellation provides a recovery mechanism for cases where the control plane has failed and is unable to replace nodes.\nThe ",(0,o.jsx)(n.code,{children:"constellation recover"})," command securely connects to all nodes in need of recovery using ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#attested-tls-atls",children:"attested TLS"})," and provides them with the keys to decrypt their state disks and continue booting."]}),"\n",(0,o.jsx)(n.h2,{id:"identify-unhealthy-clusters",children:"Identify unhealthy clusters"}),"\n",(0,o.jsx)(n.p,{children:"The first step to recovery is identifying when a cluster becomes unhealthy.\nUsually, this can be first observed when the Kubernetes API server becomes unresponsive."}),"\n",(0,o.jsx)(n.p,{children:"You can check the health status of the nodes via the cloud service provider (CSP).\nConstellation provides logging information on the boot process and status via serial console output.\nIn the following, you'll find detailed descriptions for identifying clusters stuck in recovery for each CSP."}),"\n",(0,o.jsxs)(i,{groupId:"csp",children:[(0,o.jsxs)(t,{value:"aws",label:"AWS",children:[(0,o.jsxs)(n.p,{children:["First, open the AWS console to view all Auto Scaling Groups (ASGs) in the region of your cluster. Select the ASG of the control plane ",(0,o.jsx)(n.code,{children:"<cluster-name>-<UID>-control-plane"})," and check that enough members are in a ",(0,o.jsx)(n.em,{children:"Running"})," state."]}),(0,o.jsxs)(n.p,{children:["Second, check the boot logs of these ",(0,o.jsx)(n.em,{children:"Instances"}),". In the ASG's ",(0,o.jsx)(n.em,{children:"Instance management"})," view, select each desired instance. In the upper right corner, select ",(0,o.jsx)(n.strong,{children:"Action > Monitor and troubleshoot > Get system log"}),"."]}),(0,o.jsxs)(n.p,{children:["In the serial console output, search for ",(0,o.jsx)(n.code,{children:"Waiting for decryption key"}),".\nSimilar output to the following means your node was restarted and needs to decrypt the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/images#state-disk",children:"state disk"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"gcp"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}\n'})}),(0,o.jsxs)(n.p,{children:["The node will then try to connect to the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#joinservice",children:(0,o.jsx)(n.em,{children:"JoinService"})})," and obtain the decryption key.\nIf this fails due to an unhealthy control plane, you will see log messages similar to the following:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["192.168.178.4:30090","192.168.178.2:30090"]}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.4:30090"}\n{"level":"WARN","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.4:30090: connect: connection refused\\"","endpoint":"192.168.178.4:30090"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.2:30090"}\n{"level":"WARN","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.2:30090: i/o timeout\\"","endpoint":"192.168.178.2:30090"}\n{"level":"ERROR","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}\n'})}),(0,o.jsx)(n.p,{children:"This means that you have to recover the node manually."})]}),(0,o.jsxs)(t,{value:"azure",label:"Azure",children:[(0,o.jsxs)(n.p,{children:["In the Azure portal, find the cluster's resource group.\nInside the resource group, open the control plane ",(0,o.jsx)(n.em,{children:"Virtual machine scale set"})," ",(0,o.jsx)(n.code,{children:"constellation-scale-set-controlplanes-<suffix>"}),".\nOn the left, go to ",(0,o.jsx)(n.strong,{children:"Settings"})," > ",(0,o.jsx)(n.strong,{children:"Instances"})," and check that enough members are in a ",(0,o.jsx)(n.em,{children:"Running"})," state."]}),(0,o.jsxs)(n.p,{children:["Second, check the boot logs of these ",(0,o.jsx)(n.em,{children:"Instances"}),".\nIn the scale set's ",(0,o.jsx)(n.em,{children:"Instances"})," view, open the details page of the desired instance.\nOn the left, go to ",(0,o.jsx)(n.strong,{children:"Support + troubleshooting"})," > ",(0,o.jsx)(n.strong,{children:"Serial console"}),"."]}),(0,o.jsxs)(n.p,{children:["In the serial console output, search for ",(0,o.jsx)(n.code,{children:"Waiting for decryption key"}),".\nSimilar output to the following means your node was restarted and needs to decrypt the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/images#state-disk",children:"state disk"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T09:56:41Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"azure"}\n{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}\n{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}\n{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}\n'})}),(0,o.jsxs)(n.p,{children:["The node will then try to connect to the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#joinservice",children:(0,o.jsx)(n.em,{children:"JoinService"})})," and obtain the decryption key.\nIf this fails due to an unhealthy control plane, you will see log messages similar to the following:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["10.9.0.5:30090","10.9.0.6:30090"]}\n{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"10.9.0.5:30090"}\n{"level":"WARN","ts":"2022-09-08T09:57:03Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 10.9.0.5:30090: i/o timeout\\"","endpoint":"10.9.0.5:30090"}\n{"level":"INFO","ts":"2022-09-08T09:57:03Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"10.9.0.6:30090"}\n{"level":"WARN","ts":"2022-09-08T09:57:23Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 10.9.0.6:30090: i/o timeout\\"","endpoint":"10.9.0.6:30090"}\n{"level":"ERROR","ts":"2022-09-08T09:57:23Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}\n'})}),(0,o.jsx)(n.p,{children:"This means that you have to recover the node manually."})]}),(0,o.jsxs)(t,{value:"gcp",label:"GCP",children:[(0,o.jsxs)(n.p,{children:["First, check that the control plane ",(0,o.jsx)(n.em,{children:"Instance Group"})," has enough members in a ",(0,o.jsx)(n.em,{children:"Ready"})," state.\nIn the GCP Console, go to ",(0,o.jsx)(n.strong,{children:"Instance Groups"})," and check the group for the cluster's control plane ",(0,o.jsx)(n.code,{children:"<cluster-name>-control-plane-<suffix>"}),"."]}),(0,o.jsxs)(n.p,{children:["Second, check the status of the ",(0,o.jsx)(n.em,{children:"VM Instances"}),".\nGo to ",(0,o.jsx)(n.strong,{children:"VM Instances"})," and open the details of the desired instance.\nCheck the serial console output of that instance by opening the ",(0,o.jsx)(n.strong,{children:"Logs"})," > ",(0,o.jsx)(n.strong,{children:"Serial port 1 (console)"})," page:"]}),(0,o.jsx)(n.p,{children:(0,o.jsx)(n.img,{alt:"GCP portal serial console link",src:r(57710).A+"",width:"846",height:"415"})}),(0,o.jsxs)(n.p,{children:["In the serial console output, search for ",(0,o.jsx)(n.code,{children:"Waiting for decryption key"}),".\nSimilar output to the following means your node was restarted and needs to decrypt the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/images#state-disk",children:"state disk"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"gcp"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}\n'})}),(0,o.jsxs)(n.p,{children:["The node will then try to connect to the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#joinservice",children:(0,o.jsx)(n.em,{children:"JoinService"})})," and obtain the decryption key.\nIf this fails due to an unhealthy control plane, you will see log messages similar to the following:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["192.168.178.4:30090","192.168.178.2:30090"]}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.4:30090"}\n{"level":"WARN","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.4:30090: connect: connection refused\\"","endpoint":"192.168.178.4:30090"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.2:30090"}\n{"level":"WARN","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.2:30090: i/o timeout\\"","endpoint":"192.168.178.2:30090"}\n{"level":"ERROR","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}\n'})}),(0,o.jsx)(n.p,{children:"This means that you have to recover the node manually."})]}),(0,o.jsxs)(t,{value:"stackit",label:"STACKIT",children:[(0,o.jsxs)(n.p,{children:["First, open the STACKIT portal to view all servers in your project. Select individual control plane nodes ",(0,o.jsx)(n.code,{children:"<cluster-name>-<UID>-control-plane-<UID>-<index>"})," and check that enough members are in a ",(0,o.jsx)(n.em,{children:"Running"})," state."]}),(0,o.jsxs)(n.p,{children:["Second, check the boot logs of these servers. Click on a server name and select ",(0,o.jsx)(n.strong,{children:"Overview"}),". Find the ",(0,o.jsx)(n.strong,{children:"Machine Setup"})," section and click on ",(0,o.jsx)(n.strong,{children:"Web console"})," > ",(0,o.jsx)(n.strong,{children:"Open console"}),"."]}),(0,o.jsxs)(n.p,{children:["In the serial console output, search for ",(0,o.jsx)(n.code,{children:"Waiting for decryption key"}),".\nSimilar output to the following means your node was restarted and needs to decrypt the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/images#state-disk",children:"state disk"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"gcp"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}\n'})}),(0,o.jsxs)(n.p,{children:["The node will then try to connect to the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#joinservice",children:(0,o.jsx)(n.em,{children:"JoinService"})})," and obtain the decryption key.\nIf this fails due to an unhealthy control plane, you will see log messages similar to the following:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["192.168.178.4:30090","192.168.178.2:30090"]}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.4:30090"}\n{"level":"WARN","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.4:30090: connect: connection refused\\"","endpoint":"192.168.178.4:30090"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.2:30090"}\n{"level":"WARN","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.2:30090: i/o timeout\\"","endpoint":"192.168.178.2:30090"}\n{"level":"ERROR","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}\n'})}),(0,o.jsx)(n.p,{children:"This means that you have to recover the node manually."})]})]}),"\n",(0,o.jsx)(n.h2,{id:"recover-a-cluster",children:"Recover a cluster"}),"\n",(0,o.jsx)(n.p,{children:"Recovering a cluster requires the following parameters:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The ",(0,o.jsx)(n.code,{children:"constellation-state.yaml"})," file in your working directory or the cluster's endpoint"]}),"\n",(0,o.jsx)(n.li,{children:"The master secret of the cluster"}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"A cluster can be recovered like this:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"$ constellation recover\nPushed recovery key.\nPushed recovery key.\nPushed recovery key.\nRecovered 3 control-plane nodes.\n"})}),"\n",(0,o.jsx)(n.p,{children:"In the serial console output of the node you'll see a similar output to the following:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer","caller":"recoveryserver/server.go:93","msg":"Received recover call"}\n{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer","caller":"recoveryserver/server.go:125","msg":"Received state disk key and measurement secret, shutting down server"}\n{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer.gRPC","caller":"zap/server_interceptors.go:61","msg":"finished streaming call with code OK","grpc.start_time":"2022-09-08T10:26:59Z","system":"grpc","span.kind":"server","grpc.service":"recoverproto.API","grpc.method":"Recover","peer.address":"192.0.2.3:41752","grpc.code":"OK","grpc.time_ms":15.701}\n{"level":"INFO","ts":"2022-09-08T10:27:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:87","msg":"RejoinClient stopped"}\n'})})]})}function h(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}function g(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/2130.b53d8919.js b/pr-preview/pr-4027/assets/js/2130.b53d8919.js deleted file mode 100644 index 899ffc583..000000000 --- a/pr-preview/pr-4027/assets/js/2130.b53d8919.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2130],{22130:(e,t,r)=>{r.d(t,{default:()=>rn});class a{constructor(e,t,r){this.lexer=void 0,this.start=void 0,this.end=void 0,this.lexer=e,this.start=t,this.end=r}static range(e,t){return t?e&&e.loc&&t.loc&&e.loc.lexer===t.loc.lexer?new a(e.loc.lexer,e.loc.start,t.loc.end):null:e&&e.loc}}class n{constructor(e,t){this.text=void 0,this.loc=void 0,this.noexpand=void 0,this.treatAsRelax=void 0,this.text=e,this.loc=t}range(e,t){return new n(t,a.range(this,e))}}class i{constructor(e,t){this.name=void 0,this.position=void 0,this.length=void 0,this.rawMessage=void 0;var r,a,n="KaTeX parse error: "+e,o=t&&t.loc;if(o&&o.start<=o.end){var s=o.lexer.input;r=o.start,a=o.end,r===s.length?n+=" at end of input: ":n+=" at position "+(r+1)+": ";var l=s.slice(r,a).replace(/[^]/g,"$&\u0332");n+=(r>15?"\u2026"+s.slice(r-15,r):s.slice(0,r))+l+(a+15<s.length?s.slice(a,a+15)+"\u2026":s.slice(a))}var h=new Error(n);return h.name="ParseError",h.__proto__=i.prototype,h.position=r,null!=r&&null!=a&&(h.length=a-r),h.rawMessage=e,h}}i.prototype.__proto__=Error.prototype;var o=/([A-Z])/g,s={"&":"&",">":">","<":"<",'"':""","'":"'"},l=/[&><"']/g;var h=function e(t){return"ordgroup"===t.type||"color"===t.type?1===t.body.length?e(t.body[0]):t:"font"===t.type?e(t.body):t},m={deflt:function(e,t){return void 0===e?t:e},escape:function(e){return String(e).replace(l,e=>s[e])},hyphenate:function(e){return e.replace(o,"-$1").toLowerCase()},getBaseElem:h,isCharacterBox:function(e){var t=h(e);return"mathord"===t.type||"textord"===t.type||"atom"===t.type},protocolFromUrl:function(e){var t=/^[\x00-\x20]*([^\\/#?]*?)(:|�*58|�*3a|&colon)/i.exec(e);return t?":"!==t[2]?null:/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(t[1])?t[1].toLowerCase():null:"_relative"}},c={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format <type>"},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color <color>",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:e=>"#"+e},macros:{type:"object",cli:"-m, --macro <def>",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:(e,t)=>(t.push(e),t)},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:e=>Math.max(0,e),cli:"--min-rule-thickness <size>",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:e=>Math.max(0,e),cli:"-s, --max-size <n>",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:e=>Math.max(0,e),cli:"-e, --max-expand <n>",cliProcessor:e=>"Infinity"===e?1/0:parseInt(e)},globalGroup:{type:"boolean",cli:!1}};function p(e){if(e.default)return e.default;var t=e.type,r=Array.isArray(t)?t[0]:t;if("string"!=typeof r)return r.enum[0];switch(r){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}class u{constructor(e){for(var t in this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{},c)if(c.hasOwnProperty(t)){var r=c[t];this[t]=void 0!==e[t]?r.processor?r.processor(e[t]):e[t]:p(r)}}reportNonstrict(e,t,r){var a=this.strict;if("function"==typeof a&&(a=a(e,t,r)),a&&"ignore"!==a){if(!0===a||"error"===a)throw new i("LaTeX-incompatible input and strict mode is set to 'error': "+t+" ["+e+"]",r);"warn"===a?"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"):"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+t+" ["+e+"]")}}useStrictBehavior(e,t,r){var a=this.strict;if("function"==typeof a)try{a=a(e,t,r)}catch(n){a="error"}return!(!a||"ignore"===a)&&(!0===a||"error"===a||("warn"===a?("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"),!1):("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+t+" ["+e+"]"),!1)))}isTrusted(e){if(e.url&&!e.protocol){var t=m.protocolFromUrl(e.url);if(null==t)return!1;e.protocol=t}var r="function"==typeof this.trust?this.trust(e):this.trust;return Boolean(r)}}class d{constructor(e,t,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=t,this.cramped=r}sup(){return g[f[this.id]]}sub(){return g[v[this.id]]}fracNum(){return g[b[this.id]]}fracDen(){return g[y[this.id]]}cramp(){return g[x[this.id]]}text(){return g[w[this.id]]}isTight(){return this.size>=2}}var g=[new d(0,0,!1),new d(1,0,!0),new d(2,1,!1),new d(3,1,!0),new d(4,2,!1),new d(5,2,!0),new d(6,3,!1),new d(7,3,!0)],f=[4,5,4,5,6,7,6,7],v=[5,5,5,5,7,7,7,7],b=[2,3,4,5,6,7,6,7],y=[3,3,5,5,7,7,7,7],x=[1,1,3,3,5,5,7,7],w=[0,1,2,3,2,3,2,3],k={DISPLAY:g[0],TEXT:g[2],SCRIPT:g[4],SCRIPTSCRIPT:g[6]},S=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];var M=[];function z(e){for(var t=0;t<M.length;t+=2)if(e>=M[t]&&e<=M[t+1])return!0;return!1}S.forEach(e=>e.blocks.forEach(e=>M.push(...e)));var A=80,T={doubleleftarrow:"M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",doublerightarrow:"M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",leftarrow:"M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",leftbrace:"M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",leftbraceunder:"M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",leftgroup:"M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",leftgroupunder:"M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",leftharpoon:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",leftharpoonplus:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",leftharpoondown:"M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",leftharpoondownplus:"M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",lefthook:"M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",leftlinesegment:"M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",leftmapsto:"M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",leftToFrom:"M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",longequal:"M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",midbrace:"M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",midbraceunder:"M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",oiintSize1:"M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",oiintSize2:"M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",oiiintSize1:"M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",oiiintSize2:"M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",rightarrow:"M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",rightbrace:"M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",rightbraceunder:"M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",rightgroup:"M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",rightgroupunder:"M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",rightharpoon:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",rightharpoonplus:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",rightharpoondown:"M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",rightharpoondownplus:"M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",righthook:"M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",rightlinesegment:"M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",rightToFrom:"M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",twoheadleftarrow:"M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",twoheadrightarrow:"M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",tilde1:"M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",tilde2:"M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",tilde3:"M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",tilde4:"M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",vec:"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",widehat1:"M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",widehat2:"M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat3:"M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat4:"M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widecheck1:"M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",widecheck2:"M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck3:"M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck4:"M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",baraboveleftarrow:"M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",rightarrowabovebar:"M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",baraboveshortleftharpoon:"M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",rightharpoonaboveshortbar:"M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",shortbaraboveleftharpoon:"M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",shortrightharpoonabovebar:"M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"};class B{constructor(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}hasClass(e){return this.classes.includes(e)}toNode(){for(var e=document.createDocumentFragment(),t=0;t<this.children.length;t++)e.appendChild(this.children[t].toNode());return e}toMarkup(){for(var e="",t=0;t<this.children.length;t++)e+=this.children[t].toMarkup();return e}toText(){return this.children.map(e=>e.toText()).join("")}}var C={"AMS-Regular":{32:[0,0,0,0,.25],65:[0,.68889,0,0,.72222],66:[0,.68889,0,0,.66667],67:[0,.68889,0,0,.72222],68:[0,.68889,0,0,.72222],69:[0,.68889,0,0,.66667],70:[0,.68889,0,0,.61111],71:[0,.68889,0,0,.77778],72:[0,.68889,0,0,.77778],73:[0,.68889,0,0,.38889],74:[.16667,.68889,0,0,.5],75:[0,.68889,0,0,.77778],76:[0,.68889,0,0,.66667],77:[0,.68889,0,0,.94445],78:[0,.68889,0,0,.72222],79:[.16667,.68889,0,0,.77778],80:[0,.68889,0,0,.61111],81:[.16667,.68889,0,0,.77778],82:[0,.68889,0,0,.72222],83:[0,.68889,0,0,.55556],84:[0,.68889,0,0,.66667],85:[0,.68889,0,0,.72222],86:[0,.68889,0,0,.72222],87:[0,.68889,0,0,1],88:[0,.68889,0,0,.72222],89:[0,.68889,0,0,.72222],90:[0,.68889,0,0,.66667],107:[0,.68889,0,0,.55556],160:[0,0,0,0,.25],165:[0,.675,.025,0,.75],174:[.15559,.69224,0,0,.94666],240:[0,.68889,0,0,.55556],295:[0,.68889,0,0,.54028],710:[0,.825,0,0,2.33334],732:[0,.9,0,0,2.33334],770:[0,.825,0,0,2.33334],771:[0,.9,0,0,2.33334],989:[.08167,.58167,0,0,.77778],1008:[0,.43056,.04028,0,.66667],8245:[0,.54986,0,0,.275],8463:[0,.68889,0,0,.54028],8487:[0,.68889,0,0,.72222],8498:[0,.68889,0,0,.55556],8502:[0,.68889,0,0,.66667],8503:[0,.68889,0,0,.44445],8504:[0,.68889,0,0,.66667],8513:[0,.68889,0,0,.63889],8592:[-.03598,.46402,0,0,.5],8594:[-.03598,.46402,0,0,.5],8602:[-.13313,.36687,0,0,1],8603:[-.13313,.36687,0,0,1],8606:[.01354,.52239,0,0,1],8608:[.01354,.52239,0,0,1],8610:[.01354,.52239,0,0,1.11111],8611:[.01354,.52239,0,0,1.11111],8619:[0,.54986,0,0,1],8620:[0,.54986,0,0,1],8621:[-.13313,.37788,0,0,1.38889],8622:[-.13313,.36687,0,0,1],8624:[0,.69224,0,0,.5],8625:[0,.69224,0,0,.5],8630:[0,.43056,0,0,1],8631:[0,.43056,0,0,1],8634:[.08198,.58198,0,0,.77778],8635:[.08198,.58198,0,0,.77778],8638:[.19444,.69224,0,0,.41667],8639:[.19444,.69224,0,0,.41667],8642:[.19444,.69224,0,0,.41667],8643:[.19444,.69224,0,0,.41667],8644:[.1808,.675,0,0,1],8646:[.1808,.675,0,0,1],8647:[.1808,.675,0,0,1],8648:[.19444,.69224,0,0,.83334],8649:[.1808,.675,0,0,1],8650:[.19444,.69224,0,0,.83334],8651:[.01354,.52239,0,0,1],8652:[.01354,.52239,0,0,1],8653:[-.13313,.36687,0,0,1],8654:[-.13313,.36687,0,0,1],8655:[-.13313,.36687,0,0,1],8666:[.13667,.63667,0,0,1],8667:[.13667,.63667,0,0,1],8669:[-.13313,.37788,0,0,1],8672:[-.064,.437,0,0,1.334],8674:[-.064,.437,0,0,1.334],8705:[0,.825,0,0,.5],8708:[0,.68889,0,0,.55556],8709:[.08167,.58167,0,0,.77778],8717:[0,.43056,0,0,.42917],8722:[-.03598,.46402,0,0,.5],8724:[.08198,.69224,0,0,.77778],8726:[.08167,.58167,0,0,.77778],8733:[0,.69224,0,0,.77778],8736:[0,.69224,0,0,.72222],8737:[0,.69224,0,0,.72222],8738:[.03517,.52239,0,0,.72222],8739:[.08167,.58167,0,0,.22222],8740:[.25142,.74111,0,0,.27778],8741:[.08167,.58167,0,0,.38889],8742:[.25142,.74111,0,0,.5],8756:[0,.69224,0,0,.66667],8757:[0,.69224,0,0,.66667],8764:[-.13313,.36687,0,0,.77778],8765:[-.13313,.37788,0,0,.77778],8769:[-.13313,.36687,0,0,.77778],8770:[-.03625,.46375,0,0,.77778],8774:[.30274,.79383,0,0,.77778],8776:[-.01688,.48312,0,0,.77778],8778:[.08167,.58167,0,0,.77778],8782:[.06062,.54986,0,0,.77778],8783:[.06062,.54986,0,0,.77778],8785:[.08198,.58198,0,0,.77778],8786:[.08198,.58198,0,0,.77778],8787:[.08198,.58198,0,0,.77778],8790:[0,.69224,0,0,.77778],8791:[.22958,.72958,0,0,.77778],8796:[.08198,.91667,0,0,.77778],8806:[.25583,.75583,0,0,.77778],8807:[.25583,.75583,0,0,.77778],8808:[.25142,.75726,0,0,.77778],8809:[.25142,.75726,0,0,.77778],8812:[.25583,.75583,0,0,.5],8814:[.20576,.70576,0,0,.77778],8815:[.20576,.70576,0,0,.77778],8816:[.30274,.79383,0,0,.77778],8817:[.30274,.79383,0,0,.77778],8818:[.22958,.72958,0,0,.77778],8819:[.22958,.72958,0,0,.77778],8822:[.1808,.675,0,0,.77778],8823:[.1808,.675,0,0,.77778],8828:[.13667,.63667,0,0,.77778],8829:[.13667,.63667,0,0,.77778],8830:[.22958,.72958,0,0,.77778],8831:[.22958,.72958,0,0,.77778],8832:[.20576,.70576,0,0,.77778],8833:[.20576,.70576,0,0,.77778],8840:[.30274,.79383,0,0,.77778],8841:[.30274,.79383,0,0,.77778],8842:[.13597,.63597,0,0,.77778],8843:[.13597,.63597,0,0,.77778],8847:[.03517,.54986,0,0,.77778],8848:[.03517,.54986,0,0,.77778],8858:[.08198,.58198,0,0,.77778],8859:[.08198,.58198,0,0,.77778],8861:[.08198,.58198,0,0,.77778],8862:[0,.675,0,0,.77778],8863:[0,.675,0,0,.77778],8864:[0,.675,0,0,.77778],8865:[0,.675,0,0,.77778],8872:[0,.69224,0,0,.61111],8873:[0,.69224,0,0,.72222],8874:[0,.69224,0,0,.88889],8876:[0,.68889,0,0,.61111],8877:[0,.68889,0,0,.61111],8878:[0,.68889,0,0,.72222],8879:[0,.68889,0,0,.72222],8882:[.03517,.54986,0,0,.77778],8883:[.03517,.54986,0,0,.77778],8884:[.13667,.63667,0,0,.77778],8885:[.13667,.63667,0,0,.77778],8888:[0,.54986,0,0,1.11111],8890:[.19444,.43056,0,0,.55556],8891:[.19444,.69224,0,0,.61111],8892:[.19444,.69224,0,0,.61111],8901:[0,.54986,0,0,.27778],8903:[.08167,.58167,0,0,.77778],8905:[.08167,.58167,0,0,.77778],8906:[.08167,.58167,0,0,.77778],8907:[0,.69224,0,0,.77778],8908:[0,.69224,0,0,.77778],8909:[-.03598,.46402,0,0,.77778],8910:[0,.54986,0,0,.76042],8911:[0,.54986,0,0,.76042],8912:[.03517,.54986,0,0,.77778],8913:[.03517,.54986,0,0,.77778],8914:[0,.54986,0,0,.66667],8915:[0,.54986,0,0,.66667],8916:[0,.69224,0,0,.66667],8918:[.0391,.5391,0,0,.77778],8919:[.0391,.5391,0,0,.77778],8920:[.03517,.54986,0,0,1.33334],8921:[.03517,.54986,0,0,1.33334],8922:[.38569,.88569,0,0,.77778],8923:[.38569,.88569,0,0,.77778],8926:[.13667,.63667,0,0,.77778],8927:[.13667,.63667,0,0,.77778],8928:[.30274,.79383,0,0,.77778],8929:[.30274,.79383,0,0,.77778],8934:[.23222,.74111,0,0,.77778],8935:[.23222,.74111,0,0,.77778],8936:[.23222,.74111,0,0,.77778],8937:[.23222,.74111,0,0,.77778],8938:[.20576,.70576,0,0,.77778],8939:[.20576,.70576,0,0,.77778],8940:[.30274,.79383,0,0,.77778],8941:[.30274,.79383,0,0,.77778],8994:[.19444,.69224,0,0,.77778],8995:[.19444,.69224,0,0,.77778],9416:[.15559,.69224,0,0,.90222],9484:[0,.69224,0,0,.5],9488:[0,.69224,0,0,.5],9492:[0,.37788,0,0,.5],9496:[0,.37788,0,0,.5],9585:[.19444,.68889,0,0,.88889],9586:[.19444,.74111,0,0,.88889],9632:[0,.675,0,0,.77778],9633:[0,.675,0,0,.77778],9650:[0,.54986,0,0,.72222],9651:[0,.54986,0,0,.72222],9654:[.03517,.54986,0,0,.77778],9660:[0,.54986,0,0,.72222],9661:[0,.54986,0,0,.72222],9664:[.03517,.54986,0,0,.77778],9674:[.11111,.69224,0,0,.66667],9733:[.19444,.69224,0,0,.94445],10003:[0,.69224,0,0,.83334],10016:[0,.69224,0,0,.83334],10731:[.11111,.69224,0,0,.66667],10846:[.19444,.75583,0,0,.61111],10877:[.13667,.63667,0,0,.77778],10878:[.13667,.63667,0,0,.77778],10885:[.25583,.75583,0,0,.77778],10886:[.25583,.75583,0,0,.77778],10887:[.13597,.63597,0,0,.77778],10888:[.13597,.63597,0,0,.77778],10889:[.26167,.75726,0,0,.77778],10890:[.26167,.75726,0,0,.77778],10891:[.48256,.98256,0,0,.77778],10892:[.48256,.98256,0,0,.77778],10901:[.13667,.63667,0,0,.77778],10902:[.13667,.63667,0,0,.77778],10933:[.25142,.75726,0,0,.77778],10934:[.25142,.75726,0,0,.77778],10935:[.26167,.75726,0,0,.77778],10936:[.26167,.75726,0,0,.77778],10937:[.26167,.75726,0,0,.77778],10938:[.26167,.75726,0,0,.77778],10949:[.25583,.75583,0,0,.77778],10950:[.25583,.75583,0,0,.77778],10955:[.28481,.79383,0,0,.77778],10956:[.28481,.79383,0,0,.77778],57350:[.08167,.58167,0,0,.22222],57351:[.08167,.58167,0,0,.38889],57352:[.08167,.58167,0,0,.77778],57353:[0,.43056,.04028,0,.66667],57356:[.25142,.75726,0,0,.77778],57357:[.25142,.75726,0,0,.77778],57358:[.41951,.91951,0,0,.77778],57359:[.30274,.79383,0,0,.77778],57360:[.30274,.79383,0,0,.77778],57361:[.41951,.91951,0,0,.77778],57366:[.25142,.75726,0,0,.77778],57367:[.25142,.75726,0,0,.77778],57368:[.25142,.75726,0,0,.77778],57369:[.25142,.75726,0,0,.77778],57370:[.13597,.63597,0,0,.77778],57371:[.13597,.63597,0,0,.77778]},"Caligraphic-Regular":{32:[0,0,0,0,.25],65:[0,.68333,0,.19445,.79847],66:[0,.68333,.03041,.13889,.65681],67:[0,.68333,.05834,.13889,.52653],68:[0,.68333,.02778,.08334,.77139],69:[0,.68333,.08944,.11111,.52778],70:[0,.68333,.09931,.11111,.71875],71:[.09722,.68333,.0593,.11111,.59487],72:[0,.68333,.00965,.11111,.84452],73:[0,.68333,.07382,0,.54452],74:[.09722,.68333,.18472,.16667,.67778],75:[0,.68333,.01445,.05556,.76195],76:[0,.68333,0,.13889,.68972],77:[0,.68333,0,.13889,1.2009],78:[0,.68333,.14736,.08334,.82049],79:[0,.68333,.02778,.11111,.79611],80:[0,.68333,.08222,.08334,.69556],81:[.09722,.68333,0,.11111,.81667],82:[0,.68333,0,.08334,.8475],83:[0,.68333,.075,.13889,.60556],84:[0,.68333,.25417,0,.54464],85:[0,.68333,.09931,.08334,.62583],86:[0,.68333,.08222,0,.61278],87:[0,.68333,.08222,.08334,.98778],88:[0,.68333,.14643,.13889,.7133],89:[.09722,.68333,.08222,.08334,.66834],90:[0,.68333,.07944,.13889,.72473],160:[0,0,0,0,.25]},"Fraktur-Regular":{32:[0,0,0,0,.25],33:[0,.69141,0,0,.29574],34:[0,.69141,0,0,.21471],38:[0,.69141,0,0,.73786],39:[0,.69141,0,0,.21201],40:[.24982,.74947,0,0,.38865],41:[.24982,.74947,0,0,.38865],42:[0,.62119,0,0,.27764],43:[.08319,.58283,0,0,.75623],44:[0,.10803,0,0,.27764],45:[.08319,.58283,0,0,.75623],46:[0,.10803,0,0,.27764],47:[.24982,.74947,0,0,.50181],48:[0,.47534,0,0,.50181],49:[0,.47534,0,0,.50181],50:[0,.47534,0,0,.50181],51:[.18906,.47534,0,0,.50181],52:[.18906,.47534,0,0,.50181],53:[.18906,.47534,0,0,.50181],54:[0,.69141,0,0,.50181],55:[.18906,.47534,0,0,.50181],56:[0,.69141,0,0,.50181],57:[.18906,.47534,0,0,.50181],58:[0,.47534,0,0,.21606],59:[.12604,.47534,0,0,.21606],61:[-.13099,.36866,0,0,.75623],63:[0,.69141,0,0,.36245],65:[0,.69141,0,0,.7176],66:[0,.69141,0,0,.88397],67:[0,.69141,0,0,.61254],68:[0,.69141,0,0,.83158],69:[0,.69141,0,0,.66278],70:[.12604,.69141,0,0,.61119],71:[0,.69141,0,0,.78539],72:[.06302,.69141,0,0,.7203],73:[0,.69141,0,0,.55448],74:[.12604,.69141,0,0,.55231],75:[0,.69141,0,0,.66845],76:[0,.69141,0,0,.66602],77:[0,.69141,0,0,1.04953],78:[0,.69141,0,0,.83212],79:[0,.69141,0,0,.82699],80:[.18906,.69141,0,0,.82753],81:[.03781,.69141,0,0,.82699],82:[0,.69141,0,0,.82807],83:[0,.69141,0,0,.82861],84:[0,.69141,0,0,.66899],85:[0,.69141,0,0,.64576],86:[0,.69141,0,0,.83131],87:[0,.69141,0,0,1.04602],88:[0,.69141,0,0,.71922],89:[.18906,.69141,0,0,.83293],90:[.12604,.69141,0,0,.60201],91:[.24982,.74947,0,0,.27764],93:[.24982,.74947,0,0,.27764],94:[0,.69141,0,0,.49965],97:[0,.47534,0,0,.50046],98:[0,.69141,0,0,.51315],99:[0,.47534,0,0,.38946],100:[0,.62119,0,0,.49857],101:[0,.47534,0,0,.40053],102:[.18906,.69141,0,0,.32626],103:[.18906,.47534,0,0,.5037],104:[.18906,.69141,0,0,.52126],105:[0,.69141,0,0,.27899],106:[0,.69141,0,0,.28088],107:[0,.69141,0,0,.38946],108:[0,.69141,0,0,.27953],109:[0,.47534,0,0,.76676],110:[0,.47534,0,0,.52666],111:[0,.47534,0,0,.48885],112:[.18906,.52396,0,0,.50046],113:[.18906,.47534,0,0,.48912],114:[0,.47534,0,0,.38919],115:[0,.47534,0,0,.44266],116:[0,.62119,0,0,.33301],117:[0,.47534,0,0,.5172],118:[0,.52396,0,0,.5118],119:[0,.52396,0,0,.77351],120:[.18906,.47534,0,0,.38865],121:[.18906,.47534,0,0,.49884],122:[.18906,.47534,0,0,.39054],160:[0,0,0,0,.25],8216:[0,.69141,0,0,.21471],8217:[0,.69141,0,0,.21471],58112:[0,.62119,0,0,.49749],58113:[0,.62119,0,0,.4983],58114:[.18906,.69141,0,0,.33328],58115:[.18906,.69141,0,0,.32923],58116:[.18906,.47534,0,0,.50343],58117:[0,.69141,0,0,.33301],58118:[0,.62119,0,0,.33409],58119:[0,.47534,0,0,.50073]},"Main-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.35],34:[0,.69444,0,0,.60278],35:[.19444,.69444,0,0,.95833],36:[.05556,.75,0,0,.575],37:[.05556,.75,0,0,.95833],38:[0,.69444,0,0,.89444],39:[0,.69444,0,0,.31944],40:[.25,.75,0,0,.44722],41:[.25,.75,0,0,.44722],42:[0,.75,0,0,.575],43:[.13333,.63333,0,0,.89444],44:[.19444,.15556,0,0,.31944],45:[0,.44444,0,0,.38333],46:[0,.15556,0,0,.31944],47:[.25,.75,0,0,.575],48:[0,.64444,0,0,.575],49:[0,.64444,0,0,.575],50:[0,.64444,0,0,.575],51:[0,.64444,0,0,.575],52:[0,.64444,0,0,.575],53:[0,.64444,0,0,.575],54:[0,.64444,0,0,.575],55:[0,.64444,0,0,.575],56:[0,.64444,0,0,.575],57:[0,.64444,0,0,.575],58:[0,.44444,0,0,.31944],59:[.19444,.44444,0,0,.31944],60:[.08556,.58556,0,0,.89444],61:[-.10889,.39111,0,0,.89444],62:[.08556,.58556,0,0,.89444],63:[0,.69444,0,0,.54305],64:[0,.69444,0,0,.89444],65:[0,.68611,0,0,.86944],66:[0,.68611,0,0,.81805],67:[0,.68611,0,0,.83055],68:[0,.68611,0,0,.88194],69:[0,.68611,0,0,.75555],70:[0,.68611,0,0,.72361],71:[0,.68611,0,0,.90416],72:[0,.68611,0,0,.9],73:[0,.68611,0,0,.43611],74:[0,.68611,0,0,.59444],75:[0,.68611,0,0,.90138],76:[0,.68611,0,0,.69166],77:[0,.68611,0,0,1.09166],78:[0,.68611,0,0,.9],79:[0,.68611,0,0,.86388],80:[0,.68611,0,0,.78611],81:[.19444,.68611,0,0,.86388],82:[0,.68611,0,0,.8625],83:[0,.68611,0,0,.63889],84:[0,.68611,0,0,.8],85:[0,.68611,0,0,.88472],86:[0,.68611,.01597,0,.86944],87:[0,.68611,.01597,0,1.18888],88:[0,.68611,0,0,.86944],89:[0,.68611,.02875,0,.86944],90:[0,.68611,0,0,.70277],91:[.25,.75,0,0,.31944],92:[.25,.75,0,0,.575],93:[.25,.75,0,0,.31944],94:[0,.69444,0,0,.575],95:[.31,.13444,.03194,0,.575],97:[0,.44444,0,0,.55902],98:[0,.69444,0,0,.63889],99:[0,.44444,0,0,.51111],100:[0,.69444,0,0,.63889],101:[0,.44444,0,0,.52708],102:[0,.69444,.10903,0,.35139],103:[.19444,.44444,.01597,0,.575],104:[0,.69444,0,0,.63889],105:[0,.69444,0,0,.31944],106:[.19444,.69444,0,0,.35139],107:[0,.69444,0,0,.60694],108:[0,.69444,0,0,.31944],109:[0,.44444,0,0,.95833],110:[0,.44444,0,0,.63889],111:[0,.44444,0,0,.575],112:[.19444,.44444,0,0,.63889],113:[.19444,.44444,0,0,.60694],114:[0,.44444,0,0,.47361],115:[0,.44444,0,0,.45361],116:[0,.63492,0,0,.44722],117:[0,.44444,0,0,.63889],118:[0,.44444,.01597,0,.60694],119:[0,.44444,.01597,0,.83055],120:[0,.44444,0,0,.60694],121:[.19444,.44444,.01597,0,.60694],122:[0,.44444,0,0,.51111],123:[.25,.75,0,0,.575],124:[.25,.75,0,0,.31944],125:[.25,.75,0,0,.575],126:[.35,.34444,0,0,.575],160:[0,0,0,0,.25],163:[0,.69444,0,0,.86853],168:[0,.69444,0,0,.575],172:[0,.44444,0,0,.76666],176:[0,.69444,0,0,.86944],177:[.13333,.63333,0,0,.89444],184:[.17014,0,0,0,.51111],198:[0,.68611,0,0,1.04166],215:[.13333,.63333,0,0,.89444],216:[.04861,.73472,0,0,.89444],223:[0,.69444,0,0,.59722],230:[0,.44444,0,0,.83055],247:[.13333,.63333,0,0,.89444],248:[.09722,.54167,0,0,.575],305:[0,.44444,0,0,.31944],338:[0,.68611,0,0,1.16944],339:[0,.44444,0,0,.89444],567:[.19444,.44444,0,0,.35139],710:[0,.69444,0,0,.575],711:[0,.63194,0,0,.575],713:[0,.59611,0,0,.575],714:[0,.69444,0,0,.575],715:[0,.69444,0,0,.575],728:[0,.69444,0,0,.575],729:[0,.69444,0,0,.31944],730:[0,.69444,0,0,.86944],732:[0,.69444,0,0,.575],733:[0,.69444,0,0,.575],915:[0,.68611,0,0,.69166],916:[0,.68611,0,0,.95833],920:[0,.68611,0,0,.89444],923:[0,.68611,0,0,.80555],926:[0,.68611,0,0,.76666],928:[0,.68611,0,0,.9],931:[0,.68611,0,0,.83055],933:[0,.68611,0,0,.89444],934:[0,.68611,0,0,.83055],936:[0,.68611,0,0,.89444],937:[0,.68611,0,0,.83055],8211:[0,.44444,.03194,0,.575],8212:[0,.44444,.03194,0,1.14999],8216:[0,.69444,0,0,.31944],8217:[0,.69444,0,0,.31944],8220:[0,.69444,0,0,.60278],8221:[0,.69444,0,0,.60278],8224:[.19444,.69444,0,0,.51111],8225:[.19444,.69444,0,0,.51111],8242:[0,.55556,0,0,.34444],8407:[0,.72444,.15486,0,.575],8463:[0,.69444,0,0,.66759],8465:[0,.69444,0,0,.83055],8467:[0,.69444,0,0,.47361],8472:[.19444,.44444,0,0,.74027],8476:[0,.69444,0,0,.83055],8501:[0,.69444,0,0,.70277],8592:[-.10889,.39111,0,0,1.14999],8593:[.19444,.69444,0,0,.575],8594:[-.10889,.39111,0,0,1.14999],8595:[.19444,.69444,0,0,.575],8596:[-.10889,.39111,0,0,1.14999],8597:[.25,.75,0,0,.575],8598:[.19444,.69444,0,0,1.14999],8599:[.19444,.69444,0,0,1.14999],8600:[.19444,.69444,0,0,1.14999],8601:[.19444,.69444,0,0,1.14999],8636:[-.10889,.39111,0,0,1.14999],8637:[-.10889,.39111,0,0,1.14999],8640:[-.10889,.39111,0,0,1.14999],8641:[-.10889,.39111,0,0,1.14999],8656:[-.10889,.39111,0,0,1.14999],8657:[.19444,.69444,0,0,.70277],8658:[-.10889,.39111,0,0,1.14999],8659:[.19444,.69444,0,0,.70277],8660:[-.10889,.39111,0,0,1.14999],8661:[.25,.75,0,0,.70277],8704:[0,.69444,0,0,.63889],8706:[0,.69444,.06389,0,.62847],8707:[0,.69444,0,0,.63889],8709:[.05556,.75,0,0,.575],8711:[0,.68611,0,0,.95833],8712:[.08556,.58556,0,0,.76666],8715:[.08556,.58556,0,0,.76666],8722:[.13333,.63333,0,0,.89444],8723:[.13333,.63333,0,0,.89444],8725:[.25,.75,0,0,.575],8726:[.25,.75,0,0,.575],8727:[-.02778,.47222,0,0,.575],8728:[-.02639,.47361,0,0,.575],8729:[-.02639,.47361,0,0,.575],8730:[.18,.82,0,0,.95833],8733:[0,.44444,0,0,.89444],8734:[0,.44444,0,0,1.14999],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.31944],8741:[.25,.75,0,0,.575],8743:[0,.55556,0,0,.76666],8744:[0,.55556,0,0,.76666],8745:[0,.55556,0,0,.76666],8746:[0,.55556,0,0,.76666],8747:[.19444,.69444,.12778,0,.56875],8764:[-.10889,.39111,0,0,.89444],8768:[.19444,.69444,0,0,.31944],8771:[.00222,.50222,0,0,.89444],8773:[.027,.638,0,0,.894],8776:[.02444,.52444,0,0,.89444],8781:[.00222,.50222,0,0,.89444],8801:[.00222,.50222,0,0,.89444],8804:[.19667,.69667,0,0,.89444],8805:[.19667,.69667,0,0,.89444],8810:[.08556,.58556,0,0,1.14999],8811:[.08556,.58556,0,0,1.14999],8826:[.08556,.58556,0,0,.89444],8827:[.08556,.58556,0,0,.89444],8834:[.08556,.58556,0,0,.89444],8835:[.08556,.58556,0,0,.89444],8838:[.19667,.69667,0,0,.89444],8839:[.19667,.69667,0,0,.89444],8846:[0,.55556,0,0,.76666],8849:[.19667,.69667,0,0,.89444],8850:[.19667,.69667,0,0,.89444],8851:[0,.55556,0,0,.76666],8852:[0,.55556,0,0,.76666],8853:[.13333,.63333,0,0,.89444],8854:[.13333,.63333,0,0,.89444],8855:[.13333,.63333,0,0,.89444],8856:[.13333,.63333,0,0,.89444],8857:[.13333,.63333,0,0,.89444],8866:[0,.69444,0,0,.70277],8867:[0,.69444,0,0,.70277],8868:[0,.69444,0,0,.89444],8869:[0,.69444,0,0,.89444],8900:[-.02639,.47361,0,0,.575],8901:[-.02639,.47361,0,0,.31944],8902:[-.02778,.47222,0,0,.575],8968:[.25,.75,0,0,.51111],8969:[.25,.75,0,0,.51111],8970:[.25,.75,0,0,.51111],8971:[.25,.75,0,0,.51111],8994:[-.13889,.36111,0,0,1.14999],8995:[-.13889,.36111,0,0,1.14999],9651:[.19444,.69444,0,0,1.02222],9657:[-.02778,.47222,0,0,.575],9661:[.19444,.69444,0,0,1.02222],9667:[-.02778,.47222,0,0,.575],9711:[.19444,.69444,0,0,1.14999],9824:[.12963,.69444,0,0,.89444],9825:[.12963,.69444,0,0,.89444],9826:[.12963,.69444,0,0,.89444],9827:[.12963,.69444,0,0,.89444],9837:[0,.75,0,0,.44722],9838:[.19444,.69444,0,0,.44722],9839:[.19444,.69444,0,0,.44722],10216:[.25,.75,0,0,.44722],10217:[.25,.75,0,0,.44722],10815:[0,.68611,0,0,.9],10927:[.19667,.69667,0,0,.89444],10928:[.19667,.69667,0,0,.89444],57376:[.19444,.69444,0,0,0]},"Main-BoldItalic":{32:[0,0,0,0,.25],33:[0,.69444,.11417,0,.38611],34:[0,.69444,.07939,0,.62055],35:[.19444,.69444,.06833,0,.94444],37:[.05556,.75,.12861,0,.94444],38:[0,.69444,.08528,0,.88555],39:[0,.69444,.12945,0,.35555],40:[.25,.75,.15806,0,.47333],41:[.25,.75,.03306,0,.47333],42:[0,.75,.14333,0,.59111],43:[.10333,.60333,.03306,0,.88555],44:[.19444,.14722,0,0,.35555],45:[0,.44444,.02611,0,.41444],46:[0,.14722,0,0,.35555],47:[.25,.75,.15806,0,.59111],48:[0,.64444,.13167,0,.59111],49:[0,.64444,.13167,0,.59111],50:[0,.64444,.13167,0,.59111],51:[0,.64444,.13167,0,.59111],52:[.19444,.64444,.13167,0,.59111],53:[0,.64444,.13167,0,.59111],54:[0,.64444,.13167,0,.59111],55:[.19444,.64444,.13167,0,.59111],56:[0,.64444,.13167,0,.59111],57:[0,.64444,.13167,0,.59111],58:[0,.44444,.06695,0,.35555],59:[.19444,.44444,.06695,0,.35555],61:[-.10889,.39111,.06833,0,.88555],63:[0,.69444,.11472,0,.59111],64:[0,.69444,.09208,0,.88555],65:[0,.68611,0,0,.86555],66:[0,.68611,.0992,0,.81666],67:[0,.68611,.14208,0,.82666],68:[0,.68611,.09062,0,.87555],69:[0,.68611,.11431,0,.75666],70:[0,.68611,.12903,0,.72722],71:[0,.68611,.07347,0,.89527],72:[0,.68611,.17208,0,.8961],73:[0,.68611,.15681,0,.47166],74:[0,.68611,.145,0,.61055],75:[0,.68611,.14208,0,.89499],76:[0,.68611,0,0,.69777],77:[0,.68611,.17208,0,1.07277],78:[0,.68611,.17208,0,.8961],79:[0,.68611,.09062,0,.85499],80:[0,.68611,.0992,0,.78721],81:[.19444,.68611,.09062,0,.85499],82:[0,.68611,.02559,0,.85944],83:[0,.68611,.11264,0,.64999],84:[0,.68611,.12903,0,.7961],85:[0,.68611,.17208,0,.88083],86:[0,.68611,.18625,0,.86555],87:[0,.68611,.18625,0,1.15999],88:[0,.68611,.15681,0,.86555],89:[0,.68611,.19803,0,.86555],90:[0,.68611,.14208,0,.70888],91:[.25,.75,.1875,0,.35611],93:[.25,.75,.09972,0,.35611],94:[0,.69444,.06709,0,.59111],95:[.31,.13444,.09811,0,.59111],97:[0,.44444,.09426,0,.59111],98:[0,.69444,.07861,0,.53222],99:[0,.44444,.05222,0,.53222],100:[0,.69444,.10861,0,.59111],101:[0,.44444,.085,0,.53222],102:[.19444,.69444,.21778,0,.4],103:[.19444,.44444,.105,0,.53222],104:[0,.69444,.09426,0,.59111],105:[0,.69326,.11387,0,.35555],106:[.19444,.69326,.1672,0,.35555],107:[0,.69444,.11111,0,.53222],108:[0,.69444,.10861,0,.29666],109:[0,.44444,.09426,0,.94444],110:[0,.44444,.09426,0,.64999],111:[0,.44444,.07861,0,.59111],112:[.19444,.44444,.07861,0,.59111],113:[.19444,.44444,.105,0,.53222],114:[0,.44444,.11111,0,.50167],115:[0,.44444,.08167,0,.48694],116:[0,.63492,.09639,0,.385],117:[0,.44444,.09426,0,.62055],118:[0,.44444,.11111,0,.53222],119:[0,.44444,.11111,0,.76777],120:[0,.44444,.12583,0,.56055],121:[.19444,.44444,.105,0,.56166],122:[0,.44444,.13889,0,.49055],126:[.35,.34444,.11472,0,.59111],160:[0,0,0,0,.25],168:[0,.69444,.11473,0,.59111],176:[0,.69444,0,0,.94888],184:[.17014,0,0,0,.53222],198:[0,.68611,.11431,0,1.02277],216:[.04861,.73472,.09062,0,.88555],223:[.19444,.69444,.09736,0,.665],230:[0,.44444,.085,0,.82666],248:[.09722,.54167,.09458,0,.59111],305:[0,.44444,.09426,0,.35555],338:[0,.68611,.11431,0,1.14054],339:[0,.44444,.085,0,.82666],567:[.19444,.44444,.04611,0,.385],710:[0,.69444,.06709,0,.59111],711:[0,.63194,.08271,0,.59111],713:[0,.59444,.10444,0,.59111],714:[0,.69444,.08528,0,.59111],715:[0,.69444,0,0,.59111],728:[0,.69444,.10333,0,.59111],729:[0,.69444,.12945,0,.35555],730:[0,.69444,0,0,.94888],732:[0,.69444,.11472,0,.59111],733:[0,.69444,.11472,0,.59111],915:[0,.68611,.12903,0,.69777],916:[0,.68611,0,0,.94444],920:[0,.68611,.09062,0,.88555],923:[0,.68611,0,0,.80666],926:[0,.68611,.15092,0,.76777],928:[0,.68611,.17208,0,.8961],931:[0,.68611,.11431,0,.82666],933:[0,.68611,.10778,0,.88555],934:[0,.68611,.05632,0,.82666],936:[0,.68611,.10778,0,.88555],937:[0,.68611,.0992,0,.82666],8211:[0,.44444,.09811,0,.59111],8212:[0,.44444,.09811,0,1.18221],8216:[0,.69444,.12945,0,.35555],8217:[0,.69444,.12945,0,.35555],8220:[0,.69444,.16772,0,.62055],8221:[0,.69444,.07939,0,.62055]},"Main-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.12417,0,.30667],34:[0,.69444,.06961,0,.51444],35:[.19444,.69444,.06616,0,.81777],37:[.05556,.75,.13639,0,.81777],38:[0,.69444,.09694,0,.76666],39:[0,.69444,.12417,0,.30667],40:[.25,.75,.16194,0,.40889],41:[.25,.75,.03694,0,.40889],42:[0,.75,.14917,0,.51111],43:[.05667,.56167,.03694,0,.76666],44:[.19444,.10556,0,0,.30667],45:[0,.43056,.02826,0,.35778],46:[0,.10556,0,0,.30667],47:[.25,.75,.16194,0,.51111],48:[0,.64444,.13556,0,.51111],49:[0,.64444,.13556,0,.51111],50:[0,.64444,.13556,0,.51111],51:[0,.64444,.13556,0,.51111],52:[.19444,.64444,.13556,0,.51111],53:[0,.64444,.13556,0,.51111],54:[0,.64444,.13556,0,.51111],55:[.19444,.64444,.13556,0,.51111],56:[0,.64444,.13556,0,.51111],57:[0,.64444,.13556,0,.51111],58:[0,.43056,.0582,0,.30667],59:[.19444,.43056,.0582,0,.30667],61:[-.13313,.36687,.06616,0,.76666],63:[0,.69444,.1225,0,.51111],64:[0,.69444,.09597,0,.76666],65:[0,.68333,0,0,.74333],66:[0,.68333,.10257,0,.70389],67:[0,.68333,.14528,0,.71555],68:[0,.68333,.09403,0,.755],69:[0,.68333,.12028,0,.67833],70:[0,.68333,.13305,0,.65277],71:[0,.68333,.08722,0,.77361],72:[0,.68333,.16389,0,.74333],73:[0,.68333,.15806,0,.38555],74:[0,.68333,.14028,0,.525],75:[0,.68333,.14528,0,.76888],76:[0,.68333,0,0,.62722],77:[0,.68333,.16389,0,.89666],78:[0,.68333,.16389,0,.74333],79:[0,.68333,.09403,0,.76666],80:[0,.68333,.10257,0,.67833],81:[.19444,.68333,.09403,0,.76666],82:[0,.68333,.03868,0,.72944],83:[0,.68333,.11972,0,.56222],84:[0,.68333,.13305,0,.71555],85:[0,.68333,.16389,0,.74333],86:[0,.68333,.18361,0,.74333],87:[0,.68333,.18361,0,.99888],88:[0,.68333,.15806,0,.74333],89:[0,.68333,.19383,0,.74333],90:[0,.68333,.14528,0,.61333],91:[.25,.75,.1875,0,.30667],93:[.25,.75,.10528,0,.30667],94:[0,.69444,.06646,0,.51111],95:[.31,.12056,.09208,0,.51111],97:[0,.43056,.07671,0,.51111],98:[0,.69444,.06312,0,.46],99:[0,.43056,.05653,0,.46],100:[0,.69444,.10333,0,.51111],101:[0,.43056,.07514,0,.46],102:[.19444,.69444,.21194,0,.30667],103:[.19444,.43056,.08847,0,.46],104:[0,.69444,.07671,0,.51111],105:[0,.65536,.1019,0,.30667],106:[.19444,.65536,.14467,0,.30667],107:[0,.69444,.10764,0,.46],108:[0,.69444,.10333,0,.25555],109:[0,.43056,.07671,0,.81777],110:[0,.43056,.07671,0,.56222],111:[0,.43056,.06312,0,.51111],112:[.19444,.43056,.06312,0,.51111],113:[.19444,.43056,.08847,0,.46],114:[0,.43056,.10764,0,.42166],115:[0,.43056,.08208,0,.40889],116:[0,.61508,.09486,0,.33222],117:[0,.43056,.07671,0,.53666],118:[0,.43056,.10764,0,.46],119:[0,.43056,.10764,0,.66444],120:[0,.43056,.12042,0,.46389],121:[.19444,.43056,.08847,0,.48555],122:[0,.43056,.12292,0,.40889],126:[.35,.31786,.11585,0,.51111],160:[0,0,0,0,.25],168:[0,.66786,.10474,0,.51111],176:[0,.69444,0,0,.83129],184:[.17014,0,0,0,.46],198:[0,.68333,.12028,0,.88277],216:[.04861,.73194,.09403,0,.76666],223:[.19444,.69444,.10514,0,.53666],230:[0,.43056,.07514,0,.71555],248:[.09722,.52778,.09194,0,.51111],338:[0,.68333,.12028,0,.98499],339:[0,.43056,.07514,0,.71555],710:[0,.69444,.06646,0,.51111],711:[0,.62847,.08295,0,.51111],713:[0,.56167,.10333,0,.51111],714:[0,.69444,.09694,0,.51111],715:[0,.69444,0,0,.51111],728:[0,.69444,.10806,0,.51111],729:[0,.66786,.11752,0,.30667],730:[0,.69444,0,0,.83129],732:[0,.66786,.11585,0,.51111],733:[0,.69444,.1225,0,.51111],915:[0,.68333,.13305,0,.62722],916:[0,.68333,0,0,.81777],920:[0,.68333,.09403,0,.76666],923:[0,.68333,0,0,.69222],926:[0,.68333,.15294,0,.66444],928:[0,.68333,.16389,0,.74333],931:[0,.68333,.12028,0,.71555],933:[0,.68333,.11111,0,.76666],934:[0,.68333,.05986,0,.71555],936:[0,.68333,.11111,0,.76666],937:[0,.68333,.10257,0,.71555],8211:[0,.43056,.09208,0,.51111],8212:[0,.43056,.09208,0,1.02222],8216:[0,.69444,.12417,0,.30667],8217:[0,.69444,.12417,0,.30667],8220:[0,.69444,.1685,0,.51444],8221:[0,.69444,.06961,0,.51444],8463:[0,.68889,0,0,.54028]},"Main-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.27778],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.77778],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.19444,.10556,0,0,.27778],45:[0,.43056,0,0,.33333],46:[0,.10556,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.64444,0,0,.5],49:[0,.64444,0,0,.5],50:[0,.64444,0,0,.5],51:[0,.64444,0,0,.5],52:[0,.64444,0,0,.5],53:[0,.64444,0,0,.5],54:[0,.64444,0,0,.5],55:[0,.64444,0,0,.5],56:[0,.64444,0,0,.5],57:[0,.64444,0,0,.5],58:[0,.43056,0,0,.27778],59:[.19444,.43056,0,0,.27778],60:[.0391,.5391,0,0,.77778],61:[-.13313,.36687,0,0,.77778],62:[.0391,.5391,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.77778],65:[0,.68333,0,0,.75],66:[0,.68333,0,0,.70834],67:[0,.68333,0,0,.72222],68:[0,.68333,0,0,.76389],69:[0,.68333,0,0,.68056],70:[0,.68333,0,0,.65278],71:[0,.68333,0,0,.78472],72:[0,.68333,0,0,.75],73:[0,.68333,0,0,.36111],74:[0,.68333,0,0,.51389],75:[0,.68333,0,0,.77778],76:[0,.68333,0,0,.625],77:[0,.68333,0,0,.91667],78:[0,.68333,0,0,.75],79:[0,.68333,0,0,.77778],80:[0,.68333,0,0,.68056],81:[.19444,.68333,0,0,.77778],82:[0,.68333,0,0,.73611],83:[0,.68333,0,0,.55556],84:[0,.68333,0,0,.72222],85:[0,.68333,0,0,.75],86:[0,.68333,.01389,0,.75],87:[0,.68333,.01389,0,1.02778],88:[0,.68333,0,0,.75],89:[0,.68333,.025,0,.75],90:[0,.68333,0,0,.61111],91:[.25,.75,0,0,.27778],92:[.25,.75,0,0,.5],93:[.25,.75,0,0,.27778],94:[0,.69444,0,0,.5],95:[.31,.12056,.02778,0,.5],97:[0,.43056,0,0,.5],98:[0,.69444,0,0,.55556],99:[0,.43056,0,0,.44445],100:[0,.69444,0,0,.55556],101:[0,.43056,0,0,.44445],102:[0,.69444,.07778,0,.30556],103:[.19444,.43056,.01389,0,.5],104:[0,.69444,0,0,.55556],105:[0,.66786,0,0,.27778],106:[.19444,.66786,0,0,.30556],107:[0,.69444,0,0,.52778],108:[0,.69444,0,0,.27778],109:[0,.43056,0,0,.83334],110:[0,.43056,0,0,.55556],111:[0,.43056,0,0,.5],112:[.19444,.43056,0,0,.55556],113:[.19444,.43056,0,0,.52778],114:[0,.43056,0,0,.39167],115:[0,.43056,0,0,.39445],116:[0,.61508,0,0,.38889],117:[0,.43056,0,0,.55556],118:[0,.43056,.01389,0,.52778],119:[0,.43056,.01389,0,.72222],120:[0,.43056,0,0,.52778],121:[.19444,.43056,.01389,0,.52778],122:[0,.43056,0,0,.44445],123:[.25,.75,0,0,.5],124:[.25,.75,0,0,.27778],125:[.25,.75,0,0,.5],126:[.35,.31786,0,0,.5],160:[0,0,0,0,.25],163:[0,.69444,0,0,.76909],167:[.19444,.69444,0,0,.44445],168:[0,.66786,0,0,.5],172:[0,.43056,0,0,.66667],176:[0,.69444,0,0,.75],177:[.08333,.58333,0,0,.77778],182:[.19444,.69444,0,0,.61111],184:[.17014,0,0,0,.44445],198:[0,.68333,0,0,.90278],215:[.08333,.58333,0,0,.77778],216:[.04861,.73194,0,0,.77778],223:[0,.69444,0,0,.5],230:[0,.43056,0,0,.72222],247:[.08333,.58333,0,0,.77778],248:[.09722,.52778,0,0,.5],305:[0,.43056,0,0,.27778],338:[0,.68333,0,0,1.01389],339:[0,.43056,0,0,.77778],567:[.19444,.43056,0,0,.30556],710:[0,.69444,0,0,.5],711:[0,.62847,0,0,.5],713:[0,.56778,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.66786,0,0,.27778],730:[0,.69444,0,0,.75],732:[0,.66786,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.68333,0,0,.625],916:[0,.68333,0,0,.83334],920:[0,.68333,0,0,.77778],923:[0,.68333,0,0,.69445],926:[0,.68333,0,0,.66667],928:[0,.68333,0,0,.75],931:[0,.68333,0,0,.72222],933:[0,.68333,0,0,.77778],934:[0,.68333,0,0,.72222],936:[0,.68333,0,0,.77778],937:[0,.68333,0,0,.72222],8211:[0,.43056,.02778,0,.5],8212:[0,.43056,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5],8224:[.19444,.69444,0,0,.44445],8225:[.19444,.69444,0,0,.44445],8230:[0,.123,0,0,1.172],8242:[0,.55556,0,0,.275],8407:[0,.71444,.15382,0,.5],8463:[0,.68889,0,0,.54028],8465:[0,.69444,0,0,.72222],8467:[0,.69444,0,.11111,.41667],8472:[.19444,.43056,0,.11111,.63646],8476:[0,.69444,0,0,.72222],8501:[0,.69444,0,0,.61111],8592:[-.13313,.36687,0,0,1],8593:[.19444,.69444,0,0,.5],8594:[-.13313,.36687,0,0,1],8595:[.19444,.69444,0,0,.5],8596:[-.13313,.36687,0,0,1],8597:[.25,.75,0,0,.5],8598:[.19444,.69444,0,0,1],8599:[.19444,.69444,0,0,1],8600:[.19444,.69444,0,0,1],8601:[.19444,.69444,0,0,1],8614:[.011,.511,0,0,1],8617:[.011,.511,0,0,1.126],8618:[.011,.511,0,0,1.126],8636:[-.13313,.36687,0,0,1],8637:[-.13313,.36687,0,0,1],8640:[-.13313,.36687,0,0,1],8641:[-.13313,.36687,0,0,1],8652:[.011,.671,0,0,1],8656:[-.13313,.36687,0,0,1],8657:[.19444,.69444,0,0,.61111],8658:[-.13313,.36687,0,0,1],8659:[.19444,.69444,0,0,.61111],8660:[-.13313,.36687,0,0,1],8661:[.25,.75,0,0,.61111],8704:[0,.69444,0,0,.55556],8706:[0,.69444,.05556,.08334,.5309],8707:[0,.69444,0,0,.55556],8709:[.05556,.75,0,0,.5],8711:[0,.68333,0,0,.83334],8712:[.0391,.5391,0,0,.66667],8715:[.0391,.5391,0,0,.66667],8722:[.08333,.58333,0,0,.77778],8723:[.08333,.58333,0,0,.77778],8725:[.25,.75,0,0,.5],8726:[.25,.75,0,0,.5],8727:[-.03472,.46528,0,0,.5],8728:[-.05555,.44445,0,0,.5],8729:[-.05555,.44445,0,0,.5],8730:[.2,.8,0,0,.83334],8733:[0,.43056,0,0,.77778],8734:[0,.43056,0,0,1],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.27778],8741:[.25,.75,0,0,.5],8743:[0,.55556,0,0,.66667],8744:[0,.55556,0,0,.66667],8745:[0,.55556,0,0,.66667],8746:[0,.55556,0,0,.66667],8747:[.19444,.69444,.11111,0,.41667],8764:[-.13313,.36687,0,0,.77778],8768:[.19444,.69444,0,0,.27778],8771:[-.03625,.46375,0,0,.77778],8773:[-.022,.589,0,0,.778],8776:[-.01688,.48312,0,0,.77778],8781:[-.03625,.46375,0,0,.77778],8784:[-.133,.673,0,0,.778],8801:[-.03625,.46375,0,0,.77778],8804:[.13597,.63597,0,0,.77778],8805:[.13597,.63597,0,0,.77778],8810:[.0391,.5391,0,0,1],8811:[.0391,.5391,0,0,1],8826:[.0391,.5391,0,0,.77778],8827:[.0391,.5391,0,0,.77778],8834:[.0391,.5391,0,0,.77778],8835:[.0391,.5391,0,0,.77778],8838:[.13597,.63597,0,0,.77778],8839:[.13597,.63597,0,0,.77778],8846:[0,.55556,0,0,.66667],8849:[.13597,.63597,0,0,.77778],8850:[.13597,.63597,0,0,.77778],8851:[0,.55556,0,0,.66667],8852:[0,.55556,0,0,.66667],8853:[.08333,.58333,0,0,.77778],8854:[.08333,.58333,0,0,.77778],8855:[.08333,.58333,0,0,.77778],8856:[.08333,.58333,0,0,.77778],8857:[.08333,.58333,0,0,.77778],8866:[0,.69444,0,0,.61111],8867:[0,.69444,0,0,.61111],8868:[0,.69444,0,0,.77778],8869:[0,.69444,0,0,.77778],8872:[.249,.75,0,0,.867],8900:[-.05555,.44445,0,0,.5],8901:[-.05555,.44445,0,0,.27778],8902:[-.03472,.46528,0,0,.5],8904:[.005,.505,0,0,.9],8942:[.03,.903,0,0,.278],8943:[-.19,.313,0,0,1.172],8945:[-.1,.823,0,0,1.282],8968:[.25,.75,0,0,.44445],8969:[.25,.75,0,0,.44445],8970:[.25,.75,0,0,.44445],8971:[.25,.75,0,0,.44445],8994:[-.14236,.35764,0,0,1],8995:[-.14236,.35764,0,0,1],9136:[.244,.744,0,0,.412],9137:[.244,.745,0,0,.412],9651:[.19444,.69444,0,0,.88889],9657:[-.03472,.46528,0,0,.5],9661:[.19444,.69444,0,0,.88889],9667:[-.03472,.46528,0,0,.5],9711:[.19444,.69444,0,0,1],9824:[.12963,.69444,0,0,.77778],9825:[.12963,.69444,0,0,.77778],9826:[.12963,.69444,0,0,.77778],9827:[.12963,.69444,0,0,.77778],9837:[0,.75,0,0,.38889],9838:[.19444,.69444,0,0,.38889],9839:[.19444,.69444,0,0,.38889],10216:[.25,.75,0,0,.38889],10217:[.25,.75,0,0,.38889],10222:[.244,.744,0,0,.412],10223:[.244,.745,0,0,.412],10229:[.011,.511,0,0,1.609],10230:[.011,.511,0,0,1.638],10231:[.011,.511,0,0,1.859],10232:[.024,.525,0,0,1.609],10233:[.024,.525,0,0,1.638],10234:[.024,.525,0,0,1.858],10236:[.011,.511,0,0,1.638],10815:[0,.68333,0,0,.75],10927:[.13597,.63597,0,0,.77778],10928:[.13597,.63597,0,0,.77778],57376:[.19444,.69444,0,0,0]},"Math-BoldItalic":{32:[0,0,0,0,.25],48:[0,.44444,0,0,.575],49:[0,.44444,0,0,.575],50:[0,.44444,0,0,.575],51:[.19444,.44444,0,0,.575],52:[.19444,.44444,0,0,.575],53:[.19444,.44444,0,0,.575],54:[0,.64444,0,0,.575],55:[.19444,.44444,0,0,.575],56:[0,.64444,0,0,.575],57:[.19444,.44444,0,0,.575],65:[0,.68611,0,0,.86944],66:[0,.68611,.04835,0,.8664],67:[0,.68611,.06979,0,.81694],68:[0,.68611,.03194,0,.93812],69:[0,.68611,.05451,0,.81007],70:[0,.68611,.15972,0,.68889],71:[0,.68611,0,0,.88673],72:[0,.68611,.08229,0,.98229],73:[0,.68611,.07778,0,.51111],74:[0,.68611,.10069,0,.63125],75:[0,.68611,.06979,0,.97118],76:[0,.68611,0,0,.75555],77:[0,.68611,.11424,0,1.14201],78:[0,.68611,.11424,0,.95034],79:[0,.68611,.03194,0,.83666],80:[0,.68611,.15972,0,.72309],81:[.19444,.68611,0,0,.86861],82:[0,.68611,.00421,0,.87235],83:[0,.68611,.05382,0,.69271],84:[0,.68611,.15972,0,.63663],85:[0,.68611,.11424,0,.80027],86:[0,.68611,.25555,0,.67778],87:[0,.68611,.15972,0,1.09305],88:[0,.68611,.07778,0,.94722],89:[0,.68611,.25555,0,.67458],90:[0,.68611,.06979,0,.77257],97:[0,.44444,0,0,.63287],98:[0,.69444,0,0,.52083],99:[0,.44444,0,0,.51342],100:[0,.69444,0,0,.60972],101:[0,.44444,0,0,.55361],102:[.19444,.69444,.11042,0,.56806],103:[.19444,.44444,.03704,0,.5449],104:[0,.69444,0,0,.66759],105:[0,.69326,0,0,.4048],106:[.19444,.69326,.0622,0,.47083],107:[0,.69444,.01852,0,.6037],108:[0,.69444,.0088,0,.34815],109:[0,.44444,0,0,1.0324],110:[0,.44444,0,0,.71296],111:[0,.44444,0,0,.58472],112:[.19444,.44444,0,0,.60092],113:[.19444,.44444,.03704,0,.54213],114:[0,.44444,.03194,0,.5287],115:[0,.44444,0,0,.53125],116:[0,.63492,0,0,.41528],117:[0,.44444,0,0,.68102],118:[0,.44444,.03704,0,.56666],119:[0,.44444,.02778,0,.83148],120:[0,.44444,0,0,.65903],121:[.19444,.44444,.03704,0,.59028],122:[0,.44444,.04213,0,.55509],160:[0,0,0,0,.25],915:[0,.68611,.15972,0,.65694],916:[0,.68611,0,0,.95833],920:[0,.68611,.03194,0,.86722],923:[0,.68611,0,0,.80555],926:[0,.68611,.07458,0,.84125],928:[0,.68611,.08229,0,.98229],931:[0,.68611,.05451,0,.88507],933:[0,.68611,.15972,0,.67083],934:[0,.68611,0,0,.76666],936:[0,.68611,.11653,0,.71402],937:[0,.68611,.04835,0,.8789],945:[0,.44444,0,0,.76064],946:[.19444,.69444,.03403,0,.65972],947:[.19444,.44444,.06389,0,.59003],948:[0,.69444,.03819,0,.52222],949:[0,.44444,0,0,.52882],950:[.19444,.69444,.06215,0,.50833],951:[.19444,.44444,.03704,0,.6],952:[0,.69444,.03194,0,.5618],953:[0,.44444,0,0,.41204],954:[0,.44444,0,0,.66759],955:[0,.69444,0,0,.67083],956:[.19444,.44444,0,0,.70787],957:[0,.44444,.06898,0,.57685],958:[.19444,.69444,.03021,0,.50833],959:[0,.44444,0,0,.58472],960:[0,.44444,.03704,0,.68241],961:[.19444,.44444,0,0,.6118],962:[.09722,.44444,.07917,0,.42361],963:[0,.44444,.03704,0,.68588],964:[0,.44444,.13472,0,.52083],965:[0,.44444,.03704,0,.63055],966:[.19444,.44444,0,0,.74722],967:[.19444,.44444,0,0,.71805],968:[.19444,.69444,.03704,0,.75833],969:[0,.44444,.03704,0,.71782],977:[0,.69444,0,0,.69155],981:[.19444,.69444,0,0,.7125],982:[0,.44444,.03194,0,.975],1009:[.19444,.44444,0,0,.6118],1013:[0,.44444,0,0,.48333],57649:[0,.44444,0,0,.39352],57911:[.19444,.44444,0,0,.43889]},"Math-Italic":{32:[0,0,0,0,.25],48:[0,.43056,0,0,.5],49:[0,.43056,0,0,.5],50:[0,.43056,0,0,.5],51:[.19444,.43056,0,0,.5],52:[.19444,.43056,0,0,.5],53:[.19444,.43056,0,0,.5],54:[0,.64444,0,0,.5],55:[.19444,.43056,0,0,.5],56:[0,.64444,0,0,.5],57:[.19444,.43056,0,0,.5],65:[0,.68333,0,.13889,.75],66:[0,.68333,.05017,.08334,.75851],67:[0,.68333,.07153,.08334,.71472],68:[0,.68333,.02778,.05556,.82792],69:[0,.68333,.05764,.08334,.7382],70:[0,.68333,.13889,.08334,.64306],71:[0,.68333,0,.08334,.78625],72:[0,.68333,.08125,.05556,.83125],73:[0,.68333,.07847,.11111,.43958],74:[0,.68333,.09618,.16667,.55451],75:[0,.68333,.07153,.05556,.84931],76:[0,.68333,0,.02778,.68056],77:[0,.68333,.10903,.08334,.97014],78:[0,.68333,.10903,.08334,.80347],79:[0,.68333,.02778,.08334,.76278],80:[0,.68333,.13889,.08334,.64201],81:[.19444,.68333,0,.08334,.79056],82:[0,.68333,.00773,.08334,.75929],83:[0,.68333,.05764,.08334,.6132],84:[0,.68333,.13889,.08334,.58438],85:[0,.68333,.10903,.02778,.68278],86:[0,.68333,.22222,0,.58333],87:[0,.68333,.13889,0,.94445],88:[0,.68333,.07847,.08334,.82847],89:[0,.68333,.22222,0,.58056],90:[0,.68333,.07153,.08334,.68264],97:[0,.43056,0,0,.52859],98:[0,.69444,0,0,.42917],99:[0,.43056,0,.05556,.43276],100:[0,.69444,0,.16667,.52049],101:[0,.43056,0,.05556,.46563],102:[.19444,.69444,.10764,.16667,.48959],103:[.19444,.43056,.03588,.02778,.47697],104:[0,.69444,0,0,.57616],105:[0,.65952,0,0,.34451],106:[.19444,.65952,.05724,0,.41181],107:[0,.69444,.03148,0,.5206],108:[0,.69444,.01968,.08334,.29838],109:[0,.43056,0,0,.87801],110:[0,.43056,0,0,.60023],111:[0,.43056,0,.05556,.48472],112:[.19444,.43056,0,.08334,.50313],113:[.19444,.43056,.03588,.08334,.44641],114:[0,.43056,.02778,.05556,.45116],115:[0,.43056,0,.05556,.46875],116:[0,.61508,0,.08334,.36111],117:[0,.43056,0,.02778,.57246],118:[0,.43056,.03588,.02778,.48472],119:[0,.43056,.02691,.08334,.71592],120:[0,.43056,0,.02778,.57153],121:[.19444,.43056,.03588,.05556,.49028],122:[0,.43056,.04398,.05556,.46505],160:[0,0,0,0,.25],915:[0,.68333,.13889,.08334,.61528],916:[0,.68333,0,.16667,.83334],920:[0,.68333,.02778,.08334,.76278],923:[0,.68333,0,.16667,.69445],926:[0,.68333,.07569,.08334,.74236],928:[0,.68333,.08125,.05556,.83125],931:[0,.68333,.05764,.08334,.77986],933:[0,.68333,.13889,.05556,.58333],934:[0,.68333,0,.08334,.66667],936:[0,.68333,.11,.05556,.61222],937:[0,.68333,.05017,.08334,.7724],945:[0,.43056,.0037,.02778,.6397],946:[.19444,.69444,.05278,.08334,.56563],947:[.19444,.43056,.05556,0,.51773],948:[0,.69444,.03785,.05556,.44444],949:[0,.43056,0,.08334,.46632],950:[.19444,.69444,.07378,.08334,.4375],951:[.19444,.43056,.03588,.05556,.49653],952:[0,.69444,.02778,.08334,.46944],953:[0,.43056,0,.05556,.35394],954:[0,.43056,0,0,.57616],955:[0,.69444,0,0,.58334],956:[.19444,.43056,0,.02778,.60255],957:[0,.43056,.06366,.02778,.49398],958:[.19444,.69444,.04601,.11111,.4375],959:[0,.43056,0,.05556,.48472],960:[0,.43056,.03588,0,.57003],961:[.19444,.43056,0,.08334,.51702],962:[.09722,.43056,.07986,.08334,.36285],963:[0,.43056,.03588,0,.57141],964:[0,.43056,.1132,.02778,.43715],965:[0,.43056,.03588,.02778,.54028],966:[.19444,.43056,0,.08334,.65417],967:[.19444,.43056,0,.05556,.62569],968:[.19444,.69444,.03588,.11111,.65139],969:[0,.43056,.03588,0,.62245],977:[0,.69444,0,.08334,.59144],981:[.19444,.69444,0,.08334,.59583],982:[0,.43056,.02778,0,.82813],1009:[.19444,.43056,0,.08334,.51702],1013:[0,.43056,0,.05556,.4059],57649:[0,.43056,0,.02778,.32246],57911:[.19444,.43056,0,.08334,.38403]},"SansSerif-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.36667],34:[0,.69444,0,0,.55834],35:[.19444,.69444,0,0,.91667],36:[.05556,.75,0,0,.55],37:[.05556,.75,0,0,1.02912],38:[0,.69444,0,0,.83056],39:[0,.69444,0,0,.30556],40:[.25,.75,0,0,.42778],41:[.25,.75,0,0,.42778],42:[0,.75,0,0,.55],43:[.11667,.61667,0,0,.85556],44:[.10556,.13056,0,0,.30556],45:[0,.45833,0,0,.36667],46:[0,.13056,0,0,.30556],47:[.25,.75,0,0,.55],48:[0,.69444,0,0,.55],49:[0,.69444,0,0,.55],50:[0,.69444,0,0,.55],51:[0,.69444,0,0,.55],52:[0,.69444,0,0,.55],53:[0,.69444,0,0,.55],54:[0,.69444,0,0,.55],55:[0,.69444,0,0,.55],56:[0,.69444,0,0,.55],57:[0,.69444,0,0,.55],58:[0,.45833,0,0,.30556],59:[.10556,.45833,0,0,.30556],61:[-.09375,.40625,0,0,.85556],63:[0,.69444,0,0,.51945],64:[0,.69444,0,0,.73334],65:[0,.69444,0,0,.73334],66:[0,.69444,0,0,.73334],67:[0,.69444,0,0,.70278],68:[0,.69444,0,0,.79445],69:[0,.69444,0,0,.64167],70:[0,.69444,0,0,.61111],71:[0,.69444,0,0,.73334],72:[0,.69444,0,0,.79445],73:[0,.69444,0,0,.33056],74:[0,.69444,0,0,.51945],75:[0,.69444,0,0,.76389],76:[0,.69444,0,0,.58056],77:[0,.69444,0,0,.97778],78:[0,.69444,0,0,.79445],79:[0,.69444,0,0,.79445],80:[0,.69444,0,0,.70278],81:[.10556,.69444,0,0,.79445],82:[0,.69444,0,0,.70278],83:[0,.69444,0,0,.61111],84:[0,.69444,0,0,.73334],85:[0,.69444,0,0,.76389],86:[0,.69444,.01528,0,.73334],87:[0,.69444,.01528,0,1.03889],88:[0,.69444,0,0,.73334],89:[0,.69444,.0275,0,.73334],90:[0,.69444,0,0,.67223],91:[.25,.75,0,0,.34306],93:[.25,.75,0,0,.34306],94:[0,.69444,0,0,.55],95:[.35,.10833,.03056,0,.55],97:[0,.45833,0,0,.525],98:[0,.69444,0,0,.56111],99:[0,.45833,0,0,.48889],100:[0,.69444,0,0,.56111],101:[0,.45833,0,0,.51111],102:[0,.69444,.07639,0,.33611],103:[.19444,.45833,.01528,0,.55],104:[0,.69444,0,0,.56111],105:[0,.69444,0,0,.25556],106:[.19444,.69444,0,0,.28611],107:[0,.69444,0,0,.53056],108:[0,.69444,0,0,.25556],109:[0,.45833,0,0,.86667],110:[0,.45833,0,0,.56111],111:[0,.45833,0,0,.55],112:[.19444,.45833,0,0,.56111],113:[.19444,.45833,0,0,.56111],114:[0,.45833,.01528,0,.37222],115:[0,.45833,0,0,.42167],116:[0,.58929,0,0,.40417],117:[0,.45833,0,0,.56111],118:[0,.45833,.01528,0,.5],119:[0,.45833,.01528,0,.74445],120:[0,.45833,0,0,.5],121:[.19444,.45833,.01528,0,.5],122:[0,.45833,0,0,.47639],126:[.35,.34444,0,0,.55],160:[0,0,0,0,.25],168:[0,.69444,0,0,.55],176:[0,.69444,0,0,.73334],180:[0,.69444,0,0,.55],184:[.17014,0,0,0,.48889],305:[0,.45833,0,0,.25556],567:[.19444,.45833,0,0,.28611],710:[0,.69444,0,0,.55],711:[0,.63542,0,0,.55],713:[0,.63778,0,0,.55],728:[0,.69444,0,0,.55],729:[0,.69444,0,0,.30556],730:[0,.69444,0,0,.73334],732:[0,.69444,0,0,.55],733:[0,.69444,0,0,.55],915:[0,.69444,0,0,.58056],916:[0,.69444,0,0,.91667],920:[0,.69444,0,0,.85556],923:[0,.69444,0,0,.67223],926:[0,.69444,0,0,.73334],928:[0,.69444,0,0,.79445],931:[0,.69444,0,0,.79445],933:[0,.69444,0,0,.85556],934:[0,.69444,0,0,.79445],936:[0,.69444,0,0,.85556],937:[0,.69444,0,0,.79445],8211:[0,.45833,.03056,0,.55],8212:[0,.45833,.03056,0,1.10001],8216:[0,.69444,0,0,.30556],8217:[0,.69444,0,0,.30556],8220:[0,.69444,0,0,.55834],8221:[0,.69444,0,0,.55834]},"SansSerif-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.05733,0,.31945],34:[0,.69444,.00316,0,.5],35:[.19444,.69444,.05087,0,.83334],36:[.05556,.75,.11156,0,.5],37:[.05556,.75,.03126,0,.83334],38:[0,.69444,.03058,0,.75834],39:[0,.69444,.07816,0,.27778],40:[.25,.75,.13164,0,.38889],41:[.25,.75,.02536,0,.38889],42:[0,.75,.11775,0,.5],43:[.08333,.58333,.02536,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,.01946,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,.13164,0,.5],48:[0,.65556,.11156,0,.5],49:[0,.65556,.11156,0,.5],50:[0,.65556,.11156,0,.5],51:[0,.65556,.11156,0,.5],52:[0,.65556,.11156,0,.5],53:[0,.65556,.11156,0,.5],54:[0,.65556,.11156,0,.5],55:[0,.65556,.11156,0,.5],56:[0,.65556,.11156,0,.5],57:[0,.65556,.11156,0,.5],58:[0,.44444,.02502,0,.27778],59:[.125,.44444,.02502,0,.27778],61:[-.13,.37,.05087,0,.77778],63:[0,.69444,.11809,0,.47222],64:[0,.69444,.07555,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,.08293,0,.66667],67:[0,.69444,.11983,0,.63889],68:[0,.69444,.07555,0,.72223],69:[0,.69444,.11983,0,.59722],70:[0,.69444,.13372,0,.56945],71:[0,.69444,.11983,0,.66667],72:[0,.69444,.08094,0,.70834],73:[0,.69444,.13372,0,.27778],74:[0,.69444,.08094,0,.47222],75:[0,.69444,.11983,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,.08094,0,.875],78:[0,.69444,.08094,0,.70834],79:[0,.69444,.07555,0,.73611],80:[0,.69444,.08293,0,.63889],81:[.125,.69444,.07555,0,.73611],82:[0,.69444,.08293,0,.64584],83:[0,.69444,.09205,0,.55556],84:[0,.69444,.13372,0,.68056],85:[0,.69444,.08094,0,.6875],86:[0,.69444,.1615,0,.66667],87:[0,.69444,.1615,0,.94445],88:[0,.69444,.13372,0,.66667],89:[0,.69444,.17261,0,.66667],90:[0,.69444,.11983,0,.61111],91:[.25,.75,.15942,0,.28889],93:[.25,.75,.08719,0,.28889],94:[0,.69444,.0799,0,.5],95:[.35,.09444,.08616,0,.5],97:[0,.44444,.00981,0,.48056],98:[0,.69444,.03057,0,.51667],99:[0,.44444,.08336,0,.44445],100:[0,.69444,.09483,0,.51667],101:[0,.44444,.06778,0,.44445],102:[0,.69444,.21705,0,.30556],103:[.19444,.44444,.10836,0,.5],104:[0,.69444,.01778,0,.51667],105:[0,.67937,.09718,0,.23889],106:[.19444,.67937,.09162,0,.26667],107:[0,.69444,.08336,0,.48889],108:[0,.69444,.09483,0,.23889],109:[0,.44444,.01778,0,.79445],110:[0,.44444,.01778,0,.51667],111:[0,.44444,.06613,0,.5],112:[.19444,.44444,.0389,0,.51667],113:[.19444,.44444,.04169,0,.51667],114:[0,.44444,.10836,0,.34167],115:[0,.44444,.0778,0,.38333],116:[0,.57143,.07225,0,.36111],117:[0,.44444,.04169,0,.51667],118:[0,.44444,.10836,0,.46111],119:[0,.44444,.10836,0,.68334],120:[0,.44444,.09169,0,.46111],121:[.19444,.44444,.10836,0,.46111],122:[0,.44444,.08752,0,.43472],126:[.35,.32659,.08826,0,.5],160:[0,0,0,0,.25],168:[0,.67937,.06385,0,.5],176:[0,.69444,0,0,.73752],184:[.17014,0,0,0,.44445],305:[0,.44444,.04169,0,.23889],567:[.19444,.44444,.04169,0,.26667],710:[0,.69444,.0799,0,.5],711:[0,.63194,.08432,0,.5],713:[0,.60889,.08776,0,.5],714:[0,.69444,.09205,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,.09483,0,.5],729:[0,.67937,.07774,0,.27778],730:[0,.69444,0,0,.73752],732:[0,.67659,.08826,0,.5],733:[0,.69444,.09205,0,.5],915:[0,.69444,.13372,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,.07555,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,.12816,0,.66667],928:[0,.69444,.08094,0,.70834],931:[0,.69444,.11983,0,.72222],933:[0,.69444,.09031,0,.77778],934:[0,.69444,.04603,0,.72222],936:[0,.69444,.09031,0,.77778],937:[0,.69444,.08293,0,.72222],8211:[0,.44444,.08616,0,.5],8212:[0,.44444,.08616,0,1],8216:[0,.69444,.07816,0,.27778],8217:[0,.69444,.07816,0,.27778],8220:[0,.69444,.14205,0,.5],8221:[0,.69444,.00316,0,.5]},"SansSerif-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.31945],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.75834],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,0,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.65556,0,0,.5],49:[0,.65556,0,0,.5],50:[0,.65556,0,0,.5],51:[0,.65556,0,0,.5],52:[0,.65556,0,0,.5],53:[0,.65556,0,0,.5],54:[0,.65556,0,0,.5],55:[0,.65556,0,0,.5],56:[0,.65556,0,0,.5],57:[0,.65556,0,0,.5],58:[0,.44444,0,0,.27778],59:[.125,.44444,0,0,.27778],61:[-.13,.37,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,0,0,.66667],67:[0,.69444,0,0,.63889],68:[0,.69444,0,0,.72223],69:[0,.69444,0,0,.59722],70:[0,.69444,0,0,.56945],71:[0,.69444,0,0,.66667],72:[0,.69444,0,0,.70834],73:[0,.69444,0,0,.27778],74:[0,.69444,0,0,.47222],75:[0,.69444,0,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,0,0,.875],78:[0,.69444,0,0,.70834],79:[0,.69444,0,0,.73611],80:[0,.69444,0,0,.63889],81:[.125,.69444,0,0,.73611],82:[0,.69444,0,0,.64584],83:[0,.69444,0,0,.55556],84:[0,.69444,0,0,.68056],85:[0,.69444,0,0,.6875],86:[0,.69444,.01389,0,.66667],87:[0,.69444,.01389,0,.94445],88:[0,.69444,0,0,.66667],89:[0,.69444,.025,0,.66667],90:[0,.69444,0,0,.61111],91:[.25,.75,0,0,.28889],93:[.25,.75,0,0,.28889],94:[0,.69444,0,0,.5],95:[.35,.09444,.02778,0,.5],97:[0,.44444,0,0,.48056],98:[0,.69444,0,0,.51667],99:[0,.44444,0,0,.44445],100:[0,.69444,0,0,.51667],101:[0,.44444,0,0,.44445],102:[0,.69444,.06944,0,.30556],103:[.19444,.44444,.01389,0,.5],104:[0,.69444,0,0,.51667],105:[0,.67937,0,0,.23889],106:[.19444,.67937,0,0,.26667],107:[0,.69444,0,0,.48889],108:[0,.69444,0,0,.23889],109:[0,.44444,0,0,.79445],110:[0,.44444,0,0,.51667],111:[0,.44444,0,0,.5],112:[.19444,.44444,0,0,.51667],113:[.19444,.44444,0,0,.51667],114:[0,.44444,.01389,0,.34167],115:[0,.44444,0,0,.38333],116:[0,.57143,0,0,.36111],117:[0,.44444,0,0,.51667],118:[0,.44444,.01389,0,.46111],119:[0,.44444,.01389,0,.68334],120:[0,.44444,0,0,.46111],121:[.19444,.44444,.01389,0,.46111],122:[0,.44444,0,0,.43472],126:[.35,.32659,0,0,.5],160:[0,0,0,0,.25],168:[0,.67937,0,0,.5],176:[0,.69444,0,0,.66667],184:[.17014,0,0,0,.44445],305:[0,.44444,0,0,.23889],567:[.19444,.44444,0,0,.26667],710:[0,.69444,0,0,.5],711:[0,.63194,0,0,.5],713:[0,.60889,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.67937,0,0,.27778],730:[0,.69444,0,0,.66667],732:[0,.67659,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.69444,0,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,0,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,0,0,.66667],928:[0,.69444,0,0,.70834],931:[0,.69444,0,0,.72222],933:[0,.69444,0,0,.77778],934:[0,.69444,0,0,.72222],936:[0,.69444,0,0,.77778],937:[0,.69444,0,0,.72222],8211:[0,.44444,.02778,0,.5],8212:[0,.44444,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5]},"Script-Regular":{32:[0,0,0,0,.25],65:[0,.7,.22925,0,.80253],66:[0,.7,.04087,0,.90757],67:[0,.7,.1689,0,.66619],68:[0,.7,.09371,0,.77443],69:[0,.7,.18583,0,.56162],70:[0,.7,.13634,0,.89544],71:[0,.7,.17322,0,.60961],72:[0,.7,.29694,0,.96919],73:[0,.7,.19189,0,.80907],74:[.27778,.7,.19189,0,1.05159],75:[0,.7,.31259,0,.91364],76:[0,.7,.19189,0,.87373],77:[0,.7,.15981,0,1.08031],78:[0,.7,.3525,0,.9015],79:[0,.7,.08078,0,.73787],80:[0,.7,.08078,0,1.01262],81:[0,.7,.03305,0,.88282],82:[0,.7,.06259,0,.85],83:[0,.7,.19189,0,.86767],84:[0,.7,.29087,0,.74697],85:[0,.7,.25815,0,.79996],86:[0,.7,.27523,0,.62204],87:[0,.7,.27523,0,.80532],88:[0,.7,.26006,0,.94445],89:[0,.7,.2939,0,.70961],90:[0,.7,.24037,0,.8212],160:[0,0,0,0,.25]},"Size1-Regular":{32:[0,0,0,0,.25],40:[.35001,.85,0,0,.45834],41:[.35001,.85,0,0,.45834],47:[.35001,.85,0,0,.57778],91:[.35001,.85,0,0,.41667],92:[.35001,.85,0,0,.57778],93:[.35001,.85,0,0,.41667],123:[.35001,.85,0,0,.58334],125:[.35001,.85,0,0,.58334],160:[0,0,0,0,.25],710:[0,.72222,0,0,.55556],732:[0,.72222,0,0,.55556],770:[0,.72222,0,0,.55556],771:[0,.72222,0,0,.55556],8214:[-99e-5,.601,0,0,.77778],8593:[1e-5,.6,0,0,.66667],8595:[1e-5,.6,0,0,.66667],8657:[1e-5,.6,0,0,.77778],8659:[1e-5,.6,0,0,.77778],8719:[.25001,.75,0,0,.94445],8720:[.25001,.75,0,0,.94445],8721:[.25001,.75,0,0,1.05556],8730:[.35001,.85,0,0,1],8739:[-.00599,.606,0,0,.33333],8741:[-.00599,.606,0,0,.55556],8747:[.30612,.805,.19445,0,.47222],8748:[.306,.805,.19445,0,.47222],8749:[.306,.805,.19445,0,.47222],8750:[.30612,.805,.19445,0,.47222],8896:[.25001,.75,0,0,.83334],8897:[.25001,.75,0,0,.83334],8898:[.25001,.75,0,0,.83334],8899:[.25001,.75,0,0,.83334],8968:[.35001,.85,0,0,.47222],8969:[.35001,.85,0,0,.47222],8970:[.35001,.85,0,0,.47222],8971:[.35001,.85,0,0,.47222],9168:[-99e-5,.601,0,0,.66667],10216:[.35001,.85,0,0,.47222],10217:[.35001,.85,0,0,.47222],10752:[.25001,.75,0,0,1.11111],10753:[.25001,.75,0,0,1.11111],10754:[.25001,.75,0,0,1.11111],10756:[.25001,.75,0,0,.83334],10758:[.25001,.75,0,0,.83334]},"Size2-Regular":{32:[0,0,0,0,.25],40:[.65002,1.15,0,0,.59722],41:[.65002,1.15,0,0,.59722],47:[.65002,1.15,0,0,.81111],91:[.65002,1.15,0,0,.47222],92:[.65002,1.15,0,0,.81111],93:[.65002,1.15,0,0,.47222],123:[.65002,1.15,0,0,.66667],125:[.65002,1.15,0,0,.66667],160:[0,0,0,0,.25],710:[0,.75,0,0,1],732:[0,.75,0,0,1],770:[0,.75,0,0,1],771:[0,.75,0,0,1],8719:[.55001,1.05,0,0,1.27778],8720:[.55001,1.05,0,0,1.27778],8721:[.55001,1.05,0,0,1.44445],8730:[.65002,1.15,0,0,1],8747:[.86225,1.36,.44445,0,.55556],8748:[.862,1.36,.44445,0,.55556],8749:[.862,1.36,.44445,0,.55556],8750:[.86225,1.36,.44445,0,.55556],8896:[.55001,1.05,0,0,1.11111],8897:[.55001,1.05,0,0,1.11111],8898:[.55001,1.05,0,0,1.11111],8899:[.55001,1.05,0,0,1.11111],8968:[.65002,1.15,0,0,.52778],8969:[.65002,1.15,0,0,.52778],8970:[.65002,1.15,0,0,.52778],8971:[.65002,1.15,0,0,.52778],10216:[.65002,1.15,0,0,.61111],10217:[.65002,1.15,0,0,.61111],10752:[.55001,1.05,0,0,1.51112],10753:[.55001,1.05,0,0,1.51112],10754:[.55001,1.05,0,0,1.51112],10756:[.55001,1.05,0,0,1.11111],10758:[.55001,1.05,0,0,1.11111]},"Size3-Regular":{32:[0,0,0,0,.25],40:[.95003,1.45,0,0,.73611],41:[.95003,1.45,0,0,.73611],47:[.95003,1.45,0,0,1.04445],91:[.95003,1.45,0,0,.52778],92:[.95003,1.45,0,0,1.04445],93:[.95003,1.45,0,0,.52778],123:[.95003,1.45,0,0,.75],125:[.95003,1.45,0,0,.75],160:[0,0,0,0,.25],710:[0,.75,0,0,1.44445],732:[0,.75,0,0,1.44445],770:[0,.75,0,0,1.44445],771:[0,.75,0,0,1.44445],8730:[.95003,1.45,0,0,1],8968:[.95003,1.45,0,0,.58334],8969:[.95003,1.45,0,0,.58334],8970:[.95003,1.45,0,0,.58334],8971:[.95003,1.45,0,0,.58334],10216:[.95003,1.45,0,0,.75],10217:[.95003,1.45,0,0,.75]},"Size4-Regular":{32:[0,0,0,0,.25],40:[1.25003,1.75,0,0,.79167],41:[1.25003,1.75,0,0,.79167],47:[1.25003,1.75,0,0,1.27778],91:[1.25003,1.75,0,0,.58334],92:[1.25003,1.75,0,0,1.27778],93:[1.25003,1.75,0,0,.58334],123:[1.25003,1.75,0,0,.80556],125:[1.25003,1.75,0,0,.80556],160:[0,0,0,0,.25],710:[0,.825,0,0,1.8889],732:[0,.825,0,0,1.8889],770:[0,.825,0,0,1.8889],771:[0,.825,0,0,1.8889],8730:[1.25003,1.75,0,0,1],8968:[1.25003,1.75,0,0,.63889],8969:[1.25003,1.75,0,0,.63889],8970:[1.25003,1.75,0,0,.63889],8971:[1.25003,1.75,0,0,.63889],9115:[.64502,1.155,0,0,.875],9116:[1e-5,.6,0,0,.875],9117:[.64502,1.155,0,0,.875],9118:[.64502,1.155,0,0,.875],9119:[1e-5,.6,0,0,.875],9120:[.64502,1.155,0,0,.875],9121:[.64502,1.155,0,0,.66667],9122:[-99e-5,.601,0,0,.66667],9123:[.64502,1.155,0,0,.66667],9124:[.64502,1.155,0,0,.66667],9125:[-99e-5,.601,0,0,.66667],9126:[.64502,1.155,0,0,.66667],9127:[1e-5,.9,0,0,.88889],9128:[.65002,1.15,0,0,.88889],9129:[.90001,0,0,0,.88889],9130:[0,.3,0,0,.88889],9131:[1e-5,.9,0,0,.88889],9132:[.65002,1.15,0,0,.88889],9133:[.90001,0,0,0,.88889],9143:[.88502,.915,0,0,1.05556],10216:[1.25003,1.75,0,0,.80556],10217:[1.25003,1.75,0,0,.80556],57344:[-.00499,.605,0,0,1.05556],57345:[-.00499,.605,0,0,1.05556],57680:[0,.12,0,0,.45],57681:[0,.12,0,0,.45],57682:[0,.12,0,0,.45],57683:[0,.12,0,0,.45]},"Typewriter-Regular":{32:[0,0,0,0,.525],33:[0,.61111,0,0,.525],34:[0,.61111,0,0,.525],35:[0,.61111,0,0,.525],36:[.08333,.69444,0,0,.525],37:[.08333,.69444,0,0,.525],38:[0,.61111,0,0,.525],39:[0,.61111,0,0,.525],40:[.08333,.69444,0,0,.525],41:[.08333,.69444,0,0,.525],42:[0,.52083,0,0,.525],43:[-.08056,.53055,0,0,.525],44:[.13889,.125,0,0,.525],45:[-.08056,.53055,0,0,.525],46:[0,.125,0,0,.525],47:[.08333,.69444,0,0,.525],48:[0,.61111,0,0,.525],49:[0,.61111,0,0,.525],50:[0,.61111,0,0,.525],51:[0,.61111,0,0,.525],52:[0,.61111,0,0,.525],53:[0,.61111,0,0,.525],54:[0,.61111,0,0,.525],55:[0,.61111,0,0,.525],56:[0,.61111,0,0,.525],57:[0,.61111,0,0,.525],58:[0,.43056,0,0,.525],59:[.13889,.43056,0,0,.525],60:[-.05556,.55556,0,0,.525],61:[-.19549,.41562,0,0,.525],62:[-.05556,.55556,0,0,.525],63:[0,.61111,0,0,.525],64:[0,.61111,0,0,.525],65:[0,.61111,0,0,.525],66:[0,.61111,0,0,.525],67:[0,.61111,0,0,.525],68:[0,.61111,0,0,.525],69:[0,.61111,0,0,.525],70:[0,.61111,0,0,.525],71:[0,.61111,0,0,.525],72:[0,.61111,0,0,.525],73:[0,.61111,0,0,.525],74:[0,.61111,0,0,.525],75:[0,.61111,0,0,.525],76:[0,.61111,0,0,.525],77:[0,.61111,0,0,.525],78:[0,.61111,0,0,.525],79:[0,.61111,0,0,.525],80:[0,.61111,0,0,.525],81:[.13889,.61111,0,0,.525],82:[0,.61111,0,0,.525],83:[0,.61111,0,0,.525],84:[0,.61111,0,0,.525],85:[0,.61111,0,0,.525],86:[0,.61111,0,0,.525],87:[0,.61111,0,0,.525],88:[0,.61111,0,0,.525],89:[0,.61111,0,0,.525],90:[0,.61111,0,0,.525],91:[.08333,.69444,0,0,.525],92:[.08333,.69444,0,0,.525],93:[.08333,.69444,0,0,.525],94:[0,.61111,0,0,.525],95:[.09514,0,0,0,.525],96:[0,.61111,0,0,.525],97:[0,.43056,0,0,.525],98:[0,.61111,0,0,.525],99:[0,.43056,0,0,.525],100:[0,.61111,0,0,.525],101:[0,.43056,0,0,.525],102:[0,.61111,0,0,.525],103:[.22222,.43056,0,0,.525],104:[0,.61111,0,0,.525],105:[0,.61111,0,0,.525],106:[.22222,.61111,0,0,.525],107:[0,.61111,0,0,.525],108:[0,.61111,0,0,.525],109:[0,.43056,0,0,.525],110:[0,.43056,0,0,.525],111:[0,.43056,0,0,.525],112:[.22222,.43056,0,0,.525],113:[.22222,.43056,0,0,.525],114:[0,.43056,0,0,.525],115:[0,.43056,0,0,.525],116:[0,.55358,0,0,.525],117:[0,.43056,0,0,.525],118:[0,.43056,0,0,.525],119:[0,.43056,0,0,.525],120:[0,.43056,0,0,.525],121:[.22222,.43056,0,0,.525],122:[0,.43056,0,0,.525],123:[.08333,.69444,0,0,.525],124:[.08333,.69444,0,0,.525],125:[.08333,.69444,0,0,.525],126:[0,.61111,0,0,.525],127:[0,.61111,0,0,.525],160:[0,0,0,0,.525],176:[0,.61111,0,0,.525],184:[.19445,0,0,0,.525],305:[0,.43056,0,0,.525],567:[.22222,.43056,0,0,.525],711:[0,.56597,0,0,.525],713:[0,.56555,0,0,.525],714:[0,.61111,0,0,.525],715:[0,.61111,0,0,.525],728:[0,.61111,0,0,.525],730:[0,.61111,0,0,.525],770:[0,.61111,0,0,.525],771:[0,.61111,0,0,.525],776:[0,.61111,0,0,.525],915:[0,.61111,0,0,.525],916:[0,.61111,0,0,.525],920:[0,.61111,0,0,.525],923:[0,.61111,0,0,.525],926:[0,.61111,0,0,.525],928:[0,.61111,0,0,.525],931:[0,.61111,0,0,.525],933:[0,.61111,0,0,.525],934:[0,.61111,0,0,.525],936:[0,.61111,0,0,.525],937:[0,.61111,0,0,.525],8216:[0,.61111,0,0,.525],8217:[0,.61111,0,0,.525],8242:[0,.61111,0,0,.525],9251:[.11111,.21944,0,0,.525]}},N={slant:[.25,.25,.25],space:[0,0,0],stretch:[0,0,0],shrink:[0,0,0],xHeight:[.431,.431,.431],quad:[1,1.171,1.472],extraSpace:[0,0,0],num1:[.677,.732,.925],num2:[.394,.384,.387],num3:[.444,.471,.504],denom1:[.686,.752,1.025],denom2:[.345,.344,.532],sup1:[.413,.503,.504],sup2:[.363,.431,.404],sup3:[.289,.286,.294],sub1:[.15,.143,.2],sub2:[.247,.286,.4],supDrop:[.386,.353,.494],subDrop:[.05,.071,.1],delim1:[2.39,1.7,1.98],delim2:[1.01,1.157,1.42],axisHeight:[.25,.25,.25],defaultRuleThickness:[.04,.049,.049],bigOpSpacing1:[.111,.111,.111],bigOpSpacing2:[.166,.166,.166],bigOpSpacing3:[.2,.2,.2],bigOpSpacing4:[.6,.611,.611],bigOpSpacing5:[.1,.143,.143],sqrtRuleThickness:[.04,.04,.04],ptPerEm:[10,10,10],doubleRuleSep:[.2,.2,.2],arrayRuleWidth:[.04,.04,.04],fboxsep:[.3,.3,.3],fboxrule:[.04,.04,.04]},q={"\xc5":"A","\xd0":"D","\xde":"o","\xe5":"a","\xf0":"d","\xfe":"o","\u0410":"A","\u0411":"B","\u0412":"B","\u0413":"F","\u0414":"A","\u0415":"E","\u0416":"K","\u0417":"3","\u0418":"N","\u0419":"N","\u041a":"K","\u041b":"N","\u041c":"M","\u041d":"H","\u041e":"O","\u041f":"N","\u0420":"P","\u0421":"C","\u0422":"T","\u0423":"y","\u0424":"O","\u0425":"X","\u0426":"U","\u0427":"h","\u0428":"W","\u0429":"W","\u042a":"B","\u042b":"X","\u042c":"B","\u042d":"3","\u042e":"X","\u042f":"R","\u0430":"a","\u0431":"b","\u0432":"a","\u0433":"r","\u0434":"y","\u0435":"e","\u0436":"m","\u0437":"e","\u0438":"n","\u0439":"n","\u043a":"n","\u043b":"n","\u043c":"m","\u043d":"n","\u043e":"o","\u043f":"n","\u0440":"p","\u0441":"c","\u0442":"o","\u0443":"y","\u0444":"b","\u0445":"x","\u0446":"n","\u0447":"n","\u0448":"w","\u0449":"w","\u044a":"a","\u044b":"m","\u044c":"a","\u044d":"e","\u044e":"m","\u044f":"r"};function I(e,t,r){if(!C[t])throw new Error("Font metrics not found for font: "+t+".");var a=e.charCodeAt(0),n=C[t][a];if(!n&&e[0]in q&&(a=q[e[0]].charCodeAt(0),n=C[t][a]),n||"text"!==r||z(a)&&(n=C[t][77]),n)return{depth:n[0],height:n[1],italic:n[2],skew:n[3],width:n[4]}}var R={};var H=[[1,1,1],[2,1,1],[3,1,1],[4,2,1],[5,2,1],[6,3,1],[7,4,2],[8,6,3],[9,7,6],[10,8,7],[11,10,9]],O=[.5,.6,.7,.8,.9,1,1.2,1.44,1.728,2.074,2.488],E=function(e,t){return t.size<2?e:H[e-1][t.size-1]};class L{constructor(e){this.style=void 0,this.color=void 0,this.size=void 0,this.textSize=void 0,this.phantom=void 0,this.font=void 0,this.fontFamily=void 0,this.fontWeight=void 0,this.fontShape=void 0,this.sizeMultiplier=void 0,this.maxSize=void 0,this.minRuleThickness=void 0,this._fontMetrics=void 0,this.style=e.style,this.color=e.color,this.size=e.size||L.BASESIZE,this.textSize=e.textSize||this.size,this.phantom=!!e.phantom,this.font=e.font||"",this.fontFamily=e.fontFamily||"",this.fontWeight=e.fontWeight||"",this.fontShape=e.fontShape||"",this.sizeMultiplier=O[this.size-1],this.maxSize=e.maxSize,this.minRuleThickness=e.minRuleThickness,this._fontMetrics=void 0}extend(e){var t={style:this.style,size:this.size,textSize:this.textSize,color:this.color,phantom:this.phantom,font:this.font,fontFamily:this.fontFamily,fontWeight:this.fontWeight,fontShape:this.fontShape,maxSize:this.maxSize,minRuleThickness:this.minRuleThickness};for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);return new L(t)}havingStyle(e){return this.style===e?this:this.extend({style:e,size:E(this.textSize,e)})}havingCrampedStyle(){return this.havingStyle(this.style.cramp())}havingSize(e){return this.size===e&&this.textSize===e?this:this.extend({style:this.style.text(),size:e,textSize:e,sizeMultiplier:O[e-1]})}havingBaseStyle(e){e=e||this.style.text();var t=E(L.BASESIZE,e);return this.size===t&&this.textSize===L.BASESIZE&&this.style===e?this:this.extend({style:e,size:t})}havingBaseSizing(){var e;switch(this.style.id){case 4:case 5:e=3;break;case 6:case 7:e=1;break;default:e=6}return this.extend({style:this.style.text(),size:e})}withColor(e){return this.extend({color:e})}withPhantom(){return this.extend({phantom:!0})}withFont(e){return this.extend({font:e})}withTextFontFamily(e){return this.extend({fontFamily:e,font:""})}withTextFontWeight(e){return this.extend({fontWeight:e,font:""})}withTextFontShape(e){return this.extend({fontShape:e,font:""})}sizingClasses(e){return e.size!==this.size?["sizing","reset-size"+e.size,"size"+this.size]:[]}baseSizingClasses(){return this.size!==L.BASESIZE?["sizing","reset-size"+this.size,"size"+L.BASESIZE]:[]}fontMetrics(){return this._fontMetrics||(this._fontMetrics=function(e){var t;if(!R[t=e>=5?0:e>=3?1:2]){var r=R[t]={cssEmPerMu:N.quad[t]/18};for(var a in N)N.hasOwnProperty(a)&&(r[a]=N[a][t])}return R[t]}(this.size)),this._fontMetrics}getColor(){return this.phantom?"transparent":this.color}}L.BASESIZE=6;var D={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:1.00375,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:1.00375},V={ex:!0,em:!0,mu:!0},P=function(e){return"string"!=typeof e&&(e=e.unit),e in D||e in V||"ex"===e},F=function(e,t){var r;if(e.unit in D)r=D[e.unit]/t.fontMetrics().ptPerEm/t.sizeMultiplier;else if("mu"===e.unit)r=t.fontMetrics().cssEmPerMu;else{var a;if(a=t.style.isTight()?t.havingStyle(t.style.text()):t,"ex"===e.unit)r=a.fontMetrics().xHeight;else{if("em"!==e.unit)throw new i("Invalid unit: '"+e.unit+"'");r=a.fontMetrics().quad}a!==t&&(r*=a.sizeMultiplier/t.sizeMultiplier)}return Math.min(e.number*r,t.maxSize)},G=function(e){return+e.toFixed(4)+"em"},U=function(e){return e.filter(e=>e).join(" ")},Y=function(e,t,r){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=r||{},t){t.style.isTight()&&this.classes.push("mtight");var a=t.getColor();a&&(this.style.color=a)}},X=function(e){var t=document.createElement(e);for(var r in t.className=U(this.classes),this.style)this.style.hasOwnProperty(r)&&(t.style[r]=this.style[r]);for(var a in this.attributes)this.attributes.hasOwnProperty(a)&&t.setAttribute(a,this.attributes[a]);for(var n=0;n<this.children.length;n++)t.appendChild(this.children[n].toNode());return t},W=/[\s"'>/=\x00-\x1f]/,_=function(e){var t="<"+e;this.classes.length&&(t+=' class="'+m.escape(U(this.classes))+'"');var r="";for(var a in this.style)this.style.hasOwnProperty(a)&&(r+=m.hyphenate(a)+":"+this.style[a]+";");for(var n in r&&(t+=' style="'+m.escape(r)+'"'),this.attributes)if(this.attributes.hasOwnProperty(n)){if(W.test(n))throw new i("Invalid attribute name '"+n+"'");t+=" "+n+'="'+m.escape(this.attributes[n])+'"'}t+=">";for(var o=0;o<this.children.length;o++)t+=this.children[o].toMarkup();return t+="</"+e+">"};class j{constructor(e,t,r,a){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,Y.call(this,e,r,a),this.children=t||[]}setAttribute(e,t){this.attributes[e]=t}hasClass(e){return this.classes.includes(e)}toNode(){return X.call(this,"span")}toMarkup(){return _.call(this,"span")}}class ${constructor(e,t,r,a){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,Y.call(this,t,a),this.children=r||[],this.setAttribute("href",e)}setAttribute(e,t){this.attributes[e]=t}hasClass(e){return this.classes.includes(e)}toNode(){return X.call(this,"a")}toMarkup(){return _.call(this,"a")}}class Z{constructor(e,t,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=t,this.src=e,this.classes=["mord"],this.style=r}hasClass(e){return this.classes.includes(e)}toNode(){var e=document.createElement("img");for(var t in e.src=this.src,e.alt=this.alt,e.className="mord",this.style)this.style.hasOwnProperty(t)&&(e.style[t]=this.style[t]);return e}toMarkup(){var e='<img src="'+m.escape(this.src)+'" alt="'+m.escape(this.alt)+'"',t="";for(var r in this.style)this.style.hasOwnProperty(r)&&(t+=m.hyphenate(r)+":"+this.style[r]+";");return t&&(e+=' style="'+m.escape(t)+'"'),e+="'/>"}}var K={"\xee":"\u0131\u0302","\xef":"\u0131\u0308","\xed":"\u0131\u0301","\xec":"\u0131\u0300"};class J{constructor(e,t,r,a,n,i,o,s){this.text=void 0,this.height=void 0,this.depth=void 0,this.italic=void 0,this.skew=void 0,this.width=void 0,this.maxFontSize=void 0,this.classes=void 0,this.style=void 0,this.text=e,this.height=t||0,this.depth=r||0,this.italic=a||0,this.skew=n||0,this.width=i||0,this.classes=o||[],this.style=s||{},this.maxFontSize=0;var l=function(e){for(var t=0;t<S.length;t++)for(var r=S[t],a=0;a<r.blocks.length;a++){var n=r.blocks[a];if(e>=n[0]&&e<=n[1])return r.name}return null}(this.text.charCodeAt(0));l&&this.classes.push(l+"_fallback"),/[\xee\xef\xed\xec]/.test(this.text)&&(this.text=K[this.text])}hasClass(e){return this.classes.includes(e)}toNode(){var e=document.createTextNode(this.text),t=null;for(var r in this.italic>0&&((t=document.createElement("span")).style.marginRight=G(this.italic)),this.classes.length>0&&((t=t||document.createElement("span")).className=U(this.classes)),this.style)this.style.hasOwnProperty(r)&&((t=t||document.createElement("span")).style[r]=this.style[r]);return t?(t.appendChild(e),t):e}toMarkup(){var e=!1,t="<span";this.classes.length&&(e=!0,t+=' class="',t+=m.escape(U(this.classes)),t+='"');var r="";for(var a in this.italic>0&&(r+="margin-right:"+this.italic+"em;"),this.style)this.style.hasOwnProperty(a)&&(r+=m.hyphenate(a)+":"+this.style[a]+";");r&&(e=!0,t+=' style="'+m.escape(r)+'"');var n=m.escape(this.text);return e?(t+=">",t+=n,t+="</span>"):n}}class Q{constructor(e,t){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=t||{}}toNode(){var e=document.createElementNS("http://www.w3.org/2000/svg","svg");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);for(var r=0;r<this.children.length;r++)e.appendChild(this.children[r].toNode());return e}toMarkup(){var e='<svg xmlns="http://www.w3.org/2000/svg"';for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&(e+=" "+t+'="'+m.escape(this.attributes[t])+'"');e+=">";for(var r=0;r<this.children.length;r++)e+=this.children[r].toMarkup();return e+="</svg>"}}class ee{constructor(e,t){this.pathName=void 0,this.alternate=void 0,this.pathName=e,this.alternate=t}toNode(){var e=document.createElementNS("http://www.w3.org/2000/svg","path");return this.alternate?e.setAttribute("d",this.alternate):e.setAttribute("d",T[this.pathName]),e}toMarkup(){return this.alternate?'<path d="'+m.escape(this.alternate)+'"/>':'<path d="'+m.escape(T[this.pathName])+'"/>'}}class te{constructor(e){this.attributes=void 0,this.attributes=e||{}}toNode(){var e=document.createElementNS("http://www.w3.org/2000/svg","line");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);return e}toMarkup(){var e="<line";for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&(e+=" "+t+'="'+m.escape(this.attributes[t])+'"');return e+="/>"}}function re(e){if(e instanceof J)return e;throw new Error("Expected symbolNode but got "+String(e)+".")}var ae={bin:1,close:1,inner:1,open:1,punct:1,rel:1},ne={"accent-token":1,mathord:1,"op-token":1,spacing:1,textord:1},ie={math:{},text:{}};function oe(e,t,r,a,n,i){ie[e][n]={font:t,group:r,replace:a},i&&a&&(ie[e][a]=ie[e][n])}var se="math",le="text",he="main",me="ams",ce="accent-token",pe="bin",ue="close",de="inner",ge="mathord",fe="op-token",ve="open",be="punct",ye="rel",xe="spacing",we="textord";oe(se,he,ye,"\u2261","\\equiv",!0),oe(se,he,ye,"\u227a","\\prec",!0),oe(se,he,ye,"\u227b","\\succ",!0),oe(se,he,ye,"\u223c","\\sim",!0),oe(se,he,ye,"\u22a5","\\perp"),oe(se,he,ye,"\u2aaf","\\preceq",!0),oe(se,he,ye,"\u2ab0","\\succeq",!0),oe(se,he,ye,"\u2243","\\simeq",!0),oe(se,he,ye,"\u2223","\\mid",!0),oe(se,he,ye,"\u226a","\\ll",!0),oe(se,he,ye,"\u226b","\\gg",!0),oe(se,he,ye,"\u224d","\\asymp",!0),oe(se,he,ye,"\u2225","\\parallel"),oe(se,he,ye,"\u22c8","\\bowtie",!0),oe(se,he,ye,"\u2323","\\smile",!0),oe(se,he,ye,"\u2291","\\sqsubseteq",!0),oe(se,he,ye,"\u2292","\\sqsupseteq",!0),oe(se,he,ye,"\u2250","\\doteq",!0),oe(se,he,ye,"\u2322","\\frown",!0),oe(se,he,ye,"\u220b","\\ni",!0),oe(se,he,ye,"\u221d","\\propto",!0),oe(se,he,ye,"\u22a2","\\vdash",!0),oe(se,he,ye,"\u22a3","\\dashv",!0),oe(se,he,ye,"\u220b","\\owns"),oe(se,he,be,".","\\ldotp"),oe(se,he,be,"\u22c5","\\cdotp"),oe(se,he,we,"#","\\#"),oe(le,he,we,"#","\\#"),oe(se,he,we,"&","\\&"),oe(le,he,we,"&","\\&"),oe(se,he,we,"\u2135","\\aleph",!0),oe(se,he,we,"\u2200","\\forall",!0),oe(se,he,we,"\u210f","\\hbar",!0),oe(se,he,we,"\u2203","\\exists",!0),oe(se,he,we,"\u2207","\\nabla",!0),oe(se,he,we,"\u266d","\\flat",!0),oe(se,he,we,"\u2113","\\ell",!0),oe(se,he,we,"\u266e","\\natural",!0),oe(se,he,we,"\u2663","\\clubsuit",!0),oe(se,he,we,"\u2118","\\wp",!0),oe(se,he,we,"\u266f","\\sharp",!0),oe(se,he,we,"\u2662","\\diamondsuit",!0),oe(se,he,we,"\u211c","\\Re",!0),oe(se,he,we,"\u2661","\\heartsuit",!0),oe(se,he,we,"\u2111","\\Im",!0),oe(se,he,we,"\u2660","\\spadesuit",!0),oe(se,he,we,"\xa7","\\S",!0),oe(le,he,we,"\xa7","\\S"),oe(se,he,we,"\xb6","\\P",!0),oe(le,he,we,"\xb6","\\P"),oe(se,he,we,"\u2020","\\dag"),oe(le,he,we,"\u2020","\\dag"),oe(le,he,we,"\u2020","\\textdagger"),oe(se,he,we,"\u2021","\\ddag"),oe(le,he,we,"\u2021","\\ddag"),oe(le,he,we,"\u2021","\\textdaggerdbl"),oe(se,he,ue,"\u23b1","\\rmoustache",!0),oe(se,he,ve,"\u23b0","\\lmoustache",!0),oe(se,he,ue,"\u27ef","\\rgroup",!0),oe(se,he,ve,"\u27ee","\\lgroup",!0),oe(se,he,pe,"\u2213","\\mp",!0),oe(se,he,pe,"\u2296","\\ominus",!0),oe(se,he,pe,"\u228e","\\uplus",!0),oe(se,he,pe,"\u2293","\\sqcap",!0),oe(se,he,pe,"\u2217","\\ast"),oe(se,he,pe,"\u2294","\\sqcup",!0),oe(se,he,pe,"\u25ef","\\bigcirc",!0),oe(se,he,pe,"\u2219","\\bullet",!0),oe(se,he,pe,"\u2021","\\ddagger"),oe(se,he,pe,"\u2240","\\wr",!0),oe(se,he,pe,"\u2a3f","\\amalg"),oe(se,he,pe,"&","\\And"),oe(se,he,ye,"\u27f5","\\longleftarrow",!0),oe(se,he,ye,"\u21d0","\\Leftarrow",!0),oe(se,he,ye,"\u27f8","\\Longleftarrow",!0),oe(se,he,ye,"\u27f6","\\longrightarrow",!0),oe(se,he,ye,"\u21d2","\\Rightarrow",!0),oe(se,he,ye,"\u27f9","\\Longrightarrow",!0),oe(se,he,ye,"\u2194","\\leftrightarrow",!0),oe(se,he,ye,"\u27f7","\\longleftrightarrow",!0),oe(se,he,ye,"\u21d4","\\Leftrightarrow",!0),oe(se,he,ye,"\u27fa","\\Longleftrightarrow",!0),oe(se,he,ye,"\u21a6","\\mapsto",!0),oe(se,he,ye,"\u27fc","\\longmapsto",!0),oe(se,he,ye,"\u2197","\\nearrow",!0),oe(se,he,ye,"\u21a9","\\hookleftarrow",!0),oe(se,he,ye,"\u21aa","\\hookrightarrow",!0),oe(se,he,ye,"\u2198","\\searrow",!0),oe(se,he,ye,"\u21bc","\\leftharpoonup",!0),oe(se,he,ye,"\u21c0","\\rightharpoonup",!0),oe(se,he,ye,"\u2199","\\swarrow",!0),oe(se,he,ye,"\u21bd","\\leftharpoondown",!0),oe(se,he,ye,"\u21c1","\\rightharpoondown",!0),oe(se,he,ye,"\u2196","\\nwarrow",!0),oe(se,he,ye,"\u21cc","\\rightleftharpoons",!0),oe(se,me,ye,"\u226e","\\nless",!0),oe(se,me,ye,"\ue010","\\@nleqslant"),oe(se,me,ye,"\ue011","\\@nleqq"),oe(se,me,ye,"\u2a87","\\lneq",!0),oe(se,me,ye,"\u2268","\\lneqq",!0),oe(se,me,ye,"\ue00c","\\@lvertneqq"),oe(se,me,ye,"\u22e6","\\lnsim",!0),oe(se,me,ye,"\u2a89","\\lnapprox",!0),oe(se,me,ye,"\u2280","\\nprec",!0),oe(se,me,ye,"\u22e0","\\npreceq",!0),oe(se,me,ye,"\u22e8","\\precnsim",!0),oe(se,me,ye,"\u2ab9","\\precnapprox",!0),oe(se,me,ye,"\u2241","\\nsim",!0),oe(se,me,ye,"\ue006","\\@nshortmid"),oe(se,me,ye,"\u2224","\\nmid",!0),oe(se,me,ye,"\u22ac","\\nvdash",!0),oe(se,me,ye,"\u22ad","\\nvDash",!0),oe(se,me,ye,"\u22ea","\\ntriangleleft"),oe(se,me,ye,"\u22ec","\\ntrianglelefteq",!0),oe(se,me,ye,"\u228a","\\subsetneq",!0),oe(se,me,ye,"\ue01a","\\@varsubsetneq"),oe(se,me,ye,"\u2acb","\\subsetneqq",!0),oe(se,me,ye,"\ue017","\\@varsubsetneqq"),oe(se,me,ye,"\u226f","\\ngtr",!0),oe(se,me,ye,"\ue00f","\\@ngeqslant"),oe(se,me,ye,"\ue00e","\\@ngeqq"),oe(se,me,ye,"\u2a88","\\gneq",!0),oe(se,me,ye,"\u2269","\\gneqq",!0),oe(se,me,ye,"\ue00d","\\@gvertneqq"),oe(se,me,ye,"\u22e7","\\gnsim",!0),oe(se,me,ye,"\u2a8a","\\gnapprox",!0),oe(se,me,ye,"\u2281","\\nsucc",!0),oe(se,me,ye,"\u22e1","\\nsucceq",!0),oe(se,me,ye,"\u22e9","\\succnsim",!0),oe(se,me,ye,"\u2aba","\\succnapprox",!0),oe(se,me,ye,"\u2246","\\ncong",!0),oe(se,me,ye,"\ue007","\\@nshortparallel"),oe(se,me,ye,"\u2226","\\nparallel",!0),oe(se,me,ye,"\u22af","\\nVDash",!0),oe(se,me,ye,"\u22eb","\\ntriangleright"),oe(se,me,ye,"\u22ed","\\ntrianglerighteq",!0),oe(se,me,ye,"\ue018","\\@nsupseteqq"),oe(se,me,ye,"\u228b","\\supsetneq",!0),oe(se,me,ye,"\ue01b","\\@varsupsetneq"),oe(se,me,ye,"\u2acc","\\supsetneqq",!0),oe(se,me,ye,"\ue019","\\@varsupsetneqq"),oe(se,me,ye,"\u22ae","\\nVdash",!0),oe(se,me,ye,"\u2ab5","\\precneqq",!0),oe(se,me,ye,"\u2ab6","\\succneqq",!0),oe(se,me,ye,"\ue016","\\@nsubseteqq"),oe(se,me,pe,"\u22b4","\\unlhd"),oe(se,me,pe,"\u22b5","\\unrhd"),oe(se,me,ye,"\u219a","\\nleftarrow",!0),oe(se,me,ye,"\u219b","\\nrightarrow",!0),oe(se,me,ye,"\u21cd","\\nLeftarrow",!0),oe(se,me,ye,"\u21cf","\\nRightarrow",!0),oe(se,me,ye,"\u21ae","\\nleftrightarrow",!0),oe(se,me,ye,"\u21ce","\\nLeftrightarrow",!0),oe(se,me,ye,"\u25b3","\\vartriangle"),oe(se,me,we,"\u210f","\\hslash"),oe(se,me,we,"\u25bd","\\triangledown"),oe(se,me,we,"\u25ca","\\lozenge"),oe(se,me,we,"\u24c8","\\circledS"),oe(se,me,we,"\xae","\\circledR"),oe(le,me,we,"\xae","\\circledR"),oe(se,me,we,"\u2221","\\measuredangle",!0),oe(se,me,we,"\u2204","\\nexists"),oe(se,me,we,"\u2127","\\mho"),oe(se,me,we,"\u2132","\\Finv",!0),oe(se,me,we,"\u2141","\\Game",!0),oe(se,me,we,"\u2035","\\backprime"),oe(se,me,we,"\u25b2","\\blacktriangle"),oe(se,me,we,"\u25bc","\\blacktriangledown"),oe(se,me,we,"\u25a0","\\blacksquare"),oe(se,me,we,"\u29eb","\\blacklozenge"),oe(se,me,we,"\u2605","\\bigstar"),oe(se,me,we,"\u2222","\\sphericalangle",!0),oe(se,me,we,"\u2201","\\complement",!0),oe(se,me,we,"\xf0","\\eth",!0),oe(le,he,we,"\xf0","\xf0"),oe(se,me,we,"\u2571","\\diagup"),oe(se,me,we,"\u2572","\\diagdown"),oe(se,me,we,"\u25a1","\\square"),oe(se,me,we,"\u25a1","\\Box"),oe(se,me,we,"\u25ca","\\Diamond"),oe(se,me,we,"\xa5","\\yen",!0),oe(le,me,we,"\xa5","\\yen",!0),oe(se,me,we,"\u2713","\\checkmark",!0),oe(le,me,we,"\u2713","\\checkmark"),oe(se,me,we,"\u2136","\\beth",!0),oe(se,me,we,"\u2138","\\daleth",!0),oe(se,me,we,"\u2137","\\gimel",!0),oe(se,me,we,"\u03dd","\\digamma",!0),oe(se,me,we,"\u03f0","\\varkappa"),oe(se,me,ve,"\u250c","\\@ulcorner",!0),oe(se,me,ue,"\u2510","\\@urcorner",!0),oe(se,me,ve,"\u2514","\\@llcorner",!0),oe(se,me,ue,"\u2518","\\@lrcorner",!0),oe(se,me,ye,"\u2266","\\leqq",!0),oe(se,me,ye,"\u2a7d","\\leqslant",!0),oe(se,me,ye,"\u2a95","\\eqslantless",!0),oe(se,me,ye,"\u2272","\\lesssim",!0),oe(se,me,ye,"\u2a85","\\lessapprox",!0),oe(se,me,ye,"\u224a","\\approxeq",!0),oe(se,me,pe,"\u22d6","\\lessdot"),oe(se,me,ye,"\u22d8","\\lll",!0),oe(se,me,ye,"\u2276","\\lessgtr",!0),oe(se,me,ye,"\u22da","\\lesseqgtr",!0),oe(se,me,ye,"\u2a8b","\\lesseqqgtr",!0),oe(se,me,ye,"\u2251","\\doteqdot"),oe(se,me,ye,"\u2253","\\risingdotseq",!0),oe(se,me,ye,"\u2252","\\fallingdotseq",!0),oe(se,me,ye,"\u223d","\\backsim",!0),oe(se,me,ye,"\u22cd","\\backsimeq",!0),oe(se,me,ye,"\u2ac5","\\subseteqq",!0),oe(se,me,ye,"\u22d0","\\Subset",!0),oe(se,me,ye,"\u228f","\\sqsubset",!0),oe(se,me,ye,"\u227c","\\preccurlyeq",!0),oe(se,me,ye,"\u22de","\\curlyeqprec",!0),oe(se,me,ye,"\u227e","\\precsim",!0),oe(se,me,ye,"\u2ab7","\\precapprox",!0),oe(se,me,ye,"\u22b2","\\vartriangleleft"),oe(se,me,ye,"\u22b4","\\trianglelefteq"),oe(se,me,ye,"\u22a8","\\vDash",!0),oe(se,me,ye,"\u22aa","\\Vvdash",!0),oe(se,me,ye,"\u2323","\\smallsmile"),oe(se,me,ye,"\u2322","\\smallfrown"),oe(se,me,ye,"\u224f","\\bumpeq",!0),oe(se,me,ye,"\u224e","\\Bumpeq",!0),oe(se,me,ye,"\u2267","\\geqq",!0),oe(se,me,ye,"\u2a7e","\\geqslant",!0),oe(se,me,ye,"\u2a96","\\eqslantgtr",!0),oe(se,me,ye,"\u2273","\\gtrsim",!0),oe(se,me,ye,"\u2a86","\\gtrapprox",!0),oe(se,me,pe,"\u22d7","\\gtrdot"),oe(se,me,ye,"\u22d9","\\ggg",!0),oe(se,me,ye,"\u2277","\\gtrless",!0),oe(se,me,ye,"\u22db","\\gtreqless",!0),oe(se,me,ye,"\u2a8c","\\gtreqqless",!0),oe(se,me,ye,"\u2256","\\eqcirc",!0),oe(se,me,ye,"\u2257","\\circeq",!0),oe(se,me,ye,"\u225c","\\triangleq",!0),oe(se,me,ye,"\u223c","\\thicksim"),oe(se,me,ye,"\u2248","\\thickapprox"),oe(se,me,ye,"\u2ac6","\\supseteqq",!0),oe(se,me,ye,"\u22d1","\\Supset",!0),oe(se,me,ye,"\u2290","\\sqsupset",!0),oe(se,me,ye,"\u227d","\\succcurlyeq",!0),oe(se,me,ye,"\u22df","\\curlyeqsucc",!0),oe(se,me,ye,"\u227f","\\succsim",!0),oe(se,me,ye,"\u2ab8","\\succapprox",!0),oe(se,me,ye,"\u22b3","\\vartriangleright"),oe(se,me,ye,"\u22b5","\\trianglerighteq"),oe(se,me,ye,"\u22a9","\\Vdash",!0),oe(se,me,ye,"\u2223","\\shortmid"),oe(se,me,ye,"\u2225","\\shortparallel"),oe(se,me,ye,"\u226c","\\between",!0),oe(se,me,ye,"\u22d4","\\pitchfork",!0),oe(se,me,ye,"\u221d","\\varpropto"),oe(se,me,ye,"\u25c0","\\blacktriangleleft"),oe(se,me,ye,"\u2234","\\therefore",!0),oe(se,me,ye,"\u220d","\\backepsilon"),oe(se,me,ye,"\u25b6","\\blacktriangleright"),oe(se,me,ye,"\u2235","\\because",!0),oe(se,me,ye,"\u22d8","\\llless"),oe(se,me,ye,"\u22d9","\\gggtr"),oe(se,me,pe,"\u22b2","\\lhd"),oe(se,me,pe,"\u22b3","\\rhd"),oe(se,me,ye,"\u2242","\\eqsim",!0),oe(se,he,ye,"\u22c8","\\Join"),oe(se,me,ye,"\u2251","\\Doteq",!0),oe(se,me,pe,"\u2214","\\dotplus",!0),oe(se,me,pe,"\u2216","\\smallsetminus"),oe(se,me,pe,"\u22d2","\\Cap",!0),oe(se,me,pe,"\u22d3","\\Cup",!0),oe(se,me,pe,"\u2a5e","\\doublebarwedge",!0),oe(se,me,pe,"\u229f","\\boxminus",!0),oe(se,me,pe,"\u229e","\\boxplus",!0),oe(se,me,pe,"\u22c7","\\divideontimes",!0),oe(se,me,pe,"\u22c9","\\ltimes",!0),oe(se,me,pe,"\u22ca","\\rtimes",!0),oe(se,me,pe,"\u22cb","\\leftthreetimes",!0),oe(se,me,pe,"\u22cc","\\rightthreetimes",!0),oe(se,me,pe,"\u22cf","\\curlywedge",!0),oe(se,me,pe,"\u22ce","\\curlyvee",!0),oe(se,me,pe,"\u229d","\\circleddash",!0),oe(se,me,pe,"\u229b","\\circledast",!0),oe(se,me,pe,"\u22c5","\\centerdot"),oe(se,me,pe,"\u22ba","\\intercal",!0),oe(se,me,pe,"\u22d2","\\doublecap"),oe(se,me,pe,"\u22d3","\\doublecup"),oe(se,me,pe,"\u22a0","\\boxtimes",!0),oe(se,me,ye,"\u21e2","\\dashrightarrow",!0),oe(se,me,ye,"\u21e0","\\dashleftarrow",!0),oe(se,me,ye,"\u21c7","\\leftleftarrows",!0),oe(se,me,ye,"\u21c6","\\leftrightarrows",!0),oe(se,me,ye,"\u21da","\\Lleftarrow",!0),oe(se,me,ye,"\u219e","\\twoheadleftarrow",!0),oe(se,me,ye,"\u21a2","\\leftarrowtail",!0),oe(se,me,ye,"\u21ab","\\looparrowleft",!0),oe(se,me,ye,"\u21cb","\\leftrightharpoons",!0),oe(se,me,ye,"\u21b6","\\curvearrowleft",!0),oe(se,me,ye,"\u21ba","\\circlearrowleft",!0),oe(se,me,ye,"\u21b0","\\Lsh",!0),oe(se,me,ye,"\u21c8","\\upuparrows",!0),oe(se,me,ye,"\u21bf","\\upharpoonleft",!0),oe(se,me,ye,"\u21c3","\\downharpoonleft",!0),oe(se,he,ye,"\u22b6","\\origof",!0),oe(se,he,ye,"\u22b7","\\imageof",!0),oe(se,me,ye,"\u22b8","\\multimap",!0),oe(se,me,ye,"\u21ad","\\leftrightsquigarrow",!0),oe(se,me,ye,"\u21c9","\\rightrightarrows",!0),oe(se,me,ye,"\u21c4","\\rightleftarrows",!0),oe(se,me,ye,"\u21a0","\\twoheadrightarrow",!0),oe(se,me,ye,"\u21a3","\\rightarrowtail",!0),oe(se,me,ye,"\u21ac","\\looparrowright",!0),oe(se,me,ye,"\u21b7","\\curvearrowright",!0),oe(se,me,ye,"\u21bb","\\circlearrowright",!0),oe(se,me,ye,"\u21b1","\\Rsh",!0),oe(se,me,ye,"\u21ca","\\downdownarrows",!0),oe(se,me,ye,"\u21be","\\upharpoonright",!0),oe(se,me,ye,"\u21c2","\\downharpoonright",!0),oe(se,me,ye,"\u21dd","\\rightsquigarrow",!0),oe(se,me,ye,"\u21dd","\\leadsto"),oe(se,me,ye,"\u21db","\\Rrightarrow",!0),oe(se,me,ye,"\u21be","\\restriction"),oe(se,he,we,"\u2018","`"),oe(se,he,we,"$","\\$"),oe(le,he,we,"$","\\$"),oe(le,he,we,"$","\\textdollar"),oe(se,he,we,"%","\\%"),oe(le,he,we,"%","\\%"),oe(se,he,we,"_","\\_"),oe(le,he,we,"_","\\_"),oe(le,he,we,"_","\\textunderscore"),oe(se,he,we,"\u2220","\\angle",!0),oe(se,he,we,"\u221e","\\infty",!0),oe(se,he,we,"\u2032","\\prime"),oe(se,he,we,"\u25b3","\\triangle"),oe(se,he,we,"\u0393","\\Gamma",!0),oe(se,he,we,"\u0394","\\Delta",!0),oe(se,he,we,"\u0398","\\Theta",!0),oe(se,he,we,"\u039b","\\Lambda",!0),oe(se,he,we,"\u039e","\\Xi",!0),oe(se,he,we,"\u03a0","\\Pi",!0),oe(se,he,we,"\u03a3","\\Sigma",!0),oe(se,he,we,"\u03a5","\\Upsilon",!0),oe(se,he,we,"\u03a6","\\Phi",!0),oe(se,he,we,"\u03a8","\\Psi",!0),oe(se,he,we,"\u03a9","\\Omega",!0),oe(se,he,we,"A","\u0391"),oe(se,he,we,"B","\u0392"),oe(se,he,we,"E","\u0395"),oe(se,he,we,"Z","\u0396"),oe(se,he,we,"H","\u0397"),oe(se,he,we,"I","\u0399"),oe(se,he,we,"K","\u039a"),oe(se,he,we,"M","\u039c"),oe(se,he,we,"N","\u039d"),oe(se,he,we,"O","\u039f"),oe(se,he,we,"P","\u03a1"),oe(se,he,we,"T","\u03a4"),oe(se,he,we,"X","\u03a7"),oe(se,he,we,"\xac","\\neg",!0),oe(se,he,we,"\xac","\\lnot"),oe(se,he,we,"\u22a4","\\top"),oe(se,he,we,"\u22a5","\\bot"),oe(se,he,we,"\u2205","\\emptyset"),oe(se,me,we,"\u2205","\\varnothing"),oe(se,he,ge,"\u03b1","\\alpha",!0),oe(se,he,ge,"\u03b2","\\beta",!0),oe(se,he,ge,"\u03b3","\\gamma",!0),oe(se,he,ge,"\u03b4","\\delta",!0),oe(se,he,ge,"\u03f5","\\epsilon",!0),oe(se,he,ge,"\u03b6","\\zeta",!0),oe(se,he,ge,"\u03b7","\\eta",!0),oe(se,he,ge,"\u03b8","\\theta",!0),oe(se,he,ge,"\u03b9","\\iota",!0),oe(se,he,ge,"\u03ba","\\kappa",!0),oe(se,he,ge,"\u03bb","\\lambda",!0),oe(se,he,ge,"\u03bc","\\mu",!0),oe(se,he,ge,"\u03bd","\\nu",!0),oe(se,he,ge,"\u03be","\\xi",!0),oe(se,he,ge,"\u03bf","\\omicron",!0),oe(se,he,ge,"\u03c0","\\pi",!0),oe(se,he,ge,"\u03c1","\\rho",!0),oe(se,he,ge,"\u03c3","\\sigma",!0),oe(se,he,ge,"\u03c4","\\tau",!0),oe(se,he,ge,"\u03c5","\\upsilon",!0),oe(se,he,ge,"\u03d5","\\phi",!0),oe(se,he,ge,"\u03c7","\\chi",!0),oe(se,he,ge,"\u03c8","\\psi",!0),oe(se,he,ge,"\u03c9","\\omega",!0),oe(se,he,ge,"\u03b5","\\varepsilon",!0),oe(se,he,ge,"\u03d1","\\vartheta",!0),oe(se,he,ge,"\u03d6","\\varpi",!0),oe(se,he,ge,"\u03f1","\\varrho",!0),oe(se,he,ge,"\u03c2","\\varsigma",!0),oe(se,he,ge,"\u03c6","\\varphi",!0),oe(se,he,pe,"\u2217","*",!0),oe(se,he,pe,"+","+"),oe(se,he,pe,"\u2212","-",!0),oe(se,he,pe,"\u22c5","\\cdot",!0),oe(se,he,pe,"\u2218","\\circ",!0),oe(se,he,pe,"\xf7","\\div",!0),oe(se,he,pe,"\xb1","\\pm",!0),oe(se,he,pe,"\xd7","\\times",!0),oe(se,he,pe,"\u2229","\\cap",!0),oe(se,he,pe,"\u222a","\\cup",!0),oe(se,he,pe,"\u2216","\\setminus",!0),oe(se,he,pe,"\u2227","\\land"),oe(se,he,pe,"\u2228","\\lor"),oe(se,he,pe,"\u2227","\\wedge",!0),oe(se,he,pe,"\u2228","\\vee",!0),oe(se,he,we,"\u221a","\\surd"),oe(se,he,ve,"\u27e8","\\langle",!0),oe(se,he,ve,"\u2223","\\lvert"),oe(se,he,ve,"\u2225","\\lVert"),oe(se,he,ue,"?","?"),oe(se,he,ue,"!","!"),oe(se,he,ue,"\u27e9","\\rangle",!0),oe(se,he,ue,"\u2223","\\rvert"),oe(se,he,ue,"\u2225","\\rVert"),oe(se,he,ye,"=","="),oe(se,he,ye,":",":"),oe(se,he,ye,"\u2248","\\approx",!0),oe(se,he,ye,"\u2245","\\cong",!0),oe(se,he,ye,"\u2265","\\ge"),oe(se,he,ye,"\u2265","\\geq",!0),oe(se,he,ye,"\u2190","\\gets"),oe(se,he,ye,">","\\gt",!0),oe(se,he,ye,"\u2208","\\in",!0),oe(se,he,ye,"\ue020","\\@not"),oe(se,he,ye,"\u2282","\\subset",!0),oe(se,he,ye,"\u2283","\\supset",!0),oe(se,he,ye,"\u2286","\\subseteq",!0),oe(se,he,ye,"\u2287","\\supseteq",!0),oe(se,me,ye,"\u2288","\\nsubseteq",!0),oe(se,me,ye,"\u2289","\\nsupseteq",!0),oe(se,he,ye,"\u22a8","\\models"),oe(se,he,ye,"\u2190","\\leftarrow",!0),oe(se,he,ye,"\u2264","\\le"),oe(se,he,ye,"\u2264","\\leq",!0),oe(se,he,ye,"<","\\lt",!0),oe(se,he,ye,"\u2192","\\rightarrow",!0),oe(se,he,ye,"\u2192","\\to"),oe(se,me,ye,"\u2271","\\ngeq",!0),oe(se,me,ye,"\u2270","\\nleq",!0),oe(se,he,xe,"\xa0","\\ "),oe(se,he,xe,"\xa0","\\space"),oe(se,he,xe,"\xa0","\\nobreakspace"),oe(le,he,xe,"\xa0","\\ "),oe(le,he,xe,"\xa0"," "),oe(le,he,xe,"\xa0","\\space"),oe(le,he,xe,"\xa0","\\nobreakspace"),oe(se,he,xe,null,"\\nobreak"),oe(se,he,xe,null,"\\allowbreak"),oe(se,he,be,",",","),oe(se,he,be,";",";"),oe(se,me,pe,"\u22bc","\\barwedge",!0),oe(se,me,pe,"\u22bb","\\veebar",!0),oe(se,he,pe,"\u2299","\\odot",!0),oe(se,he,pe,"\u2295","\\oplus",!0),oe(se,he,pe,"\u2297","\\otimes",!0),oe(se,he,we,"\u2202","\\partial",!0),oe(se,he,pe,"\u2298","\\oslash",!0),oe(se,me,pe,"\u229a","\\circledcirc",!0),oe(se,me,pe,"\u22a1","\\boxdot",!0),oe(se,he,pe,"\u25b3","\\bigtriangleup"),oe(se,he,pe,"\u25bd","\\bigtriangledown"),oe(se,he,pe,"\u2020","\\dagger"),oe(se,he,pe,"\u22c4","\\diamond"),oe(se,he,pe,"\u22c6","\\star"),oe(se,he,pe,"\u25c3","\\triangleleft"),oe(se,he,pe,"\u25b9","\\triangleright"),oe(se,he,ve,"{","\\{"),oe(le,he,we,"{","\\{"),oe(le,he,we,"{","\\textbraceleft"),oe(se,he,ue,"}","\\}"),oe(le,he,we,"}","\\}"),oe(le,he,we,"}","\\textbraceright"),oe(se,he,ve,"{","\\lbrace"),oe(se,he,ue,"}","\\rbrace"),oe(se,he,ve,"[","\\lbrack",!0),oe(le,he,we,"[","\\lbrack",!0),oe(se,he,ue,"]","\\rbrack",!0),oe(le,he,we,"]","\\rbrack",!0),oe(se,he,ve,"(","\\lparen",!0),oe(se,he,ue,")","\\rparen",!0),oe(le,he,we,"<","\\textless",!0),oe(le,he,we,">","\\textgreater",!0),oe(se,he,ve,"\u230a","\\lfloor",!0),oe(se,he,ue,"\u230b","\\rfloor",!0),oe(se,he,ve,"\u2308","\\lceil",!0),oe(se,he,ue,"\u2309","\\rceil",!0),oe(se,he,we,"\\","\\backslash"),oe(se,he,we,"\u2223","|"),oe(se,he,we,"\u2223","\\vert"),oe(le,he,we,"|","\\textbar",!0),oe(se,he,we,"\u2225","\\|"),oe(se,he,we,"\u2225","\\Vert"),oe(le,he,we,"\u2225","\\textbardbl"),oe(le,he,we,"~","\\textasciitilde"),oe(le,he,we,"\\","\\textbackslash"),oe(le,he,we,"^","\\textasciicircum"),oe(se,he,ye,"\u2191","\\uparrow",!0),oe(se,he,ye,"\u21d1","\\Uparrow",!0),oe(se,he,ye,"\u2193","\\downarrow",!0),oe(se,he,ye,"\u21d3","\\Downarrow",!0),oe(se,he,ye,"\u2195","\\updownarrow",!0),oe(se,he,ye,"\u21d5","\\Updownarrow",!0),oe(se,he,fe,"\u2210","\\coprod"),oe(se,he,fe,"\u22c1","\\bigvee"),oe(se,he,fe,"\u22c0","\\bigwedge"),oe(se,he,fe,"\u2a04","\\biguplus"),oe(se,he,fe,"\u22c2","\\bigcap"),oe(se,he,fe,"\u22c3","\\bigcup"),oe(se,he,fe,"\u222b","\\int"),oe(se,he,fe,"\u222b","\\intop"),oe(se,he,fe,"\u222c","\\iint"),oe(se,he,fe,"\u222d","\\iiint"),oe(se,he,fe,"\u220f","\\prod"),oe(se,he,fe,"\u2211","\\sum"),oe(se,he,fe,"\u2a02","\\bigotimes"),oe(se,he,fe,"\u2a01","\\bigoplus"),oe(se,he,fe,"\u2a00","\\bigodot"),oe(se,he,fe,"\u222e","\\oint"),oe(se,he,fe,"\u222f","\\oiint"),oe(se,he,fe,"\u2230","\\oiiint"),oe(se,he,fe,"\u2a06","\\bigsqcup"),oe(se,he,fe,"\u222b","\\smallint"),oe(le,he,de,"\u2026","\\textellipsis"),oe(se,he,de,"\u2026","\\mathellipsis"),oe(le,he,de,"\u2026","\\ldots",!0),oe(se,he,de,"\u2026","\\ldots",!0),oe(se,he,de,"\u22ef","\\@cdots",!0),oe(se,he,de,"\u22f1","\\ddots",!0),oe(se,he,we,"\u22ee","\\varvdots"),oe(le,he,we,"\u22ee","\\varvdots"),oe(se,he,ce,"\u02ca","\\acute"),oe(se,he,ce,"\u02cb","\\grave"),oe(se,he,ce,"\xa8","\\ddot"),oe(se,he,ce,"~","\\tilde"),oe(se,he,ce,"\u02c9","\\bar"),oe(se,he,ce,"\u02d8","\\breve"),oe(se,he,ce,"\u02c7","\\check"),oe(se,he,ce,"^","\\hat"),oe(se,he,ce,"\u20d7","\\vec"),oe(se,he,ce,"\u02d9","\\dot"),oe(se,he,ce,"\u02da","\\mathring"),oe(se,he,ge,"\ue131","\\@imath"),oe(se,he,ge,"\ue237","\\@jmath"),oe(se,he,we,"\u0131","\u0131"),oe(se,he,we,"\u0237","\u0237"),oe(le,he,we,"\u0131","\\i",!0),oe(le,he,we,"\u0237","\\j",!0),oe(le,he,we,"\xdf","\\ss",!0),oe(le,he,we,"\xe6","\\ae",!0),oe(le,he,we,"\u0153","\\oe",!0),oe(le,he,we,"\xf8","\\o",!0),oe(le,he,we,"\xc6","\\AE",!0),oe(le,he,we,"\u0152","\\OE",!0),oe(le,he,we,"\xd8","\\O",!0),oe(le,he,ce,"\u02ca","\\'"),oe(le,he,ce,"\u02cb","\\`"),oe(le,he,ce,"\u02c6","\\^"),oe(le,he,ce,"\u02dc","\\~"),oe(le,he,ce,"\u02c9","\\="),oe(le,he,ce,"\u02d8","\\u"),oe(le,he,ce,"\u02d9","\\."),oe(le,he,ce,"\xb8","\\c"),oe(le,he,ce,"\u02da","\\r"),oe(le,he,ce,"\u02c7","\\v"),oe(le,he,ce,"\xa8",'\\"'),oe(le,he,ce,"\u02dd","\\H"),oe(le,he,ce,"\u25ef","\\textcircled");var ke={"--":!0,"---":!0,"``":!0,"''":!0};oe(le,he,we,"\u2013","--",!0),oe(le,he,we,"\u2013","\\textendash"),oe(le,he,we,"\u2014","---",!0),oe(le,he,we,"\u2014","\\textemdash"),oe(le,he,we,"\u2018","`",!0),oe(le,he,we,"\u2018","\\textquoteleft"),oe(le,he,we,"\u2019","'",!0),oe(le,he,we,"\u2019","\\textquoteright"),oe(le,he,we,"\u201c","``",!0),oe(le,he,we,"\u201c","\\textquotedblleft"),oe(le,he,we,"\u201d","''",!0),oe(le,he,we,"\u201d","\\textquotedblright"),oe(se,he,we,"\xb0","\\degree",!0),oe(le,he,we,"\xb0","\\degree"),oe(le,he,we,"\xb0","\\textdegree",!0),oe(se,he,we,"\xa3","\\pounds"),oe(se,he,we,"\xa3","\\mathsterling",!0),oe(le,he,we,"\xa3","\\pounds"),oe(le,he,we,"\xa3","\\textsterling",!0),oe(se,me,we,"\u2720","\\maltese"),oe(le,me,we,"\u2720","\\maltese");for(var Se='0123456789/@."',Me=0;Me<14;Me++){var ze=Se.charAt(Me);oe(se,he,we,ze,ze)}for(var Ae='0123456789!@*()-=+";:?/.,',Te=0;Te<25;Te++){var Be=Ae.charAt(Te);oe(le,he,we,Be,Be)}for(var Ce="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Ne=0;Ne<52;Ne++){var qe=Ce.charAt(Ne);oe(se,he,ge,qe,qe),oe(le,he,we,qe,qe)}oe(se,me,we,"C","\u2102"),oe(le,me,we,"C","\u2102"),oe(se,me,we,"H","\u210d"),oe(le,me,we,"H","\u210d"),oe(se,me,we,"N","\u2115"),oe(le,me,we,"N","\u2115"),oe(se,me,we,"P","\u2119"),oe(le,me,we,"P","\u2119"),oe(se,me,we,"Q","\u211a"),oe(le,me,we,"Q","\u211a"),oe(se,me,we,"R","\u211d"),oe(le,me,we,"R","\u211d"),oe(se,me,we,"Z","\u2124"),oe(le,me,we,"Z","\u2124"),oe(se,he,ge,"h","\u210e"),oe(le,he,ge,"h","\u210e");for(var Ie="",Re=0;Re<52;Re++){var He=Ce.charAt(Re);oe(se,he,ge,He,Ie=String.fromCharCode(55349,56320+Re)),oe(le,he,we,He,Ie),oe(se,he,ge,He,Ie=String.fromCharCode(55349,56372+Re)),oe(le,he,we,He,Ie),oe(se,he,ge,He,Ie=String.fromCharCode(55349,56424+Re)),oe(le,he,we,He,Ie),oe(se,he,ge,He,Ie=String.fromCharCode(55349,56580+Re)),oe(le,he,we,He,Ie),oe(se,he,ge,He,Ie=String.fromCharCode(55349,56684+Re)),oe(le,he,we,He,Ie),oe(se,he,ge,He,Ie=String.fromCharCode(55349,56736+Re)),oe(le,he,we,He,Ie),oe(se,he,ge,He,Ie=String.fromCharCode(55349,56788+Re)),oe(le,he,we,He,Ie),oe(se,he,ge,He,Ie=String.fromCharCode(55349,56840+Re)),oe(le,he,we,He,Ie),oe(se,he,ge,He,Ie=String.fromCharCode(55349,56944+Re)),oe(le,he,we,He,Ie),Re<26&&(oe(se,he,ge,He,Ie=String.fromCharCode(55349,56632+Re)),oe(le,he,we,He,Ie),oe(se,he,ge,He,Ie=String.fromCharCode(55349,56476+Re)),oe(le,he,we,He,Ie))}oe(se,he,ge,"k",Ie=String.fromCharCode(55349,56668)),oe(le,he,we,"k",Ie);for(var Oe=0;Oe<10;Oe++){var Ee=Oe.toString();oe(se,he,ge,Ee,Ie=String.fromCharCode(55349,57294+Oe)),oe(le,he,we,Ee,Ie),oe(se,he,ge,Ee,Ie=String.fromCharCode(55349,57314+Oe)),oe(le,he,we,Ee,Ie),oe(se,he,ge,Ee,Ie=String.fromCharCode(55349,57324+Oe)),oe(le,he,we,Ee,Ie),oe(se,he,ge,Ee,Ie=String.fromCharCode(55349,57334+Oe)),oe(le,he,we,Ee,Ie)}for(var Le="\xd0\xde\xfe",De=0;De<3;De++){var Ve=Le.charAt(De);oe(se,he,ge,Ve,Ve),oe(le,he,we,Ve,Ve)}var Pe=[["mathbf","textbf","Main-Bold"],["mathbf","textbf","Main-Bold"],["mathnormal","textit","Math-Italic"],["mathnormal","textit","Math-Italic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["mathscr","textscr","Script-Regular"],["","",""],["","",""],["","",""],["mathfrak","textfrak","Fraktur-Regular"],["mathfrak","textfrak","Fraktur-Regular"],["mathbb","textbb","AMS-Regular"],["mathbb","textbb","AMS-Regular"],["mathboldfrak","textboldfrak","Fraktur-Regular"],["mathboldfrak","textboldfrak","Fraktur-Regular"],["mathsf","textsf","SansSerif-Regular"],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathitsf","textitsf","SansSerif-Italic"],["mathitsf","textitsf","SansSerif-Italic"],["","",""],["","",""],["mathtt","texttt","Typewriter-Regular"],["mathtt","texttt","Typewriter-Regular"]],Fe=[["mathbf","textbf","Main-Bold"],["","",""],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathtt","texttt","Typewriter-Regular"]],Ge=function(e,t,r){return ie[r][e]&&ie[r][e].replace&&(e=ie[r][e].replace),{value:e,metrics:I(e,t,r)}},Ue=function(e,t,r,a,n){var i,o=Ge(e,t,r),s=o.metrics;if(e=o.value,s){var l=s.italic;("text"===r||a&&"mathit"===a.font)&&(l=0),i=new J(e,s.height,s.depth,l,s.skew,s.width,n)}else"undefined"!=typeof console&&console.warn("No character metrics for '"+e+"' in style '"+t+"' and mode '"+r+"'"),i=new J(e,0,0,0,0,0,n);if(a){i.maxFontSize=a.sizeMultiplier,a.style.isTight()&&i.classes.push("mtight");var h=a.getColor();h&&(i.style.color=h)}return i},Ye=(e,t)=>{if(U(e.classes)!==U(t.classes)||e.skew!==t.skew||e.maxFontSize!==t.maxFontSize)return!1;if(1===e.classes.length){var r=e.classes[0];if("mbin"===r||"mord"===r)return!1}for(var a in e.style)if(e.style.hasOwnProperty(a)&&e.style[a]!==t.style[a])return!1;for(var n in t.style)if(t.style.hasOwnProperty(n)&&e.style[n]!==t.style[n])return!1;return!0},Xe=function(e){for(var t=0,r=0,a=0,n=0;n<e.children.length;n++){var i=e.children[n];i.height>t&&(t=i.height),i.depth>r&&(r=i.depth),i.maxFontSize>a&&(a=i.maxFontSize)}e.height=t,e.depth=r,e.maxFontSize=a},We=function(e,t,r,a){var n=new j(e,t,r,a);return Xe(n),n},_e=(e,t,r,a)=>new j(e,t,r,a),je=function(e){var t=new B(e);return Xe(t),t},$e=function(e,t,r){var a="";switch(e){case"amsrm":a="AMS";break;case"textrm":a="Main";break;case"textsf":a="SansSerif";break;case"texttt":a="Typewriter";break;default:a=e}return a+"-"+("textbf"===t&&"textit"===r?"BoldItalic":"textbf"===t?"Bold":"textit"===t?"Italic":"Regular")},Ze={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathsfit:{variant:"sans-serif-italic",fontName:"SansSerif-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},Ke={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},Je={fontMap:Ze,makeSymbol:Ue,mathsym:function(e,t,r,a){return void 0===a&&(a=[]),"boldsymbol"===r.font&&Ge(e,"Main-Bold",t).metrics?Ue(e,"Main-Bold",t,r,a.concat(["mathbf"])):"\\"===e||"main"===ie[t][e].font?Ue(e,"Main-Regular",t,r,a):Ue(e,"AMS-Regular",t,r,a.concat(["amsrm"]))},makeSpan:We,makeSvgSpan:_e,makeLineSpan:function(e,t,r){var a=We([e],[],t);return a.height=Math.max(r||t.fontMetrics().defaultRuleThickness,t.minRuleThickness),a.style.borderBottomWidth=G(a.height),a.maxFontSize=1,a},makeAnchor:function(e,t,r,a){var n=new $(e,t,r,a);return Xe(n),n},makeFragment:je,wrapFragment:function(e,t){return e instanceof B?We([],[e],t):e},makeVList:function(e,t){for(var{children:r,depth:a}=function(e){if("individualShift"===e.positionType){for(var t=e.children,r=[t[0]],a=-t[0].shift-t[0].elem.depth,n=a,i=1;i<t.length;i++){var o=-t[i].shift-n-t[i].elem.depth,s=o-(t[i-1].elem.height+t[i-1].elem.depth);n+=o,r.push({type:"kern",size:s}),r.push(t[i])}return{children:r,depth:a}}var l;if("top"===e.positionType){for(var h=e.positionData,m=0;m<e.children.length;m++){var c=e.children[m];h-="kern"===c.type?c.size:c.elem.height+c.elem.depth}l=h}else if("bottom"===e.positionType)l=-e.positionData;else{var p=e.children[0];if("elem"!==p.type)throw new Error('First child must have type "elem".');if("shift"===e.positionType)l=-p.elem.depth-e.positionData;else{if("firstBaseline"!==e.positionType)throw new Error("Invalid positionType "+e.positionType+".");l=-p.elem.depth}}return{children:e.children,depth:l}}(e),n=0,i=0;i<r.length;i++){var o=r[i];if("elem"===o.type){var s=o.elem;n=Math.max(n,s.maxFontSize,s.height)}}n+=2;var l=We(["pstrut"],[]);l.style.height=G(n);for(var h=[],m=a,c=a,p=a,u=0;u<r.length;u++){var d=r[u];if("kern"===d.type)p+=d.size;else{var g=d.elem,f=d.wrapperClasses||[],v=d.wrapperStyle||{},b=We(f,[l,g],void 0,v);b.style.top=G(-n-p-g.depth),d.marginLeft&&(b.style.marginLeft=d.marginLeft),d.marginRight&&(b.style.marginRight=d.marginRight),h.push(b),p+=g.height+g.depth}m=Math.min(m,p),c=Math.max(c,p)}var y,x=We(["vlist"],h);if(x.style.height=G(c),m<0){var w=We([],[]),k=We(["vlist"],[w]);k.style.height=G(-m);var S=We(["vlist-s"],[new J("\u200b")]);y=[We(["vlist-r"],[x,S]),We(["vlist-r"],[k])]}else y=[We(["vlist-r"],[x])];var M=We(["vlist-t"],y);return 2===y.length&&M.classes.push("vlist-t2"),M.height=c,M.depth=-m,M},makeOrd:function(e,t,r){var a=e.mode,n=e.text,o=["mord"],s="math"===a||"text"===a&&t.font,l=s?t.font:t.fontFamily,h="",m="";if(55349===n.charCodeAt(0)&&([h,m]=function(e,t){var r=1024*(e.charCodeAt(0)-55296)+(e.charCodeAt(1)-56320)+65536,a="math"===t?0:1;if(119808<=r&&r<120484){var n=Math.floor((r-119808)/26);return[Pe[n][2],Pe[n][a]]}if(120782<=r&&r<=120831){var o=Math.floor((r-120782)/10);return[Fe[o][2],Fe[o][a]]}if(120485===r||120486===r)return[Pe[0][2],Pe[0][a]];if(120486<r&&r<120782)return["",""];throw new i("Unsupported character: "+e)}(n,a)),h.length>0)return Ue(n,h,a,t,o.concat(m));if(l){var c,p;if("boldsymbol"===l){var u=function(e,t,r,a,n){return"textord"!==n&&Ge(e,"Math-BoldItalic",t).metrics?{fontName:"Math-BoldItalic",fontClass:"boldsymbol"}:{fontName:"Main-Bold",fontClass:"mathbf"}}(n,a,0,0,r);c=u.fontName,p=[u.fontClass]}else s?(c=Ze[l].fontName,p=[l]):(c=$e(l,t.fontWeight,t.fontShape),p=[l,t.fontWeight,t.fontShape]);if(Ge(n,c,a).metrics)return Ue(n,c,a,t,o.concat(p));if(ke.hasOwnProperty(n)&&"Typewriter"===c.slice(0,10)){for(var d=[],g=0;g<n.length;g++)d.push(Ue(n[g],c,a,t,o.concat(p)));return je(d)}}if("mathord"===r)return Ue(n,"Math-Italic",a,t,o.concat(["mathnormal"]));if("textord"===r){var f=ie[a][n]&&ie[a][n].font;if("ams"===f){var v=$e("amsrm",t.fontWeight,t.fontShape);return Ue(n,v,a,t,o.concat("amsrm",t.fontWeight,t.fontShape))}if("main"!==f&&f){var b=$e(f,t.fontWeight,t.fontShape);return Ue(n,b,a,t,o.concat(b,t.fontWeight,t.fontShape))}var y=$e("textrm",t.fontWeight,t.fontShape);return Ue(n,y,a,t,o.concat(t.fontWeight,t.fontShape))}throw new Error("unexpected type: "+r+" in makeOrd")},makeGlue:(e,t)=>{var r=We(["mspace"],[],t),a=F(e,t);return r.style.marginRight=G(a),r},staticSvg:function(e,t){var[r,a,n]=Ke[e],i=new ee(r),o=new Q([i],{width:G(a),height:G(n),style:"width:"+G(a),viewBox:"0 0 "+1e3*a+" "+1e3*n,preserveAspectRatio:"xMinYMin"}),s=_e(["overlay"],[o],t);return s.height=n,s.style.height=G(n),s.style.width=G(a),s},svgData:Ke,tryCombineChars:e=>{for(var t=0;t<e.length-1;t++){var r=e[t],a=e[t+1];r instanceof J&&a instanceof J&&Ye(r,a)&&(r.text+=a.text,r.height=Math.max(r.height,a.height),r.depth=Math.max(r.depth,a.depth),r.italic=a.italic,e.splice(t+1,1),t--)}return e}},Qe={number:3,unit:"mu"},et={number:4,unit:"mu"},tt={number:5,unit:"mu"},rt={mord:{mop:Qe,mbin:et,mrel:tt,minner:Qe},mop:{mord:Qe,mop:Qe,mrel:tt,minner:Qe},mbin:{mord:et,mop:et,mopen:et,minner:et},mrel:{mord:tt,mop:tt,mopen:tt,minner:tt},mopen:{},mclose:{mop:Qe,mbin:et,mrel:tt,minner:Qe},mpunct:{mord:Qe,mop:Qe,mrel:tt,mopen:Qe,mclose:Qe,mpunct:Qe,minner:Qe},minner:{mord:Qe,mop:Qe,mbin:et,mrel:tt,mopen:Qe,mpunct:Qe,minner:Qe}},at={mord:{mop:Qe},mop:{mord:Qe,mop:Qe},mbin:{},mrel:{},mopen:{},mclose:{mop:Qe},mpunct:{},minner:{mop:Qe}},nt={},it={},ot={};function st(e){for(var{type:t,names:r,props:a,handler:n,htmlBuilder:i,mathmlBuilder:o}=e,s={type:t,numArgs:a.numArgs,argTypes:a.argTypes,allowedInArgument:!!a.allowedInArgument,allowedInText:!!a.allowedInText,allowedInMath:void 0===a.allowedInMath||a.allowedInMath,numOptionalArgs:a.numOptionalArgs||0,infix:!!a.infix,primitive:!!a.primitive,handler:n},l=0;l<r.length;++l)nt[r[l]]=s;t&&(i&&(it[t]=i),o&&(ot[t]=o))}function lt(e){var{type:t,htmlBuilder:r,mathmlBuilder:a}=e;st({type:t,names:[],props:{numArgs:0},handler(){throw new Error("Should never be called.")},htmlBuilder:r,mathmlBuilder:a})}var ht=function(e){return"ordgroup"===e.type&&1===e.body.length?e.body[0]:e},mt=function(e){return"ordgroup"===e.type?e.body:[e]},ct=Je.makeSpan,pt=["leftmost","mbin","mopen","mrel","mop","mpunct"],ut=["rightmost","mrel","mclose","mpunct"],dt={display:k.DISPLAY,text:k.TEXT,script:k.SCRIPT,scriptscript:k.SCRIPTSCRIPT},gt={mord:"mord",mop:"mop",mbin:"mbin",mrel:"mrel",mopen:"mopen",mclose:"mclose",mpunct:"mpunct",minner:"minner"},ft=function(e,t,r,a){void 0===a&&(a=[null,null]);for(var n=[],i=0;i<e.length;i++){var o=kt(e[i],t);if(o instanceof B){var s=o.children;n.push(...s)}else n.push(o)}if(Je.tryCombineChars(n),!r)return n;var l=t;if(1===e.length){var h=e[0];"sizing"===h.type?l=t.havingSize(h.size):"styling"===h.type&&(l=t.havingStyle(dt[h.style]))}var m=ct([a[0]||"leftmost"],[],t),c=ct([a[1]||"rightmost"],[],t),p="root"===r;return vt(n,(e,t)=>{var r=t.classes[0],a=e.classes[0];"mbin"===r&&ut.includes(a)?t.classes[0]="mord":"mbin"===a&&pt.includes(r)&&(e.classes[0]="mord")},{node:m},c,p),vt(n,(e,t)=>{var r=xt(t),a=xt(e),n=r&&a?e.hasClass("mtight")?at[r][a]:rt[r][a]:null;if(n)return Je.makeGlue(n,l)},{node:m},c,p),n},vt=function e(t,r,a,n,i){n&&t.push(n);for(var o=0;o<t.length;o++){var s=t[o],l=bt(s);if(l)e(l.children,r,a,null,i);else{var h=!s.hasClass("mspace");if(h){var m=r(s,a.node);m&&(a.insertAfter?a.insertAfter(m):(t.unshift(m),o++))}h?a.node=s:i&&s.hasClass("newline")&&(a.node=ct(["leftmost"])),a.insertAfter=(e=>r=>{t.splice(e+1,0,r),o++})(o)}}n&&t.pop()},bt=function(e){return e instanceof B||e instanceof $||e instanceof j&&e.hasClass("enclosing")?e:null},yt=function e(t,r){var a=bt(t);if(a){var n=a.children;if(n.length){if("right"===r)return e(n[n.length-1],"right");if("left"===r)return e(n[0],"left")}}return t},xt=function(e,t){return e?(t&&(e=yt(e,t)),gt[e.classes[0]]||null):null},wt=function(e,t){var r=["nulldelimiter"].concat(e.baseSizingClasses());return ct(t.concat(r))},kt=function(e,t,r){if(!e)return ct();if(it[e.type]){var a=it[e.type](e,t);if(r&&t.size!==r.size){a=ct(t.sizingClasses(r),[a],t);var n=t.sizeMultiplier/r.sizeMultiplier;a.height*=n,a.depth*=n}return a}throw new i("Got group of unknown type: '"+e.type+"'")};function St(e,t){var r=ct(["base"],e,t),a=ct(["strut"]);return a.style.height=G(r.height+r.depth),r.depth&&(a.style.verticalAlign=G(-r.depth)),r.children.unshift(a),r}function Mt(e,t){var r=null;1===e.length&&"tag"===e[0].type&&(r=e[0].tag,e=e[0].body);var a,n=ft(e,t,"root");2===n.length&&n[1].hasClass("tag")&&(a=n.pop());for(var i,o=[],s=[],l=0;l<n.length;l++)if(s.push(n[l]),n[l].hasClass("mbin")||n[l].hasClass("mrel")||n[l].hasClass("allowbreak")){for(var h=!1;l<n.length-1&&n[l+1].hasClass("mspace")&&!n[l+1].hasClass("newline");)l++,s.push(n[l]),n[l].hasClass("nobreak")&&(h=!0);h||(o.push(St(s,t)),s=[])}else n[l].hasClass("newline")&&(s.pop(),s.length>0&&(o.push(St(s,t)),s=[]),o.push(n[l]));s.length>0&&o.push(St(s,t)),r?((i=St(ft(r,t,!0))).classes=["tag"],o.push(i)):a&&o.push(a);var m=ct(["katex-html"],o);if(m.setAttribute("aria-hidden","true"),i){var c=i.children[0];c.style.height=G(m.height+m.depth),m.depth&&(c.style.verticalAlign=G(-m.depth))}return m}function zt(e){return new B(e)}class At{constructor(e,t,r){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=t||[],this.classes=r||[]}setAttribute(e,t){this.attributes[e]=t}getAttribute(e){return this.attributes[e]}toNode(){var e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);this.classes.length>0&&(e.className=U(this.classes));for(var r=0;r<this.children.length;r++)if(this.children[r]instanceof Tt&&this.children[r+1]instanceof Tt){for(var a=this.children[r].toText()+this.children[++r].toText();this.children[r+1]instanceof Tt;)a+=this.children[++r].toText();e.appendChild(new Tt(a).toNode())}else e.appendChild(this.children[r].toNode());return e}toMarkup(){var e="<"+this.type;for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&(e+=" "+t+'="',e+=m.escape(this.attributes[t]),e+='"');this.classes.length>0&&(e+=' class ="'+m.escape(U(this.classes))+'"'),e+=">";for(var r=0;r<this.children.length;r++)e+=this.children[r].toMarkup();return e+="</"+this.type+">"}toText(){return this.children.map(e=>e.toText()).join("")}}class Tt{constructor(e){this.text=void 0,this.text=e}toNode(){return document.createTextNode(this.text)}toMarkup(){return m.escape(this.toText())}toText(){return this.text}}var Bt={MathNode:At,TextNode:Tt,SpaceNode:class{constructor(e){this.width=void 0,this.character=void 0,this.width=e,this.character=e>=.05555&&e<=.05556?"\u200a":e>=.1666&&e<=.1667?"\u2009":e>=.2222&&e<=.2223?"\u2005":e>=.2777&&e<=.2778?"\u2005\u200a":e>=-.05556&&e<=-.05555?"\u200a\u2063":e>=-.1667&&e<=-.1666?"\u2009\u2063":e>=-.2223&&e<=-.2222?"\u205f\u2063":e>=-.2778&&e<=-.2777?"\u2005\u2063":null}toNode(){if(this.character)return document.createTextNode(this.character);var e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",G(this.width)),e}toMarkup(){return this.character?"<mtext>"+this.character+"</mtext>":'<mspace width="'+G(this.width)+'"/>'}toText(){return this.character?this.character:" "}},newDocumentFragment:zt},Ct=function(e,t,r){return!ie[t][e]||!ie[t][e].replace||55349===e.charCodeAt(0)||ke.hasOwnProperty(e)&&r&&(r.fontFamily&&"tt"===r.fontFamily.slice(4,6)||r.font&&"tt"===r.font.slice(4,6))||(e=ie[t][e].replace),new Bt.TextNode(e)},Nt=function(e){return 1===e.length?e[0]:new Bt.MathNode("mrow",e)},qt=function(e,t){if("texttt"===t.fontFamily)return"monospace";if("textsf"===t.fontFamily)return"textit"===t.fontShape&&"textbf"===t.fontWeight?"sans-serif-bold-italic":"textit"===t.fontShape?"sans-serif-italic":"textbf"===t.fontWeight?"bold-sans-serif":"sans-serif";if("textit"===t.fontShape&&"textbf"===t.fontWeight)return"bold-italic";if("textit"===t.fontShape)return"italic";if("textbf"===t.fontWeight)return"bold";var r=t.font;if(!r||"mathnormal"===r)return null;var a=e.mode;if("mathit"===r)return"italic";if("boldsymbol"===r)return"textord"===e.type?"bold":"bold-italic";if("mathbf"===r)return"bold";if("mathbb"===r)return"double-struck";if("mathsfit"===r)return"sans-serif-italic";if("mathfrak"===r)return"fraktur";if("mathscr"===r||"mathcal"===r)return"script";if("mathsf"===r)return"sans-serif";if("mathtt"===r)return"monospace";var n=e.text;return["\\imath","\\jmath"].includes(n)?null:(ie[a][n]&&ie[a][n].replace&&(n=ie[a][n].replace),I(n,Je.fontMap[r].fontName,a)?Je.fontMap[r].variant:null)};function It(e){if(!e)return!1;if("mi"===e.type&&1===e.children.length){var t=e.children[0];return t instanceof Tt&&"."===t.text}if("mo"===e.type&&1===e.children.length&&"true"===e.getAttribute("separator")&&"0em"===e.getAttribute("lspace")&&"0em"===e.getAttribute("rspace")){var r=e.children[0];return r instanceof Tt&&","===r.text}return!1}var Rt=function(e,t,r){if(1===e.length){var a=Ot(e[0],t);return r&&a instanceof At&&"mo"===a.type&&(a.setAttribute("lspace","0em"),a.setAttribute("rspace","0em")),[a]}for(var n,i=[],o=0;o<e.length;o++){var s=Ot(e[o],t);if(s instanceof At&&n instanceof At){if("mtext"===s.type&&"mtext"===n.type&&s.getAttribute("mathvariant")===n.getAttribute("mathvariant")){n.children.push(...s.children);continue}if("mn"===s.type&&"mn"===n.type){n.children.push(...s.children);continue}if(It(s)&&"mn"===n.type){n.children.push(...s.children);continue}if("mn"===s.type&&It(n))s.children=[...n.children,...s.children],i.pop();else if(("msup"===s.type||"msub"===s.type)&&s.children.length>=1&&("mn"===n.type||It(n))){var l=s.children[0];l instanceof At&&"mn"===l.type&&(l.children=[...n.children,...l.children],i.pop())}else if("mi"===n.type&&1===n.children.length){var h=n.children[0];if(h instanceof Tt&&"\u0338"===h.text&&("mo"===s.type||"mi"===s.type||"mn"===s.type)){var m=s.children[0];m instanceof Tt&&m.text.length>0&&(m.text=m.text.slice(0,1)+"\u0338"+m.text.slice(1),i.pop())}}}i.push(s),n=s}return i},Ht=function(e,t,r){return Nt(Rt(e,t,r))},Ot=function(e,t){if(!e)return new Bt.MathNode("mrow");if(ot[e.type])return ot[e.type](e,t);throw new i("Got group of unknown type: '"+e.type+"'")};function Et(e,t,r,a,n){var i,o=Rt(e,r);i=1===o.length&&o[0]instanceof At&&["mrow","mtable"].includes(o[0].type)?o[0]:new Bt.MathNode("mrow",o);var s=new Bt.MathNode("annotation",[new Bt.TextNode(t)]);s.setAttribute("encoding","application/x-tex");var l=new Bt.MathNode("semantics",[i,s]),h=new Bt.MathNode("math",[l]);h.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),a&&h.setAttribute("display","block");var m=n?"katex":"katex-mathml";return Je.makeSpan([m],[h])}var Lt=function(e){return new L({style:e.displayMode?k.DISPLAY:k.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},Dt=function(e,t){if(t.displayMode){var r=["katex-display"];t.leqno&&r.push("leqno"),t.fleqn&&r.push("fleqn"),e=Je.makeSpan(r,[e])}return e},Vt={widehat:"^",widecheck:"\u02c7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23df",overbrace:"\u23de",overgroup:"\u23e0",undergroup:"\u23e1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21d2",xRightarrow:"\u21d2",overleftharpoon:"\u21bc",xleftharpoonup:"\u21bc",overrightharpoon:"\u21c0",xrightharpoonup:"\u21c0",xLeftarrow:"\u21d0",xLeftrightarrow:"\u21d4",xhookleftarrow:"\u21a9",xhookrightarrow:"\u21aa",xmapsto:"\u21a6",xrightharpoondown:"\u21c1",xleftharpoondown:"\u21bd",xrightleftharpoons:"\u21cc",xleftrightharpoons:"\u21cb",xtwoheadleftarrow:"\u219e",xtwoheadrightarrow:"\u21a0",xlongequal:"=",xtofrom:"\u21c4",xrightleftarrows:"\u21c4",xrightequilibrium:"\u21cc",xleftequilibrium:"\u21cb","\\cdrightarrow":"\u2192","\\cdleftarrow":"\u2190","\\cdlongequal":"="},Pt={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},Ft=function(e,t,r,a,n){var i,o=e.height+e.depth+r+a;if(/fbox|color|angl/.test(t)){if(i=Je.makeSpan(["stretchy",t],[],n),"fbox"===t){var s=n.color&&n.getColor();s&&(i.style.borderColor=s)}}else{var l=[];/^[bx]cancel$/.test(t)&&l.push(new te({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(t)&&l.push(new te({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var h=new Q(l,{width:"100%",height:G(o)});i=Je.makeSvgSpan([],[h],n)}return i.height=o,i.style.height=G(o),i},Gt=function(e){var t=new Bt.MathNode("mo",[new Bt.TextNode(Vt[e.replace(/^\\/,"")])]);return t.setAttribute("stretchy","true"),t},Ut=function(e,t){var{span:r,minWidth:a,height:n}=function(){var r=4e5,a=e.label.slice(1);if(["widehat","widecheck","widetilde","utilde"].includes(a)){var n,i,o,s="ordgroup"===(u=e.base).type?u.body.length:1;if(s>5)"widehat"===a||"widecheck"===a?(n=420,r=2364,o=.42,i=a+"4"):(n=312,r=2340,o=.34,i="tilde4");else{var l=[1,1,2,2,3,3][s];"widehat"===a||"widecheck"===a?(r=[0,1062,2364,2364,2364][l],n=[0,239,300,360,420][l],o=[0,.24,.3,.3,.36,.42][l],i=a+l):(r=[0,600,1033,2339,2340][l],n=[0,260,286,306,312][l],o=[0,.26,.286,.3,.306,.34][l],i="tilde"+l)}var h=new ee(i),m=new Q([h],{width:"100%",height:G(o),viewBox:"0 0 "+r+" "+n,preserveAspectRatio:"none"});return{span:Je.makeSvgSpan([],[m],t),minWidth:0,height:o}}var c,p,u,d=[],g=Pt[a],[f,v,b]=g,y=b/1e3,x=f.length;if(1===x)c=["hide-tail"],p=[g[3]];else if(2===x)c=["halfarrow-left","halfarrow-right"],p=["xMinYMin","xMaxYMin"];else{if(3!==x)throw new Error("Correct katexImagesData or update code here to support\n "+x+" children.");c=["brace-left","brace-center","brace-right"],p=["xMinYMin","xMidYMin","xMaxYMin"]}for(var w=0;w<x;w++){var k=new ee(f[w]),S=new Q([k],{width:"400em",height:G(y),viewBox:"0 0 "+r+" "+b,preserveAspectRatio:p[w]+" slice"}),M=Je.makeSvgSpan([c[w]],[S],t);if(1===x)return{span:M,minWidth:v,height:y};M.style.height=G(y),d.push(M)}return{span:Je.makeSpan(["stretchy"],d,t),minWidth:v,height:y}}();return r.height=n,r.style.height=G(n),a>0&&(r.style.minWidth=G(a)),r};function Yt(e,t){if(!e||e.type!==t)throw new Error("Expected node of type "+t+", but got "+(e?"node of type "+e.type:String(e)));return e}function Xt(e){var t=Wt(e);if(!t)throw new Error("Expected node of symbol group type, but got "+(e?"node of type "+e.type:String(e)));return t}function Wt(e){return e&&("atom"===e.type||ne.hasOwnProperty(e.type))?e:null}var _t=(e,t)=>{var r,a,n;e&&"supsub"===e.type?(r=(a=Yt(e.base,"accent")).base,e.base=r,n=function(e){if(e instanceof j)return e;throw new Error("Expected span<HtmlDomNode> but got "+String(e)+".")}(kt(e,t)),e.base=a):r=(a=Yt(e,"accent")).base;var i=kt(r,t.havingCrampedStyle()),o=0;if(a.isShifty&&m.isCharacterBox(r)){var s=m.getBaseElem(r);o=re(kt(s,t.havingCrampedStyle())).skew}var l,h="\\c"===a.label,c=h?i.height+i.depth:Math.min(i.height,t.fontMetrics().xHeight);if(a.isStretchy)l=Ut(a,t),l=Je.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"elem",elem:l,wrapperClasses:["svg-align"],wrapperStyle:o>0?{width:"calc(100% - "+G(2*o)+")",marginLeft:G(2*o)}:void 0}]},t);else{var p,u;"\\vec"===a.label?(p=Je.staticSvg("vec",t),u=Je.svgData.vec[1]):((p=re(p=Je.makeOrd({mode:a.mode,text:a.label},t,"textord"))).italic=0,u=p.width,h&&(c+=p.depth)),l=Je.makeSpan(["accent-body"],[p]);var d="\\textcircled"===a.label;d&&(l.classes.push("accent-full"),c=i.height);var g=o;d||(g-=u/2),l.style.left=G(g),"\\textcircled"===a.label&&(l.style.top=".2em"),l=Je.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"kern",size:-c},{type:"elem",elem:l}]},t)}var f=Je.makeSpan(["mord","accent"],[l],t);return n?(n.children[0]=f,n.height=Math.max(f.height,n.height),n.classes[0]="mord",n):f},jt=(e,t)=>{var r=e.isStretchy?Gt(e.label):new Bt.MathNode("mo",[Ct(e.label,e.mode)]),a=new Bt.MathNode("mover",[Ot(e.base,t),r]);return a.setAttribute("accent","true"),a},$t=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map(e=>"\\"+e).join("|"));st({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:(e,t)=>{var r=ht(t[0]),a=!$t.test(e.funcName),n=!a||"\\widehat"===e.funcName||"\\widetilde"===e.funcName||"\\widecheck"===e.funcName;return{type:"accent",mode:e.parser.mode,label:e.funcName,isStretchy:a,isShifty:n,base:r}},htmlBuilder:_t,mathmlBuilder:jt}),st({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:(e,t)=>{var r=t[0],a=e.parser.mode;return"math"===a&&(e.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+e.funcName+" works only in text mode"),a="text"),{type:"accent",mode:a,label:e.funcName,isStretchy:!1,isShifty:!0,base:r}},htmlBuilder:_t,mathmlBuilder:jt}),st({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=t[0];return{type:"accentUnder",mode:r.mode,label:a,base:n}},htmlBuilder:(e,t)=>{var r=kt(e.base,t),a=Ut(e,t),n="\\utilde"===e.label?.12:0,i=Je.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:a,wrapperClasses:["svg-align"]},{type:"kern",size:n},{type:"elem",elem:r}]},t);return Je.makeSpan(["mord","accentunder"],[i],t)},mathmlBuilder:(e,t)=>{var r=Gt(e.label),a=new Bt.MathNode("munder",[Ot(e.base,t),r]);return a.setAttribute("accentunder","true"),a}});var Zt=e=>{var t=new Bt.MathNode("mpadded",e?[e]:[]);return t.setAttribute("width","+0.6em"),t.setAttribute("lspace","0.3em"),t};st({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler(e,t,r){var{parser:a,funcName:n}=e;return{type:"xArrow",mode:a.mode,label:n,body:t[0],below:r[0]}},htmlBuilder(e,t){var r,a=t.style,n=t.havingStyle(a.sup()),i=Je.wrapFragment(kt(e.body,n,t),t),o="\\x"===e.label.slice(0,2)?"x":"cd";i.classes.push(o+"-arrow-pad"),e.below&&(n=t.havingStyle(a.sub()),(r=Je.wrapFragment(kt(e.below,n,t),t)).classes.push(o+"-arrow-pad"));var s,l=Ut(e,t),h=-t.fontMetrics().axisHeight+.5*l.height,m=-t.fontMetrics().axisHeight-.5*l.height-.111;if((i.depth>.25||"\\xleftequilibrium"===e.label)&&(m-=i.depth),r){var c=-t.fontMetrics().axisHeight+r.height+.5*l.height+.111;s=Je.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h},{type:"elem",elem:r,shift:c}]},t)}else s=Je.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h}]},t);return s.children[0].children[0].children[1].classes.push("svg-align"),Je.makeSpan(["mrel","x-arrow"],[s],t)},mathmlBuilder(e,t){var r,a=Gt(e.label);if(a.setAttribute("minsize","x"===e.label.charAt(0)?"1.75em":"3.0em"),e.body){var n=Zt(Ot(e.body,t));if(e.below){var i=Zt(Ot(e.below,t));r=new Bt.MathNode("munderover",[a,i,n])}else r=new Bt.MathNode("mover",[a,n])}else if(e.below){var o=Zt(Ot(e.below,t));r=new Bt.MathNode("munder",[a,o])}else r=Zt(),r=new Bt.MathNode("mover",[a,r]);return r}});var Kt=Je.makeSpan;function Jt(e,t){var r=ft(e.body,t,!0);return Kt([e.mclass],r,t)}function Qt(e,t){var r,a=Rt(e.body,t);return"minner"===e.mclass?r=new Bt.MathNode("mpadded",a):"mord"===e.mclass?e.isCharacterBox?(r=a[0]).type="mi":r=new Bt.MathNode("mi",a):(e.isCharacterBox?(r=a[0]).type="mo":r=new Bt.MathNode("mo",a),"mbin"===e.mclass?(r.attributes.lspace="0.22em",r.attributes.rspace="0.22em"):"mpunct"===e.mclass?(r.attributes.lspace="0em",r.attributes.rspace="0.17em"):"mopen"===e.mclass||"mclose"===e.mclass?(r.attributes.lspace="0em",r.attributes.rspace="0em"):"minner"===e.mclass&&(r.attributes.lspace="0.0556em",r.attributes.width="+0.1111em")),r}st({type:"mclass",names:["\\mathord","\\mathbin","\\mathrel","\\mathopen","\\mathclose","\\mathpunct","\\mathinner"],props:{numArgs:1,primitive:!0},handler(e,t){var{parser:r,funcName:a}=e,n=t[0];return{type:"mclass",mode:r.mode,mclass:"m"+a.slice(5),body:mt(n),isCharacterBox:m.isCharacterBox(n)}},htmlBuilder:Jt,mathmlBuilder:Qt});var er=e=>{var t="ordgroup"===e.type&&e.body.length?e.body[0]:e;return"atom"!==t.type||"bin"!==t.family&&"rel"!==t.family?"mord":"m"+t.family};st({type:"mclass",names:["\\@binrel"],props:{numArgs:2},handler(e,t){var{parser:r}=e;return{type:"mclass",mode:r.mode,mclass:er(t[0]),body:mt(t[1]),isCharacterBox:m.isCharacterBox(t[1])}}}),st({type:"mclass",names:["\\stackrel","\\overset","\\underset"],props:{numArgs:2},handler(e,t){var r,{parser:a,funcName:n}=e,i=t[1],o=t[0];r="\\stackrel"!==n?er(i):"mrel";var s={type:"op",mode:i.mode,limits:!0,alwaysHandleSupSub:!0,parentIsSupSub:!1,symbol:!1,suppressBaseShift:"\\stackrel"!==n,body:mt(i)},l={type:"supsub",mode:o.mode,base:s,sup:"\\underset"===n?null:o,sub:"\\underset"===n?o:null};return{type:"mclass",mode:a.mode,mclass:r,body:[l],isCharacterBox:m.isCharacterBox(l)}},htmlBuilder:Jt,mathmlBuilder:Qt}),st({type:"pmb",names:["\\pmb"],props:{numArgs:1,allowedInText:!0},handler(e,t){var{parser:r}=e;return{type:"pmb",mode:r.mode,mclass:er(t[0]),body:mt(t[0])}},htmlBuilder(e,t){var r=ft(e.body,t,!0),a=Je.makeSpan([e.mclass],r,t);return a.style.textShadow="0.02em 0.01em 0.04px",a},mathmlBuilder(e,t){var r=Rt(e.body,t),a=new Bt.MathNode("mstyle",r);return a.setAttribute("style","text-shadow: 0.02em 0.01em 0.04px"),a}});var tr={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},rr=()=>({type:"styling",body:[],mode:"math",style:"display"}),ar=e=>"textord"===e.type&&"@"===e.text,nr=(e,t)=>("mathord"===e.type||"atom"===e.type)&&e.text===t;function ir(e,t,r){var a=tr[e];switch(a){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return r.callFunction(a,[t[0]],[t[1]]);case"\\uparrow":case"\\downarrow":var n={type:"atom",text:a,mode:"math",family:"rel"},i={type:"ordgroup",mode:"math",body:[r.callFunction("\\\\cdleft",[t[0]],[]),r.callFunction("\\Big",[n],[]),r.callFunction("\\\\cdright",[t[1]],[])]};return r.callFunction("\\\\cdparent",[i],[]);case"\\\\cdlongequal":return r.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":return r.callFunction("\\Big",[{type:"textord",text:"\\Vert",mode:"math"}],[]);default:return{type:"textord",text:" ",mode:"math"}}}st({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler(e,t){var{parser:r,funcName:a}=e;return{type:"cdlabel",mode:r.mode,side:a.slice(4),label:t[0]}},htmlBuilder(e,t){var r=t.havingStyle(t.style.sup()),a=Je.wrapFragment(kt(e.label,r,t),t);return a.classes.push("cd-label-"+e.side),a.style.bottom=G(.8-a.depth),a.height=0,a.depth=0,a},mathmlBuilder(e,t){var r=new Bt.MathNode("mrow",[Ot(e.label,t)]);return(r=new Bt.MathNode("mpadded",[r])).setAttribute("width","0"),"left"===e.side&&r.setAttribute("lspace","-1width"),r.setAttribute("voffset","0.7em"),(r=new Bt.MathNode("mstyle",[r])).setAttribute("displaystyle","false"),r.setAttribute("scriptlevel","1"),r}}),st({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler(e,t){var{parser:r}=e;return{type:"cdlabelparent",mode:r.mode,fragment:t[0]}},htmlBuilder(e,t){var r=Je.wrapFragment(kt(e.fragment,t),t);return r.classes.push("cd-vert-arrow"),r},mathmlBuilder:(e,t)=>new Bt.MathNode("mrow",[Ot(e.fragment,t)])}),st({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler(e,t){for(var{parser:r}=e,a=Yt(t[0],"ordgroup").body,n="",o=0;o<a.length;o++){n+=Yt(a[o],"textord").text}var s,l=parseInt(n);if(isNaN(l))throw new i("\\@char has non-numeric argument "+n);if(l<0||l>=1114111)throw new i("\\@char with invalid code point "+n);return l<=65535?s=String.fromCharCode(l):(l-=65536,s=String.fromCharCode(55296+(l>>10),56320+(1023&l))),{type:"textord",mode:r.mode,text:s}}});var or=(e,t)=>{var r=ft(e.body,t.withColor(e.color),!1);return Je.makeFragment(r)},sr=(e,t)=>{var r=Rt(e.body,t.withColor(e.color)),a=new Bt.MathNode("mstyle",r);return a.setAttribute("mathcolor",e.color),a};st({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler(e,t){var{parser:r}=e,a=Yt(t[0],"color-token").color,n=t[1];return{type:"color",mode:r.mode,color:a,body:mt(n)}},htmlBuilder:or,mathmlBuilder:sr}),st({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler(e,t){var{parser:r,breakOnTokenText:a}=e,n=Yt(t[0],"color-token").color;r.gullet.macros.set("\\current@color",n);var i=r.parseExpression(!0,a);return{type:"color",mode:r.mode,color:n,body:i}},htmlBuilder:or,mathmlBuilder:sr}),st({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:0,allowedInText:!0},handler(e,t,r){var{parser:a}=e,n="["===a.gullet.future().text?a.parseSizeGroup(!0):null,i=!a.settings.displayMode||!a.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:a.mode,newLine:i,size:n&&Yt(n,"size").value}},htmlBuilder(e,t){var r=Je.makeSpan(["mspace"],[],t);return e.newLine&&(r.classes.push("newline"),e.size&&(r.style.marginTop=G(F(e.size,t)))),r},mathmlBuilder(e,t){var r=new Bt.MathNode("mspace");return e.newLine&&(r.setAttribute("linebreak","newline"),e.size&&r.setAttribute("height",G(F(e.size,t)))),r}});var lr={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},hr=e=>{var t=e.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(t))throw new i("Expected a control sequence",e);return t},mr=(e,t,r,a)=>{var n=e.gullet.macros.get(r.text);null==n&&(r.noexpand=!0,n={tokens:[r],numArgs:0,unexpandable:!e.gullet.isExpandable(r.text)}),e.gullet.macros.set(t,n,a)};st({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler(e){var{parser:t,funcName:r}=e;t.consumeSpaces();var a=t.fetch();if(lr[a.text])return"\\global"!==r&&"\\\\globallong"!==r||(a.text=lr[a.text]),Yt(t.parseFunction(),"internal");throw new i("Invalid token after macro prefix",a)}}),st({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){var{parser:t,funcName:r}=e,a=t.gullet.popToken(),n=a.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(n))throw new i("Expected a control sequence",a);for(var o,s=0,l=[[]];"{"!==t.gullet.future().text;)if("#"===(a=t.gullet.popToken()).text){if("{"===t.gullet.future().text){o=t.gullet.future(),l[s].push("{");break}if(a=t.gullet.popToken(),!/^[1-9]$/.test(a.text))throw new i('Invalid argument number "'+a.text+'"');if(parseInt(a.text)!==s+1)throw new i('Argument number "'+a.text+'" out of order');s++,l.push([])}else{if("EOF"===a.text)throw new i("Expected a macro definition");l[s].push(a.text)}var{tokens:h}=t.gullet.consumeArg();return o&&h.unshift(o),"\\edef"!==r&&"\\xdef"!==r||(h=t.gullet.expandTokens(h)).reverse(),t.gullet.macros.set(n,{tokens:h,numArgs:s,delimiters:l},r===lr[r]),{type:"internal",mode:t.mode}}}),st({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){var{parser:t,funcName:r}=e,a=hr(t.gullet.popToken());t.gullet.consumeSpaces();var n=(e=>{var t=e.gullet.popToken();return"="===t.text&&" "===(t=e.gullet.popToken()).text&&(t=e.gullet.popToken()),t})(t);return mr(t,a,n,"\\\\globallet"===r),{type:"internal",mode:t.mode}}}),st({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){var{parser:t,funcName:r}=e,a=hr(t.gullet.popToken()),n=t.gullet.popToken(),i=t.gullet.popToken();return mr(t,a,i,"\\\\globalfuture"===r),t.gullet.pushToken(i),t.gullet.pushToken(n),{type:"internal",mode:t.mode}}});var cr=function(e,t,r){var a=I(ie.math[e]&&ie.math[e].replace||e,t,r);if(!a)throw new Error("Unsupported symbol "+e+" and font size "+t+".");return a},pr=function(e,t,r,a){var n=r.havingBaseStyle(t),i=Je.makeSpan(a.concat(n.sizingClasses(r)),[e],r),o=n.sizeMultiplier/r.sizeMultiplier;return i.height*=o,i.depth*=o,i.maxFontSize=n.sizeMultiplier,i},ur=function(e,t,r){var a=t.havingBaseStyle(r),n=(1-t.sizeMultiplier/a.sizeMultiplier)*t.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=G(n),e.height-=n,e.depth+=n},dr=function(e,t,r,a,n,i){var o=function(e,t,r,a){return Je.makeSymbol(e,"Size"+t+"-Regular",r,a)}(e,t,n,a),s=pr(Je.makeSpan(["delimsizing","size"+t],[o],a),k.TEXT,a,i);return r&&ur(s,a,k.TEXT),s},gr=function(e,t,r){var a;return a="Size1-Regular"===t?"delim-size1":"delim-size4",{type:"elem",elem:Je.makeSpan(["delimsizinginner",a],[Je.makeSpan([],[Je.makeSymbol(e,t,r)])])}},fr=function(e,t,r){var a=C["Size4-Regular"][e.charCodeAt(0)]?C["Size4-Regular"][e.charCodeAt(0)][4]:C["Size1-Regular"][e.charCodeAt(0)][4],n=new ee("inner",function(e,t){switch(e){case"\u239c":return"M291 0 H417 V"+t+" H291z M291 0 H417 V"+t+" H291z";case"\u2223":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z";case"\u2225":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145zM367 0 H410 V"+t+" H367z M367 0 H410 V"+t+" H367z";case"\u239f":return"M457 0 H583 V"+t+" H457z M457 0 H583 V"+t+" H457z";case"\u23a2":return"M319 0 H403 V"+t+" H319z M319 0 H403 V"+t+" H319z";case"\u23a5":return"M263 0 H347 V"+t+" H263z M263 0 H347 V"+t+" H263z";case"\u23aa":return"M384 0 H504 V"+t+" H384z M384 0 H504 V"+t+" H384z";case"\u23d0":return"M312 0 H355 V"+t+" H312z M312 0 H355 V"+t+" H312z";case"\u2016":return"M257 0 H300 V"+t+" H257z M257 0 H300 V"+t+" H257zM478 0 H521 V"+t+" H478z M478 0 H521 V"+t+" H478z";default:return""}}(e,Math.round(1e3*t))),i=new Q([n],{width:G(a),height:G(t),style:"width:"+G(a),viewBox:"0 0 "+1e3*a+" "+Math.round(1e3*t),preserveAspectRatio:"xMinYMin"}),o=Je.makeSvgSpan([],[i],r);return o.height=t,o.style.height=G(t),o.style.width=G(a),{type:"elem",elem:o}},vr={type:"kern",size:-.008},br=["|","\\lvert","\\rvert","\\vert"],yr=["\\|","\\lVert","\\rVert","\\Vert"],xr=function(e,t,r,a,n,i){var o,s,l,h,m="",c=0;o=l=h=e,s=null;var p="Size1-Regular";"\\uparrow"===e?l=h="\u23d0":"\\Uparrow"===e?l=h="\u2016":"\\downarrow"===e?o=l="\u23d0":"\\Downarrow"===e?o=l="\u2016":"\\updownarrow"===e?(o="\\uparrow",l="\u23d0",h="\\downarrow"):"\\Updownarrow"===e?(o="\\Uparrow",l="\u2016",h="\\Downarrow"):br.includes(e)?(l="\u2223",m="vert",c=333):yr.includes(e)?(l="\u2225",m="doublevert",c=556):"["===e||"\\lbrack"===e?(o="\u23a1",l="\u23a2",h="\u23a3",p="Size4-Regular",m="lbrack",c=667):"]"===e||"\\rbrack"===e?(o="\u23a4",l="\u23a5",h="\u23a6",p="Size4-Regular",m="rbrack",c=667):"\\lfloor"===e||"\u230a"===e?(l=o="\u23a2",h="\u23a3",p="Size4-Regular",m="lfloor",c=667):"\\lceil"===e||"\u2308"===e?(o="\u23a1",l=h="\u23a2",p="Size4-Regular",m="lceil",c=667):"\\rfloor"===e||"\u230b"===e?(l=o="\u23a5",h="\u23a6",p="Size4-Regular",m="rfloor",c=667):"\\rceil"===e||"\u2309"===e?(o="\u23a4",l=h="\u23a5",p="Size4-Regular",m="rceil",c=667):"("===e||"\\lparen"===e?(o="\u239b",l="\u239c",h="\u239d",p="Size4-Regular",m="lparen",c=875):")"===e||"\\rparen"===e?(o="\u239e",l="\u239f",h="\u23a0",p="Size4-Regular",m="rparen",c=875):"\\{"===e||"\\lbrace"===e?(o="\u23a7",s="\u23a8",h="\u23a9",l="\u23aa",p="Size4-Regular"):"\\}"===e||"\\rbrace"===e?(o="\u23ab",s="\u23ac",h="\u23ad",l="\u23aa",p="Size4-Regular"):"\\lgroup"===e||"\u27ee"===e?(o="\u23a7",h="\u23a9",l="\u23aa",p="Size4-Regular"):"\\rgroup"===e||"\u27ef"===e?(o="\u23ab",h="\u23ad",l="\u23aa",p="Size4-Regular"):"\\lmoustache"===e||"\u23b0"===e?(o="\u23a7",h="\u23ad",l="\u23aa",p="Size4-Regular"):"\\rmoustache"!==e&&"\u23b1"!==e||(o="\u23ab",h="\u23a9",l="\u23aa",p="Size4-Regular");var u=cr(o,p,n),d=u.height+u.depth,g=cr(l,p,n),f=g.height+g.depth,v=cr(h,p,n),b=v.height+v.depth,y=0,x=1;if(null!==s){var w=cr(s,p,n);y=w.height+w.depth,x=2}var S=d+b+y,M=S+Math.max(0,Math.ceil((t-S)/(x*f)))*x*f,z=a.fontMetrics().axisHeight;r&&(z*=a.sizeMultiplier);var A=M/2-z,T=[];if(m.length>0){var B=M-d-b,C=Math.round(1e3*M),N=function(e,t){switch(e){case"lbrack":return"M403 1759 V84 H666 V0 H319 V1759 v"+t+" v1759 h347 v-84\nH403z M403 1759 V0 H319 V1759 v"+t+" v1759 h84z";case"rbrack":return"M347 1759 V0 H0 V84 H263 V1759 v"+t+" v1759 H0 v84 H347z\nM347 1759 V0 H263 V1759 v"+t+" v1759 h84z";case"vert":return"M145 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v"+t+" v585 h43z";case"doublevert":return"M145 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v"+t+" v585 h43z\nM367 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M410 15 H367 v585 v"+t+" v585 h43z";case"lfloor":return"M319 602 V0 H403 V602 v"+t+" v1715 h263 v84 H319z\nMM319 602 V0 H403 V602 v"+t+" v1715 H319z";case"rfloor":return"M319 602 V0 H403 V602 v"+t+" v1799 H0 v-84 H319z\nMM319 602 V0 H403 V602 v"+t+" v1715 H319z";case"lceil":return"M403 1759 V84 H666 V0 H319 V1759 v"+t+" v602 h84z\nM403 1759 V0 H319 V1759 v"+t+" v602 h84z";case"rceil":return"M347 1759 V0 H0 V84 H263 V1759 v"+t+" v602 h84z\nM347 1759 V0 h-84 V1759 v"+t+" v602 h84z";case"lparen":return"M863,9c0,-2,-2,-5,-6,-9c0,0,-17,0,-17,0c-12.7,0,-19.3,0.3,-20,1\nc-5.3,5.3,-10.3,11,-15,17c-242.7,294.7,-395.3,682,-458,1162c-21.3,163.3,-33.3,349,\n-36,557 l0,"+(t+84)+"c0.2,6,0,26,0,60c2,159.3,10,310.7,24,454c53.3,528,210,\n949.7,470,1265c4.7,6,9.7,11.7,15,17c0.7,0.7,7,1,19,1c0,0,18,0,18,0c4,-4,6,-7,6,-9\nc0,-2.7,-3.3,-8.7,-10,-18c-135.3,-192.7,-235.5,-414.3,-300.5,-665c-65,-250.7,-102.5,\n-544.7,-112.5,-882c-2,-104,-3,-167,-3,-189\nl0,-"+(t+92)+"c0,-162.7,5.7,-314,17,-454c20.7,-272,63.7,-513,129,-723c65.3,\n-210,155.3,-396.3,270,-559c6.7,-9.3,10,-15.3,10,-18z";case"rparen":return"M76,0c-16.7,0,-25,3,-25,9c0,2,2,6.3,6,13c21.3,28.7,42.3,60.3,\n63,95c96.7,156.7,172.8,332.5,228.5,527.5c55.7,195,92.8,416.5,111.5,664.5\nc11.3,139.3,17,290.7,17,454c0,28,1.7,43,3.3,45l0,"+(t+9)+"\nc-3,4,-3.3,16.7,-3.3,38c0,162,-5.7,313.7,-17,455c-18.7,248,-55.8,469.3,-111.5,664\nc-55.7,194.7,-131.8,370.3,-228.5,527c-20.7,34.7,-41.7,66.3,-63,95c-2,3.3,-4,7,-6,11\nc0,7.3,5.7,11,17,11c0,0,11,0,11,0c9.3,0,14.3,-0.3,15,-1c5.3,-5.3,10.3,-11,15,-17\nc242.7,-294.7,395.3,-681.7,458,-1161c21.3,-164.7,33.3,-350.7,36,-558\nl0,-"+(t+144)+"c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7,\n-470,-1265c-4.7,-6,-9.7,-11.7,-15,-17c-0.7,-0.7,-6.7,-1,-18,-1z";default:throw new Error("Unknown stretchy delimiter.")}}(m,Math.round(1e3*B)),q=new ee(m,N),I=(c/1e3).toFixed(3)+"em",R=(C/1e3).toFixed(3)+"em",H=new Q([q],{width:I,height:R,viewBox:"0 0 "+c+" "+C}),O=Je.makeSvgSpan([],[H],a);O.height=C/1e3,O.style.width=I,O.style.height=R,T.push({type:"elem",elem:O})}else{if(T.push(gr(h,p,n)),T.push(vr),null===s){var E=M-d-b+.016;T.push(fr(l,E,a))}else{var L=(M-d-b-y)/2+.016;T.push(fr(l,L,a)),T.push(vr),T.push(gr(s,p,n)),T.push(vr),T.push(fr(l,L,a))}T.push(vr),T.push(gr(o,p,n))}var D=a.havingBaseStyle(k.TEXT),V=Je.makeVList({positionType:"bottom",positionData:A,children:T},D);return pr(Je.makeSpan(["delimsizing","mult"],[V],D),k.TEXT,a,i)},wr=.08,kr=function(e,t,r,a,n){var i=function(e,t,r){t*=1e3;var a="";switch(e){case"sqrtMain":a=function(e,t){return"M95,"+(622+e+t)+"\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl"+e/2.075+" -"+e+"\nc5.3,-9.3,12,-14,20,-14\nH400000v"+(40+e)+"H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM"+(834+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,A);break;case"sqrtSize1":a=function(e,t){return"M263,"+(601+e+t)+"c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl"+e/2.084+" -"+e+"\nc4.7,-7.3,11,-11,19,-11\nH40000v"+(40+e)+"H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,A);break;case"sqrtSize2":a=function(e,t){return"M983 "+(10+e+t)+"\nl"+e/3.13+" -"+e+"\nc4,-6.7,10,-10,18,-10 H400000v"+(40+e)+"\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,A);break;case"sqrtSize3":a=function(e,t){return"M424,"+(2398+e+t)+"\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl"+e/4.223+" -"+e+"c4,-6.7,10,-10,18,-10 H400000\nv"+(40+e)+"H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M"+(1001+e)+" "+t+"\nh400000v"+(40+e)+"h-400000z"}(t,A);break;case"sqrtSize4":a=function(e,t){return"M473,"+(2713+e+t)+"\nc339.3,-1799.3,509.3,-2700,510,-2702 l"+e/5.298+" -"+e+"\nc3.3,-7.3,9.3,-11,18,-11 H400000v"+(40+e)+"H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM"+(1001+e)+" "+t+"h400000v"+(40+e)+"H1017.7z"}(t,A);break;case"sqrtTall":a=function(e,t,r){return"M702 "+(e+t)+"H400000"+(40+e)+"\nH742v"+(r-54-t-e)+"l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 "+t+"H400000v"+(40+e)+"H742z"}(t,A,r)}return a}(e,a,r),o=new ee(e,i),s=new Q([o],{width:"400em",height:G(t),viewBox:"0 0 400000 "+r,preserveAspectRatio:"xMinYMin slice"});return Je.makeSvgSpan(["hide-tail"],[s],n)},Sr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","\\surd"],Mr=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1"],zr=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],Ar=[0,1.2,1.8,2.4,3],Tr=[{type:"small",style:k.SCRIPTSCRIPT},{type:"small",style:k.SCRIPT},{type:"small",style:k.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],Br=[{type:"small",style:k.SCRIPTSCRIPT},{type:"small",style:k.SCRIPT},{type:"small",style:k.TEXT},{type:"stack"}],Cr=[{type:"small",style:k.SCRIPTSCRIPT},{type:"small",style:k.SCRIPT},{type:"small",style:k.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],Nr=function(e){if("small"===e.type)return"Main-Regular";if("large"===e.type)return"Size"+e.size+"-Regular";if("stack"===e.type)return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},qr=function(e,t,r,a){for(var n=Math.min(2,3-a.style.size);n<r.length&&"stack"!==r[n].type;n++){var i=cr(e,Nr(r[n]),"math"),o=i.height+i.depth;if("small"===r[n].type&&(o*=a.havingBaseStyle(r[n].style).sizeMultiplier),o>t)return r[n]}return r[r.length-1]},Ir=function(e,t,r,a,n,i){var o;"<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),o=zr.includes(e)?Tr:Sr.includes(e)?Cr:Br;var s=qr(e,t,o,a);return"small"===s.type?function(e,t,r,a,n,i){var o=Je.makeSymbol(e,"Main-Regular",n,a),s=pr(o,t,a,i);return r&&ur(s,a,t),s}(e,s.style,r,a,n,i):"large"===s.type?dr(e,s.size,r,a,n,i):xr(e,t,r,a,n,i)},Rr={sqrtImage:function(e,t){var r,a,n=t.havingBaseSizing(),i=qr("\\surd",e*n.sizeMultiplier,Cr,n),o=n.sizeMultiplier,s=Math.max(0,t.minRuleThickness-t.fontMetrics().sqrtRuleThickness),l=0,h=0,m=0;return"small"===i.type?(e<1?o=1:e<1.4&&(o=.7),h=(1+s)/o,(r=kr("sqrtMain",l=(1+s+wr)/o,m=1e3+1e3*s+80,s,t)).style.minWidth="0.853em",a=.833/o):"large"===i.type?(m=1080*Ar[i.size],h=(Ar[i.size]+s)/o,l=(Ar[i.size]+s+wr)/o,(r=kr("sqrtSize"+i.size,l,m,s,t)).style.minWidth="1.02em",a=1/o):(l=e+s+wr,h=e+s,m=Math.floor(1e3*e+s)+80,(r=kr("sqrtTall",l,m,s,t)).style.minWidth="0.742em",a=1.056),r.height=h,r.style.height=G(l),{span:r,advanceWidth:a,ruleWidth:(t.fontMetrics().sqrtRuleThickness+s)*o}},sizedDelim:function(e,t,r,a,n){if("<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),Sr.includes(e)||zr.includes(e))return dr(e,t,!1,r,a,n);if(Mr.includes(e))return xr(e,Ar[t],!1,r,a,n);throw new i("Illegal delimiter: '"+e+"'")},sizeToMaxHeight:Ar,customSizedDelim:Ir,leftRightDelim:function(e,t,r,a,n,i){var o=a.fontMetrics().axisHeight*a.sizeMultiplier,s=5/a.fontMetrics().ptPerEm,l=Math.max(t-o,r+o),h=Math.max(l/500*901,2*l-s);return Ir(e,h,!0,a,n,i)}},Hr={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},Or=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27e8","\\rangle","\u27e9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function Er(e,t){var r=Wt(e);if(r&&Or.includes(r.text))return r;throw new i(r?"Invalid delimiter '"+r.text+"' after '"+t.funcName+"'":"Invalid delimiter type '"+e.type+"'",e)}function Lr(e){if(!e.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}st({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:(e,t)=>{var r=Er(t[0],e);return{type:"delimsizing",mode:e.parser.mode,size:Hr[e.funcName].size,mclass:Hr[e.funcName].mclass,delim:r.text}},htmlBuilder:(e,t)=>"."===e.delim?Je.makeSpan([e.mclass]):Rr.sizedDelim(e.delim,e.size,t,e.mode,[e.mclass]),mathmlBuilder:e=>{var t=[];"."!==e.delim&&t.push(Ct(e.delim,e.mode));var r=new Bt.MathNode("mo",t);"mopen"===e.mclass||"mclose"===e.mclass?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r.setAttribute("stretchy","true");var a=G(Rr.sizeToMaxHeight[e.size]);return r.setAttribute("minsize",a),r.setAttribute("maxsize",a),r}}),st({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var r=e.parser.gullet.macros.get("\\current@color");if(r&&"string"!=typeof r)throw new i("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:e.parser.mode,delim:Er(t[0],e).text,color:r}}}),st({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var r=Er(t[0],e),a=e.parser;++a.leftrightDepth;var n=a.parseExpression(!1);--a.leftrightDepth,a.expect("\\right",!1);var i=Yt(a.parseFunction(),"leftright-right");return{type:"leftright",mode:a.mode,body:n,left:r.text,right:i.delim,rightColor:i.color}},htmlBuilder:(e,t)=>{Lr(e);for(var r,a,n=ft(e.body,t,!0,["mopen","mclose"]),i=0,o=0,s=!1,l=0;l<n.length;l++)n[l].isMiddle?s=!0:(i=Math.max(n[l].height,i),o=Math.max(n[l].depth,o));if(i*=t.sizeMultiplier,o*=t.sizeMultiplier,r="."===e.left?wt(t,["mopen"]):Rr.leftRightDelim(e.left,i,o,t,e.mode,["mopen"]),n.unshift(r),s)for(var h=1;h<n.length;h++){var m=n[h].isMiddle;m&&(n[h]=Rr.leftRightDelim(m.delim,i,o,m.options,e.mode,[]))}if("."===e.right)a=wt(t,["mclose"]);else{var c=e.rightColor?t.withColor(e.rightColor):t;a=Rr.leftRightDelim(e.right,i,o,c,e.mode,["mclose"])}return n.push(a),Je.makeSpan(["minner"],n,t)},mathmlBuilder:(e,t)=>{Lr(e);var r=Rt(e.body,t);if("."!==e.left){var a=new Bt.MathNode("mo",[Ct(e.left,e.mode)]);a.setAttribute("fence","true"),r.unshift(a)}if("."!==e.right){var n=new Bt.MathNode("mo",[Ct(e.right,e.mode)]);n.setAttribute("fence","true"),e.rightColor&&n.setAttribute("mathcolor",e.rightColor),r.push(n)}return Nt(r)}}),st({type:"middle",names:["\\middle"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var r=Er(t[0],e);if(!e.parser.leftrightDepth)throw new i("\\middle without preceding \\left",r);return{type:"middle",mode:e.parser.mode,delim:r.text}},htmlBuilder:(e,t)=>{var r;if("."===e.delim)r=wt(t,[]);else{r=Rr.sizedDelim(e.delim,1,t,e.mode,[]);var a={delim:e.delim,options:t};r.isMiddle=a}return r},mathmlBuilder:(e,t)=>{var r="\\vert"===e.delim||"|"===e.delim?Ct("|","text"):Ct(e.delim,e.mode),a=new Bt.MathNode("mo",[r]);return a.setAttribute("fence","true"),a.setAttribute("lspace","0.05em"),a.setAttribute("rspace","0.05em"),a}});var Dr=(e,t)=>{var r,a,n,i=Je.wrapFragment(kt(e.body,t),t),o=e.label.slice(1),s=t.sizeMultiplier,l=0,h=m.isCharacterBox(e.body);if("sout"===o)(r=Je.makeSpan(["stretchy","sout"])).height=t.fontMetrics().defaultRuleThickness/s,l=-.5*t.fontMetrics().xHeight;else if("phase"===o){var c=F({number:.6,unit:"pt"},t),p=F({number:.35,unit:"ex"},t);s/=t.havingBaseSizing().sizeMultiplier;var u=i.height+i.depth+c+p;i.style.paddingLeft=G(u/2+c);var d=Math.floor(1e3*u*s),g="M400000 "+(a=d)+" H0 L"+a/2+" 0 l65 45 L145 "+(a-80)+" H400000z",f=new Q([new ee("phase",g)],{width:"400em",height:G(d/1e3),viewBox:"0 0 400000 "+d,preserveAspectRatio:"xMinYMin slice"});(r=Je.makeSvgSpan(["hide-tail"],[f],t)).style.height=G(u),l=i.depth+c+p}else{/cancel/.test(o)?h||i.classes.push("cancel-pad"):"angl"===o?i.classes.push("anglpad"):i.classes.push("boxpad");var v=0,b=0,y=0;/box/.test(o)?(y=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness),b=v=t.fontMetrics().fboxsep+("colorbox"===o?0:y)):"angl"===o?(v=4*(y=Math.max(t.fontMetrics().defaultRuleThickness,t.minRuleThickness)),b=Math.max(0,.25-i.depth)):b=v=h?.2:0,r=Ft(i,o,v,b,t),/fbox|boxed|fcolorbox/.test(o)?(r.style.borderStyle="solid",r.style.borderWidth=G(y)):"angl"===o&&.049!==y&&(r.style.borderTopWidth=G(y),r.style.borderRightWidth=G(y)),l=i.depth+b,e.backgroundColor&&(r.style.backgroundColor=e.backgroundColor,e.borderColor&&(r.style.borderColor=e.borderColor))}if(e.backgroundColor)n=Je.makeVList({positionType:"individualShift",children:[{type:"elem",elem:r,shift:l},{type:"elem",elem:i,shift:0}]},t);else{var x=/cancel|phase/.test(o)?["svg-align"]:[];n=Je.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:0},{type:"elem",elem:r,shift:l,wrapperClasses:x}]},t)}return/cancel/.test(o)&&(n.height=i.height,n.depth=i.depth),/cancel/.test(o)&&!h?Je.makeSpan(["mord","cancel-lap"],[n],t):Je.makeSpan(["mord"],[n],t)},Vr=(e,t)=>{var r=0,a=new Bt.MathNode(e.label.indexOf("colorbox")>-1?"mpadded":"menclose",[Ot(e.body,t)]);switch(e.label){case"\\cancel":a.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":a.setAttribute("notation","downdiagonalstrike");break;case"\\phase":a.setAttribute("notation","phasorangle");break;case"\\sout":a.setAttribute("notation","horizontalstrike");break;case"\\fbox":a.setAttribute("notation","box");break;case"\\angl":a.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(r=t.fontMetrics().fboxsep*t.fontMetrics().ptPerEm,a.setAttribute("width","+"+2*r+"pt"),a.setAttribute("height","+"+2*r+"pt"),a.setAttribute("lspace",r+"pt"),a.setAttribute("voffset",r+"pt"),"\\fcolorbox"===e.label){var n=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness);a.setAttribute("style","border: "+n+"em solid "+String(e.borderColor))}break;case"\\xcancel":a.setAttribute("notation","updiagonalstrike downdiagonalstrike")}return e.backgroundColor&&a.setAttribute("mathbackground",e.backgroundColor),a};st({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler(e,t,r){var{parser:a,funcName:n}=e,i=Yt(t[0],"color-token").color,o=t[1];return{type:"enclose",mode:a.mode,label:n,backgroundColor:i,body:o}},htmlBuilder:Dr,mathmlBuilder:Vr}),st({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler(e,t,r){var{parser:a,funcName:n}=e,i=Yt(t[0],"color-token").color,o=Yt(t[1],"color-token").color,s=t[2];return{type:"enclose",mode:a.mode,label:n,backgroundColor:o,borderColor:i,body:s}},htmlBuilder:Dr,mathmlBuilder:Vr}),st({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler(e,t){var{parser:r}=e;return{type:"enclose",mode:r.mode,label:"\\fbox",body:t[0]}}}),st({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler(e,t){var{parser:r,funcName:a}=e,n=t[0];return{type:"enclose",mode:r.mode,label:a,body:n}},htmlBuilder:Dr,mathmlBuilder:Vr}),st({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler(e,t){var{parser:r}=e;return{type:"enclose",mode:r.mode,label:"\\angl",body:t[0]}}});var Pr={};function Fr(e){for(var{type:t,names:r,props:a,handler:n,htmlBuilder:i,mathmlBuilder:o}=e,s={type:t,numArgs:a.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:n},l=0;l<r.length;++l)Pr[r[l]]=s;i&&(it[t]=i),o&&(ot[t]=o)}var Gr={};function Ur(e,t){Gr[e]=t}function Yr(e){var t=[];e.consumeSpaces();var r=e.fetch().text;for("\\relax"===r&&(e.consume(),e.consumeSpaces(),r=e.fetch().text);"\\hline"===r||"\\hdashline"===r;)e.consume(),t.push("\\hdashline"===r),e.consumeSpaces(),r=e.fetch().text;return t}var Xr=e=>{if(!e.parser.settings.displayMode)throw new i("{"+e.envName+"} can be used only in display mode.")};function Wr(e){if(-1===e.indexOf("ed"))return-1===e.indexOf("*")}function _r(e,t,r){var{hskipBeforeAndAfter:a,addJot:o,cols:s,arraystretch:l,colSeparationType:h,autoTag:m,singleRow:c,emptySingleRow:p,maxNumCols:u,leqno:d}=t;if(e.gullet.beginGroup(),c||e.gullet.macros.set("\\cr","\\\\\\relax"),!l){var g=e.gullet.expandMacroAsText("\\arraystretch");if(null==g)l=1;else if(!(l=parseFloat(g))||l<0)throw new i("Invalid \\arraystretch: "+g)}e.gullet.beginGroup();var f=[],v=[f],b=[],y=[],x=null!=m?[]:void 0;function w(){m&&e.gullet.macros.set("\\@eqnsw","1",!0)}function k(){x&&(e.gullet.macros.get("\\df@tag")?(x.push(e.subparse([new n("\\df@tag")])),e.gullet.macros.set("\\df@tag",void 0,!0)):x.push(Boolean(m)&&"1"===e.gullet.macros.get("\\@eqnsw")))}for(w(),y.push(Yr(e));;){var S=e.parseExpression(!1,c?"\\end":"\\\\");e.gullet.endGroup(),e.gullet.beginGroup(),S={type:"ordgroup",mode:e.mode,body:S},r&&(S={type:"styling",mode:e.mode,style:r,body:[S]}),f.push(S);var M=e.fetch().text;if("&"===M){if(u&&f.length===u){if(c||h)throw new i("Too many tab characters: &",e.nextToken);e.settings.reportNonstrict("textEnv","Too few columns specified in the {array} column argument.")}e.consume()}else{if("\\end"===M){k(),1===f.length&&"styling"===S.type&&0===S.body[0].body.length&&(v.length>1||!p)&&v.pop(),y.length<v.length+1&&y.push([]);break}if("\\\\"!==M)throw new i("Expected & or \\\\ or \\cr or \\end",e.nextToken);e.consume();var z=void 0;" "!==e.gullet.future().text&&(z=e.parseSizeGroup(!0)),b.push(z?z.value:null),k(),y.push(Yr(e)),f=[],v.push(f),w()}}return e.gullet.endGroup(),e.gullet.endGroup(),{type:"array",mode:e.mode,addJot:o,arraystretch:l,body:v,cols:s,rowGaps:b,hskipBeforeAndAfter:a,hLinesBeforeRow:y,colSeparationType:h,tags:x,leqno:d}}function jr(e){return"d"===e.slice(0,1)?"display":"text"}var $r=function(e,t){var r,a,n=e.body.length,o=e.hLinesBeforeRow,s=0,l=new Array(n),h=[],c=Math.max(t.fontMetrics().arrayRuleWidth,t.minRuleThickness),p=1/t.fontMetrics().ptPerEm,u=5*p;e.colSeparationType&&"small"===e.colSeparationType&&(u=t.havingStyle(k.SCRIPT).sizeMultiplier/t.sizeMultiplier*.2778);var d="CD"===e.colSeparationType?F({number:3,unit:"ex"},t):12*p,g=3*p,f=e.arraystretch*d,v=.7*f,b=.3*f,y=0;function x(e){for(var t=0;t<e.length;++t)t>0&&(y+=.25),h.push({pos:y,isDashed:e[t]})}for(x(o[0]),r=0;r<e.body.length;++r){var w=e.body[r],S=v,M=b;s<w.length&&(s=w.length);var z=new Array(w.length);for(a=0;a<w.length;++a){var A=kt(w[a],t);M<A.depth&&(M=A.depth),S<A.height&&(S=A.height),z[a]=A}var T=e.rowGaps[r],B=0;T&&(B=F(T,t))>0&&(M<(B+=b)&&(M=B),B=0),e.addJot&&(M+=g),z.height=S,z.depth=M,y+=S,z.pos=y,y+=M+B,l[r]=z,x(o[r+1])}var C,N,q=y/2+t.fontMetrics().axisHeight,I=e.cols||[],R=[],H=[];if(e.tags&&e.tags.some(e=>e))for(r=0;r<n;++r){var O=l[r],E=O.pos-q,L=e.tags[r],D=void 0;(D=!0===L?Je.makeSpan(["eqn-num"],[],t):!1===L?Je.makeSpan([],[],t):Je.makeSpan([],ft(L,t,!0),t)).depth=O.depth,D.height=O.height,H.push({type:"elem",elem:D,shift:E})}for(a=0,N=0;a<s||N<I.length;++a,++N){for(var V=I[N]||{},P=!0;"separator"===V.type;){if(P||((C=Je.makeSpan(["arraycolsep"],[])).style.width=G(t.fontMetrics().doubleRuleSep),R.push(C)),"|"!==V.separator&&":"!==V.separator)throw new i("Invalid separator type: "+V.separator);var U="|"===V.separator?"solid":"dashed",Y=Je.makeSpan(["vertical-separator"],[],t);Y.style.height=G(y),Y.style.borderRightWidth=G(c),Y.style.borderRightStyle=U,Y.style.margin="0 "+G(-c/2);var X=y-q;X&&(Y.style.verticalAlign=G(-X)),R.push(Y),V=I[++N]||{},P=!1}if(!(a>=s)){var W=void 0;(a>0||e.hskipBeforeAndAfter)&&0!==(W=m.deflt(V.pregap,u))&&((C=Je.makeSpan(["arraycolsep"],[])).style.width=G(W),R.push(C));var _=[];for(r=0;r<n;++r){var j=l[r],$=j[a];if($){var Z=j.pos-q;$.depth=j.depth,$.height=j.height,_.push({type:"elem",elem:$,shift:Z})}}_=Je.makeVList({positionType:"individualShift",children:_},t),_=Je.makeSpan(["col-align-"+(V.align||"c")],[_]),R.push(_),(a<s-1||e.hskipBeforeAndAfter)&&0!==(W=m.deflt(V.postgap,u))&&((C=Je.makeSpan(["arraycolsep"],[])).style.width=G(W),R.push(C))}}if(l=Je.makeSpan(["mtable"],R),h.length>0){for(var K=Je.makeLineSpan("hline",t,c),J=Je.makeLineSpan("hdashline",t,c),Q=[{type:"elem",elem:l,shift:0}];h.length>0;){var ee=h.pop(),te=ee.pos-q;ee.isDashed?Q.push({type:"elem",elem:J,shift:te}):Q.push({type:"elem",elem:K,shift:te})}l=Je.makeVList({positionType:"individualShift",children:Q},t)}if(0===H.length)return Je.makeSpan(["mord"],[l],t);var re=Je.makeVList({positionType:"individualShift",children:H},t);return re=Je.makeSpan(["tag"],[re],t),Je.makeFragment([l,re])},Zr={c:"center ",l:"left ",r:"right "},Kr=function(e,t){for(var r=[],a=new Bt.MathNode("mtd",[],["mtr-glue"]),n=new Bt.MathNode("mtd",[],["mml-eqn-num"]),i=0;i<e.body.length;i++){for(var o=e.body[i],s=[],l=0;l<o.length;l++)s.push(new Bt.MathNode("mtd",[Ot(o[l],t)]));e.tags&&e.tags[i]&&(s.unshift(a),s.push(a),e.leqno?s.unshift(n):s.push(n)),r.push(new Bt.MathNode("mtr",s))}var h=new Bt.MathNode("mtable",r),m=.5===e.arraystretch?.1:.16+e.arraystretch-1+(e.addJot?.09:0);h.setAttribute("rowspacing",G(m));var c="",p="";if(e.cols&&e.cols.length>0){var u=e.cols,d="",g=!1,f=0,v=u.length;"separator"===u[0].type&&(c+="top ",f=1),"separator"===u[u.length-1].type&&(c+="bottom ",v-=1);for(var b=f;b<v;b++)"align"===u[b].type?(p+=Zr[u[b].align],g&&(d+="none "),g=!0):"separator"===u[b].type&&g&&(d+="|"===u[b].separator?"solid ":"dashed ",g=!1);h.setAttribute("columnalign",p.trim()),/[sd]/.test(d)&&h.setAttribute("columnlines",d.trim())}if("align"===e.colSeparationType){for(var y=e.cols||[],x="",w=1;w<y.length;w++)x+=w%2?"0em ":"1em ";h.setAttribute("columnspacing",x.trim())}else"alignat"===e.colSeparationType||"gather"===e.colSeparationType?h.setAttribute("columnspacing","0em"):"small"===e.colSeparationType?h.setAttribute("columnspacing","0.2778em"):"CD"===e.colSeparationType?h.setAttribute("columnspacing","0.5em"):h.setAttribute("columnspacing","1em");var k="",S=e.hLinesBeforeRow;c+=S[0].length>0?"left ":"",c+=S[S.length-1].length>0?"right ":"";for(var M=1;M<S.length-1;M++)k+=0===S[M].length?"none ":S[M][0]?"dashed ":"solid ";return/[sd]/.test(k)&&h.setAttribute("rowlines",k.trim()),""!==c&&(h=new Bt.MathNode("menclose",[h])).setAttribute("notation",c.trim()),e.arraystretch&&e.arraystretch<1&&(h=new Bt.MathNode("mstyle",[h])).setAttribute("scriptlevel","1"),h},Jr=function(e,t){-1===e.envName.indexOf("ed")&&Xr(e);var r,a=[],n=e.envName.indexOf("at")>-1?"alignat":"align",o="split"===e.envName,s=_r(e.parser,{cols:a,addJot:!0,autoTag:o?void 0:Wr(e.envName),emptySingleRow:!0,colSeparationType:n,maxNumCols:o?2:void 0,leqno:e.parser.settings.leqno},"display"),l=0,h={type:"ordgroup",mode:e.mode,body:[]};if(t[0]&&"ordgroup"===t[0].type){for(var m="",c=0;c<t[0].body.length;c++){m+=Yt(t[0].body[c],"textord").text}r=Number(m),l=2*r}var p=!l;s.body.forEach(function(e){for(var t=1;t<e.length;t+=2){var a=Yt(e[t],"styling");Yt(a.body[0],"ordgroup").body.unshift(h)}if(p)l<e.length&&(l=e.length);else{var n=e.length/2;if(r<n)throw new i("Too many math in a row: expected "+r+", but got "+n,e[0])}});for(var u=0;u<l;++u){var d="r",g=0;u%2==1?d="l":u>0&&p&&(g=1),a[u]={type:"align",align:d,pregap:g,postgap:0}}return s.colSeparationType=p?"align":"alignat",s};Fr({type:"array",names:["array","darray"],props:{numArgs:1},handler(e,t){var r=(Wt(t[0])?[t[0]]:Yt(t[0],"ordgroup").body).map(function(e){var t=Xt(e).text;if(-1!=="lcr".indexOf(t))return{type:"align",align:t};if("|"===t)return{type:"separator",separator:"|"};if(":"===t)return{type:"separator",separator:":"};throw new i("Unknown column alignment: "+t,e)}),a={cols:r,hskipBeforeAndAfter:!0,maxNumCols:r.length};return _r(e.parser,a,jr(e.envName))},htmlBuilder:$r,mathmlBuilder:Kr}),Fr({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler(e){var t={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[e.envName.replace("*","")],r="c",a={hskipBeforeAndAfter:!1,cols:[{type:"align",align:r}]};if("*"===e.envName.charAt(e.envName.length-1)){var n=e.parser;if(n.consumeSpaces(),"["===n.fetch().text){if(n.consume(),n.consumeSpaces(),r=n.fetch().text,-1==="lcr".indexOf(r))throw new i("Expected l or c or r",n.nextToken);n.consume(),n.consumeSpaces(),n.expect("]"),n.consume(),a.cols=[{type:"align",align:r}]}}var o=_r(e.parser,a,jr(e.envName)),s=Math.max(0,...o.body.map(e=>e.length));return o.cols=new Array(s).fill({type:"align",align:r}),t?{type:"leftright",mode:e.mode,body:[o],left:t[0],right:t[1],rightColor:void 0}:o},htmlBuilder:$r,mathmlBuilder:Kr}),Fr({type:"array",names:["smallmatrix"],props:{numArgs:0},handler(e){var t=_r(e.parser,{arraystretch:.5},"script");return t.colSeparationType="small",t},htmlBuilder:$r,mathmlBuilder:Kr}),Fr({type:"array",names:["subarray"],props:{numArgs:1},handler(e,t){var r=(Wt(t[0])?[t[0]]:Yt(t[0],"ordgroup").body).map(function(e){var t=Xt(e).text;if(-1!=="lc".indexOf(t))return{type:"align",align:t};throw new i("Unknown column alignment: "+t,e)});if(r.length>1)throw new i("{subarray} can contain only one column");var a={cols:r,hskipBeforeAndAfter:!1,arraystretch:.5};if((a=_r(e.parser,a,"script")).body.length>0&&a.body[0].length>1)throw new i("{subarray} can contain only one column");return a},htmlBuilder:$r,mathmlBuilder:Kr}),Fr({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler(e){var t=_r(e.parser,{arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},jr(e.envName));return{type:"leftright",mode:e.mode,body:[t],left:e.envName.indexOf("r")>-1?".":"\\{",right:e.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:$r,mathmlBuilder:Kr}),Fr({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:Jr,htmlBuilder:$r,mathmlBuilder:Kr}),Fr({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler(e){["gather","gather*"].includes(e.envName)&&Xr(e);var t={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",autoTag:Wr(e.envName),emptySingleRow:!0,leqno:e.parser.settings.leqno};return _r(e.parser,t,"display")},htmlBuilder:$r,mathmlBuilder:Kr}),Fr({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:Jr,htmlBuilder:$r,mathmlBuilder:Kr}),Fr({type:"array",names:["equation","equation*"],props:{numArgs:0},handler(e){Xr(e);var t={autoTag:Wr(e.envName),emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:e.parser.settings.leqno};return _r(e.parser,t,"display")},htmlBuilder:$r,mathmlBuilder:Kr}),Fr({type:"array",names:["CD"],props:{numArgs:0},handler:e=>(Xr(e),function(e){var t=[];for(e.gullet.beginGroup(),e.gullet.macros.set("\\cr","\\\\\\relax"),e.gullet.beginGroup();;){t.push(e.parseExpression(!1,"\\\\")),e.gullet.endGroup(),e.gullet.beginGroup();var r=e.fetch().text;if("&"!==r&&"\\\\"!==r){if("\\end"===r){0===t[t.length-1].length&&t.pop();break}throw new i("Expected \\\\ or \\cr or \\end",e.nextToken)}e.consume()}for(var a=[],n=[a],o=0;o<t.length;o++){for(var s=t[o],l=rr(),h=0;h<s.length;h++)if(ar(s[h])){a.push(l);var m=Xt(s[h+=1]).text,c=new Array(2);if(c[0]={type:"ordgroup",mode:"math",body:[]},c[1]={type:"ordgroup",mode:"math",body:[]},"=|.".indexOf(m)>-1);else{if(!("<>AV".indexOf(m)>-1))throw new i('Expected one of "<>AV=|." after @',s[h]);for(var p=0;p<2;p++){for(var u=!0,d=h+1;d<s.length;d++){if(nr(s[d],m)){u=!1,h=d;break}if(ar(s[d]))throw new i("Missing a "+m+" character to complete a CD arrow.",s[d]);c[p].body.push(s[d])}if(u)throw new i("Missing a "+m+" character to complete a CD arrow.",s[h])}}var g={type:"styling",body:[ir(m,c,e)],mode:"math",style:"display"};a.push(g),l=rr()}else l.body.push(s[h]);o%2==0?a.push(l):a.shift(),a=[],n.push(a)}return e.gullet.endGroup(),e.gullet.endGroup(),{type:"array",mode:"math",body:n,arraystretch:1,addJot:!0,rowGaps:[null],cols:new Array(n[0].length).fill({type:"align",align:"c",pregap:.25,postgap:.25}),colSeparationType:"CD",hLinesBeforeRow:new Array(n.length+1).fill([])}}(e.parser)),htmlBuilder:$r,mathmlBuilder:Kr}),Ur("\\nonumber","\\gdef\\@eqnsw{0}"),Ur("\\notag","\\nonumber"),st({type:"text",names:["\\hline","\\hdashline"],props:{numArgs:0,allowedInText:!0,allowedInMath:!0},handler(e,t){throw new i(e.funcName+" valid only within array environment")}});var Qr=Pr;st({type:"environment",names:["\\begin","\\end"],props:{numArgs:1,argTypes:["text"]},handler(e,t){var{parser:r,funcName:a}=e,n=t[0];if("ordgroup"!==n.type)throw new i("Invalid environment name",n);for(var o="",s=0;s<n.body.length;++s)o+=Yt(n.body[s],"textord").text;if("\\begin"===a){if(!Qr.hasOwnProperty(o))throw new i("No such environment: "+o,n);var l=Qr[o],{args:h,optArgs:m}=r.parseArguments("\\begin{"+o+"}",l),c={mode:r.mode,envName:o,parser:r},p=l.handler(c,h,m);r.expect("\\end",!1);var u=r.nextToken,d=Yt(r.parseFunction(),"environment");if(d.name!==o)throw new i("Mismatch: \\begin{"+o+"} matched by \\end{"+d.name+"}",u);return p}return{type:"environment",mode:r.mode,name:o,nameGroup:n}}});var ea=(e,t)=>{var r=e.font,a=t.withFont(r);return kt(e.body,a)},ta=(e,t)=>{var r=e.font,a=t.withFont(r);return Ot(e.body,a)},ra={"\\Bbb":"\\mathbb","\\bold":"\\mathbf","\\frak":"\\mathfrak","\\bm":"\\boldsymbol"};st({type:"font",names:["\\mathrm","\\mathit","\\mathbf","\\mathnormal","\\mathsfit","\\mathbb","\\mathcal","\\mathfrak","\\mathscr","\\mathsf","\\mathtt","\\Bbb","\\bold","\\frak"],props:{numArgs:1,allowedInArgument:!0},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=ht(t[0]),i=a;return i in ra&&(i=ra[i]),{type:"font",mode:r.mode,font:i.slice(1),body:n}},htmlBuilder:ea,mathmlBuilder:ta}),st({type:"mclass",names:["\\boldsymbol","\\bm"],props:{numArgs:1},handler:(e,t)=>{var{parser:r}=e,a=t[0],n=m.isCharacterBox(a);return{type:"mclass",mode:r.mode,mclass:er(a),body:[{type:"font",mode:r.mode,font:"boldsymbol",body:a}],isCharacterBox:n}}}),st({type:"font",names:["\\rm","\\sf","\\tt","\\bf","\\it","\\cal"],props:{numArgs:0,allowedInText:!0},handler:(e,t)=>{var{parser:r,funcName:a,breakOnTokenText:n}=e,{mode:i}=r,o=r.parseExpression(!0,n);return{type:"font",mode:i,font:"math"+a.slice(1),body:{type:"ordgroup",mode:r.mode,body:o}}},htmlBuilder:ea,mathmlBuilder:ta});var aa=(e,t)=>{var r=t;return"display"===e?r=r.id>=k.SCRIPT.id?r.text():k.DISPLAY:"text"===e&&r.size===k.DISPLAY.size?r=k.TEXT:"script"===e?r=k.SCRIPT:"scriptscript"===e&&(r=k.SCRIPTSCRIPT),r},na=(e,t)=>{var r,a=aa(e.size,t.style),n=a.fracNum(),i=a.fracDen();r=t.havingStyle(n);var o=kt(e.numer,r,t);if(e.continued){var s=8.5/t.fontMetrics().ptPerEm,l=3.5/t.fontMetrics().ptPerEm;o.height=o.height<s?s:o.height,o.depth=o.depth<l?l:o.depth}r=t.havingStyle(i);var h,m,c,p,u,d,g,f,v,b,y=kt(e.denom,r,t);if(e.hasBarLine?(e.barSize?(m=F(e.barSize,t),h=Je.makeLineSpan("frac-line",t,m)):h=Je.makeLineSpan("frac-line",t),m=h.height,c=h.height):(h=null,m=0,c=t.fontMetrics().defaultRuleThickness),a.size===k.DISPLAY.size||"display"===e.size?(p=t.fontMetrics().num1,u=m>0?3*c:7*c,d=t.fontMetrics().denom1):(m>0?(p=t.fontMetrics().num2,u=c):(p=t.fontMetrics().num3,u=3*c),d=t.fontMetrics().denom2),h){var x=t.fontMetrics().axisHeight;p-o.depth-(x+.5*m)<u&&(p+=u-(p-o.depth-(x+.5*m))),x-.5*m-(y.height-d)<u&&(d+=u-(x-.5*m-(y.height-d)));var w=-(x-.5*m);g=Je.makeVList({positionType:"individualShift",children:[{type:"elem",elem:y,shift:d},{type:"elem",elem:h,shift:w},{type:"elem",elem:o,shift:-p}]},t)}else{var S=p-o.depth-(y.height-d);S<u&&(p+=.5*(u-S),d+=.5*(u-S)),g=Je.makeVList({positionType:"individualShift",children:[{type:"elem",elem:y,shift:d},{type:"elem",elem:o,shift:-p}]},t)}return r=t.havingStyle(a),g.height*=r.sizeMultiplier/t.sizeMultiplier,g.depth*=r.sizeMultiplier/t.sizeMultiplier,f=a.size===k.DISPLAY.size?t.fontMetrics().delim1:a.size===k.SCRIPTSCRIPT.size?t.havingStyle(k.SCRIPT).fontMetrics().delim2:t.fontMetrics().delim2,v=null==e.leftDelim?wt(t,["mopen"]):Rr.customSizedDelim(e.leftDelim,f,!0,t.havingStyle(a),e.mode,["mopen"]),b=e.continued?Je.makeSpan([]):null==e.rightDelim?wt(t,["mclose"]):Rr.customSizedDelim(e.rightDelim,f,!0,t.havingStyle(a),e.mode,["mclose"]),Je.makeSpan(["mord"].concat(r.sizingClasses(t)),[v,Je.makeSpan(["mfrac"],[g]),b],t)},ia=(e,t)=>{var r=new Bt.MathNode("mfrac",[Ot(e.numer,t),Ot(e.denom,t)]);if(e.hasBarLine){if(e.barSize){var a=F(e.barSize,t);r.setAttribute("linethickness",G(a))}}else r.setAttribute("linethickness","0px");var n=aa(e.size,t.style);if(n.size!==t.style.size){r=new Bt.MathNode("mstyle",[r]);var i=n.size===k.DISPLAY.size?"true":"false";r.setAttribute("displaystyle",i),r.setAttribute("scriptlevel","0")}if(null!=e.leftDelim||null!=e.rightDelim){var o=[];if(null!=e.leftDelim){var s=new Bt.MathNode("mo",[new Bt.TextNode(e.leftDelim.replace("\\",""))]);s.setAttribute("fence","true"),o.push(s)}if(o.push(r),null!=e.rightDelim){var l=new Bt.MathNode("mo",[new Bt.TextNode(e.rightDelim.replace("\\",""))]);l.setAttribute("fence","true"),o.push(l)}return Nt(o)}return r};st({type:"genfrac",names:["\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom","\\\\atopfrac","\\\\bracefrac","\\\\brackfrac"],props:{numArgs:2,allowedInArgument:!0},handler:(e,t)=>{var r,{parser:a,funcName:n}=e,i=t[0],o=t[1],s=null,l=null,h="auto";switch(n){case"\\dfrac":case"\\frac":case"\\tfrac":r=!0;break;case"\\\\atopfrac":r=!1;break;case"\\dbinom":case"\\binom":case"\\tbinom":r=!1,s="(",l=")";break;case"\\\\bracefrac":r=!1,s="\\{",l="\\}";break;case"\\\\brackfrac":r=!1,s="[",l="]";break;default:throw new Error("Unrecognized genfrac command")}switch(n){case"\\dfrac":case"\\dbinom":h="display";break;case"\\tfrac":case"\\tbinom":h="text"}return{type:"genfrac",mode:a.mode,continued:!1,numer:i,denom:o,hasBarLine:r,leftDelim:s,rightDelim:l,size:h,barSize:null}},htmlBuilder:na,mathmlBuilder:ia}),st({type:"genfrac",names:["\\cfrac"],props:{numArgs:2},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=t[0],i=t[1];return{type:"genfrac",mode:r.mode,continued:!0,numer:n,denom:i,hasBarLine:!0,leftDelim:null,rightDelim:null,size:"display",barSize:null}}}),st({type:"infix",names:["\\over","\\choose","\\atop","\\brace","\\brack"],props:{numArgs:0,infix:!0},handler(e){var t,{parser:r,funcName:a,token:n}=e;switch(a){case"\\over":t="\\frac";break;case"\\choose":t="\\binom";break;case"\\atop":t="\\\\atopfrac";break;case"\\brace":t="\\\\bracefrac";break;case"\\brack":t="\\\\brackfrac";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",mode:r.mode,replaceWith:t,token:n}}});var oa=["display","text","script","scriptscript"],sa=function(e){var t=null;return e.length>0&&(t="."===(t=e)?null:t),t};st({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler(e,t){var r,{parser:a}=e,n=t[4],i=t[5],o=ht(t[0]),s="atom"===o.type&&"open"===o.family?sa(o.text):null,l=ht(t[1]),h="atom"===l.type&&"close"===l.family?sa(l.text):null,m=Yt(t[2],"size"),c=null;r=!!m.isBlank||(c=m.value).number>0;var p="auto",u=t[3];if("ordgroup"===u.type){if(u.body.length>0){var d=Yt(u.body[0],"textord");p=oa[Number(d.text)]}}else u=Yt(u,"textord"),p=oa[Number(u.text)];return{type:"genfrac",mode:a.mode,numer:n,denom:i,continued:!1,hasBarLine:r,barSize:c,leftDelim:s,rightDelim:h,size:p}},htmlBuilder:na,mathmlBuilder:ia}),st({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler(e,t){var{parser:r,funcName:a,token:n}=e;return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:Yt(t[0],"size").value,token:n}}}),st({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=t[0],i=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e}(Yt(t[1],"infix").size),o=t[2],s=i.number>0;return{type:"genfrac",mode:r.mode,numer:n,denom:o,continued:!1,hasBarLine:s,barSize:i,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:na,mathmlBuilder:ia});var la=(e,t)=>{var r,a,n=t.style;"supsub"===e.type?(r=e.sup?kt(e.sup,t.havingStyle(n.sup()),t):kt(e.sub,t.havingStyle(n.sub()),t),a=Yt(e.base,"horizBrace")):a=Yt(e,"horizBrace");var i,o=kt(a.base,t.havingBaseStyle(k.DISPLAY)),s=Ut(a,t);if(a.isOver?(i=Je.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:o},{type:"kern",size:.1},{type:"elem",elem:s}]},t)).children[0].children[0].children[1].classes.push("svg-align"):(i=Je.makeVList({positionType:"bottom",positionData:o.depth+.1+s.height,children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:o}]},t)).children[0].children[0].children[0].classes.push("svg-align"),r){var l=Je.makeSpan(["mord",a.isOver?"mover":"munder"],[i],t);i=a.isOver?Je.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:l},{type:"kern",size:.2},{type:"elem",elem:r}]},t):Je.makeVList({positionType:"bottom",positionData:l.depth+.2+r.height+r.depth,children:[{type:"elem",elem:r},{type:"kern",size:.2},{type:"elem",elem:l}]},t)}return Je.makeSpan(["mord",a.isOver?"mover":"munder"],[i],t)};st({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler(e,t){var{parser:r,funcName:a}=e;return{type:"horizBrace",mode:r.mode,label:a,isOver:/^\\over/.test(a),base:t[0]}},htmlBuilder:la,mathmlBuilder:(e,t)=>{var r=Gt(e.label);return new Bt.MathNode(e.isOver?"mover":"munder",[Ot(e.base,t),r])}}),st({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=t[1],n=Yt(t[0],"url").url;return r.settings.isTrusted({command:"\\href",url:n})?{type:"href",mode:r.mode,href:n,body:mt(a)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:(e,t)=>{var r=ft(e.body,t,!1);return Je.makeAnchor(e.href,[],r,t)},mathmlBuilder:(e,t)=>{var r=Ht(e.body,t);return r instanceof At||(r=new At("mrow",[r])),r.setAttribute("href",e.href),r}}),st({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=Yt(t[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:a}))return r.formatUnsupportedCmd("\\url");for(var n=[],i=0;i<a.length;i++){var o=a[i];"~"===o&&(o="\\textasciitilde"),n.push({type:"textord",mode:"text",text:o})}var s={type:"text",mode:r.mode,font:"\\texttt",body:n};return{type:"href",mode:r.mode,href:a,body:mt(s)}}}),st({type:"hbox",names:["\\hbox"],props:{numArgs:1,argTypes:["text"],allowedInText:!0,primitive:!0},handler(e,t){var{parser:r}=e;return{type:"hbox",mode:r.mode,body:mt(t[0])}},htmlBuilder(e,t){var r=ft(e.body,t,!1);return Je.makeFragment(r)},mathmlBuilder:(e,t)=>new Bt.MathNode("mrow",Rt(e.body,t))}),st({type:"html",names:["\\htmlClass","\\htmlId","\\htmlStyle","\\htmlData"],props:{numArgs:2,argTypes:["raw","original"],allowedInText:!0},handler:(e,t)=>{var r,{parser:a,funcName:n,token:o}=e,s=Yt(t[0],"raw").string,l=t[1];a.settings.strict&&a.settings.reportNonstrict("htmlExtension","HTML extension is disabled on strict mode");var h={};switch(n){case"\\htmlClass":h.class=s,r={command:"\\htmlClass",class:s};break;case"\\htmlId":h.id=s,r={command:"\\htmlId",id:s};break;case"\\htmlStyle":h.style=s,r={command:"\\htmlStyle",style:s};break;case"\\htmlData":for(var m=s.split(","),c=0;c<m.length;c++){var p=m[c].split("=");if(2!==p.length)throw new i("Error parsing key-value for \\htmlData");h["data-"+p[0].trim()]=p[1].trim()}r={command:"\\htmlData",attributes:h};break;default:throw new Error("Unrecognized html command")}return a.settings.isTrusted(r)?{type:"html",mode:a.mode,attributes:h,body:mt(l)}:a.formatUnsupportedCmd(n)},htmlBuilder:(e,t)=>{var r=ft(e.body,t,!1),a=["enclosing"];e.attributes.class&&a.push(...e.attributes.class.trim().split(/\s+/));var n=Je.makeSpan(a,r,t);for(var i in e.attributes)"class"!==i&&e.attributes.hasOwnProperty(i)&&n.setAttribute(i,e.attributes[i]);return n},mathmlBuilder:(e,t)=>Ht(e.body,t)}),st({type:"htmlmathml",names:["\\html@mathml"],props:{numArgs:2,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e;return{type:"htmlmathml",mode:r.mode,html:mt(t[0]),mathml:mt(t[1])}},htmlBuilder:(e,t)=>{var r=ft(e.html,t,!1);return Je.makeFragment(r)},mathmlBuilder:(e,t)=>Ht(e.mathml,t)});var ha=function(e){if(/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(e))return{number:+e,unit:"bp"};var t=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(e);if(!t)throw new i("Invalid size: '"+e+"' in \\includegraphics");var r={number:+(t[1]+t[2]),unit:t[3]};if(!P(r))throw new i("Invalid unit: '"+r.unit+"' in \\includegraphics.");return r};st({type:"includegraphics",names:["\\includegraphics"],props:{numArgs:1,numOptionalArgs:1,argTypes:["raw","url"],allowedInText:!1},handler:(e,t,r)=>{var{parser:a}=e,n={number:0,unit:"em"},o={number:.9,unit:"em"},s={number:0,unit:"em"},l="";if(r[0])for(var h=Yt(r[0],"raw").string.split(","),m=0;m<h.length;m++){var c=h[m].split("=");if(2===c.length){var p=c[1].trim();switch(c[0].trim()){case"alt":l=p;break;case"width":n=ha(p);break;case"height":o=ha(p);break;case"totalheight":s=ha(p);break;default:throw new i("Invalid key: '"+c[0]+"' in \\includegraphics.")}}}var u=Yt(t[0],"url").url;return""===l&&(l=(l=(l=u).replace(/^.*[\\/]/,"")).substring(0,l.lastIndexOf("."))),a.settings.isTrusted({command:"\\includegraphics",url:u})?{type:"includegraphics",mode:a.mode,alt:l,width:n,height:o,totalheight:s,src:u}:a.formatUnsupportedCmd("\\includegraphics")},htmlBuilder:(e,t)=>{var r=F(e.height,t),a=0;e.totalheight.number>0&&(a=F(e.totalheight,t)-r);var n=0;e.width.number>0&&(n=F(e.width,t));var i={height:G(r+a)};n>0&&(i.width=G(n)),a>0&&(i.verticalAlign=G(-a));var o=new Z(e.src,e.alt,i);return o.height=r,o.depth=a,o},mathmlBuilder:(e,t)=>{var r=new Bt.MathNode("mglyph",[]);r.setAttribute("alt",e.alt);var a=F(e.height,t),n=0;if(e.totalheight.number>0&&(n=F(e.totalheight,t)-a,r.setAttribute("valign",G(-n))),r.setAttribute("height",G(a+n)),e.width.number>0){var i=F(e.width,t);r.setAttribute("width",G(i))}return r.setAttribute("src",e.src),r}}),st({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler(e,t){var{parser:r,funcName:a}=e,n=Yt(t[0],"size");if(r.settings.strict){var i="m"===a[1],o="mu"===n.value.unit;i?(o||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" supports only mu units, not "+n.value.unit+" units"),"math"!==r.mode&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" works only in math mode")):o&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:n.value}},htmlBuilder:(e,t)=>Je.makeGlue(e.dimension,t),mathmlBuilder(e,t){var r=F(e.dimension,t);return new Bt.SpaceNode(r)}}),st({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=t[0];return{type:"lap",mode:r.mode,alignment:a.slice(5),body:n}},htmlBuilder:(e,t)=>{var r;"clap"===e.alignment?(r=Je.makeSpan([],[kt(e.body,t)]),r=Je.makeSpan(["inner"],[r],t)):r=Je.makeSpan(["inner"],[kt(e.body,t)]);var a=Je.makeSpan(["fix"],[]),n=Je.makeSpan([e.alignment],[r,a],t),i=Je.makeSpan(["strut"]);return i.style.height=G(n.height+n.depth),n.depth&&(i.style.verticalAlign=G(-n.depth)),n.children.unshift(i),n=Je.makeSpan(["thinbox"],[n],t),Je.makeSpan(["mord","vbox"],[n],t)},mathmlBuilder:(e,t)=>{var r=new Bt.MathNode("mpadded",[Ot(e.body,t)]);if("rlap"!==e.alignment){var a="llap"===e.alignment?"-1":"-0.5";r.setAttribute("lspace",a+"width")}return r.setAttribute("width","0px"),r}}),st({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(e,t){var{funcName:r,parser:a}=e,n=a.mode;a.switchMode("math");var i="\\("===r?"\\)":"$",o=a.parseExpression(!1,i);return a.expect(i),a.switchMode(n),{type:"styling",mode:a.mode,style:"text",body:o}}}),st({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(e,t){throw new i("Mismatched "+e.funcName)}});var ma=(e,t)=>{switch(t.style.size){case k.DISPLAY.size:return e.display;case k.TEXT.size:return e.text;case k.SCRIPT.size:return e.script;case k.SCRIPTSCRIPT.size:return e.scriptscript;default:return e.text}};st({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:(e,t)=>{var{parser:r}=e;return{type:"mathchoice",mode:r.mode,display:mt(t[0]),text:mt(t[1]),script:mt(t[2]),scriptscript:mt(t[3])}},htmlBuilder:(e,t)=>{var r=ma(e,t),a=ft(r,t,!1);return Je.makeFragment(a)},mathmlBuilder:(e,t)=>{var r=ma(e,t);return Ht(r,t)}});var ca=(e,t,r,a,n,i,o)=>{e=Je.makeSpan([],[e]);var s,l,h,c=r&&m.isCharacterBox(r);if(t){var p=kt(t,a.havingStyle(n.sup()),a);l={elem:p,kern:Math.max(a.fontMetrics().bigOpSpacing1,a.fontMetrics().bigOpSpacing3-p.depth)}}if(r){var u=kt(r,a.havingStyle(n.sub()),a);s={elem:u,kern:Math.max(a.fontMetrics().bigOpSpacing2,a.fontMetrics().bigOpSpacing4-u.height)}}if(l&&s){var d=a.fontMetrics().bigOpSpacing5+s.elem.height+s.elem.depth+s.kern+e.depth+o;h=Je.makeVList({positionType:"bottom",positionData:d,children:[{type:"kern",size:a.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:G(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e},{type:"kern",size:l.kern},{type:"elem",elem:l.elem,marginLeft:G(i)},{type:"kern",size:a.fontMetrics().bigOpSpacing5}]},a)}else if(s){var g=e.height-o;h=Je.makeVList({positionType:"top",positionData:g,children:[{type:"kern",size:a.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:G(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e}]},a)}else{if(!l)return e;var f=e.depth+o;h=Je.makeVList({positionType:"bottom",positionData:f,children:[{type:"elem",elem:e},{type:"kern",size:l.kern},{type:"elem",elem:l.elem,marginLeft:G(i)},{type:"kern",size:a.fontMetrics().bigOpSpacing5}]},a)}var v=[h];if(s&&0!==i&&!c){var b=Je.makeSpan(["mspace"],[],a);b.style.marginRight=G(i),v.unshift(b)}return Je.makeSpan(["mop","op-limits"],v,a)},pa=["\\smallint"],ua=(e,t)=>{var r,a,n,i=!1;"supsub"===e.type?(r=e.sup,a=e.sub,n=Yt(e.base,"op"),i=!0):n=Yt(e,"op");var o,s=t.style,l=!1;if(s.size===k.DISPLAY.size&&n.symbol&&!pa.includes(n.name)&&(l=!0),n.symbol){var h=l?"Size2-Regular":"Size1-Regular",m="";if("\\oiint"!==n.name&&"\\oiiint"!==n.name||(m=n.name.slice(1),n.name="oiint"===m?"\\iint":"\\iiint"),o=Je.makeSymbol(n.name,h,"math",t,["mop","op-symbol",l?"large-op":"small-op"]),m.length>0){var c=o.italic,p=Je.staticSvg(m+"Size"+(l?"2":"1"),t);o=Je.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:0},{type:"elem",elem:p,shift:l?.08:0}]},t),n.name="\\"+m,o.classes.unshift("mop"),o.italic=c}}else if(n.body){var u=ft(n.body,t,!0);1===u.length&&u[0]instanceof J?(o=u[0]).classes[0]="mop":o=Je.makeSpan(["mop"],u,t)}else{for(var d=[],g=1;g<n.name.length;g++)d.push(Je.mathsym(n.name[g],n.mode,t));o=Je.makeSpan(["mop"],d,t)}var f=0,v=0;return(o instanceof J||"\\oiint"===n.name||"\\oiiint"===n.name)&&!n.suppressBaseShift&&(f=(o.height-o.depth)/2-t.fontMetrics().axisHeight,v=o.italic),i?ca(o,r,a,t,s,v,f):(f&&(o.style.position="relative",o.style.top=G(f)),o)},da=(e,t)=>{var r;if(e.symbol)r=new At("mo",[Ct(e.name,e.mode)]),pa.includes(e.name)&&r.setAttribute("largeop","false");else if(e.body)r=new At("mo",Rt(e.body,t));else{r=new At("mi",[new Tt(e.name.slice(1))]);var a=new At("mo",[Ct("\u2061","text")]);r=e.parentIsSupSub?new At("mrow",[r,a]):zt([r,a])}return r},ga={"\u220f":"\\prod","\u2210":"\\coprod","\u2211":"\\sum","\u22c0":"\\bigwedge","\u22c1":"\\bigvee","\u22c2":"\\bigcap","\u22c3":"\\bigcup","\u2a00":"\\bigodot","\u2a01":"\\bigoplus","\u2a02":"\\bigotimes","\u2a04":"\\biguplus","\u2a06":"\\bigsqcup"};st({type:"op",names:["\\coprod","\\bigvee","\\bigwedge","\\biguplus","\\bigcap","\\bigcup","\\intop","\\prod","\\sum","\\bigotimes","\\bigoplus","\\bigodot","\\bigsqcup","\\smallint","\u220f","\u2210","\u2211","\u22c0","\u22c1","\u22c2","\u22c3","\u2a00","\u2a01","\u2a02","\u2a04","\u2a06"],props:{numArgs:0},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=a;return 1===n.length&&(n=ga[n]),{type:"op",mode:r.mode,limits:!0,parentIsSupSub:!1,symbol:!0,name:n}},htmlBuilder:ua,mathmlBuilder:da}),st({type:"op",names:["\\mathop"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var{parser:r}=e,a=t[0];return{type:"op",mode:r.mode,limits:!1,parentIsSupSub:!1,symbol:!1,body:mt(a)}},htmlBuilder:ua,mathmlBuilder:da});var fa={"\u222b":"\\int","\u222c":"\\iint","\u222d":"\\iiint","\u222e":"\\oint","\u222f":"\\oiint","\u2230":"\\oiiint"};st({type:"op",names:["\\arcsin","\\arccos","\\arctan","\\arctg","\\arcctg","\\arg","\\ch","\\cos","\\cosec","\\cosh","\\cot","\\cotg","\\coth","\\csc","\\ctg","\\cth","\\deg","\\dim","\\exp","\\hom","\\ker","\\lg","\\ln","\\log","\\sec","\\sin","\\sinh","\\sh","\\tan","\\tanh","\\tg","\\th"],props:{numArgs:0},handler(e){var{parser:t,funcName:r}=e;return{type:"op",mode:t.mode,limits:!1,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:ua,mathmlBuilder:da}),st({type:"op",names:["\\det","\\gcd","\\inf","\\lim","\\max","\\min","\\Pr","\\sup"],props:{numArgs:0},handler(e){var{parser:t,funcName:r}=e;return{type:"op",mode:t.mode,limits:!0,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:ua,mathmlBuilder:da}),st({type:"op",names:["\\int","\\iint","\\iiint","\\oint","\\oiint","\\oiiint","\u222b","\u222c","\u222d","\u222e","\u222f","\u2230"],props:{numArgs:0},handler(e){var{parser:t,funcName:r}=e,a=r;return 1===a.length&&(a=fa[a]),{type:"op",mode:t.mode,limits:!1,parentIsSupSub:!1,symbol:!0,name:a}},htmlBuilder:ua,mathmlBuilder:da});var va=(e,t)=>{var r,a,n,i,o=!1;if("supsub"===e.type?(r=e.sup,a=e.sub,n=Yt(e.base,"operatorname"),o=!0):n=Yt(e,"operatorname"),n.body.length>0){for(var s=n.body.map(e=>{var t=e.text;return"string"==typeof t?{type:"textord",mode:e.mode,text:t}:e}),l=ft(s,t.withFont("mathrm"),!0),h=0;h<l.length;h++){var m=l[h];m instanceof J&&(m.text=m.text.replace(/\u2212/,"-").replace(/\u2217/,"*"))}i=Je.makeSpan(["mop"],l,t)}else i=Je.makeSpan(["mop"],[],t);return o?ca(i,r,a,t,t.style,0,0):i};function ba(e,t,r){for(var a=ft(e,t,!1),n=t.sizeMultiplier/r.sizeMultiplier,i=0;i<a.length;i++){var o=a[i].classes.indexOf("sizing");o<0?Array.prototype.push.apply(a[i].classes,t.sizingClasses(r)):a[i].classes[o+1]==="reset-size"+t.size&&(a[i].classes[o+1]="reset-size"+r.size),a[i].height*=n,a[i].depth*=n}return Je.makeFragment(a)}st({type:"operatorname",names:["\\operatorname@","\\operatornamewithlimits"],props:{numArgs:1},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=t[0];return{type:"operatorname",mode:r.mode,body:mt(n),alwaysHandleSupSub:"\\operatornamewithlimits"===a,limits:!1,parentIsSupSub:!1}},htmlBuilder:va,mathmlBuilder:(e,t)=>{for(var r=Rt(e.body,t.withFont("mathrm")),a=!0,n=0;n<r.length;n++){var i=r[n];if(i instanceof Bt.SpaceNode);else if(i instanceof Bt.MathNode)switch(i.type){case"mi":case"mn":case"ms":case"mspace":case"mtext":break;case"mo":var o=i.children[0];1===i.children.length&&o instanceof Bt.TextNode?o.text=o.text.replace(/\u2212/,"-").replace(/\u2217/,"*"):a=!1;break;default:a=!1}else a=!1}if(a){var s=r.map(e=>e.toText()).join("");r=[new Bt.TextNode(s)]}var l=new Bt.MathNode("mi",r);l.setAttribute("mathvariant","normal");var h=new Bt.MathNode("mo",[Ct("\u2061","text")]);return e.parentIsSupSub?new Bt.MathNode("mrow",[l,h]):Bt.newDocumentFragment([l,h])}}),Ur("\\operatorname","\\@ifstar\\operatornamewithlimits\\operatorname@"),lt({type:"ordgroup",htmlBuilder:(e,t)=>e.semisimple?Je.makeFragment(ft(e.body,t,!1)):Je.makeSpan(["mord"],ft(e.body,t,!0),t),mathmlBuilder:(e,t)=>Ht(e.body,t,!0)}),st({type:"overline",names:["\\overline"],props:{numArgs:1},handler(e,t){var{parser:r}=e,a=t[0];return{type:"overline",mode:r.mode,body:a}},htmlBuilder(e,t){var r=kt(e.body,t.havingCrampedStyle()),a=Je.makeLineSpan("overline-line",t),n=t.fontMetrics().defaultRuleThickness,i=Je.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r},{type:"kern",size:3*n},{type:"elem",elem:a},{type:"kern",size:n}]},t);return Je.makeSpan(["mord","overline"],[i],t)},mathmlBuilder(e,t){var r=new Bt.MathNode("mo",[new Bt.TextNode("\u203e")]);r.setAttribute("stretchy","true");var a=new Bt.MathNode("mover",[Ot(e.body,t),r]);return a.setAttribute("accent","true"),a}}),st({type:"phantom",names:["\\phantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=t[0];return{type:"phantom",mode:r.mode,body:mt(a)}},htmlBuilder:(e,t)=>{var r=ft(e.body,t.withPhantom(),!1);return Je.makeFragment(r)},mathmlBuilder:(e,t)=>{var r=Rt(e.body,t);return new Bt.MathNode("mphantom",r)}}),st({type:"hphantom",names:["\\hphantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=t[0];return{type:"hphantom",mode:r.mode,body:a}},htmlBuilder:(e,t)=>{var r=Je.makeSpan([],[kt(e.body,t.withPhantom())]);if(r.height=0,r.depth=0,r.children)for(var a=0;a<r.children.length;a++)r.children[a].height=0,r.children[a].depth=0;return r=Je.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r}]},t),Je.makeSpan(["mord"],[r],t)},mathmlBuilder:(e,t)=>{var r=Rt(mt(e.body),t),a=new Bt.MathNode("mphantom",r),n=new Bt.MathNode("mpadded",[a]);return n.setAttribute("height","0px"),n.setAttribute("depth","0px"),n}}),st({type:"vphantom",names:["\\vphantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=t[0];return{type:"vphantom",mode:r.mode,body:a}},htmlBuilder:(e,t)=>{var r=Je.makeSpan(["inner"],[kt(e.body,t.withPhantom())]),a=Je.makeSpan(["fix"],[]);return Je.makeSpan(["mord","rlap"],[r,a],t)},mathmlBuilder:(e,t)=>{var r=Rt(mt(e.body),t),a=new Bt.MathNode("mphantom",r),n=new Bt.MathNode("mpadded",[a]);return n.setAttribute("width","0px"),n}}),st({type:"raisebox",names:["\\raisebox"],props:{numArgs:2,argTypes:["size","hbox"],allowedInText:!0},handler(e,t){var{parser:r}=e,a=Yt(t[0],"size").value,n=t[1];return{type:"raisebox",mode:r.mode,dy:a,body:n}},htmlBuilder(e,t){var r=kt(e.body,t),a=F(e.dy,t);return Je.makeVList({positionType:"shift",positionData:-a,children:[{type:"elem",elem:r}]},t)},mathmlBuilder(e,t){var r=new Bt.MathNode("mpadded",[Ot(e.body,t)]),a=e.dy.number+e.dy.unit;return r.setAttribute("voffset",a),r}}),st({type:"internal",names:["\\relax"],props:{numArgs:0,allowedInText:!0,allowedInArgument:!0},handler(e){var{parser:t}=e;return{type:"internal",mode:t.mode}}}),st({type:"rule",names:["\\rule"],props:{numArgs:2,numOptionalArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["size","size","size"]},handler(e,t,r){var{parser:a}=e,n=r[0],i=Yt(t[0],"size"),o=Yt(t[1],"size");return{type:"rule",mode:a.mode,shift:n&&Yt(n,"size").value,width:i.value,height:o.value}},htmlBuilder(e,t){var r=Je.makeSpan(["mord","rule"],[],t),a=F(e.width,t),n=F(e.height,t),i=e.shift?F(e.shift,t):0;return r.style.borderRightWidth=G(a),r.style.borderTopWidth=G(n),r.style.bottom=G(i),r.width=a,r.height=n+i,r.depth=-i,r.maxFontSize=1.125*n*t.sizeMultiplier,r},mathmlBuilder(e,t){var r=F(e.width,t),a=F(e.height,t),n=e.shift?F(e.shift,t):0,i=t.color&&t.getColor()||"black",o=new Bt.MathNode("mspace");o.setAttribute("mathbackground",i),o.setAttribute("width",G(r)),o.setAttribute("height",G(a));var s=new Bt.MathNode("mpadded",[o]);return n>=0?s.setAttribute("height",G(n)):(s.setAttribute("height",G(n)),s.setAttribute("depth",G(-n))),s.setAttribute("voffset",G(n)),s}});var ya=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"];st({type:"sizing",names:ya,props:{numArgs:0,allowedInText:!0},handler:(e,t)=>{var{breakOnTokenText:r,funcName:a,parser:n}=e,i=n.parseExpression(!1,r);return{type:"sizing",mode:n.mode,size:ya.indexOf(a)+1,body:i}},htmlBuilder:(e,t)=>{var r=t.havingSize(e.size);return ba(e.body,r,t)},mathmlBuilder:(e,t)=>{var r=t.havingSize(e.size),a=Rt(e.body,r),n=new Bt.MathNode("mstyle",a);return n.setAttribute("mathsize",G(r.sizeMultiplier)),n}}),st({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:(e,t,r)=>{var{parser:a}=e,n=!1,i=!1,o=r[0]&&Yt(r[0],"ordgroup");if(o)for(var s="",l=0;l<o.body.length;++l){if("t"===(s=o.body[l].text))n=!0;else{if("b"!==s){n=!1,i=!1;break}i=!0}}else n=!0,i=!0;var h=t[0];return{type:"smash",mode:a.mode,body:h,smashHeight:n,smashDepth:i}},htmlBuilder:(e,t)=>{var r=Je.makeSpan([],[kt(e.body,t)]);if(!e.smashHeight&&!e.smashDepth)return r;if(e.smashHeight&&(r.height=0,r.children))for(var a=0;a<r.children.length;a++)r.children[a].height=0;if(e.smashDepth&&(r.depth=0,r.children))for(var n=0;n<r.children.length;n++)r.children[n].depth=0;var i=Je.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r}]},t);return Je.makeSpan(["mord"],[i],t)},mathmlBuilder:(e,t)=>{var r=new Bt.MathNode("mpadded",[Ot(e.body,t)]);return e.smashHeight&&r.setAttribute("height","0px"),e.smashDepth&&r.setAttribute("depth","0px"),r}}),st({type:"sqrt",names:["\\sqrt"],props:{numArgs:1,numOptionalArgs:1},handler(e,t,r){var{parser:a}=e,n=r[0],i=t[0];return{type:"sqrt",mode:a.mode,body:i,index:n}},htmlBuilder(e,t){var r=kt(e.body,t.havingCrampedStyle());0===r.height&&(r.height=t.fontMetrics().xHeight),r=Je.wrapFragment(r,t);var a=t.fontMetrics().defaultRuleThickness,n=a;t.style.id<k.TEXT.id&&(n=t.fontMetrics().xHeight);var i=a+n/4,o=r.height+r.depth+i+a,{span:s,ruleWidth:l,advanceWidth:h}=Rr.sqrtImage(o,t),m=s.height-l;m>r.height+r.depth+i&&(i=(i+m-r.height-r.depth)/2);var c=s.height-r.height-i-l;r.style.paddingLeft=G(h);var p=Je.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+c)},{type:"elem",elem:s},{type:"kern",size:l}]},t);if(e.index){var u=t.havingStyle(k.SCRIPTSCRIPT),d=kt(e.index,u,t),g=.6*(p.height-p.depth),f=Je.makeVList({positionType:"shift",positionData:-g,children:[{type:"elem",elem:d}]},t),v=Je.makeSpan(["root"],[f]);return Je.makeSpan(["mord","sqrt"],[v,p],t)}return Je.makeSpan(["mord","sqrt"],[p],t)},mathmlBuilder(e,t){var{body:r,index:a}=e;return a?new Bt.MathNode("mroot",[Ot(r,t),Ot(a,t)]):new Bt.MathNode("msqrt",[Ot(r,t)])}});var xa={display:k.DISPLAY,text:k.TEXT,script:k.SCRIPT,scriptscript:k.SCRIPTSCRIPT};st({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e,t){var{breakOnTokenText:r,funcName:a,parser:n}=e,i=n.parseExpression(!0,r),o=a.slice(1,a.length-5);return{type:"styling",mode:n.mode,style:o,body:i}},htmlBuilder(e,t){var r=xa[e.style],a=t.havingStyle(r).withFont("");return ba(e.body,a,t)},mathmlBuilder(e,t){var r=xa[e.style],a=t.havingStyle(r),n=Rt(e.body,a),i=new Bt.MathNode("mstyle",n),o={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]}[e.style];return i.setAttribute("scriptlevel",o[0]),i.setAttribute("displaystyle",o[1]),i}});lt({type:"supsub",htmlBuilder(e,t){var r=function(e,t){var r=e.base;return r?"op"===r.type?r.limits&&(t.style.size===k.DISPLAY.size||r.alwaysHandleSupSub)?ua:null:"operatorname"===r.type?r.alwaysHandleSupSub&&(t.style.size===k.DISPLAY.size||r.limits)?va:null:"accent"===r.type?m.isCharacterBox(r.base)?_t:null:"horizBrace"===r.type&&!e.sub===r.isOver?la:null:null}(e,t);if(r)return r(e,t);var a,n,i,{base:o,sup:s,sub:l}=e,h=kt(o,t),c=t.fontMetrics(),p=0,u=0,d=o&&m.isCharacterBox(o);if(s){var g=t.havingStyle(t.style.sup());a=kt(s,g,t),d||(p=h.height-g.fontMetrics().supDrop*g.sizeMultiplier/t.sizeMultiplier)}if(l){var f=t.havingStyle(t.style.sub());n=kt(l,f,t),d||(u=h.depth+f.fontMetrics().subDrop*f.sizeMultiplier/t.sizeMultiplier)}i=t.style===k.DISPLAY?c.sup1:t.style.cramped?c.sup3:c.sup2;var v,b=t.sizeMultiplier,y=G(.5/c.ptPerEm/b),x=null;if(n){var w=e.base&&"op"===e.base.type&&e.base.name&&("\\oiint"===e.base.name||"\\oiiint"===e.base.name);(h instanceof J||w)&&(x=G(-h.italic))}if(a&&n){p=Math.max(p,i,a.depth+.25*c.xHeight),u=Math.max(u,c.sub2);var S=4*c.defaultRuleThickness;if(p-a.depth-(n.height-u)<S){u=S-(p-a.depth)+n.height;var M=.8*c.xHeight-(p-a.depth);M>0&&(p+=M,u-=M)}var z=[{type:"elem",elem:n,shift:u,marginRight:y,marginLeft:x},{type:"elem",elem:a,shift:-p,marginRight:y}];v=Je.makeVList({positionType:"individualShift",children:z},t)}else if(n){u=Math.max(u,c.sub1,n.height-.8*c.xHeight);var A=[{type:"elem",elem:n,marginLeft:x,marginRight:y}];v=Je.makeVList({positionType:"shift",positionData:u,children:A},t)}else{if(!a)throw new Error("supsub must have either sup or sub.");p=Math.max(p,i,a.depth+.25*c.xHeight),v=Je.makeVList({positionType:"shift",positionData:-p,children:[{type:"elem",elem:a,marginRight:y}]},t)}var T=xt(h,"right")||"mord";return Je.makeSpan([T],[h,Je.makeSpan(["msupsub"],[v])],t)},mathmlBuilder(e,t){var r,a=!1;e.base&&"horizBrace"===e.base.type&&!!e.sup===e.base.isOver&&(a=!0,r=e.base.isOver),!e.base||"op"!==e.base.type&&"operatorname"!==e.base.type||(e.base.parentIsSupSub=!0);var n,i=[Ot(e.base,t)];if(e.sub&&i.push(Ot(e.sub,t)),e.sup&&i.push(Ot(e.sup,t)),a)n=r?"mover":"munder";else if(e.sub)if(e.sup){var o=e.base;n=o&&"op"===o.type&&o.limits&&t.style===k.DISPLAY||o&&"operatorname"===o.type&&o.alwaysHandleSupSub&&(t.style===k.DISPLAY||o.limits)?"munderover":"msubsup"}else{var s=e.base;n=s&&"op"===s.type&&s.limits&&(t.style===k.DISPLAY||s.alwaysHandleSupSub)||s&&"operatorname"===s.type&&s.alwaysHandleSupSub&&(s.limits||t.style===k.DISPLAY)?"munder":"msub"}else{var l=e.base;n=l&&"op"===l.type&&l.limits&&(t.style===k.DISPLAY||l.alwaysHandleSupSub)||l&&"operatorname"===l.type&&l.alwaysHandleSupSub&&(l.limits||t.style===k.DISPLAY)?"mover":"msup"}return new Bt.MathNode(n,i)}}),lt({type:"atom",htmlBuilder:(e,t)=>Je.mathsym(e.text,e.mode,t,["m"+e.family]),mathmlBuilder(e,t){var r=new Bt.MathNode("mo",[Ct(e.text,e.mode)]);if("bin"===e.family){var a=qt(e,t);"bold-italic"===a&&r.setAttribute("mathvariant",a)}else"punct"===e.family?r.setAttribute("separator","true"):"open"!==e.family&&"close"!==e.family||r.setAttribute("stretchy","false");return r}});var wa={mi:"italic",mn:"normal",mtext:"normal"};lt({type:"mathord",htmlBuilder:(e,t)=>Je.makeOrd(e,t,"mathord"),mathmlBuilder(e,t){var r=new Bt.MathNode("mi",[Ct(e.text,e.mode,t)]),a=qt(e,t)||"italic";return a!==wa[r.type]&&r.setAttribute("mathvariant",a),r}}),lt({type:"textord",htmlBuilder:(e,t)=>Je.makeOrd(e,t,"textord"),mathmlBuilder(e,t){var r,a=Ct(e.text,e.mode,t),n=qt(e,t)||"normal";return r="text"===e.mode?new Bt.MathNode("mtext",[a]):/[0-9]/.test(e.text)?new Bt.MathNode("mn",[a]):"\\prime"===e.text?new Bt.MathNode("mo",[a]):new Bt.MathNode("mi",[a]),n!==wa[r.type]&&r.setAttribute("mathvariant",n),r}});var ka={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},Sa={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};lt({type:"spacing",htmlBuilder(e,t){if(Sa.hasOwnProperty(e.text)){var r=Sa[e.text].className||"";if("text"===e.mode){var a=Je.makeOrd(e,t,"textord");return a.classes.push(r),a}return Je.makeSpan(["mspace",r],[Je.mathsym(e.text,e.mode,t)],t)}if(ka.hasOwnProperty(e.text))return Je.makeSpan(["mspace",ka[e.text]],[],t);throw new i('Unknown type of space "'+e.text+'"')},mathmlBuilder(e,t){if(!Sa.hasOwnProperty(e.text)){if(ka.hasOwnProperty(e.text))return new Bt.MathNode("mspace");throw new i('Unknown type of space "'+e.text+'"')}return new Bt.MathNode("mtext",[new Bt.TextNode("\xa0")])}});var Ma=()=>{var e=new Bt.MathNode("mtd",[]);return e.setAttribute("width","50%"),e};lt({type:"tag",mathmlBuilder(e,t){var r=new Bt.MathNode("mtable",[new Bt.MathNode("mtr",[Ma(),new Bt.MathNode("mtd",[Ht(e.body,t)]),Ma(),new Bt.MathNode("mtd",[Ht(e.tag,t)])])]);return r.setAttribute("width","100%"),r}});var za={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},Aa={"\\textbf":"textbf","\\textmd":"textmd"},Ta={"\\textit":"textit","\\textup":"textup"},Ba=(e,t)=>{var r=e.font;return r?za[r]?t.withTextFontFamily(za[r]):Aa[r]?t.withTextFontWeight(Aa[r]):"\\emph"===r?"textit"===t.fontShape?t.withTextFontShape("textup"):t.withTextFontShape("textit"):t.withTextFontShape(Ta[r]):t};st({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup","\\emph"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler(e,t){var{parser:r,funcName:a}=e,n=t[0];return{type:"text",mode:r.mode,body:mt(n),font:a}},htmlBuilder(e,t){var r=Ba(e,t),a=ft(e.body,r,!0);return Je.makeSpan(["mord","text"],a,r)},mathmlBuilder(e,t){var r=Ba(e,t);return Ht(e.body,r)}}),st({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler(e,t){var{parser:r}=e;return{type:"underline",mode:r.mode,body:t[0]}},htmlBuilder(e,t){var r=kt(e.body,t),a=Je.makeLineSpan("underline-line",t),n=t.fontMetrics().defaultRuleThickness,i=Je.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:n},{type:"elem",elem:a},{type:"kern",size:3*n},{type:"elem",elem:r}]},t);return Je.makeSpan(["mord","underline"],[i],t)},mathmlBuilder(e,t){var r=new Bt.MathNode("mo",[new Bt.TextNode("\u203e")]);r.setAttribute("stretchy","true");var a=new Bt.MathNode("munder",[Ot(e.body,t),r]);return a.setAttribute("accentunder","true"),a}}),st({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler(e,t){var{parser:r}=e;return{type:"vcenter",mode:r.mode,body:t[0]}},htmlBuilder(e,t){var r=kt(e.body,t),a=t.fontMetrics().axisHeight,n=.5*(r.height-a-(r.depth+a));return Je.makeVList({positionType:"shift",positionData:n,children:[{type:"elem",elem:r}]},t)},mathmlBuilder:(e,t)=>new Bt.MathNode("mpadded",[Ot(e.body,t)],["vcenter"])}),st({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler(e,t,r){throw new i("\\verb ended by end of line instead of matching delimiter")},htmlBuilder(e,t){for(var r=Ca(e),a=[],n=t.havingStyle(t.style.text()),i=0;i<r.length;i++){var o=r[i];"~"===o&&(o="\\textasciitilde"),a.push(Je.makeSymbol(o,"Typewriter-Regular",e.mode,n,["mord","texttt"]))}return Je.makeSpan(["mord","text"].concat(n.sizingClasses(t)),Je.tryCombineChars(a),n)},mathmlBuilder(e,t){var r=new Bt.TextNode(Ca(e)),a=new Bt.MathNode("mtext",[r]);return a.setAttribute("mathvariant","monospace"),a}});var Ca=e=>e.body.replace(/ /g,e.star?"\u2423":"\xa0"),Na=nt,qa="[ \r\n\t]",Ia="(\\\\[a-zA-Z@]+)"+qa+"*",Ra="[\u0300-\u036f]",Ha=new RegExp(Ra+"+$"),Oa="("+qa+"+)|\\\\(\n|[ \r\t]+\n?)[ \r\t]*|([!-\\[\\]-\u2027\u202a-\ud7ff\uf900-\uffff]"+Ra+"*|[\ud800-\udbff][\udc00-\udfff]"+Ra+"*|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5|"+Ia+"|\\\\[^\ud800-\udfff])";class Ea{constructor(e,t){this.input=void 0,this.settings=void 0,this.tokenRegex=void 0,this.catcodes=void 0,this.input=e,this.settings=t,this.tokenRegex=new RegExp(Oa,"g"),this.catcodes={"%":14,"~":13}}setCatcode(e,t){this.catcodes[e]=t}lex(){var e=this.input,t=this.tokenRegex.lastIndex;if(t===e.length)return new n("EOF",new a(this,t,t));var r=this.tokenRegex.exec(e);if(null===r||r.index!==t)throw new i("Unexpected character: '"+e[t]+"'",new n(e[t],new a(this,t,t+1)));var o=r[6]||r[3]||(r[2]?"\\ ":" ");if(14===this.catcodes[o]){var s=e.indexOf("\n",this.tokenRegex.lastIndex);return-1===s?(this.tokenRegex.lastIndex=e.length,this.settings.reportNonstrict("commentAtEnd","% comment has no terminating newline; LaTeX would fail because of commenting the end of math mode (e.g. $)")):this.tokenRegex.lastIndex=s+1,this.lex()}return new n(o,new a(this,t,this.tokenRegex.lastIndex))}}class La{constructor(e,t){void 0===e&&(e={}),void 0===t&&(t={}),this.current=void 0,this.builtins=void 0,this.undefStack=void 0,this.current=t,this.builtins=e,this.undefStack=[]}beginGroup(){this.undefStack.push({})}endGroup(){if(0===this.undefStack.length)throw new i("Unbalanced namespace destruction: attempt to pop global namespace; please report this as a bug");var e=this.undefStack.pop();for(var t in e)e.hasOwnProperty(t)&&(null==e[t]?delete this.current[t]:this.current[t]=e[t])}endGroups(){for(;this.undefStack.length>0;)this.endGroup()}has(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)}get(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]}set(e,t,r){if(void 0===r&&(r=!1),r){for(var a=0;a<this.undefStack.length;a++)delete this.undefStack[a][e];this.undefStack.length>0&&(this.undefStack[this.undefStack.length-1][e]=t)}else{var n=this.undefStack[this.undefStack.length-1];n&&!n.hasOwnProperty(e)&&(n[e]=this.current[e])}null==t?delete this.current[e]:this.current[e]=t}}var Da=Gr;Ur("\\noexpand",function(e){var t=e.popToken();return e.isExpandable(t.text)&&(t.noexpand=!0,t.treatAsRelax=!0),{tokens:[t],numArgs:0}}),Ur("\\expandafter",function(e){var t=e.popToken();return e.expandOnce(!0),{tokens:[t],numArgs:0}}),Ur("\\@firstoftwo",function(e){return{tokens:e.consumeArgs(2)[0],numArgs:0}}),Ur("\\@secondoftwo",function(e){return{tokens:e.consumeArgs(2)[1],numArgs:0}}),Ur("\\@ifnextchar",function(e){var t=e.consumeArgs(3);e.consumeSpaces();var r=e.future();return 1===t[0].length&&t[0][0].text===r.text?{tokens:t[1],numArgs:0}:{tokens:t[2],numArgs:0}}),Ur("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}"),Ur("\\TextOrMath",function(e){var t=e.consumeArgs(2);return"text"===e.mode?{tokens:t[0],numArgs:0}:{tokens:t[1],numArgs:0}});var Va={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};Ur("\\char",function(e){var t,r=e.popToken(),a="";if("'"===r.text)t=8,r=e.popToken();else if('"'===r.text)t=16,r=e.popToken();else if("`"===r.text)if("\\"===(r=e.popToken()).text[0])a=r.text.charCodeAt(1);else{if("EOF"===r.text)throw new i("\\char` missing argument");a=r.text.charCodeAt(0)}else t=10;if(t){if(null==(a=Va[r.text])||a>=t)throw new i("Invalid base-"+t+" digit "+r.text);for(var n;null!=(n=Va[e.future().text])&&n<t;)a*=t,a+=n,e.popToken()}return"\\@char{"+a+"}"});var Pa=(e,t,r,a)=>{var n=e.consumeArg().tokens;if(1!==n.length)throw new i("\\newcommand's first argument must be a macro name");var o=n[0].text,s=e.isDefined(o);if(s&&!t)throw new i("\\newcommand{"+o+"} attempting to redefine "+o+"; use \\renewcommand");if(!s&&!r)throw new i("\\renewcommand{"+o+"} when command "+o+" does not yet exist; use \\newcommand");var l=0;if(1===(n=e.consumeArg().tokens).length&&"["===n[0].text){for(var h="",m=e.expandNextToken();"]"!==m.text&&"EOF"!==m.text;)h+=m.text,m=e.expandNextToken();if(!h.match(/^\s*[0-9]+\s*$/))throw new i("Invalid number of arguments: "+h);l=parseInt(h),n=e.consumeArg().tokens}return s&&a||e.macros.set(o,{tokens:n,numArgs:l}),""};Ur("\\newcommand",e=>Pa(e,!1,!0,!1)),Ur("\\renewcommand",e=>Pa(e,!0,!1,!1)),Ur("\\providecommand",e=>Pa(e,!0,!0,!0)),Ur("\\message",e=>{var t=e.consumeArgs(1)[0];return console.log(t.reverse().map(e=>e.text).join("")),""}),Ur("\\errmessage",e=>{var t=e.consumeArgs(1)[0];return console.error(t.reverse().map(e=>e.text).join("")),""}),Ur("\\show",e=>{var t=e.popToken(),r=t.text;return console.log(t,e.macros.get(r),Na[r],ie.math[r],ie.text[r]),""}),Ur("\\bgroup","{"),Ur("\\egroup","}"),Ur("~","\\nobreakspace"),Ur("\\lq","`"),Ur("\\rq","'"),Ur("\\aa","\\r a"),Ur("\\AA","\\r A"),Ur("\\textcopyright","\\html@mathml{\\textcircled{c}}{\\char`\xa9}"),Ur("\\copyright","\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}"),Ur("\\textregistered","\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`\xae}"),Ur("\u212c","\\mathscr{B}"),Ur("\u2130","\\mathscr{E}"),Ur("\u2131","\\mathscr{F}"),Ur("\u210b","\\mathscr{H}"),Ur("\u2110","\\mathscr{I}"),Ur("\u2112","\\mathscr{L}"),Ur("\u2133","\\mathscr{M}"),Ur("\u211b","\\mathscr{R}"),Ur("\u212d","\\mathfrak{C}"),Ur("\u210c","\\mathfrak{H}"),Ur("\u2128","\\mathfrak{Z}"),Ur("\\Bbbk","\\Bbb{k}"),Ur("\xb7","\\cdotp"),Ur("\\llap","\\mathllap{\\textrm{#1}}"),Ur("\\rlap","\\mathrlap{\\textrm{#1}}"),Ur("\\clap","\\mathclap{\\textrm{#1}}"),Ur("\\mathstrut","\\vphantom{(}"),Ur("\\underbar","\\underline{\\text{#1}}"),Ur("\\not",'\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}'),Ur("\\neq","\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`\u2260}}"),Ur("\\ne","\\neq"),Ur("\u2260","\\neq"),Ur("\\notin","\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}{\\mathrel{\\char`\u2209}}"),Ur("\u2209","\\notin"),Ur("\u2258","\\html@mathml{\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}}{\\mathrel{\\char`\u2258}}"),Ur("\u2259","\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`\u2258}}"),Ur("\u225a","\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`\u225a}}"),Ur("\u225b","\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}{\\mathrel{\\char`\u225b}}"),Ur("\u225d","\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}{\\mathrel{\\char`\u225d}}"),Ur("\u225e","\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}{\\mathrel{\\char`\u225e}}"),Ur("\u225f","\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`\u225f}}"),Ur("\u27c2","\\perp"),Ur("\u203c","\\mathclose{!\\mkern-0.8mu!}"),Ur("\u220c","\\notni"),Ur("\u231c","\\ulcorner"),Ur("\u231d","\\urcorner"),Ur("\u231e","\\llcorner"),Ur("\u231f","\\lrcorner"),Ur("\xa9","\\copyright"),Ur("\xae","\\textregistered"),Ur("\ufe0f","\\textregistered"),Ur("\\ulcorner",'\\html@mathml{\\@ulcorner}{\\mathop{\\char"231c}}'),Ur("\\urcorner",'\\html@mathml{\\@urcorner}{\\mathop{\\char"231d}}'),Ur("\\llcorner",'\\html@mathml{\\@llcorner}{\\mathop{\\char"231e}}'),Ur("\\lrcorner",'\\html@mathml{\\@lrcorner}{\\mathop{\\char"231f}}'),Ur("\\vdots","{\\varvdots\\rule{0pt}{15pt}}"),Ur("\u22ee","\\vdots"),Ur("\\varGamma","\\mathit{\\Gamma}"),Ur("\\varDelta","\\mathit{\\Delta}"),Ur("\\varTheta","\\mathit{\\Theta}"),Ur("\\varLambda","\\mathit{\\Lambda}"),Ur("\\varXi","\\mathit{\\Xi}"),Ur("\\varPi","\\mathit{\\Pi}"),Ur("\\varSigma","\\mathit{\\Sigma}"),Ur("\\varUpsilon","\\mathit{\\Upsilon}"),Ur("\\varPhi","\\mathit{\\Phi}"),Ur("\\varPsi","\\mathit{\\Psi}"),Ur("\\varOmega","\\mathit{\\Omega}"),Ur("\\substack","\\begin{subarray}{c}#1\\end{subarray}"),Ur("\\colon","\\nobreak\\mskip2mu\\mathpunct{}\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax"),Ur("\\boxed","\\fbox{$\\displaystyle{#1}$}"),Ur("\\iff","\\DOTSB\\;\\Longleftrightarrow\\;"),Ur("\\implies","\\DOTSB\\;\\Longrightarrow\\;"),Ur("\\impliedby","\\DOTSB\\;\\Longleftarrow\\;"),Ur("\\dddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ...}}{#1}}"),Ur("\\ddddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ....}}{#1}}");var Fa={",":"\\dotsc","\\not":"\\dotsb","+":"\\dotsb","=":"\\dotsb","<":"\\dotsb",">":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};Ur("\\dots",function(e){var t="\\dotso",r=e.expandAfterFuture().text;return r in Fa?t=Fa[r]:("\\not"===r.slice(0,4)||r in ie.math&&["bin","rel"].includes(ie.math[r].group))&&(t="\\dotsb"),t});var Ga={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};Ur("\\dotso",function(e){return e.future().text in Ga?"\\ldots\\,":"\\ldots"}),Ur("\\dotsc",function(e){var t=e.future().text;return t in Ga&&","!==t?"\\ldots\\,":"\\ldots"}),Ur("\\cdots",function(e){return e.future().text in Ga?"\\@cdots\\,":"\\@cdots"}),Ur("\\dotsb","\\cdots"),Ur("\\dotsm","\\cdots"),Ur("\\dotsi","\\!\\cdots"),Ur("\\dotsx","\\ldots\\,"),Ur("\\DOTSI","\\relax"),Ur("\\DOTSB","\\relax"),Ur("\\DOTSX","\\relax"),Ur("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),Ur("\\,","\\tmspace+{3mu}{.1667em}"),Ur("\\thinspace","\\,"),Ur("\\>","\\mskip{4mu}"),Ur("\\:","\\tmspace+{4mu}{.2222em}"),Ur("\\medspace","\\:"),Ur("\\;","\\tmspace+{5mu}{.2777em}"),Ur("\\thickspace","\\;"),Ur("\\!","\\tmspace-{3mu}{.1667em}"),Ur("\\negthinspace","\\!"),Ur("\\negmedspace","\\tmspace-{4mu}{.2222em}"),Ur("\\negthickspace","\\tmspace-{5mu}{.277em}"),Ur("\\enspace","\\kern.5em "),Ur("\\enskip","\\hskip.5em\\relax"),Ur("\\quad","\\hskip1em\\relax"),Ur("\\qquad","\\hskip2em\\relax"),Ur("\\tag","\\@ifstar\\tag@literal\\tag@paren"),Ur("\\tag@paren","\\tag@literal{({#1})}"),Ur("\\tag@literal",e=>{if(e.macros.get("\\df@tag"))throw new i("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"}),Ur("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),Ur("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),Ur("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),Ur("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),Ur("\\newline","\\\\\\relax"),Ur("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");var Ua=G(C["Main-Regular"]["T".charCodeAt(0)][1]-.7*C["Main-Regular"]["A".charCodeAt(0)][1]);Ur("\\LaTeX","\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{"+Ua+"}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}"),Ur("\\KaTeX","\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{"+Ua+"}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}"),Ur("\\hspace","\\@ifstar\\@hspacer\\@hspace"),Ur("\\@hspace","\\hskip #1\\relax"),Ur("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),Ur("\\ordinarycolon",":"),Ur("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),Ur("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),Ur("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),Ur("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),Ur("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),Ur("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),Ur("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),Ur("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),Ur("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),Ur("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),Ur("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),Ur("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),Ur("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),Ur("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),Ur("\u2237","\\dblcolon"),Ur("\u2239","\\eqcolon"),Ur("\u2254","\\coloneqq"),Ur("\u2255","\\eqqcolon"),Ur("\u2a74","\\Coloneqq"),Ur("\\ratio","\\vcentcolon"),Ur("\\coloncolon","\\dblcolon"),Ur("\\colonequals","\\coloneqq"),Ur("\\coloncolonequals","\\Coloneqq"),Ur("\\equalscolon","\\eqqcolon"),Ur("\\equalscoloncolon","\\Eqqcolon"),Ur("\\colonminus","\\coloneq"),Ur("\\coloncolonminus","\\Coloneq"),Ur("\\minuscolon","\\eqcolon"),Ur("\\minuscoloncolon","\\Eqcolon"),Ur("\\coloncolonapprox","\\Colonapprox"),Ur("\\coloncolonsim","\\Colonsim"),Ur("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Ur("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Ur("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Ur("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Ur("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220c}}"),Ur("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),Ur("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),Ur("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}"),Ur("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}"),Ur("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}"),Ur("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}"),Ur("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}"),Ur("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}"),Ur("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}"),Ur("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}"),Ur("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}"),Ur("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}"),Ur("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}"),Ur("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}"),Ur("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}"),Ur("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}"),Ur("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}"),Ur("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}"),Ur("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228a}"),Ur("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2acb}"),Ur("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228b}"),Ur("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2acc}"),Ur("\\imath","\\html@mathml{\\@imath}{\u0131}"),Ur("\\jmath","\\html@mathml{\\@jmath}{\u0237}"),Ur("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27e6}}"),Ur("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27e7}}"),Ur("\u27e6","\\llbracket"),Ur("\u27e7","\\rrbracket"),Ur("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}"),Ur("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}"),Ur("\u2983","\\lBrace"),Ur("\u2984","\\rBrace"),Ur("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29b5}}"),Ur("\u29b5","\\minuso"),Ur("\\darr","\\downarrow"),Ur("\\dArr","\\Downarrow"),Ur("\\Darr","\\Downarrow"),Ur("\\lang","\\langle"),Ur("\\rang","\\rangle"),Ur("\\uarr","\\uparrow"),Ur("\\uArr","\\Uparrow"),Ur("\\Uarr","\\Uparrow"),Ur("\\N","\\mathbb{N}"),Ur("\\R","\\mathbb{R}"),Ur("\\Z","\\mathbb{Z}"),Ur("\\alef","\\aleph"),Ur("\\alefsym","\\aleph"),Ur("\\Alpha","\\mathrm{A}"),Ur("\\Beta","\\mathrm{B}"),Ur("\\bull","\\bullet"),Ur("\\Chi","\\mathrm{X}"),Ur("\\clubs","\\clubsuit"),Ur("\\cnums","\\mathbb{C}"),Ur("\\Complex","\\mathbb{C}"),Ur("\\Dagger","\\ddagger"),Ur("\\diamonds","\\diamondsuit"),Ur("\\empty","\\emptyset"),Ur("\\Epsilon","\\mathrm{E}"),Ur("\\Eta","\\mathrm{H}"),Ur("\\exist","\\exists"),Ur("\\harr","\\leftrightarrow"),Ur("\\hArr","\\Leftrightarrow"),Ur("\\Harr","\\Leftrightarrow"),Ur("\\hearts","\\heartsuit"),Ur("\\image","\\Im"),Ur("\\infin","\\infty"),Ur("\\Iota","\\mathrm{I}"),Ur("\\isin","\\in"),Ur("\\Kappa","\\mathrm{K}"),Ur("\\larr","\\leftarrow"),Ur("\\lArr","\\Leftarrow"),Ur("\\Larr","\\Leftarrow"),Ur("\\lrarr","\\leftrightarrow"),Ur("\\lrArr","\\Leftrightarrow"),Ur("\\Lrarr","\\Leftrightarrow"),Ur("\\Mu","\\mathrm{M}"),Ur("\\natnums","\\mathbb{N}"),Ur("\\Nu","\\mathrm{N}"),Ur("\\Omicron","\\mathrm{O}"),Ur("\\plusmn","\\pm"),Ur("\\rarr","\\rightarrow"),Ur("\\rArr","\\Rightarrow"),Ur("\\Rarr","\\Rightarrow"),Ur("\\real","\\Re"),Ur("\\reals","\\mathbb{R}"),Ur("\\Reals","\\mathbb{R}"),Ur("\\Rho","\\mathrm{P}"),Ur("\\sdot","\\cdot"),Ur("\\sect","\\S"),Ur("\\spades","\\spadesuit"),Ur("\\sub","\\subset"),Ur("\\sube","\\subseteq"),Ur("\\supe","\\supseteq"),Ur("\\Tau","\\mathrm{T}"),Ur("\\thetasym","\\vartheta"),Ur("\\weierp","\\wp"),Ur("\\Zeta","\\mathrm{Z}"),Ur("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),Ur("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),Ur("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),Ur("\\bra","\\mathinner{\\langle{#1}|}"),Ur("\\ket","\\mathinner{|{#1}\\rangle}"),Ur("\\braket","\\mathinner{\\langle{#1}\\rangle}"),Ur("\\Bra","\\left\\langle#1\\right|"),Ur("\\Ket","\\left|#1\\right\\rangle");var Ya=e=>t=>{var r=t.consumeArg().tokens,a=t.consumeArg().tokens,n=t.consumeArg().tokens,i=t.consumeArg().tokens,o=t.macros.get("|"),s=t.macros.get("\\|");t.macros.beginGroup();var l=t=>r=>{e&&(r.macros.set("|",o),n.length&&r.macros.set("\\|",s));var i=t;!t&&n.length&&("|"===r.future().text&&(r.popToken(),i=!0));return{tokens:i?n:a,numArgs:0}};t.macros.set("|",l(!1)),n.length&&t.macros.set("\\|",l(!0));var h=t.consumeArg().tokens,m=t.expandTokens([...i,...h,...r]);return t.macros.endGroup(),{tokens:m.reverse(),numArgs:0}};Ur("\\bra@ket",Ya(!1)),Ur("\\bra@set",Ya(!0)),Ur("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}"),Ur("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}"),Ur("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}"),Ur("\\angln","{\\angl n}"),Ur("\\blue","\\textcolor{##6495ed}{#1}"),Ur("\\orange","\\textcolor{##ffa500}{#1}"),Ur("\\pink","\\textcolor{##ff00af}{#1}"),Ur("\\red","\\textcolor{##df0030}{#1}"),Ur("\\green","\\textcolor{##28ae7b}{#1}"),Ur("\\gray","\\textcolor{gray}{#1}"),Ur("\\purple","\\textcolor{##9d38bd}{#1}"),Ur("\\blueA","\\textcolor{##ccfaff}{#1}"),Ur("\\blueB","\\textcolor{##80f6ff}{#1}"),Ur("\\blueC","\\textcolor{##63d9ea}{#1}"),Ur("\\blueD","\\textcolor{##11accd}{#1}"),Ur("\\blueE","\\textcolor{##0c7f99}{#1}"),Ur("\\tealA","\\textcolor{##94fff5}{#1}"),Ur("\\tealB","\\textcolor{##26edd5}{#1}"),Ur("\\tealC","\\textcolor{##01d1c1}{#1}"),Ur("\\tealD","\\textcolor{##01a995}{#1}"),Ur("\\tealE","\\textcolor{##208170}{#1}"),Ur("\\greenA","\\textcolor{##b6ffb0}{#1}"),Ur("\\greenB","\\textcolor{##8af281}{#1}"),Ur("\\greenC","\\textcolor{##74cf70}{#1}"),Ur("\\greenD","\\textcolor{##1fab54}{#1}"),Ur("\\greenE","\\textcolor{##0d923f}{#1}"),Ur("\\goldA","\\textcolor{##ffd0a9}{#1}"),Ur("\\goldB","\\textcolor{##ffbb71}{#1}"),Ur("\\goldC","\\textcolor{##ff9c39}{#1}"),Ur("\\goldD","\\textcolor{##e07d10}{#1}"),Ur("\\goldE","\\textcolor{##a75a05}{#1}"),Ur("\\redA","\\textcolor{##fca9a9}{#1}"),Ur("\\redB","\\textcolor{##ff8482}{#1}"),Ur("\\redC","\\textcolor{##f9685d}{#1}"),Ur("\\redD","\\textcolor{##e84d39}{#1}"),Ur("\\redE","\\textcolor{##bc2612}{#1}"),Ur("\\maroonA","\\textcolor{##ffbde0}{#1}"),Ur("\\maroonB","\\textcolor{##ff92c6}{#1}"),Ur("\\maroonC","\\textcolor{##ed5fa6}{#1}"),Ur("\\maroonD","\\textcolor{##ca337c}{#1}"),Ur("\\maroonE","\\textcolor{##9e034e}{#1}"),Ur("\\purpleA","\\textcolor{##ddd7ff}{#1}"),Ur("\\purpleB","\\textcolor{##c6b9fc}{#1}"),Ur("\\purpleC","\\textcolor{##aa87ff}{#1}"),Ur("\\purpleD","\\textcolor{##7854ab}{#1}"),Ur("\\purpleE","\\textcolor{##543b78}{#1}"),Ur("\\mintA","\\textcolor{##f5f9e8}{#1}"),Ur("\\mintB","\\textcolor{##edf2df}{#1}"),Ur("\\mintC","\\textcolor{##e0e5cc}{#1}"),Ur("\\grayA","\\textcolor{##f6f7f7}{#1}"),Ur("\\grayB","\\textcolor{##f0f1f2}{#1}"),Ur("\\grayC","\\textcolor{##e3e5e6}{#1}"),Ur("\\grayD","\\textcolor{##d6d8da}{#1}"),Ur("\\grayE","\\textcolor{##babec2}{#1}"),Ur("\\grayF","\\textcolor{##888d93}{#1}"),Ur("\\grayG","\\textcolor{##626569}{#1}"),Ur("\\grayH","\\textcolor{##3b3e40}{#1}"),Ur("\\grayI","\\textcolor{##21242c}{#1}"),Ur("\\kaBlue","\\textcolor{##314453}{#1}"),Ur("\\kaGreen","\\textcolor{##71B307}{#1}");var Xa={"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0};class Wa{constructor(e,t,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=t,this.expansionCount=0,this.feed(e),this.macros=new La(Da,t.macros),this.mode=r,this.stack=[]}feed(e){this.lexer=new Ea(e,this.settings)}switchMode(e){this.mode=e}beginGroup(){this.macros.beginGroup()}endGroup(){this.macros.endGroup()}endGroups(){this.macros.endGroups()}future(){return 0===this.stack.length&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]}popToken(){return this.future(),this.stack.pop()}pushToken(e){this.stack.push(e)}pushTokens(e){this.stack.push(...e)}scanArgument(e){var t,r,i;if(e){if(this.consumeSpaces(),"["!==this.future().text)return null;t=this.popToken(),({tokens:i,end:r}=this.consumeArg(["]"]))}else({tokens:i,start:t,end:r}=this.consumeArg());return this.pushToken(new n("EOF",r.loc)),this.pushTokens(i),new n("",a.range(t,r))}consumeSpaces(){for(;;){if(" "!==this.future().text)break;this.stack.pop()}}consumeArg(e){var t=[],r=e&&e.length>0;r||this.consumeSpaces();var a,n=this.future(),o=0,s=0;do{if(a=this.popToken(),t.push(a),"{"===a.text)++o;else if("}"===a.text){if(-1===--o)throw new i("Extra }",a)}else if("EOF"===a.text)throw new i("Unexpected end of input in a macro argument, expected '"+(e&&r?e[s]:"}")+"'",a);if(e&&r)if((0===o||1===o&&"{"===e[s])&&a.text===e[s]){if(++s===e.length){t.splice(-s,s);break}}else s=0}while(0!==o||r);return"{"===n.text&&"}"===t[t.length-1].text&&(t.pop(),t.shift()),t.reverse(),{tokens:t,start:n,end:a}}consumeArgs(e,t){if(t){if(t.length!==e+1)throw new i("The length of delimiters doesn't match the number of args!");for(var r=t[0],a=0;a<r.length;a++){var n=this.popToken();if(r[a]!==n.text)throw new i("Use of the macro doesn't match its definition",n)}}for(var o=[],s=0;s<e;s++)o.push(this.consumeArg(t&&t[s+1]).tokens);return o}countExpansion(e){if(this.expansionCount+=e,this.expansionCount>this.settings.maxExpand)throw new i("Too many expansions: infinite loop or need to increase maxExpand setting")}expandOnce(e){var t=this.popToken(),r=t.text,a=t.noexpand?null:this._getExpansion(r);if(null==a||e&&a.unexpandable){if(e&&null==a&&"\\"===r[0]&&!this.isDefined(r))throw new i("Undefined control sequence: "+r);return this.pushToken(t),!1}this.countExpansion(1);var n=a.tokens,o=this.consumeArgs(a.numArgs,a.delimiters);if(a.numArgs)for(var s=(n=n.slice()).length-1;s>=0;--s){var l=n[s];if("#"===l.text){if(0===s)throw new i("Incomplete placeholder at end of macro body",l);if("#"===(l=n[--s]).text)n.splice(s+1,1);else{if(!/^[1-9]$/.test(l.text))throw new i("Not a valid argument number",l);n.splice(s,2,...o[+l.text-1])}}}return this.pushTokens(n),n.length}expandAfterFuture(){return this.expandOnce(),this.future()}expandNextToken(){for(;;)if(!1===this.expandOnce()){var e=this.stack.pop();return e.treatAsRelax&&(e.text="\\relax"),e}throw new Error}expandMacro(e){return this.macros.has(e)?this.expandTokens([new n(e)]):void 0}expandTokens(e){var t=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;)if(!1===this.expandOnce(!0)){var a=this.stack.pop();a.treatAsRelax&&(a.noexpand=!1,a.treatAsRelax=!1),t.push(a)}return this.countExpansion(t.length),t}expandMacroAsText(e){var t=this.expandMacro(e);return t?t.map(e=>e.text).join(""):t}_getExpansion(e){var t=this.macros.get(e);if(null==t)return t;if(1===e.length){var r=this.lexer.catcodes[e];if(null!=r&&13!==r)return}var a="function"==typeof t?t(this):t;if("string"==typeof a){var n=0;if(-1!==a.indexOf("#"))for(var i=a.replace(/##/g,"");-1!==i.indexOf("#"+(n+1));)++n;for(var o=new Ea(a,this.settings),s=[],l=o.lex();"EOF"!==l.text;)s.push(l),l=o.lex();return s.reverse(),{tokens:s,numArgs:n}}return a}isDefined(e){return this.macros.has(e)||Na.hasOwnProperty(e)||ie.math.hasOwnProperty(e)||ie.text.hasOwnProperty(e)||Xa.hasOwnProperty(e)}isExpandable(e){var t=this.macros.get(e);return null!=t?"string"==typeof t||"function"==typeof t||!t.unexpandable:Na.hasOwnProperty(e)&&!Na[e].primitive}}var _a=/^[\u208a\u208b\u208c\u208d\u208e\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089\u2090\u2091\u2095\u1d62\u2c7c\u2096\u2097\u2098\u2099\u2092\u209a\u1d63\u209b\u209c\u1d64\u1d65\u2093\u1d66\u1d67\u1d68\u1d69\u1d6a]/,ja=Object.freeze({"\u208a":"+","\u208b":"-","\u208c":"=","\u208d":"(","\u208e":")","\u2080":"0","\u2081":"1","\u2082":"2","\u2083":"3","\u2084":"4","\u2085":"5","\u2086":"6","\u2087":"7","\u2088":"8","\u2089":"9","\u2090":"a","\u2091":"e","\u2095":"h","\u1d62":"i","\u2c7c":"j","\u2096":"k","\u2097":"l","\u2098":"m","\u2099":"n","\u2092":"o","\u209a":"p","\u1d63":"r","\u209b":"s","\u209c":"t","\u1d64":"u","\u1d65":"v","\u2093":"x","\u1d66":"\u03b2","\u1d67":"\u03b3","\u1d68":"\u03c1","\u1d69":"\u03d5","\u1d6a":"\u03c7","\u207a":"+","\u207b":"-","\u207c":"=","\u207d":"(","\u207e":")","\u2070":"0","\xb9":"1","\xb2":"2","\xb3":"3","\u2074":"4","\u2075":"5","\u2076":"6","\u2077":"7","\u2078":"8","\u2079":"9","\u1d2c":"A","\u1d2e":"B","\u1d30":"D","\u1d31":"E","\u1d33":"G","\u1d34":"H","\u1d35":"I","\u1d36":"J","\u1d37":"K","\u1d38":"L","\u1d39":"M","\u1d3a":"N","\u1d3c":"O","\u1d3e":"P","\u1d3f":"R","\u1d40":"T","\u1d41":"U","\u2c7d":"V","\u1d42":"W","\u1d43":"a","\u1d47":"b","\u1d9c":"c","\u1d48":"d","\u1d49":"e","\u1da0":"f","\u1d4d":"g","\u02b0":"h","\u2071":"i","\u02b2":"j","\u1d4f":"k","\u02e1":"l","\u1d50":"m","\u207f":"n","\u1d52":"o","\u1d56":"p","\u02b3":"r","\u02e2":"s","\u1d57":"t","\u1d58":"u","\u1d5b":"v","\u02b7":"w","\u02e3":"x","\u02b8":"y","\u1dbb":"z","\u1d5d":"\u03b2","\u1d5e":"\u03b3","\u1d5f":"\u03b4","\u1d60":"\u03d5","\u1d61":"\u03c7","\u1dbf":"\u03b8"}),$a={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030c":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030a":{text:"\\r",math:"\\mathring"},"\u030b":{text:"\\H"},"\u0327":{text:"\\c"}},Za={"\xe1":"a\u0301","\xe0":"a\u0300","\xe4":"a\u0308","\u01df":"a\u0308\u0304","\xe3":"a\u0303","\u0101":"a\u0304","\u0103":"a\u0306","\u1eaf":"a\u0306\u0301","\u1eb1":"a\u0306\u0300","\u1eb5":"a\u0306\u0303","\u01ce":"a\u030c","\xe2":"a\u0302","\u1ea5":"a\u0302\u0301","\u1ea7":"a\u0302\u0300","\u1eab":"a\u0302\u0303","\u0227":"a\u0307","\u01e1":"a\u0307\u0304","\xe5":"a\u030a","\u01fb":"a\u030a\u0301","\u1e03":"b\u0307","\u0107":"c\u0301","\u1e09":"c\u0327\u0301","\u010d":"c\u030c","\u0109":"c\u0302","\u010b":"c\u0307","\xe7":"c\u0327","\u010f":"d\u030c","\u1e0b":"d\u0307","\u1e11":"d\u0327","\xe9":"e\u0301","\xe8":"e\u0300","\xeb":"e\u0308","\u1ebd":"e\u0303","\u0113":"e\u0304","\u1e17":"e\u0304\u0301","\u1e15":"e\u0304\u0300","\u0115":"e\u0306","\u1e1d":"e\u0327\u0306","\u011b":"e\u030c","\xea":"e\u0302","\u1ebf":"e\u0302\u0301","\u1ec1":"e\u0302\u0300","\u1ec5":"e\u0302\u0303","\u0117":"e\u0307","\u0229":"e\u0327","\u1e1f":"f\u0307","\u01f5":"g\u0301","\u1e21":"g\u0304","\u011f":"g\u0306","\u01e7":"g\u030c","\u011d":"g\u0302","\u0121":"g\u0307","\u0123":"g\u0327","\u1e27":"h\u0308","\u021f":"h\u030c","\u0125":"h\u0302","\u1e23":"h\u0307","\u1e29":"h\u0327","\xed":"i\u0301","\xec":"i\u0300","\xef":"i\u0308","\u1e2f":"i\u0308\u0301","\u0129":"i\u0303","\u012b":"i\u0304","\u012d":"i\u0306","\u01d0":"i\u030c","\xee":"i\u0302","\u01f0":"j\u030c","\u0135":"j\u0302","\u1e31":"k\u0301","\u01e9":"k\u030c","\u0137":"k\u0327","\u013a":"l\u0301","\u013e":"l\u030c","\u013c":"l\u0327","\u1e3f":"m\u0301","\u1e41":"m\u0307","\u0144":"n\u0301","\u01f9":"n\u0300","\xf1":"n\u0303","\u0148":"n\u030c","\u1e45":"n\u0307","\u0146":"n\u0327","\xf3":"o\u0301","\xf2":"o\u0300","\xf6":"o\u0308","\u022b":"o\u0308\u0304","\xf5":"o\u0303","\u1e4d":"o\u0303\u0301","\u1e4f":"o\u0303\u0308","\u022d":"o\u0303\u0304","\u014d":"o\u0304","\u1e53":"o\u0304\u0301","\u1e51":"o\u0304\u0300","\u014f":"o\u0306","\u01d2":"o\u030c","\xf4":"o\u0302","\u1ed1":"o\u0302\u0301","\u1ed3":"o\u0302\u0300","\u1ed7":"o\u0302\u0303","\u022f":"o\u0307","\u0231":"o\u0307\u0304","\u0151":"o\u030b","\u1e55":"p\u0301","\u1e57":"p\u0307","\u0155":"r\u0301","\u0159":"r\u030c","\u1e59":"r\u0307","\u0157":"r\u0327","\u015b":"s\u0301","\u1e65":"s\u0301\u0307","\u0161":"s\u030c","\u1e67":"s\u030c\u0307","\u015d":"s\u0302","\u1e61":"s\u0307","\u015f":"s\u0327","\u1e97":"t\u0308","\u0165":"t\u030c","\u1e6b":"t\u0307","\u0163":"t\u0327","\xfa":"u\u0301","\xf9":"u\u0300","\xfc":"u\u0308","\u01d8":"u\u0308\u0301","\u01dc":"u\u0308\u0300","\u01d6":"u\u0308\u0304","\u01da":"u\u0308\u030c","\u0169":"u\u0303","\u1e79":"u\u0303\u0301","\u016b":"u\u0304","\u1e7b":"u\u0304\u0308","\u016d":"u\u0306","\u01d4":"u\u030c","\xfb":"u\u0302","\u016f":"u\u030a","\u0171":"u\u030b","\u1e7d":"v\u0303","\u1e83":"w\u0301","\u1e81":"w\u0300","\u1e85":"w\u0308","\u0175":"w\u0302","\u1e87":"w\u0307","\u1e98":"w\u030a","\u1e8d":"x\u0308","\u1e8b":"x\u0307","\xfd":"y\u0301","\u1ef3":"y\u0300","\xff":"y\u0308","\u1ef9":"y\u0303","\u0233":"y\u0304","\u0177":"y\u0302","\u1e8f":"y\u0307","\u1e99":"y\u030a","\u017a":"z\u0301","\u017e":"z\u030c","\u1e91":"z\u0302","\u017c":"z\u0307","\xc1":"A\u0301","\xc0":"A\u0300","\xc4":"A\u0308","\u01de":"A\u0308\u0304","\xc3":"A\u0303","\u0100":"A\u0304","\u0102":"A\u0306","\u1eae":"A\u0306\u0301","\u1eb0":"A\u0306\u0300","\u1eb4":"A\u0306\u0303","\u01cd":"A\u030c","\xc2":"A\u0302","\u1ea4":"A\u0302\u0301","\u1ea6":"A\u0302\u0300","\u1eaa":"A\u0302\u0303","\u0226":"A\u0307","\u01e0":"A\u0307\u0304","\xc5":"A\u030a","\u01fa":"A\u030a\u0301","\u1e02":"B\u0307","\u0106":"C\u0301","\u1e08":"C\u0327\u0301","\u010c":"C\u030c","\u0108":"C\u0302","\u010a":"C\u0307","\xc7":"C\u0327","\u010e":"D\u030c","\u1e0a":"D\u0307","\u1e10":"D\u0327","\xc9":"E\u0301","\xc8":"E\u0300","\xcb":"E\u0308","\u1ebc":"E\u0303","\u0112":"E\u0304","\u1e16":"E\u0304\u0301","\u1e14":"E\u0304\u0300","\u0114":"E\u0306","\u1e1c":"E\u0327\u0306","\u011a":"E\u030c","\xca":"E\u0302","\u1ebe":"E\u0302\u0301","\u1ec0":"E\u0302\u0300","\u1ec4":"E\u0302\u0303","\u0116":"E\u0307","\u0228":"E\u0327","\u1e1e":"F\u0307","\u01f4":"G\u0301","\u1e20":"G\u0304","\u011e":"G\u0306","\u01e6":"G\u030c","\u011c":"G\u0302","\u0120":"G\u0307","\u0122":"G\u0327","\u1e26":"H\u0308","\u021e":"H\u030c","\u0124":"H\u0302","\u1e22":"H\u0307","\u1e28":"H\u0327","\xcd":"I\u0301","\xcc":"I\u0300","\xcf":"I\u0308","\u1e2e":"I\u0308\u0301","\u0128":"I\u0303","\u012a":"I\u0304","\u012c":"I\u0306","\u01cf":"I\u030c","\xce":"I\u0302","\u0130":"I\u0307","\u0134":"J\u0302","\u1e30":"K\u0301","\u01e8":"K\u030c","\u0136":"K\u0327","\u0139":"L\u0301","\u013d":"L\u030c","\u013b":"L\u0327","\u1e3e":"M\u0301","\u1e40":"M\u0307","\u0143":"N\u0301","\u01f8":"N\u0300","\xd1":"N\u0303","\u0147":"N\u030c","\u1e44":"N\u0307","\u0145":"N\u0327","\xd3":"O\u0301","\xd2":"O\u0300","\xd6":"O\u0308","\u022a":"O\u0308\u0304","\xd5":"O\u0303","\u1e4c":"O\u0303\u0301","\u1e4e":"O\u0303\u0308","\u022c":"O\u0303\u0304","\u014c":"O\u0304","\u1e52":"O\u0304\u0301","\u1e50":"O\u0304\u0300","\u014e":"O\u0306","\u01d1":"O\u030c","\xd4":"O\u0302","\u1ed0":"O\u0302\u0301","\u1ed2":"O\u0302\u0300","\u1ed6":"O\u0302\u0303","\u022e":"O\u0307","\u0230":"O\u0307\u0304","\u0150":"O\u030b","\u1e54":"P\u0301","\u1e56":"P\u0307","\u0154":"R\u0301","\u0158":"R\u030c","\u1e58":"R\u0307","\u0156":"R\u0327","\u015a":"S\u0301","\u1e64":"S\u0301\u0307","\u0160":"S\u030c","\u1e66":"S\u030c\u0307","\u015c":"S\u0302","\u1e60":"S\u0307","\u015e":"S\u0327","\u0164":"T\u030c","\u1e6a":"T\u0307","\u0162":"T\u0327","\xda":"U\u0301","\xd9":"U\u0300","\xdc":"U\u0308","\u01d7":"U\u0308\u0301","\u01db":"U\u0308\u0300","\u01d5":"U\u0308\u0304","\u01d9":"U\u0308\u030c","\u0168":"U\u0303","\u1e78":"U\u0303\u0301","\u016a":"U\u0304","\u1e7a":"U\u0304\u0308","\u016c":"U\u0306","\u01d3":"U\u030c","\xdb":"U\u0302","\u016e":"U\u030a","\u0170":"U\u030b","\u1e7c":"V\u0303","\u1e82":"W\u0301","\u1e80":"W\u0300","\u1e84":"W\u0308","\u0174":"W\u0302","\u1e86":"W\u0307","\u1e8c":"X\u0308","\u1e8a":"X\u0307","\xdd":"Y\u0301","\u1ef2":"Y\u0300","\u0178":"Y\u0308","\u1ef8":"Y\u0303","\u0232":"Y\u0304","\u0176":"Y\u0302","\u1e8e":"Y\u0307","\u0179":"Z\u0301","\u017d":"Z\u030c","\u1e90":"Z\u0302","\u017b":"Z\u0307","\u03ac":"\u03b1\u0301","\u1f70":"\u03b1\u0300","\u1fb1":"\u03b1\u0304","\u1fb0":"\u03b1\u0306","\u03ad":"\u03b5\u0301","\u1f72":"\u03b5\u0300","\u03ae":"\u03b7\u0301","\u1f74":"\u03b7\u0300","\u03af":"\u03b9\u0301","\u1f76":"\u03b9\u0300","\u03ca":"\u03b9\u0308","\u0390":"\u03b9\u0308\u0301","\u1fd2":"\u03b9\u0308\u0300","\u1fd1":"\u03b9\u0304","\u1fd0":"\u03b9\u0306","\u03cc":"\u03bf\u0301","\u1f78":"\u03bf\u0300","\u03cd":"\u03c5\u0301","\u1f7a":"\u03c5\u0300","\u03cb":"\u03c5\u0308","\u03b0":"\u03c5\u0308\u0301","\u1fe2":"\u03c5\u0308\u0300","\u1fe1":"\u03c5\u0304","\u1fe0":"\u03c5\u0306","\u03ce":"\u03c9\u0301","\u1f7c":"\u03c9\u0300","\u038e":"\u03a5\u0301","\u1fea":"\u03a5\u0300","\u03ab":"\u03a5\u0308","\u1fe9":"\u03a5\u0304","\u1fe8":"\u03a5\u0306","\u038f":"\u03a9\u0301","\u1ffa":"\u03a9\u0300"};class Ka{constructor(e,t){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new Wa(e,t,this.mode),this.settings=t,this.leftrightDepth=0}expect(e,t){if(void 0===t&&(t=!0),this.fetch().text!==e)throw new i("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());t&&this.consume()}consume(){this.nextToken=null}fetch(){return null==this.nextToken&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken}switchMode(e){this.mode=e,this.gullet.switchMode(e)}parse(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}}subparse(e){var t=this.nextToken;this.consume(),this.gullet.pushToken(new n("}")),this.gullet.pushTokens(e);var r=this.parseExpression(!1);return this.expect("}"),this.nextToken=t,r}parseExpression(e,t){for(var r=[];;){"math"===this.mode&&this.consumeSpaces();var a=this.fetch();if(-1!==Ka.endOfExpression.indexOf(a.text))break;if(t&&a.text===t)break;if(e&&Na[a.text]&&Na[a.text].infix)break;var n=this.parseAtom(t);if(!n)break;"internal"!==n.type&&r.push(n)}return"text"===this.mode&&this.formLigatures(r),this.handleInfixNodes(r)}handleInfixNodes(e){for(var t,r=-1,a=0;a<e.length;a++)if("infix"===e[a].type){if(-1!==r)throw new i("only one infix operator per group",e[a].token);r=a,t=e[a].replaceWith}if(-1!==r&&t){var n,o,s=e.slice(0,r),l=e.slice(r+1);return n=1===s.length&&"ordgroup"===s[0].type?s[0]:{type:"ordgroup",mode:this.mode,body:s},o=1===l.length&&"ordgroup"===l[0].type?l[0]:{type:"ordgroup",mode:this.mode,body:l},["\\\\abovefrac"===t?this.callFunction(t,[n,e[r],o],[]):this.callFunction(t,[n,o],[])]}return e}handleSupSubscript(e){var t,r=this.fetch(),a=r.text;this.consume(),this.consumeSpaces();do{var n;t=this.parseGroup(e)}while("internal"===(null==(n=t)?void 0:n.type));if(!t)throw new i("Expected group after '"+a+"'",r);return t}formatUnsupportedCmd(e){for(var t=[],r=0;r<e.length;r++)t.push({type:"textord",mode:"text",text:e[r]});var a={type:"text",mode:this.mode,body:t};return{type:"color",mode:this.mode,color:this.settings.errorColor,body:[a]}}parseAtom(e){var t,r,a=this.parseGroup("atom",e);if("internal"===(null==a?void 0:a.type))return a;if("text"===this.mode)return a;for(;;){this.consumeSpaces();var o=this.fetch();if("\\limits"===o.text||"\\nolimits"===o.text){if(a&&"op"===a.type){var s="\\limits"===o.text;a.limits=s,a.alwaysHandleSupSub=!0}else{if(!a||"operatorname"!==a.type)throw new i("Limit controls must follow a math operator",o);a.alwaysHandleSupSub&&(a.limits="\\limits"===o.text)}this.consume()}else if("^"===o.text){if(t)throw new i("Double superscript",o);t=this.handleSupSubscript("superscript")}else if("_"===o.text){if(r)throw new i("Double subscript",o);r=this.handleSupSubscript("subscript")}else if("'"===o.text){if(t)throw new i("Double superscript",o);var l={type:"textord",mode:this.mode,text:"\\prime"},h=[l];for(this.consume();"'"===this.fetch().text;)h.push(l),this.consume();"^"===this.fetch().text&&h.push(this.handleSupSubscript("superscript")),t={type:"ordgroup",mode:this.mode,body:h}}else{if(!ja[o.text])break;var m=_a.test(o.text),c=[];for(c.push(new n(ja[o.text])),this.consume();;){var p=this.fetch().text;if(!ja[p])break;if(_a.test(p)!==m)break;c.unshift(new n(ja[p])),this.consume()}var u=this.subparse(c);m?r={type:"ordgroup",mode:"math",body:u}:t={type:"ordgroup",mode:"math",body:u}}}return t||r?{type:"supsub",mode:this.mode,base:a,sup:t,sub:r}:a}parseFunction(e,t){var r=this.fetch(),a=r.text,n=Na[a];if(!n)return null;if(this.consume(),t&&"atom"!==t&&!n.allowedInArgument)throw new i("Got function '"+a+"' with no arguments"+(t?" as "+t:""),r);if("text"===this.mode&&!n.allowedInText)throw new i("Can't use function '"+a+"' in text mode",r);if("math"===this.mode&&!1===n.allowedInMath)throw new i("Can't use function '"+a+"' in math mode",r);var{args:o,optArgs:s}=this.parseArguments(a,n);return this.callFunction(a,o,s,r,e)}callFunction(e,t,r,a,n){var o={funcName:e,parser:this,token:a,breakOnTokenText:n},s=Na[e];if(s&&s.handler)return s.handler(o,t,r);throw new i("No function handler for "+e)}parseArguments(e,t){var r=t.numArgs+t.numOptionalArgs;if(0===r)return{args:[],optArgs:[]};for(var a=[],n=[],o=0;o<r;o++){var s=t.argTypes&&t.argTypes[o],l=o<t.numOptionalArgs;(t.primitive&&null==s||"sqrt"===t.type&&1===o&&null==n[0])&&(s="primitive");var h=this.parseGroupOfType("argument to '"+e+"'",s,l);if(l)n.push(h);else{if(null==h)throw new i("Null argument, please report this as a bug");a.push(h)}}return{args:a,optArgs:n}}parseGroupOfType(e,t,r){switch(t){case"color":return this.parseColorGroup(r);case"size":return this.parseSizeGroup(r);case"url":return this.parseUrlGroup(r);case"math":case"text":return this.parseArgumentGroup(r,t);case"hbox":var a=this.parseArgumentGroup(r,"text");return null!=a?{type:"styling",mode:a.mode,body:[a],style:"text"}:null;case"raw":var n=this.parseStringGroup("raw",r);return null!=n?{type:"raw",mode:"text",string:n.text}:null;case"primitive":if(r)throw new i("A primitive argument cannot be optional");var o=this.parseGroup(e);if(null==o)throw new i("Expected group as "+e,this.fetch());return o;case"original":case null:case void 0:return this.parseArgumentGroup(r);default:throw new i("Unknown group type as "+e,this.fetch())}}consumeSpaces(){for(;" "===this.fetch().text;)this.consume()}parseStringGroup(e,t){var r=this.gullet.scanArgument(t);if(null==r)return null;for(var a,n="";"EOF"!==(a=this.fetch()).text;)n+=a.text,this.consume();return this.consume(),r.text=n,r}parseRegexGroup(e,t){for(var r,a=this.fetch(),n=a,o="";"EOF"!==(r=this.fetch()).text&&e.test(o+r.text);)o+=(n=r).text,this.consume();if(""===o)throw new i("Invalid "+t+": '"+a.text+"'",a);return a.range(n,o)}parseColorGroup(e){var t=this.parseStringGroup("color",e);if(null==t)return null;var r=/^(#[a-f0-9]{3,4}|#[a-f0-9]{6}|#[a-f0-9]{8}|[a-f0-9]{6}|[a-z]+)$/i.exec(t.text);if(!r)throw new i("Invalid color: '"+t.text+"'",t);var a=r[0];return/^[0-9a-f]{6}$/i.test(a)&&(a="#"+a),{type:"color-token",mode:this.mode,color:a}}parseSizeGroup(e){var t,r=!1;if(this.gullet.consumeSpaces(),!(t=e||"{"===this.gullet.future().text?this.parseStringGroup("size",e):this.parseRegexGroup(/^[-+]? *(?:$|\d+|\d+\.\d*|\.\d*) *[a-z]{0,2} *$/,"size")))return null;e||0!==t.text.length||(t.text="0pt",r=!0);var a=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(t.text);if(!a)throw new i("Invalid size: '"+t.text+"'",t);var n={number:+(a[1]+a[2]),unit:a[3]};if(!P(n))throw new i("Invalid unit: '"+n.unit+"'",t);return{type:"size",mode:this.mode,value:n,isBlank:r}}parseUrlGroup(e){this.gullet.lexer.setCatcode("%",13),this.gullet.lexer.setCatcode("~",12);var t=this.parseStringGroup("url",e);if(this.gullet.lexer.setCatcode("%",14),this.gullet.lexer.setCatcode("~",13),null==t)return null;var r=t.text.replace(/\\([#$%&~_^{}])/g,"$1");return{type:"url",mode:this.mode,url:r}}parseArgumentGroup(e,t){var r=this.gullet.scanArgument(e);if(null==r)return null;var a=this.mode;t&&this.switchMode(t),this.gullet.beginGroup();var n=this.parseExpression(!1,"EOF");this.expect("EOF"),this.gullet.endGroup();var i={type:"ordgroup",mode:this.mode,loc:r.loc,body:n};return t&&this.switchMode(a),i}parseGroup(e,t){var r,n=this.fetch(),o=n.text;if("{"===o||"\\begingroup"===o){this.consume();var s="{"===o?"}":"\\endgroup";this.gullet.beginGroup();var l=this.parseExpression(!1,s),h=this.fetch();this.expect(s),this.gullet.endGroup(),r={type:"ordgroup",mode:this.mode,loc:a.range(n,h),body:l,semisimple:"\\begingroup"===o||void 0}}else if(null==(r=this.parseFunction(t,e)||this.parseSymbol())&&"\\"===o[0]&&!Xa.hasOwnProperty(o)){if(this.settings.throwOnError)throw new i("Undefined control sequence: "+o,n);r=this.formatUnsupportedCmd(o),this.consume()}return r}formLigatures(e){for(var t=e.length-1,r=0;r<t;++r){var n=e[r],i=n.text;"-"===i&&"-"===e[r+1].text&&(r+1<t&&"-"===e[r+2].text?(e.splice(r,3,{type:"textord",mode:"text",loc:a.range(n,e[r+2]),text:"---"}),t-=2):(e.splice(r,2,{type:"textord",mode:"text",loc:a.range(n,e[r+1]),text:"--"}),t-=1)),"'"!==i&&"`"!==i||e[r+1].text!==i||(e.splice(r,2,{type:"textord",mode:"text",loc:a.range(n,e[r+1]),text:i+i}),t-=1)}}parseSymbol(){var e=this.fetch(),t=e.text;if(/^\\verb[^a-zA-Z]/.test(t)){this.consume();var r=t.slice(5),n="*"===r.charAt(0);if(n&&(r=r.slice(1)),r.length<2||r.charAt(0)!==r.slice(-1))throw new i("\\verb assertion failed --\n please report what input caused this bug");return{type:"verb",mode:"text",body:r=r.slice(1,-1),star:n}}Za.hasOwnProperty(t[0])&&!ie[this.mode][t[0]]&&(this.settings.strict&&"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Accented Unicode text character "'+t[0]+'" used in math mode',e),t=Za[t[0]]+t.slice(1));var o,s=Ha.exec(t);if(s&&("i"===(t=t.substring(0,s.index))?t="\u0131":"j"===t&&(t="\u0237")),ie[this.mode][t]){this.settings.strict&&"math"===this.mode&&Le.indexOf(t)>=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+t[0]+'" used in math mode',e);var l,h=ie[this.mode][t].group,m=a.range(e);if(ae.hasOwnProperty(h)){var c=h;l={type:"atom",mode:this.mode,family:c,loc:m,text:t}}else l={type:h,mode:this.mode,loc:m,text:t};o=l}else{if(!(t.charCodeAt(0)>=128))return null;this.settings.strict&&(z(t.charCodeAt(0))?"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+t[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+t[0]+'" ('+t.charCodeAt(0)+")",e)),o={type:"textord",mode:"text",loc:a.range(e),text:t}}if(this.consume(),s)for(var p=0;p<s[0].length;p++){var u=s[0][p];if(!$a[u])throw new i("Unknown accent ' "+u+"'",e);var d=$a[u][this.mode]||$a[u].text;if(!d)throw new i("Accent "+u+" unsupported in "+this.mode+" mode",e);o={type:"accent",mode:this.mode,loc:a.range(e),label:d,isStretchy:!1,isShifty:!0,base:o}}return o}}Ka.endOfExpression=["}","\\endgroup","\\end","\\right","&"];var Ja=function(e,t){if(!("string"==typeof e||e instanceof String))throw new TypeError("KaTeX can only parse string typed expression");var r=new Ka(e,t);delete r.gullet.macros.current["\\df@tag"];var a=r.parse();if(delete r.gullet.macros.current["\\current@color"],delete r.gullet.macros.current["\\color"],r.gullet.macros.get("\\df@tag")){if(!t.displayMode)throw new i("\\tag works only in display equations");a=[{type:"tag",mode:"text",body:a,tag:r.subparse([new n("\\df@tag")])}]}return a},Qa=function(e,t,r){t.textContent="";var a=tn(e,r).toNode();t.appendChild(a)};"undefined"!=typeof document&&"CSS1Compat"!==document.compatMode&&("undefined"!=typeof console&&console.warn("Warning: KaTeX doesn't work in quirks mode. Make sure your website has a suitable doctype."),Qa=function(){throw new i("KaTeX doesn't work in quirks mode.")});var en=function(e,t,r){if(r.throwOnError||!(e instanceof i))throw e;var a=Je.makeSpan(["katex-error"],[new J(t)]);return a.setAttribute("title",e.toString()),a.setAttribute("style","color:"+r.errorColor),a},tn=function(e,t){var r=new u(t);try{return function(e,t,r){var a,n=Lt(r);if("mathml"===r.output)return Et(e,t,n,r.displayMode,!0);if("html"===r.output){var i=Mt(e,n);a=Je.makeSpan(["katex"],[i])}else{var o=Et(e,t,n,r.displayMode,!1),s=Mt(e,n);a=Je.makeSpan(["katex"],[o,s])}return Dt(a,r)}(Ja(e,r),e,r)}catch(a){return en(a,e,r)}},rn={version:"0.16.25",render:Qa,renderToString:function(e,t){return tn(e,t).toMarkup()},ParseError:i,SETTINGS_SCHEMA:c,__parse:function(e,t){var r=new u(t);return Ja(e,r)},__renderToDomTree:tn,__renderToHTMLTree:function(e,t){var r=new u(t);try{return function(e,t,r){var a=Mt(e,Lt(r)),n=Je.makeSpan(["katex"],[a]);return Dt(n,r)}(Ja(e,r),0,r)}catch(a){return en(a,e,r)}},__setFontMetrics:function(e,t){C[e]=t},__defineSymbol:oe,__defineFunction:st,__defineMacro:Ur,__domTree:{Span:j,Anchor:$,SymbolNode:J,SvgNode:Q,PathNode:ee,LineNode:te}}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/2235.460f34f9.js b/pr-preview/pr-4027/assets/js/2235.460f34f9.js deleted file mode 100644 index 520384dfb..000000000 --- a/pr-preview/pr-4027/assets/js/2235.460f34f9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2235],{21152:(t,e,s)=>{s.d(e,{P:()=>r});var i=s(67633),n=s(40797),r=(0,n.K2)((t,e,s,r)=>{t.attr("class",s);const{width:c,height:l,x:h,y:d}=o(t,e);(0,i.a$)(t,l,c,r);const u=a(h,d,c,l,e);t.attr("viewBox",u),n.Rm.debug(`viewBox configured: ${u} with padding: ${e}`)},"setupViewPortForSVG"),o=(0,n.K2)((t,e)=>{const s=t.node()?.getBBox()||{width:0,height:0,x:0,y:0};return{width:s.width+2*e,height:s.height+2*e,x:s.x,y:s.y}},"calculateDimensionsWithPadding"),a=(0,n.K2)((t,e,s,i,n)=>`${t-n} ${e-n} ${s} ${i}`,"createViewBox")},54616:(t,e,s)=>{s.d(e,{Zk:()=>h,q7:()=>B,tM:()=>ot,u4:()=>rt});var i=s(89625),n=s(21152),r=s(10045),o=s(13226),a=s(67633),c=s(40797),l=function(){var t=(0,c.K2)(function(t,e,s,i){for(s=s||{},i=t.length;i--;s[t[i]]=e);return s},"o"),e=[1,2],s=[1,3],i=[1,4],n=[2,4],r=[1,9],o=[1,11],a=[1,16],l=[1,17],h=[1,18],d=[1,19],u=[1,33],p=[1,20],y=[1,21],g=[1,22],m=[1,23],f=[1,24],S=[1,26],b=[1,27],_=[1,28],k=[1,29],T=[1,30],E=[1,31],D=[1,32],x=[1,35],C=[1,36],$=[1,37],v=[1,38],I=[1,34],A=[1,4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,41,45,48,51,52,53,54,57],L=[1,4,5,14,15,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,39,40,41,45,48,51,52,53,54,57],w=[4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,41,45,48,51,52,53,54,57],R={trace:(0,c.K2)(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,SD:6,document:7,line:8,statement:9,classDefStatement:10,styleStatement:11,cssClassStatement:12,idStatement:13,DESCR:14,"--\x3e":15,HIDE_EMPTY:16,scale:17,WIDTH:18,COMPOSIT_STATE:19,STRUCT_START:20,STRUCT_STOP:21,STATE_DESCR:22,AS:23,ID:24,FORK:25,JOIN:26,CHOICE:27,CONCURRENT:28,note:29,notePosition:30,NOTE_TEXT:31,direction:32,acc_title:33,acc_title_value:34,acc_descr:35,acc_descr_value:36,acc_descr_multiline_value:37,CLICK:38,STRING:39,HREF:40,classDef:41,CLASSDEF_ID:42,CLASSDEF_STYLEOPTS:43,DEFAULT:44,style:45,STYLE_IDS:46,STYLEDEF_STYLEOPTS:47,class:48,CLASSENTITY_IDS:49,STYLECLASS:50,direction_tb:51,direction_bt:52,direction_rl:53,direction_lr:54,eol:55,";":56,EDGE_STATE:57,STYLE_SEPARATOR:58,left_of:59,right_of:60,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",6:"SD",14:"DESCR",15:"--\x3e",16:"HIDE_EMPTY",17:"scale",18:"WIDTH",19:"COMPOSIT_STATE",20:"STRUCT_START",21:"STRUCT_STOP",22:"STATE_DESCR",23:"AS",24:"ID",25:"FORK",26:"JOIN",27:"CHOICE",28:"CONCURRENT",29:"note",31:"NOTE_TEXT",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",38:"CLICK",39:"STRING",40:"HREF",41:"classDef",42:"CLASSDEF_ID",43:"CLASSDEF_STYLEOPTS",44:"DEFAULT",45:"style",46:"STYLE_IDS",47:"STYLEDEF_STYLEOPTS",48:"class",49:"CLASSENTITY_IDS",50:"STYLECLASS",51:"direction_tb",52:"direction_bt",53:"direction_rl",54:"direction_lr",56:";",57:"EDGE_STATE",58:"STYLE_SEPARATOR",59:"left_of",60:"right_of"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,3],[9,4],[9,1],[9,2],[9,1],[9,4],[9,3],[9,6],[9,1],[9,1],[9,1],[9,1],[9,4],[9,4],[9,1],[9,2],[9,2],[9,1],[9,5],[9,5],[10,3],[10,3],[11,3],[12,3],[32,1],[32,1],[32,1],[32,1],[55,1],[55,1],[13,1],[13,1],[13,3],[13,3],[30,1],[30,1]],performAction:(0,c.K2)(function(t,e,s,i,n,r,o){var a=r.length-1;switch(n){case 3:return i.setRootDoc(r[a]),r[a];case 4:this.$=[];break;case 5:"nl"!=r[a]&&(r[a-1].push(r[a]),this.$=r[a-1]);break;case 6:case 7:case 12:this.$=r[a];break;case 8:this.$="nl";break;case 13:const t=r[a-1];t.description=i.trimColon(r[a]),this.$=t;break;case 14:this.$={stmt:"relation",state1:r[a-2],state2:r[a]};break;case 15:const e=i.trimColon(r[a]);this.$={stmt:"relation",state1:r[a-3],state2:r[a-1],description:e};break;case 19:this.$={stmt:"state",id:r[a-3],type:"default",description:"",doc:r[a-1]};break;case 20:var c=r[a],l=r[a-2].trim();if(r[a].match(":")){var h=r[a].split(":");c=h[0],l=[l,h[1]]}this.$={stmt:"state",id:c,type:"default",description:l};break;case 21:this.$={stmt:"state",id:r[a-3],type:"default",description:r[a-5],doc:r[a-1]};break;case 22:this.$={stmt:"state",id:r[a],type:"fork"};break;case 23:this.$={stmt:"state",id:r[a],type:"join"};break;case 24:this.$={stmt:"state",id:r[a],type:"choice"};break;case 25:this.$={stmt:"state",id:i.getDividerId(),type:"divider"};break;case 26:this.$={stmt:"state",id:r[a-1].trim(),note:{position:r[a-2].trim(),text:r[a].trim()}};break;case 29:this.$=r[a].trim(),i.setAccTitle(this.$);break;case 30:case 31:this.$=r[a].trim(),i.setAccDescription(this.$);break;case 32:this.$={stmt:"click",id:r[a-3],url:r[a-2],tooltip:r[a-1]};break;case 33:this.$={stmt:"click",id:r[a-3],url:r[a-1],tooltip:""};break;case 34:case 35:this.$={stmt:"classDef",id:r[a-1].trim(),classes:r[a].trim()};break;case 36:this.$={stmt:"style",id:r[a-1].trim(),styleClass:r[a].trim()};break;case 37:this.$={stmt:"applyClass",id:r[a-1].trim(),styleClass:r[a].trim()};break;case 38:i.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 39:i.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 40:i.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 41:i.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 44:case 45:this.$={stmt:"state",id:r[a].trim(),type:"default",description:""};break;case 46:case 47:this.$={stmt:"state",id:r[a-2].trim(),classes:[r[a].trim()],type:"default",description:""}}},"anonymous"),table:[{3:1,4:e,5:s,6:i},{1:[3]},{3:5,4:e,5:s,6:i},{3:6,4:e,5:s,6:i},t([1,4,5,16,17,19,22,24,25,26,27,28,29,33,35,37,38,41,45,48,51,52,53,54,57],n,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:r,5:o,8:8,9:10,10:12,11:13,12:14,13:15,16:a,17:l,19:h,22:d,24:u,25:p,26:y,27:g,28:m,29:f,32:25,33:S,35:b,37:_,38:k,41:T,45:E,48:D,51:x,52:C,53:$,54:v,57:I},t(A,[2,5]),{9:39,10:12,11:13,12:14,13:15,16:a,17:l,19:h,22:d,24:u,25:p,26:y,27:g,28:m,29:f,32:25,33:S,35:b,37:_,38:k,41:T,45:E,48:D,51:x,52:C,53:$,54:v,57:I},t(A,[2,7]),t(A,[2,8]),t(A,[2,9]),t(A,[2,10]),t(A,[2,11]),t(A,[2,12],{14:[1,40],15:[1,41]}),t(A,[2,16]),{18:[1,42]},t(A,[2,18],{20:[1,43]}),{23:[1,44]},t(A,[2,22]),t(A,[2,23]),t(A,[2,24]),t(A,[2,25]),{30:45,31:[1,46],59:[1,47],60:[1,48]},t(A,[2,28]),{34:[1,49]},{36:[1,50]},t(A,[2,31]),{13:51,24:u,57:I},{42:[1,52],44:[1,53]},{46:[1,54]},{49:[1,55]},t(L,[2,44],{58:[1,56]}),t(L,[2,45],{58:[1,57]}),t(A,[2,38]),t(A,[2,39]),t(A,[2,40]),t(A,[2,41]),t(A,[2,6]),t(A,[2,13]),{13:58,24:u,57:I},t(A,[2,17]),t(w,n,{7:59}),{24:[1,60]},{24:[1,61]},{23:[1,62]},{24:[2,48]},{24:[2,49]},t(A,[2,29]),t(A,[2,30]),{39:[1,63],40:[1,64]},{43:[1,65]},{43:[1,66]},{47:[1,67]},{50:[1,68]},{24:[1,69]},{24:[1,70]},t(A,[2,14],{14:[1,71]}),{4:r,5:o,8:8,9:10,10:12,11:13,12:14,13:15,16:a,17:l,19:h,21:[1,72],22:d,24:u,25:p,26:y,27:g,28:m,29:f,32:25,33:S,35:b,37:_,38:k,41:T,45:E,48:D,51:x,52:C,53:$,54:v,57:I},t(A,[2,20],{20:[1,73]}),{31:[1,74]},{24:[1,75]},{39:[1,76]},{39:[1,77]},t(A,[2,34]),t(A,[2,35]),t(A,[2,36]),t(A,[2,37]),t(L,[2,46]),t(L,[2,47]),t(A,[2,15]),t(A,[2,19]),t(w,n,{7:78}),t(A,[2,26]),t(A,[2,27]),{5:[1,79]},{5:[1,80]},{4:r,5:o,8:8,9:10,10:12,11:13,12:14,13:15,16:a,17:l,19:h,21:[1,81],22:d,24:u,25:p,26:y,27:g,28:m,29:f,32:25,33:S,35:b,37:_,38:k,41:T,45:E,48:D,51:x,52:C,53:$,54:v,57:I},t(A,[2,32]),t(A,[2,33]),t(A,[2,21])],defaultActions:{5:[2,1],6:[2,2],47:[2,48],48:[2,49]},parseError:(0,c.K2)(function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)},"parseError"),parse:(0,c.K2)(function(t){var e=this,s=[0],i=[],n=[null],r=[],o=this.table,a="",l=0,h=0,d=0,u=r.slice.call(arguments,1),p=Object.create(this.lexer),y={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(y.yy[g]=this.yy[g]);p.setInput(t,y.yy),y.yy.lexer=p,y.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var m=p.yylloc;r.push(m);var f=p.options&&p.options.ranges;function S(){var t;return"number"!=typeof(t=i.pop()||p.lex()||1)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,c.K2)(function(t){s.length=s.length-2*t,n.length=n.length-t,r.length=r.length-t},"popStack"),(0,c.K2)(S,"lex");for(var b,_,k,T,E,D,x,C,$,v={};;){if(k=s[s.length-1],this.defaultActions[k]?T=this.defaultActions[k]:(null==b&&(b=S()),T=o[k]&&o[k][b]),void 0===T||!T.length||!T[0]){var I="";for(D in $=[],o[k])this.terminals_[D]&&D>2&&$.push("'"+this.terminals_[D]+"'");I=p.showPosition?"Parse error on line "+(l+1)+":\n"+p.showPosition()+"\nExpecting "+$.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(I,{text:p.match,token:this.terminals_[b]||b,line:p.yylineno,loc:m,expected:$})}if(T[0]instanceof Array&&T.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+b);switch(T[0]){case 1:s.push(b),n.push(p.yytext),r.push(p.yylloc),s.push(T[1]),b=null,_?(b=_,_=null):(h=p.yyleng,a=p.yytext,l=p.yylineno,m=p.yylloc,d>0&&d--);break;case 2:if(x=this.productions_[T[1]][1],v.$=n[n.length-x],v._$={first_line:r[r.length-(x||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(x||1)].first_column,last_column:r[r.length-1].last_column},f&&(v._$.range=[r[r.length-(x||1)].range[0],r[r.length-1].range[1]]),void 0!==(E=this.performAction.apply(v,[a,h,l,y.yy,T[1],n,r].concat(u))))return E;x&&(s=s.slice(0,-1*x*2),n=n.slice(0,-1*x),r=r.slice(0,-1*x)),s.push(this.productions_[T[1]][0]),n.push(v.$),r.push(v._$),C=o[s[s.length-2]][s[s.length-1]],s.push(C);break;case 3:return!0}}return!0},"parse")},N=function(){return{EOF:1,parseError:(0,c.K2)(function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},"parseError"),setInput:(0,c.K2)(function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:(0,c.K2)(function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},"input"),unput:(0,c.K2)(function(t){var e=t.length,s=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),s.length-1&&(this.yylineno-=s.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:s?(s.length===i.length?this.yylloc.first_column:0)+i[i.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},"unput"),more:(0,c.K2)(function(){return this._more=!0,this},"more"),reject:(0,c.K2)(function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"reject"),less:(0,c.K2)(function(t){this.unput(this.match.slice(t))},"less"),pastInput:(0,c.K2)(function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:(0,c.K2)(function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:(0,c.K2)(function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},"showPosition"),test_match:(0,c.K2)(function(t,e){var s,i,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},"test_match"),next:(0,c.K2)(function(){if(this.done)return this.EOF;var t,e,s,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;r<n.length;r++)if((s=this._input.match(this.rules[n[r]]))&&(!e||s[0].length>e[0].length)){if(e=s,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,n[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,n[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:(0,c.K2)(function(){var t=this.next();return t||this.lex()},"lex"),begin:(0,c.K2)(function(t){this.conditionStack.push(t)},"begin"),popState:(0,c.K2)(function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:(0,c.K2)(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:(0,c.K2)(function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},"topState"),pushState:(0,c.K2)(function(t){this.begin(t)},"pushState"),stateStackSize:(0,c.K2)(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,c.K2)(function(t,e,s,i){switch(s){case 0:return 38;case 1:return 40;case 2:return 39;case 3:return 44;case 4:case 45:return 51;case 5:case 46:return 52;case 6:case 47:return 53;case 7:case 48:return 54;case 8:case 9:case 11:case 12:case 13:case 14:case 57:case 59:case 65:break;case 10:case 80:return 5;case 15:case 35:return this.pushState("SCALE"),17;case 16:case 36:return 18;case 17:case 23:case 37:case 52:case 55:this.popState();break;case 18:return this.begin("acc_title"),33;case 19:return this.popState(),"acc_title_value";case 20:return this.begin("acc_descr"),35;case 21:return this.popState(),"acc_descr_value";case 22:this.begin("acc_descr_multiline");break;case 24:return"acc_descr_multiline_value";case 25:return this.pushState("CLASSDEF"),41;case 26:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";case 27:return this.popState(),this.pushState("CLASSDEFID"),42;case 28:return this.popState(),43;case 29:return this.pushState("CLASS"),48;case 30:return this.popState(),this.pushState("CLASS_STYLE"),49;case 31:return this.popState(),50;case 32:return this.pushState("STYLE"),45;case 33:return this.popState(),this.pushState("STYLEDEF_STYLES"),46;case 34:return this.popState(),47;case 38:this.pushState("STATE");break;case 39:case 42:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),25;case 40:case 43:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),26;case 41:case 44:return this.popState(),e.yytext=e.yytext.slice(0,-10).trim(),27;case 49:this.pushState("STATE_STRING");break;case 50:return this.pushState("STATE_ID"),"AS";case 51:case 67:return this.popState(),"ID";case 53:return"STATE_DESCR";case 54:return 19;case 56:return this.popState(),this.pushState("struct"),20;case 58:return this.popState(),21;case 60:return this.begin("NOTE"),29;case 61:return this.popState(),this.pushState("NOTE_ID"),59;case 62:return this.popState(),this.pushState("NOTE_ID"),60;case 63:this.popState(),this.pushState("FLOATING_NOTE");break;case 64:return this.popState(),this.pushState("FLOATING_NOTE_ID"),"AS";case 66:return"NOTE_TEXT";case 68:return this.popState(),this.pushState("NOTE_TEXT"),24;case 69:return this.popState(),e.yytext=e.yytext.substr(2).trim(),31;case 70:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),31;case 71:case 72:return 6;case 73:return 16;case 74:return 57;case 75:return 24;case 76:return e.yytext=e.yytext.trim(),14;case 77:return 15;case 78:return 28;case 79:return 58;case 81:return"INVALID"}},"anonymous"),rules:[/^(?:click\b)/i,/^(?:href\b)/i,/^(?:"[^"]*")/i,/^(?:default\b)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:[\s]+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:classDef\s+)/i,/^(?:DEFAULT\s+)/i,/^(?:\w+\s+)/i,/^(?:[^\n]*)/i,/^(?:class\s+)/i,/^(?:(\w+)+((,\s*\w+)*))/i,/^(?:[^\n]*)/i,/^(?:style\s+)/i,/^(?:[\w,]+\s+)/i,/^(?:[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:state\s+)/i,/^(?:.*<<fork>>)/i,/^(?:.*<<join>>)/i,/^(?:.*<<choice>>)/i,/^(?:.*\[\[fork\]\])/i,/^(?:.*\[\[join\]\])/i,/^(?:.*\[\[choice\]\])/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:["])/i,/^(?:\s*as\s+)/i,/^(?:[^\n\{]*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n\s\{]+)/i,/^(?:\n)/i,/^(?:\{)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:\})/i,/^(?:[\n])/i,/^(?:note\s+)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:")/i,/^(?:\s*as\s*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n]*)/i,/^(?:\s*[^:\n\s\-]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:[\s\S]*?end note\b)/i,/^(?:stateDiagram\s+)/i,/^(?:stateDiagram-v2\s+)/i,/^(?:hide empty description\b)/i,/^(?:\[\*\])/i,/^(?:[^:\n\s\-\{]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:-->)/i,/^(?:--)/i,/^(?::::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{LINE:{rules:[12,13],inclusive:!1},struct:{rules:[12,13,25,29,32,38,45,46,47,48,57,58,59,60,74,75,76,77,78],inclusive:!1},FLOATING_NOTE_ID:{rules:[67],inclusive:!1},FLOATING_NOTE:{rules:[64,65,66],inclusive:!1},NOTE_TEXT:{rules:[69,70],inclusive:!1},NOTE_ID:{rules:[68],inclusive:!1},NOTE:{rules:[61,62,63],inclusive:!1},STYLEDEF_STYLEOPTS:{rules:[],inclusive:!1},STYLEDEF_STYLES:{rules:[34],inclusive:!1},STYLE_IDS:{rules:[],inclusive:!1},STYLE:{rules:[33],inclusive:!1},CLASS_STYLE:{rules:[31],inclusive:!1},CLASS:{rules:[30],inclusive:!1},CLASSDEFID:{rules:[28],inclusive:!1},CLASSDEF:{rules:[26,27],inclusive:!1},acc_descr_multiline:{rules:[23,24],inclusive:!1},acc_descr:{rules:[21],inclusive:!1},acc_title:{rules:[19],inclusive:!1},SCALE:{rules:[16,17,36,37],inclusive:!1},ALIAS:{rules:[],inclusive:!1},STATE_ID:{rules:[51],inclusive:!1},STATE_STRING:{rules:[52,53],inclusive:!1},FORK_STATE:{rules:[],inclusive:!1},STATE:{rules:[12,13,39,40,41,42,43,44,49,50,54,55,56],inclusive:!1},ID:{rules:[12,13],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,9,10,11,13,14,15,18,20,22,25,29,32,35,38,56,60,71,72,73,74,75,76,77,79,80,81],inclusive:!0}}}}();function O(){this.yy={}}return R.lexer=N,(0,c.K2)(O,"Parser"),O.prototype=R,R.Parser=O,new O}();l.parser=l;var h=l,d="state",u="root",p="relation",y="default",g="divider",m="fill:none",f="fill: #333",S="text",b="normal",_="rect",k="rectWithTitle",T="divider",E="roundedWithTitle",D="statediagram",x=`${D}-state`,C="transition",$=`${C} note-edge`,v=`${D}-note`,I=`${D}-cluster`,A=`${D}-cluster-alt`,L="parent",w="note",R="----",N=`${R}${w}`,O=`${R}${L}`,K=(0,c.K2)((t,e="TB")=>{if(!t.doc)return e;let s=e;for(const i of t.doc)"dir"===i.stmt&&(s=i.value);return s},"getDir"),B={getClasses:(0,c.K2)(function(t,e){return e.db.getClasses()},"getClasses"),draw:(0,c.K2)(async function(t,e,s,l){c.Rm.info("REF0:"),c.Rm.info("Drawing state diagram (v2)",e);const{securityLevel:h,state:d,layout:u}=(0,a.D7)();l.db.extract(l.db.getRootDocV2());const p=l.db.getData(),y=(0,i.A)(e,h);p.type=l.type,p.layoutAlgorithm=u,p.nodeSpacing=d?.nodeSpacing||50,p.rankSpacing=d?.rankSpacing||50,p.markers=["barb"],p.diagramId=e,await(0,r.XX)(p,y);try{("function"==typeof l.db.getLinks?l.db.getLinks():new Map).forEach((t,e)=>{const s="string"==typeof e?e:"string"==typeof e?.id?e.id:"";if(!s)return void c.Rm.warn("\u26a0\ufe0f Invalid or missing stateId from key:",JSON.stringify(e));const i=y.node()?.querySelectorAll("g");let n;if(i?.forEach(t=>{const e=t.textContent?.trim();e===s&&(n=t)}),!n)return void c.Rm.warn("\u26a0\ufe0f Could not find node matching text:",s);const r=n.parentNode;if(!r)return void c.Rm.warn("\u26a0\ufe0f Node has no parent, cannot wrap:",s);const o=document.createElementNS("http://www.w3.org/2000/svg","a"),a=t.url.replace(/^"+|"+$/g,"");if(o.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",a),o.setAttribute("target","_blank"),t.tooltip){const e=t.tooltip.replace(/^"+|"+$/g,"");o.setAttribute("title",e)}r.replaceChild(o,n),o.appendChild(n),c.Rm.info("\ud83d\udd17 Wrapped node in <a> tag for:",s,t.url)})}catch(g){c.Rm.error("\u274c Error injecting clickable links:",g)}o._K.insertTitle(y,"statediagramTitleText",d?.titleTopMargin??25,l.db.getDiagramTitle()),(0,n.P)(y,8,D,d?.useMaxWidth??!0)},"draw"),getDir:K},F=new Map,Y=0;function P(t="",e=0,s="",i=R){return`state-${t}${null!==s&&s.length>0?`${i}${s}`:""}-${e}`}(0,c.K2)(P,"stateDomId");var G=(0,c.K2)((t,e,s,i,n,r,o,l)=>{c.Rm.trace("items",e),e.forEach(e=>{switch(e.stmt){case d:case y:V(t,e,s,i,n,r,o,l);break;case p:{V(t,e.state1,s,i,n,r,o,l),V(t,e.state2,s,i,n,r,o,l);const c={id:"edge"+Y,start:e.state1.id,end:e.state2.id,arrowhead:"normal",arrowTypeEnd:"arrow_barb",style:m,labelStyle:"",label:a.Y2.sanitizeText(e.description??"",(0,a.D7)()),arrowheadStyle:f,labelpos:"c",labelType:S,thickness:b,classes:C,look:o};n.push(c),Y++}}})},"setupDoc"),j=(0,c.K2)((t,e="TB")=>{let s=e;if(t.doc)for(const i of t.doc)"dir"===i.stmt&&(s=i.value);return s},"getDir");function z(t,e,s){if(!e.id||"</join></fork>"===e.id||"</choice>"===e.id)return;e.cssClasses&&(Array.isArray(e.cssCompiledStyles)||(e.cssCompiledStyles=[]),e.cssClasses.split(" ").forEach(t=>{const i=s.get(t);i&&(e.cssCompiledStyles=[...e.cssCompiledStyles??[],...i.styles])}));const i=t.find(t=>t.id===e.id);i?Object.assign(i,e):t.push(e)}function M(t){return t?.classes?.join(" ")??""}function U(t){return t?.styles??[]}(0,c.K2)(z,"insertOrUpdateNode"),(0,c.K2)(M,"getClassesFromDbInfo"),(0,c.K2)(U,"getStylesFromDbInfo");var V=(0,c.K2)((t,e,s,i,n,r,o,l)=>{const h=e.id,d=s.get(h),u=M(d),p=U(d),D=(0,a.D7)();if(c.Rm.info("dataFetcher parsedItem",e,d,p),"root"!==h){let s=_;!0===e.start?s="stateStart":!1===e.start&&(s="stateEnd"),e.type!==y&&(s=e.type),F.get(h)||F.set(h,{id:h,shape:s,description:a.Y2.sanitizeText(h,D),cssClasses:`${u} ${x}`,cssStyles:p});const d=F.get(h);e.description&&(Array.isArray(d.description)?(d.shape=k,d.description.push(e.description)):d.description?.length&&d.description.length>0?(d.shape=k,d.description===h?d.description=[e.description]:d.description=[d.description,e.description]):(d.shape=_,d.description=e.description),d.description=a.Y2.sanitizeTextOrArray(d.description,D)),1===d.description?.length&&d.shape===k&&("group"===d.type?d.shape=E:d.shape=_),!d.type&&e.doc&&(c.Rm.info("Setting cluster for XCX",h,j(e)),d.type="group",d.isGroup=!0,d.dir=j(e),d.shape=e.type===g?T:E,d.cssClasses=`${d.cssClasses} ${I} ${r?A:""}`);const C={labelStyle:"",shape:d.shape,label:d.description,cssClasses:d.cssClasses,cssCompiledStyles:[],cssStyles:d.cssStyles,id:h,dir:d.dir,domId:P(h,Y),type:d.type,isGroup:"group"===d.type,padding:8,rx:10,ry:10,look:o};if(C.shape===T&&(C.label=""),t&&"root"!==t.id&&(c.Rm.trace("Setting node ",h," to be child of its parent ",t.id),C.parentId=t.id),C.centerLabel=!0,e.note){const t={labelStyle:"",shape:"note",label:e.note.text,cssClasses:v,cssStyles:[],cssCompiledStyles:[],id:h+N+"-"+Y,domId:P(h,Y,w),type:d.type,isGroup:"group"===d.type,padding:D.flowchart?.padding,look:o,position:e.note.position},s=h+O,r={labelStyle:"",shape:"noteGroup",label:e.note.text,cssClasses:d.cssClasses,cssStyles:[],id:h+O,domId:P(h,Y,L),type:"group",isGroup:!0,padding:16,look:o,position:e.note.position};Y++,r.id=s,t.parentId=s,z(i,r,l),z(i,t,l),z(i,C,l);let a=h,c=t.id;"left of"===e.note.position&&(a=t.id,c=h),n.push({id:a+"-"+c,start:a,end:c,arrowhead:"none",arrowTypeEnd:"",style:m,labelStyle:"",classes:$,arrowheadStyle:f,labelpos:"c",labelType:S,thickness:b,look:o})}else z(i,C,l)}e.doc&&(c.Rm.trace("Adding nodes children "),G(e,e.doc,s,i,n,!r,o,l))},"dataFetcher"),W=(0,c.K2)(()=>{F.clear(),Y=0},"reset"),X="[*]",H="start",J="[*]",q="end",Z="color",Q="fill",tt="bgFill",et=",",st=(0,c.K2)(()=>new Map,"newClassesList"),it=(0,c.K2)(()=>({relations:[],states:new Map,documents:{}}),"newDoc"),nt=(0,c.K2)(t=>JSON.parse(JSON.stringify(t)),"clone"),rt=class{constructor(t){this.version=t,this.nodes=[],this.edges=[],this.rootDoc=[],this.classes=st(),this.documents={root:it()},this.currentDocument=this.documents.root,this.startEndCount=0,this.dividerCnt=0,this.links=new Map,this.getAccTitle=a.iN,this.setAccTitle=a.SV,this.getAccDescription=a.m7,this.setAccDescription=a.EI,this.setDiagramTitle=a.ke,this.getDiagramTitle=a.ab,this.clear(),this.setRootDoc=this.setRootDoc.bind(this),this.getDividerId=this.getDividerId.bind(this),this.setDirection=this.setDirection.bind(this),this.trimColon=this.trimColon.bind(this)}static{(0,c.K2)(this,"StateDB")}static{this.relationType={AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3}}extract(t){this.clear(!0);for(const i of Array.isArray(t)?t:t.doc)switch(i.stmt){case d:this.addState(i.id.trim(),i.type,i.doc,i.description,i.note);break;case p:this.addRelation(i.state1,i.state2,i.description);break;case"classDef":this.addStyleClass(i.id.trim(),i.classes);break;case"style":this.handleStyleDef(i);break;case"applyClass":this.setCssClass(i.id.trim(),i.styleClass);break;case"click":this.addLink(i.id,i.url,i.tooltip)}const e=this.getStates(),s=(0,a.D7)();W(),V(void 0,this.getRootDocV2(),e,this.nodes,this.edges,!0,s.look,this.classes);for(const i of this.nodes)if(Array.isArray(i.label)){if(i.description=i.label.slice(1),i.isGroup&&i.description.length>0)throw new Error(`Group nodes can only have label. Remove the additional description for node [${i.id}]`);i.label=i.label[0]}}handleStyleDef(t){const e=t.id.trim().split(","),s=t.styleClass.split(",");for(const i of e){let t=this.getState(i);if(!t){const e=i.trim();this.addState(e),t=this.getState(e)}t&&(t.styles=s.map(t=>t.replace(/;/g,"")?.trim()))}}setRootDoc(t){c.Rm.info("Setting root doc",t),this.rootDoc=t,1===this.version?this.extract(t):this.extract(this.getRootDocV2())}docTranslator(t,e,s){if(e.stmt===p)return this.docTranslator(t,e.state1,!0),void this.docTranslator(t,e.state2,!1);if(e.stmt===d&&(e.id===X?(e.id=t.id+(s?"_start":"_end"),e.start=s):e.id=e.id.trim()),e.stmt!==u&&e.stmt!==d||!e.doc)return;const i=[];let n=[];for(const r of e.doc)if(r.type===g){const t=nt(r);t.doc=nt(n),i.push(t),n=[]}else n.push(r);if(i.length>0&&n.length>0){const t={stmt:d,id:(0,o.$C)(),type:"divider",doc:nt(n)};i.push(nt(t)),e.doc=i}e.doc.forEach(t=>this.docTranslator(e,t,!0))}getRootDocV2(){return this.docTranslator({id:u,stmt:u},{id:u,stmt:u,doc:this.rootDoc},!0),{id:u,doc:this.rootDoc}}addState(t,e=y,s=void 0,i=void 0,n=void 0,r=void 0,o=void 0,l=void 0){const h=t?.trim();if(this.currentDocument.states.has(h)){const t=this.currentDocument.states.get(h);if(!t)throw new Error(`State not found: ${h}`);t.doc||(t.doc=s),t.type||(t.type=e)}else c.Rm.info("Adding state ",h,i),this.currentDocument.states.set(h,{stmt:d,id:h,descriptions:[],type:e,doc:s,note:n,classes:[],styles:[],textStyles:[]});if(i){c.Rm.info("Setting state description",h,i);(Array.isArray(i)?i:[i]).forEach(t=>this.addDescription(h,t.trim()))}if(n){const t=this.currentDocument.states.get(h);if(!t)throw new Error(`State not found: ${h}`);t.note=n,t.note.text=a.Y2.sanitizeText(t.note.text,(0,a.D7)())}if(r){c.Rm.info("Setting state classes",h,r);(Array.isArray(r)?r:[r]).forEach(t=>this.setCssClass(h,t.trim()))}if(o){c.Rm.info("Setting state styles",h,o);(Array.isArray(o)?o:[o]).forEach(t=>this.setStyle(h,t.trim()))}if(l){c.Rm.info("Setting state styles",h,o);(Array.isArray(l)?l:[l]).forEach(t=>this.setTextStyle(h,t.trim()))}}clear(t){this.nodes=[],this.edges=[],this.documents={root:it()},this.currentDocument=this.documents.root,this.startEndCount=0,this.classes=st(),t||(this.links=new Map,(0,a.IU)())}getState(t){return this.currentDocument.states.get(t)}getStates(){return this.currentDocument.states}logDocuments(){c.Rm.info("Documents = ",this.documents)}getRelations(){return this.currentDocument.relations}addLink(t,e,s){this.links.set(t,{url:e,tooltip:s}),c.Rm.warn("Adding link",t,e,s)}getLinks(){return this.links}startIdIfNeeded(t=""){return t===X?(this.startEndCount++,`${H}${this.startEndCount}`):t}startTypeIfNeeded(t="",e=y){return t===X?H:e}endIdIfNeeded(t=""){return t===J?(this.startEndCount++,`${q}${this.startEndCount}`):t}endTypeIfNeeded(t="",e=y){return t===J?q:e}addRelationObjs(t,e,s=""){const i=this.startIdIfNeeded(t.id.trim()),n=this.startTypeIfNeeded(t.id.trim(),t.type),r=this.startIdIfNeeded(e.id.trim()),o=this.startTypeIfNeeded(e.id.trim(),e.type);this.addState(i,n,t.doc,t.description,t.note,t.classes,t.styles,t.textStyles),this.addState(r,o,e.doc,e.description,e.note,e.classes,e.styles,e.textStyles),this.currentDocument.relations.push({id1:i,id2:r,relationTitle:a.Y2.sanitizeText(s,(0,a.D7)())})}addRelation(t,e,s){if("object"==typeof t&&"object"==typeof e)this.addRelationObjs(t,e,s);else if("string"==typeof t&&"string"==typeof e){const i=this.startIdIfNeeded(t.trim()),n=this.startTypeIfNeeded(t),r=this.endIdIfNeeded(e.trim()),o=this.endTypeIfNeeded(e);this.addState(i,n),this.addState(r,o),this.currentDocument.relations.push({id1:i,id2:r,relationTitle:s?a.Y2.sanitizeText(s,(0,a.D7)()):void 0})}}addDescription(t,e){const s=this.currentDocument.states.get(t),i=e.startsWith(":")?e.replace(":","").trim():e;s?.descriptions?.push(a.Y2.sanitizeText(i,(0,a.D7)()))}cleanupLabel(t){return t.startsWith(":")?t.slice(2).trim():t.trim()}getDividerId(){return this.dividerCnt++,`divider-id-${this.dividerCnt}`}addStyleClass(t,e=""){this.classes.has(t)||this.classes.set(t,{id:t,styles:[],textStyles:[]});const s=this.classes.get(t);e&&s&&e.split(et).forEach(t=>{const e=t.replace(/([^;]*);/,"$1").trim();if(RegExp(Z).exec(t)){const t=e.replace(Q,tt).replace(Z,Q);s.textStyles.push(t)}s.styles.push(e)})}getClasses(){return this.classes}setCssClass(t,e){t.split(",").forEach(t=>{let s=this.getState(t);if(!s){const e=t.trim();this.addState(e),s=this.getState(e)}s?.classes?.push(e)})}setStyle(t,e){this.getState(t)?.styles?.push(e)}setTextStyle(t,e){this.getState(t)?.textStyles?.push(e)}getDirectionStatement(){return this.rootDoc.find(t=>"dir"===t.stmt)}getDirection(){return this.getDirectionStatement()?.value??"TB"}setDirection(t){const e=this.getDirectionStatement();e?e.value=t:this.rootDoc.unshift({stmt:"dir",value:t})}trimColon(t){return t.startsWith(":")?t.slice(1).trim():t.trim()}getData(){const t=(0,a.D7)();return{nodes:this.nodes,edges:this.edges,other:{},config:t,direction:K(this.getRootDocV2())}}getConfig(){return(0,a.D7)().state}},ot=(0,c.K2)(t=>`\ndefs #statediagram-barbEnd {\n fill: ${t.transitionColor};\n stroke: ${t.transitionColor};\n }\ng.stateGroup text {\n fill: ${t.nodeBorder};\n stroke: none;\n font-size: 10px;\n}\ng.stateGroup text {\n fill: ${t.textColor};\n stroke: none;\n font-size: 10px;\n\n}\ng.stateGroup .state-title {\n font-weight: bolder;\n fill: ${t.stateLabelColor};\n}\n\ng.stateGroup rect {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n}\n\ng.stateGroup line {\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.transition {\n stroke: ${t.transitionColor};\n stroke-width: 1;\n fill: none;\n}\n\n.stateGroup .composit {\n fill: ${t.background};\n border-bottom: 1px\n}\n\n.stateGroup .alt-composit {\n fill: #e0e0e0;\n border-bottom: 1px\n}\n\n.state-note {\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n\n text {\n fill: ${t.noteTextColor};\n stroke: none;\n font-size: 10px;\n }\n}\n\n.stateLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${t.mainBkg};\n opacity: 0.5;\n}\n\n.edgeLabel .label rect {\n fill: ${t.labelBackgroundColor};\n opacity: 0.5;\n}\n.edgeLabel {\n background-color: ${t.edgeLabelBackground};\n p {\n background-color: ${t.edgeLabelBackground};\n }\n rect {\n opacity: 0.5;\n background-color: ${t.edgeLabelBackground};\n fill: ${t.edgeLabelBackground};\n }\n text-align: center;\n}\n.edgeLabel .label text {\n fill: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n.label div .edgeLabel {\n color: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n\n.stateLabel text {\n fill: ${t.stateLabelColor};\n font-size: 10px;\n font-weight: bold;\n}\n\n.node circle.state-start {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node .fork-join {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node circle.state-end {\n fill: ${t.innerEndBackground};\n stroke: ${t.background};\n stroke-width: 1.5\n}\n.end-state-inner {\n fill: ${t.compositeBackground||t.background};\n // stroke: ${t.background};\n stroke-width: 1.5\n}\n\n.node rect {\n fill: ${t.stateBkg||t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n.node polygon {\n fill: ${t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};;\n stroke-width: 1px;\n}\n#statediagram-barbEnd {\n fill: ${t.lineColor};\n}\n\n.statediagram-cluster rect {\n fill: ${t.compositeTitleBackground};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n\n.cluster-label, .nodeLabel {\n color: ${t.stateLabelColor};\n // line-height: 1;\n}\n\n.statediagram-cluster rect.outer {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state .divider {\n stroke: ${t.stateBorder||t.nodeBorder};\n}\n\n.statediagram-state .title-state {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-cluster.statediagram-cluster .inner {\n fill: ${t.compositeBackground||t.background};\n}\n.statediagram-cluster.statediagram-cluster-alt .inner {\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.statediagram-cluster .inner {\n rx:0;\n ry:0;\n}\n\n.statediagram-state rect.basic {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state rect.divider {\n stroke-dasharray: 10,10;\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.note-edge {\n stroke-dasharray: 5;\n}\n\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n\n.statediagram-note text {\n fill: ${t.noteTextColor};\n}\n\n.statediagram-note .nodeLabel {\n color: ${t.noteTextColor};\n}\n.statediagram .edgeLabel {\n color: red; // ${t.noteTextColor};\n}\n\n#dependencyStart, #dependencyEnd {\n fill: ${t.lineColor};\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.statediagramTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n}\n`,"getStyles")},89625:(t,e,s)=>{s.d(e,{A:()=>r});var i=s(40797),n=s(70451),r=(0,i.K2)((t,e)=>{let s;"sandbox"===e&&(s=(0,n.Ltv)("#i"+t));return("sandbox"===e?(0,n.Ltv)(s.nodes()[0].contentDocument.body):(0,n.Ltv)("body")).select(`[id="${t}"]`)},"getDiagramElement")}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/2279.aea29fbb.js b/pr-preview/pr-4027/assets/js/2279.aea29fbb.js deleted file mode 100644 index 52735a3fc..000000000 --- a/pr-preview/pr-4027/assets/js/2279.aea29fbb.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see 2279.aea29fbb.js.LICENSE.txt */ -(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2279],{241:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});const i=r(41917).A.Symbol},1801:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});var i=r(90565);const n=function(t,e){var r=e?(0,i.A)(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.length)}},3219:(t,e,r)=>{"use strict";r.d(e,{A:()=>s});var i=r(72453),n=r(74886);const a=t=>{const{r:e,g:r,b:a}=n.A.parse(t),o=.2126*i.A.channel.toLinear(e)+.7152*i.A.channel.toLinear(r)+.0722*i.A.channel.toLinear(a);return i.A.lang.round(o)},o=t=>a(t)>=.5,s=t=>!o(t)},3767:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var i=r(24326),n=r(6832);const a=function(t){return(0,i.A)(function(e,r){var i=-1,a=r.length,o=a>1?r[a-1]:void 0,s=a>2?r[2]:void 0;for(o=t.length>3&&"function"==typeof o?(a--,o):void 0,s&&(0,n.A)(r[0],r[1],s)&&(o=a<3?void 0:o,a=1),e=Object(e);++i<a;){var l=r[i];l&&t(e,l,i,o)}return e})}},4574:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});const i=function(t){return function(e,r,i){for(var n=-1,a=Object(e),o=i(e),s=o.length;s--;){var l=o[t?s:++n];if(!1===r(a[l],l,a))break}return e}}()},5164:(t,e,r)=>{"use strict";r.d(e,{IU:()=>x,Jo:()=>L,T_:()=>C,g0:()=>R,jP:()=>k});var i=r(28698),n=r(5894),a=r(63245),o=r(32387),s=r(30092),l=r(13226),c=r(67633),h=r(40797),u=r(70451),d=r(29893),p=(0,h.K2)((t,e,r,i,n,a)=>{e.arrowTypeStart&&g(t,"start",e.arrowTypeStart,r,i,n,a),e.arrowTypeEnd&&g(t,"end",e.arrowTypeEnd,r,i,n,a)},"addEdgeMarkers"),f={arrow_cross:{type:"cross",fill:!1},arrow_point:{type:"point",fill:!0},arrow_barb:{type:"barb",fill:!0},arrow_circle:{type:"circle",fill:!1},aggregation:{type:"aggregation",fill:!1},extension:{type:"extension",fill:!1},composition:{type:"composition",fill:!0},dependency:{type:"dependency",fill:!0},lollipop:{type:"lollipop",fill:!1},only_one:{type:"onlyOne",fill:!1},zero_or_one:{type:"zeroOrOne",fill:!1},one_or_more:{type:"oneOrMore",fill:!1},zero_or_more:{type:"zeroOrMore",fill:!1},requirement_arrow:{type:"requirement_arrow",fill:!1},requirement_contains:{type:"requirement_contains",fill:!1}},g=(0,h.K2)((t,e,r,i,n,a,o)=>{const s=f[r];if(!s)return void h.Rm.warn(`Unknown arrow type: ${r}`);const l=`${n}_${a}-${s.type}${"start"===e?"Start":"End"}`;if(o&&""!==o.trim()){const r=`${l}_${o.replace(/[^\dA-Za-z]/g,"_")}`;if(!document.getElementById(r)){const t=document.getElementById(l);if(t){const e=t.cloneNode(!0);e.id=r;e.querySelectorAll("path, circle, line").forEach(t=>{t.setAttribute("stroke",o),s.fill&&t.setAttribute("fill",o)}),t.parentNode?.appendChild(e)}}t.attr(`marker-${e}`,`url(${i}#${r})`)}else t.attr(`marker-${e}`,`url(${i}#${l})`)},"addEdgeMarker"),y=new Map,m=new Map,x=(0,h.K2)(()=>{y.clear(),m.clear()},"clear"),b=(0,h.K2)(t=>t?t.reduce((t,e)=>t+";"+e,""):"","getLabelStyles"),k=(0,h.K2)(async(t,e)=>{let r=(0,c._3)((0,c.D7)().flowchart.htmlLabels);const{labelStyles:i}=(0,o.GX)(e);e.labelStyle=i;const a=await(0,s.GZ)(t,e.label,{style:e.labelStyle,useHtmlLabels:r,addSvgBackground:!0,isNode:!1});h.Rm.info("abc82",e,e.labelType);const l=t.insert("g").attr("class","edgeLabel"),d=l.insert("g").attr("class","label").attr("data-id",e.id);d.node().appendChild(a);let p,f=a.getBBox();if(r){const t=a.children[0],e=(0,u.Ltv)(a);f=t.getBoundingClientRect(),e.attr("width",f.width),e.attr("height",f.height)}if(d.attr("transform","translate("+-f.width/2+", "+-f.height/2+")"),y.set(e.id,l),e.width=f.width,e.height=f.height,e.startLabelLeft){const r=await(0,n.DA)(e.startLabelLeft,b(e.labelStyle)),i=t.insert("g").attr("class","edgeTerminals"),a=i.insert("g").attr("class","inner");p=a.node().appendChild(r);const o=r.getBBox();a.attr("transform","translate("+-o.width/2+", "+-o.height/2+")"),m.get(e.id)||m.set(e.id,{}),m.get(e.id).startLeft=i,w(p,e.startLabelLeft)}if(e.startLabelRight){const r=await(0,n.DA)(e.startLabelRight,b(e.labelStyle)),i=t.insert("g").attr("class","edgeTerminals"),a=i.insert("g").attr("class","inner");p=i.node().appendChild(r),a.node().appendChild(r);const o=r.getBBox();a.attr("transform","translate("+-o.width/2+", "+-o.height/2+")"),m.get(e.id)||m.set(e.id,{}),m.get(e.id).startRight=i,w(p,e.startLabelRight)}if(e.endLabelLeft){const r=await(0,n.DA)(e.endLabelLeft,b(e.labelStyle)),i=t.insert("g").attr("class","edgeTerminals"),a=i.insert("g").attr("class","inner");p=a.node().appendChild(r);const o=r.getBBox();a.attr("transform","translate("+-o.width/2+", "+-o.height/2+")"),i.node().appendChild(r),m.get(e.id)||m.set(e.id,{}),m.get(e.id).endLeft=i,w(p,e.endLabelLeft)}if(e.endLabelRight){const r=await(0,n.DA)(e.endLabelRight,b(e.labelStyle)),i=t.insert("g").attr("class","edgeTerminals"),a=i.insert("g").attr("class","inner");p=a.node().appendChild(r);const o=r.getBBox();a.attr("transform","translate("+-o.width/2+", "+-o.height/2+")"),i.node().appendChild(r),m.get(e.id)||m.set(e.id,{}),m.get(e.id).endRight=i,w(p,e.endLabelRight)}return a},"insertEdgeLabel");function w(t,e){(0,c.D7)().flowchart.htmlLabels&&t&&(t.style.width=9*e.length+"px",t.style.height="12px")}(0,h.K2)(w,"setTerminalWidth");var C=(0,h.K2)((t,e)=>{h.Rm.debug("Moving label abc88 ",t.id,t.label,y.get(t.id),e);let r=e.updatedPath?e.updatedPath:e.originalPath;const i=(0,c.D7)(),{subGraphTitleTotalMargin:n}=(0,a.O)(i);if(t.label){const i=y.get(t.id);let a=t.x,o=t.y;if(r){const i=l._K.calcLabelPosition(r);h.Rm.debug("Moving label "+t.label+" from (",a,",",o,") to (",i.x,",",i.y,") abc88"),e.updatedPath&&(a=i.x,o=i.y)}i.attr("transform",`translate(${a}, ${o+n/2})`)}if(t.startLabelLeft){const e=m.get(t.id).startLeft;let i=t.x,n=t.y;if(r){const e=l._K.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",r);i=e.x,n=e.y}e.attr("transform",`translate(${i}, ${n})`)}if(t.startLabelRight){const e=m.get(t.id).startRight;let i=t.x,n=t.y;if(r){const e=l._K.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",r);i=e.x,n=e.y}e.attr("transform",`translate(${i}, ${n})`)}if(t.endLabelLeft){const e=m.get(t.id).endLeft;let i=t.x,n=t.y;if(r){const e=l._K.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",r);i=e.x,n=e.y}e.attr("transform",`translate(${i}, ${n})`)}if(t.endLabelRight){const e=m.get(t.id).endRight;let i=t.x,n=t.y;if(r){const e=l._K.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",r);i=e.x,n=e.y}e.attr("transform",`translate(${i}, ${n})`)}},"positionEdgeLabel"),_=(0,h.K2)((t,e)=>{const r=t.x,i=t.y,n=Math.abs(e.x-r),a=Math.abs(e.y-i),o=t.width/2,s=t.height/2;return n>=o||a>=s},"outsideNode"),v=(0,h.K2)((t,e,r)=>{h.Rm.debug(`intersection calc abc89:\n outsidePoint: ${JSON.stringify(e)}\n insidePoint : ${JSON.stringify(r)}\n node : x:${t.x} y:${t.y} w:${t.width} h:${t.height}`);const i=t.x,n=t.y,a=Math.abs(i-r.x),o=t.width/2;let s=r.x<e.x?o-a:o+a;const l=t.height/2,c=Math.abs(e.y-r.y),u=Math.abs(e.x-r.x);if(Math.abs(n-e.y)*o>Math.abs(i-e.x)*l){let t=r.y<e.y?e.y-l-n:n-l-e.y;s=u*t/c;const i={x:r.x<e.x?r.x+s:r.x-u+s,y:r.y<e.y?r.y+c-t:r.y-c+t};return 0===s&&(i.x=e.x,i.y=e.y),0===u&&(i.x=e.x),0===c&&(i.y=e.y),h.Rm.debug(`abc89 top/bottom calc, Q ${c}, q ${t}, R ${u}, r ${s}`,i),i}{s=r.x<e.x?e.x-o-i:i-o-e.x;let t=c*s/u,n=r.x<e.x?r.x+u-s:r.x-u+s,a=r.y<e.y?r.y+t:r.y-t;return h.Rm.debug(`sides calc abc89, Q ${c}, q ${t}, R ${u}, r ${s}`,{_x:n,_y:a}),0===s&&(n=e.x,a=e.y),0===u&&(n=e.x),0===c&&(a=e.y),{x:n,y:a}}},"intersection"),S=(0,h.K2)((t,e)=>{h.Rm.warn("abc88 cutPathAtIntersect",t,e);let r=[],i=t[0],n=!1;return t.forEach(t=>{if(h.Rm.info("abc88 checking point",t,e),_(e,t)||n)h.Rm.warn("abc88 outside",t,i),i=t,n||r.push(t);else{const a=v(e,i,t);h.Rm.debug("abc88 inside",t,i,a),h.Rm.debug("abc88 intersection",a,e);let o=!1;r.forEach(t=>{o=o||t.x===a.x&&t.y===a.y}),r.some(t=>t.x===a.x&&t.y===a.y)?h.Rm.warn("abc88 no intersect",a,r):r.push(a),n=!0}}),h.Rm.debug("returning points",r),r},"cutPathAtIntersect");function T(t){const e=[],r=[];for(let i=1;i<t.length-1;i++){const n=t[i-1],a=t[i],o=t[i+1];(n.x===a.x&&a.y===o.y&&Math.abs(a.x-o.x)>5&&Math.abs(a.y-n.y)>5||n.y===a.y&&a.x===o.x&&Math.abs(a.x-n.x)>5&&Math.abs(a.y-o.y)>5)&&(e.push(a),r.push(i))}return{cornerPoints:e,cornerPointPositions:r}}(0,h.K2)(T,"extractCornerPoints");var A=(0,h.K2)(function(t,e,r){const i=e.x-t.x,n=e.y-t.y,a=r/Math.sqrt(i*i+n*n);return{x:e.x-a*i,y:e.y-a*n}},"findAdjacentPoint"),M=(0,h.K2)(function(t){const{cornerPointPositions:e}=T(t),r=[];for(let i=0;i<t.length;i++)if(e.includes(i)){const e=t[i-1],n=t[i+1],a=t[i],o=A(e,a,5),s=A(n,a,5),l=s.x-o.x,c=s.y-o.y;r.push(o);const u=2*Math.sqrt(2);let d={x:a.x,y:a.y};if(Math.abs(n.x-e.x)>10&&Math.abs(n.y-e.y)>=10){h.Rm.debug("Corner point fixing",Math.abs(n.x-e.x),Math.abs(n.y-e.y));const t=5;d=a.x===o.x?{x:l<0?o.x-t+u:o.x+t-u,y:c<0?o.y-u:o.y+u}:{x:l<0?o.x-u:o.x+u,y:c<0?o.y-t+u:o.y+t-u}}else h.Rm.debug("Corner point skipping fixing",Math.abs(n.x-e.x),Math.abs(n.y-e.y));r.push(d,s)}else r.push(t[i]);return r},"fixCorners"),B=(0,h.K2)((t,e,r)=>{const i=t-e-r,n=Math.floor(i/4);return`0 ${e} ${Array(n).fill("2 2").join(" ")} ${r}`},"generateDashArray"),L=(0,h.K2)(function(t,e,r,n,a,s,f,g=!1){const{handDrawnSeed:y}=(0,c.D7)();let m=e.points,x=!1;const b=a;var k=s;const w=[];for(const i in e.cssCompiledStyles)(0,o.KX)(i)||w.push(e.cssCompiledStyles[i]);h.Rm.debug("UIO intersect check",e.points,k.x,b.x),k.intersect&&b.intersect&&!g&&(m=m.slice(1,e.points.length-1),m.unshift(b.intersect(m[0])),h.Rm.debug("Last point UIO",e.start,"--\x3e",e.end,m[m.length-1],k,k.intersect(m[m.length-1])),m.push(k.intersect(m[m.length-1])));const C=btoa(JSON.stringify(m));e.toCluster&&(h.Rm.info("to cluster abc88",r.get(e.toCluster)),m=S(e.points,r.get(e.toCluster).node),x=!0),e.fromCluster&&(h.Rm.debug("from cluster abc88",r.get(e.fromCluster),JSON.stringify(m,null,2)),m=S(m.reverse(),r.get(e.fromCluster).node).reverse(),x=!0);let _=m.filter(t=>!Number.isNaN(t.y));_=M(_);let v=u.qrM;switch(v=u.lUB,e.curve){case"linear":v=u.lUB;break;case"basis":default:v=u.qrM;break;case"cardinal":v=u.y8u;break;case"bumpX":v=u.Wi0;break;case"bumpY":v=u.PGM;break;case"catmullRom":v=u.oDi;break;case"monotoneX":v=u.nVG;break;case"monotoneY":v=u.uxU;break;case"natural":v=u.Xf2;break;case"step":v=u.GZz;break;case"stepAfter":v=u.UPb;break;case"stepBefore":v=u.dyv}const{x:T,y:A}=(0,i.RI)(e),L=(0,u.n8j)().x(T).y(A).curve(v);let $,D;switch(e.thickness){case"normal":default:$="edge-thickness-normal";break;case"thick":$="edge-thickness-thick";break;case"invisible":$="edge-thickness-invisible"}switch(e.pattern){case"solid":default:$+=" edge-pattern-solid";break;case"dotted":$+=" edge-pattern-dotted";break;case"dashed":$+=" edge-pattern-dashed"}let O="rounded"===e.curve?F(E(_,e),5):L(_);const R=Array.isArray(e.style)?e.style:[e.style];let K=R.find(t=>t?.startsWith("stroke:")),I=!1;if("handDrawn"===e.look){const r=d.A.svg(t);Object.assign([],_);const i=r.path(O,{roughness:.3,seed:y});$+=" transition",D=(0,u.Ltv)(i).select("path").attr("id",e.id).attr("class"," "+$+(e.classes?" "+e.classes:"")).attr("style",R?R.reduce((t,e)=>t+";"+e,""):"");let n=D.attr("d");D.attr("d",n),t.node().appendChild(D.node())}else{const r=w.join(";"),n=R?R.reduce((t,e)=>t+e+";",""):"";let a="";e.animate&&(a=" edge-animation-fast"),e.animation&&(a=" edge-animation-"+e.animation);const o=(r?r+";"+n+";":n)+";"+(R?R.reduce((t,e)=>t+";"+e,""):"");D=t.append("path").attr("d",O).attr("id",e.id).attr("class"," "+$+(e.classes?" "+e.classes:"")+(a??"")).attr("style",o),K=o.match(/stroke:([^;]+)/)?.[1],I=!0===e.animate||!!e.animation||r.includes("animation");const s=D.node(),l="function"==typeof s.getTotalLength?s.getTotalLength():0,c=i.Nq[e.arrowTypeStart]||0,h=i.Nq[e.arrowTypeEnd]||0;if("neo"===e.look&&!I){const t=`stroke-dasharray: ${"dotted"===e.pattern||"dashed"===e.pattern?B(l,c,h):`0 ${c} ${l-c-h} ${h}`}; stroke-dashoffset: 0;`;D.attr("style",t+D.attr("style"))}}D.attr("data-edge",!0),D.attr("data-et","edge"),D.attr("data-id",e.id),D.attr("data-points",C),e.showPoints&&_.forEach(e=>{t.append("circle").style("stroke","red").style("fill","red").attr("r",1).attr("cx",e.x).attr("cy",e.y)});let N="";((0,c.D7)().flowchart.arrowMarkerAbsolute||(0,c.D7)().state.arrowMarkerAbsolute)&&(N=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,N=N.replace(/\(/g,"\\(").replace(/\)/g,"\\)")),h.Rm.info("arrowTypeStart",e.arrowTypeStart),h.Rm.info("arrowTypeEnd",e.arrowTypeEnd),p(D,e,N,f,n,K);const z=m[Math.floor(m.length/2)];l._K.isLabelCoordinateInPath(z,D.attr("d"))||(x=!0);let P={};return x&&(P.updatedPath=m),P.originalPath=e.points,P},"insertEdge");function F(t,e){if(t.length<2)return"";let r="";const i=t.length,n=1e-5;for(let a=0;a<i;a++){const o=t[a],s=t[a-1],l=t[a+1];if(0===a)r+=`M${o.x},${o.y}`;else if(a===i-1)r+=`L${o.x},${o.y}`;else{const t=o.x-s.x,i=o.y-s.y,a=l.x-o.x,c=l.y-o.y,h=Math.hypot(t,i),u=Math.hypot(a,c);if(h<n||u<n){r+=`L${o.x},${o.y}`;continue}const d=t/h,p=i/h,f=a/u,g=c/u,y=d*f+p*g,m=Math.max(-1,Math.min(1,y)),x=Math.acos(m);if(x<n||Math.abs(Math.PI-x)<n){r+=`L${o.x},${o.y}`;continue}const b=Math.min(e/Math.sin(x/2),h/2,u/2),k=o.x-d*b,w=o.y-p*b,C=o.x+f*b,_=o.y+g*b;r+=`L${k},${w}`,r+=`Q${o.x},${o.y} ${C},${_}`}}return r}function $(t,e){if(!t||!e)return{angle:0,deltaX:0,deltaY:0};const r=e.x-t.x,i=e.y-t.y;return{angle:Math.atan2(i,r),deltaX:r,deltaY:i}}function E(t,e){const r=t.map(t=>({...t}));if(t.length>=2&&i.hq[e.arrowTypeStart]){const n=i.hq[e.arrowTypeStart],a=t[0],o=t[1],{angle:s}=$(a,o),l=n*Math.cos(s),c=n*Math.sin(s);r[0].x=a.x+l,r[0].y=a.y+c}const n=t.length;if(n>=2&&i.hq[e.arrowTypeEnd]){const a=i.hq[e.arrowTypeEnd],o=t[n-1],s=t[n-2],{angle:l}=$(s,o),c=a*Math.cos(l),h=a*Math.sin(l);r[n-1].x=o.x-c,r[n-1].y=o.y-h}return r}(0,h.K2)(F,"generateRoundedPath"),(0,h.K2)($,"calculateDeltaAndAngle"),(0,h.K2)(E,"applyMarkerOffsetsToPoints");var D=(0,h.K2)((t,e,r,i)=>{e.forEach(e=>{O[e](t,r,i)})},"insertMarkers"),O={extension:(0,h.K2)((t,e,r)=>{h.Rm.trace("Making markers for ",r),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionStart").attr("class","marker extension "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionEnd").attr("class","marker extension "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")},"extension"),composition:(0,h.K2)((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionStart").attr("class","marker composition "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionEnd").attr("class","marker composition "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},"composition"),aggregation:(0,h.K2)((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationStart").attr("class","marker aggregation "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationEnd").attr("class","marker aggregation "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},"aggregation"),dependency:(0,h.K2)((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyStart").attr("class","marker dependency "+e).attr("refX",6).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyEnd").attr("class","marker dependency "+e).attr("refX",13).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},"dependency"),lollipop:(0,h.K2)((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopStart").attr("class","marker lollipop "+e).attr("refX",13).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6),t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopEnd").attr("class","marker lollipop "+e).attr("refX",1).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6)},"lollipop"),point:(0,h.K2)((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-pointEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",8).attr("markerHeight",8).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-pointStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",4.5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",8).attr("markerHeight",8).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},"point"),circle:(0,h.K2)((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-circleEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-circleStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},"circle"),cross:(0,h.K2)((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-crossEnd").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-crossStart").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")},"cross"),barb:(0,h.K2)((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","userSpaceOnUse").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},"barb"),only_one:(0,h.K2)((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-onlyOneStart").attr("class","marker onlyOne "+e).attr("refX",0).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("d","M9,0 L9,18 M15,0 L15,18"),t.append("defs").append("marker").attr("id",r+"_"+e+"-onlyOneEnd").attr("class","marker onlyOne "+e).attr("refX",18).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("d","M3,0 L3,18 M9,0 L9,18")},"only_one"),zero_or_one:(0,h.K2)((t,e,r)=>{const i=t.append("defs").append("marker").attr("id",r+"_"+e+"-zeroOrOneStart").attr("class","marker zeroOrOne "+e).attr("refX",0).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto");i.append("circle").attr("fill","white").attr("cx",21).attr("cy",9).attr("r",6),i.append("path").attr("d","M9,0 L9,18");const n=t.append("defs").append("marker").attr("id",r+"_"+e+"-zeroOrOneEnd").attr("class","marker zeroOrOne "+e).attr("refX",30).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto");n.append("circle").attr("fill","white").attr("cx",9).attr("cy",9).attr("r",6),n.append("path").attr("d","M21,0 L21,18")},"zero_or_one"),one_or_more:(0,h.K2)((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-oneOrMoreStart").attr("class","marker oneOrMore "+e).attr("refX",18).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("d","M0,18 Q 18,0 36,18 Q 18,36 0,18 M42,9 L42,27"),t.append("defs").append("marker").attr("id",r+"_"+e+"-oneOrMoreEnd").attr("class","marker oneOrMore "+e).attr("refX",27).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("d","M3,9 L3,27 M9,18 Q27,0 45,18 Q27,36 9,18")},"one_or_more"),zero_or_more:(0,h.K2)((t,e,r)=>{const i=t.append("defs").append("marker").attr("id",r+"_"+e+"-zeroOrMoreStart").attr("class","marker zeroOrMore "+e).attr("refX",18).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto");i.append("circle").attr("fill","white").attr("cx",48).attr("cy",18).attr("r",6),i.append("path").attr("d","M0,18 Q18,0 36,18 Q18,36 0,18");const n=t.append("defs").append("marker").attr("id",r+"_"+e+"-zeroOrMoreEnd").attr("class","marker zeroOrMore "+e).attr("refX",39).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto");n.append("circle").attr("fill","white").attr("cx",9).attr("cy",18).attr("r",6),n.append("path").attr("d","M21,18 Q39,0 57,18 Q39,36 21,18")},"zero_or_more"),requirement_arrow:(0,h.K2)((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-requirement_arrowEnd").attr("refX",20).attr("refY",10).attr("markerWidth",20).attr("markerHeight",20).attr("orient","auto").append("path").attr("d","M0,0\n L20,10\n M20,10\n L0,20")},"requirement_arrow"),requirement_contains:(0,h.K2)((t,e,r)=>{const i=t.append("defs").append("marker").attr("id",r+"_"+e+"-requirement_containsStart").attr("refX",0).attr("refY",10).attr("markerWidth",20).attr("markerHeight",20).attr("orient","auto").append("g");i.append("circle").attr("cx",10).attr("cy",10).attr("r",9).attr("fill","none"),i.append("line").attr("x1",1).attr("x2",19).attr("y1",10).attr("y2",10),i.append("line").attr("y1",1).attr("y2",19).attr("x1",10).attr("x2",10)},"requirement_contains")},R=D},5254:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});const i=function(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=9007199254740991}},5894:(t,e,r)=>{"use strict";r.d(e,{DA:()=>w,IU:()=>L,U:()=>B,U7:()=>Te,U_:()=>Me,Zk:()=>u,aP:()=>_e,gh:()=>Ae,lC:()=>p,on:()=>Se});var i=r(63245),n=r(32387),a=r(30092),o=r(13226),s=r(67633),l=r(40797),c=r(70451),h=r(29893),u=(0,l.K2)(async(t,e,r)=>{let i;const n=e.useHtmlLabels||(0,s._3)((0,s.D7)()?.htmlLabels);i=r||"node default";const h=t.insert("g").attr("class",i).attr("id",e.domId||e.id),u=h.insert("g").attr("class","label").attr("style",(0,o.KL)(e.labelStyle));let d;d=void 0===e.label?"":"string"==typeof e.label?e.label:e.label[0];const p=await(0,a.GZ)(u,(0,s.jZ)((0,o.Sm)(d),(0,s.D7)()),{useHtmlLabels:n,width:e.width||(0,s.D7)().flowchart?.wrappingWidth,cssClasses:"markdown-node-label",style:e.labelStyle,addSvgBackground:!!e.icon||!!e.img});let f=p.getBBox();const g=(e?.padding??0)/2;if(n){const t=p.children[0],e=(0,c.Ltv)(p),r=t.getElementsByTagName("img");if(r){const t=""===d.replace(/<img[^>]*>/g,"").trim();await Promise.all([...r].map(e=>new Promise(r=>{function i(){if(e.style.display="flex",e.style.flexDirection="column",t){const t=(0,s.D7)().fontSize?(0,s.D7)().fontSize:window.getComputedStyle(document.body).fontSize,r=5,[i=s.UI.fontSize]=(0,o.I5)(t),n=i*r+"px";e.style.minWidth=n,e.style.maxWidth=n}else e.style.width="100%";r(e)}(0,l.K2)(i,"setupImage"),setTimeout(()=>{e.complete&&i()}),e.addEventListener("error",i),e.addEventListener("load",i)})))}f=t.getBoundingClientRect(),e.attr("width",f.width),e.attr("height",f.height)}return n?u.attr("transform","translate("+-f.width/2+", "+-f.height/2+")"):u.attr("transform","translate(0, "+-f.height/2+")"),e.centerLabel&&u.attr("transform","translate("+-f.width/2+", "+-f.height/2+")"),u.insert("rect",":first-child"),{shapeSvg:h,bbox:f,halfPadding:g,label:u}},"labelHelper"),d=(0,l.K2)(async(t,e,r)=>{const i=r.useHtmlLabels||(0,s._3)((0,s.D7)()?.flowchart?.htmlLabels),n=t.insert("g").attr("class","label").attr("style",r.labelStyle||""),l=await(0,a.GZ)(n,(0,s.jZ)((0,o.Sm)(e),(0,s.D7)()),{useHtmlLabels:i,width:r.width||(0,s.D7)()?.flowchart?.wrappingWidth,style:r.labelStyle,addSvgBackground:!!r.icon||!!r.img});let h=l.getBBox();const u=r.padding/2;if((0,s._3)((0,s.D7)()?.flowchart?.htmlLabels)){const t=l.children[0],e=(0,c.Ltv)(l);h=t.getBoundingClientRect(),e.attr("width",h.width),e.attr("height",h.height)}return i?n.attr("transform","translate("+-h.width/2+", "+-h.height/2+")"):n.attr("transform","translate(0, "+-h.height/2+")"),r.centerLabel&&n.attr("transform","translate("+-h.width/2+", "+-h.height/2+")"),n.insert("rect",":first-child"),{shapeSvg:t,bbox:h,halfPadding:u,label:n}},"insertLabel"),p=(0,l.K2)((t,e)=>{const r=e.node().getBBox();t.width=r.width,t.height=r.height},"updateNodeBounds"),f=(0,l.K2)((t,e)=>("handDrawn"===t.look?"rough-node":"node")+" "+t.cssClasses+" "+(e||""),"getNodeClasses");function g(t){const e=t.map((t,e)=>`${0===e?"M":"L"}${t.x},${t.y}`);return e.push("Z"),e.join(" ")}function y(t,e,r,i,n,a){const o=[],s=r-t,l=i-e,c=s/a,h=2*Math.PI/c,u=e+l/2;for(let d=0;d<=50;d++){const e=t+d/50*s,r=u+n*Math.sin(h*(e-t));o.push({x:e,y:r})}return o}function m(t,e,r,i,n,a){const o=[],s=n*Math.PI/180,l=(a*Math.PI/180-s)/(i-1);for(let c=0;c<i;c++){const i=s+c*l,n=t+r*Math.cos(i),a=e+r*Math.sin(i);o.push({x:-n,y:-a})}return o}(0,l.K2)(g,"createPathFromPoints"),(0,l.K2)(y,"generateFullSineWavePoints"),(0,l.K2)(m,"generateCirclePoints");var x=(0,l.K2)((t,e)=>{var r,i,n=t.x,a=t.y,o=e.x-n,s=e.y-a,l=t.width/2,c=t.height/2;return Math.abs(s)*l>Math.abs(o)*c?(s<0&&(c=-c),r=0===s?0:c*o/s,i=c):(o<0&&(l=-l),r=l,i=0===o?0:l*s/o),{x:n+r,y:a+i}},"intersectRect");function b(t,e){e&&t.attr("style",e)}async function k(t){const e=(0,c.Ltv)(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),r=e.append("xhtml:div"),i=(0,s.D7)();let n=t.label;t.label&&(0,s.Wi)(t.label)&&(n=await(0,s.dj)(t.label.replace(s.Y2.lineBreakRegex,"\n"),i));const a='<span class="'+(t.isNode?"nodeLabel":"edgeLabel")+'" '+(t.labelStyle?'style="'+t.labelStyle+'"':"")+">"+n+"</span>";return r.html((0,s.jZ)(a,i)),b(r,t.labelStyle),r.style("display","inline-block"),r.style("padding-right","1px"),r.style("white-space","nowrap"),r.attr("xmlns","http://www.w3.org/1999/xhtml"),e.node()}(0,l.K2)(b,"applyStyle"),(0,l.K2)(k,"addHtmlLabel");var w=(0,l.K2)(async(t,e,r,i)=>{let n=t||"";if("object"==typeof n&&(n=n[0]),(0,s._3)((0,s.D7)().flowchart.htmlLabels)){n=n.replace(/\\n|\n/g,"<br />"),l.Rm.info("vertexText"+n);const t={isNode:i,label:(0,o.Sm)(n).replace(/fa[blrs]?:fa-[\w-]+/g,t=>`<i class='${t.replace(":"," ")}'></i>`),labelStyle:e?e.replace("fill:","color:"):e};return await k(t)}{const t=document.createElementNS("http://www.w3.org/2000/svg","text");t.setAttribute("style",e.replace("color:","fill:"));let i=[];i="string"==typeof n?n.split(/\\n|\n|<br\s*\/?>/gi):Array.isArray(n)?n:[];for(const e of i){const i=document.createElementNS("http://www.w3.org/2000/svg","tspan");i.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),i.setAttribute("dy","1em"),i.setAttribute("x","0"),r?i.setAttribute("class","title-row"):i.setAttribute("class","row"),i.textContent=e.trim(),t.appendChild(i)}return t}},"createLabel"),C=(0,l.K2)((t,e,r,i,n)=>["M",t+n,e,"H",t+r-n,"A",n,n,0,0,1,t+r,e+n,"V",e+i-n,"A",n,n,0,0,1,t+r-n,e+i,"H",t+n,"A",n,n,0,0,1,t,e+i-n,"V",e+n,"A",n,n,0,0,1,t+n,e,"Z"].join(" "),"createRoundedRectPathD"),_=(0,l.K2)(async(t,e)=>{l.Rm.info("Creating subgraph rect for ",e.id,e);const r=(0,s.D7)(),{themeVariables:o,handDrawnSeed:u}=r,{clusterBkg:d,clusterBorder:p}=o,{labelStyles:f,nodeStyles:g,borderStyles:y,backgroundStyles:m}=(0,n.GX)(e),b=t.insert("g").attr("class","cluster "+e.cssClasses).attr("id",e.id).attr("data-look",e.look),k=(0,s._3)(r.flowchart.htmlLabels),w=b.insert("g").attr("class","cluster-label "),_=await(0,a.GZ)(w,e.label,{style:e.labelStyle,useHtmlLabels:k,isNode:!0});let v=_.getBBox();if((0,s._3)(r.flowchart.htmlLabels)){const t=_.children[0],e=(0,c.Ltv)(_);v=t.getBoundingClientRect(),e.attr("width",v.width),e.attr("height",v.height)}const S=e.width<=v.width+e.padding?v.width+e.padding:e.width;e.width<=v.width+e.padding?e.diff=(S-e.width)/2-e.padding:e.diff=-e.padding;const T=e.height,A=e.x-S/2,M=e.y-T/2;let B;if(l.Rm.trace("Data ",e,JSON.stringify(e)),"handDrawn"===e.look){const t=h.A.svg(b),r=(0,n.Fr)(e,{roughness:.7,fill:d,stroke:p,fillWeight:3,seed:u}),i=t.path(C(A,M,S,T,0),r);B=b.insert(()=>(l.Rm.debug("Rough node insert CXC",i),i),":first-child"),B.select("path:nth-child(2)").attr("style",y.join(";")),B.select("path").attr("style",m.join(";").replace("fill","stroke"))}else B=b.insert("rect",":first-child"),B.attr("style",g).attr("rx",e.rx).attr("ry",e.ry).attr("x",A).attr("y",M).attr("width",S).attr("height",T);const{subGraphTitleTopMargin:L}=(0,i.O)(r);if(w.attr("transform",`translate(${e.x-v.width/2}, ${e.y-e.height/2+L})`),f){const t=w.select("span");t&&t.attr("style",f)}const F=B.node().getBBox();return e.offsetX=0,e.width=F.width,e.height=F.height,e.offsetY=v.height-e.padding/2,e.intersect=function(t){return x(e,t)},{cluster:b,labelBBox:v}},"rect"),v=(0,l.K2)((t,e)=>{const r=t.insert("g").attr("class","note-cluster").attr("id",e.id),i=r.insert("rect",":first-child"),n=0*e.padding,a=n/2;i.attr("rx",e.rx).attr("ry",e.ry).attr("x",e.x-e.width/2-a).attr("y",e.y-e.height/2-a).attr("width",e.width+n).attr("height",e.height+n).attr("fill","none");const o=i.node().getBBox();return e.width=o.width,e.height=o.height,e.intersect=function(t){return x(e,t)},{cluster:r,labelBBox:{width:0,height:0}}},"noteGroup"),S=(0,l.K2)(async(t,e)=>{const r=(0,s.D7)(),{themeVariables:i,handDrawnSeed:n}=r,{altBackground:a,compositeBackground:o,compositeTitleBackground:l,nodeBorder:u}=i,d=t.insert("g").attr("class",e.cssClasses).attr("id",e.id).attr("data-id",e.id).attr("data-look",e.look),p=d.insert("g",":first-child"),f=d.insert("g").attr("class","cluster-label");let g=d.append("rect");const y=f.node().appendChild(await w(e.label,e.labelStyle,void 0,!0));let m=y.getBBox();if((0,s._3)(r.flowchart.htmlLabels)){const t=y.children[0],e=(0,c.Ltv)(y);m=t.getBoundingClientRect(),e.attr("width",m.width),e.attr("height",m.height)}const b=0*e.padding,k=b/2,_=(e.width<=m.width+e.padding?m.width+e.padding:e.width)+b;e.width<=m.width+e.padding?e.diff=(_-e.width)/2-e.padding:e.diff=-e.padding;const v=e.height+b,S=e.height+b-m.height-6,T=e.x-_/2,A=e.y-v/2;e.width=_;const M=e.y-e.height/2-k+m.height+2;let B;if("handDrawn"===e.look){const t=e.cssClasses.includes("statediagram-cluster-alt"),r=h.A.svg(d),i=e.rx||e.ry?r.path(C(T,A,_,v,10),{roughness:.7,fill:l,fillStyle:"solid",stroke:u,seed:n}):r.rectangle(T,A,_,v,{seed:n});B=d.insert(()=>i,":first-child");const s=r.rectangle(T,M,_,S,{fill:t?a:o,fillStyle:t?"hachure":"solid",stroke:u,seed:n});B=d.insert(()=>i,":first-child"),g=d.insert(()=>s)}else{B=p.insert("rect",":first-child");const t="outer";B.attr("class",t).attr("x",T).attr("y",A).attr("width",_).attr("height",v).attr("data-look",e.look),g.attr("class","inner").attr("x",T).attr("y",M).attr("width",_).attr("height",S)}f.attr("transform",`translate(${e.x-m.width/2}, ${A+1-((0,s._3)(r.flowchart.htmlLabels)?0:3)})`);const L=B.node().getBBox();return e.height=L.height,e.offsetX=0,e.offsetY=m.height-e.padding/2,e.labelBBox=m,e.intersect=function(t){return x(e,t)},{cluster:d,labelBBox:m}},"roundedWithTitle"),T=(0,l.K2)(async(t,e)=>{l.Rm.info("Creating subgraph rect for ",e.id,e);const r=(0,s.D7)(),{themeVariables:o,handDrawnSeed:u}=r,{clusterBkg:d,clusterBorder:p}=o,{labelStyles:f,nodeStyles:g,borderStyles:y,backgroundStyles:m}=(0,n.GX)(e),b=t.insert("g").attr("class","cluster "+e.cssClasses).attr("id",e.id).attr("data-look",e.look),k=(0,s._3)(r.flowchart.htmlLabels),w=b.insert("g").attr("class","cluster-label "),_=await(0,a.GZ)(w,e.label,{style:e.labelStyle,useHtmlLabels:k,isNode:!0,width:e.width});let v=_.getBBox();if((0,s._3)(r.flowchart.htmlLabels)){const t=_.children[0],e=(0,c.Ltv)(_);v=t.getBoundingClientRect(),e.attr("width",v.width),e.attr("height",v.height)}const S=e.width<=v.width+e.padding?v.width+e.padding:e.width;e.width<=v.width+e.padding?e.diff=(S-e.width)/2-e.padding:e.diff=-e.padding;const T=e.height,A=e.x-S/2,M=e.y-T/2;let B;if(l.Rm.trace("Data ",e,JSON.stringify(e)),"handDrawn"===e.look){const t=h.A.svg(b),r=(0,n.Fr)(e,{roughness:.7,fill:d,stroke:p,fillWeight:4,seed:u}),i=t.path(C(A,M,S,T,e.rx),r);B=b.insert(()=>(l.Rm.debug("Rough node insert CXC",i),i),":first-child"),B.select("path:nth-child(2)").attr("style",y.join(";")),B.select("path").attr("style",m.join(";").replace("fill","stroke"))}else B=b.insert("rect",":first-child"),B.attr("style",g).attr("rx",e.rx).attr("ry",e.ry).attr("x",A).attr("y",M).attr("width",S).attr("height",T);const{subGraphTitleTopMargin:L}=(0,i.O)(r);if(w.attr("transform",`translate(${e.x-v.width/2}, ${e.y-e.height/2+L})`),f){const t=w.select("span");t&&t.attr("style",f)}const F=B.node().getBBox();return e.offsetX=0,e.width=F.width,e.height=F.height,e.offsetY=v.height-e.padding/2,e.intersect=function(t){return x(e,t)},{cluster:b,labelBBox:v}},"kanbanSection"),A={rect:_,squareRect:_,roundedWithTitle:S,noteGroup:v,divider:(0,l.K2)((t,e)=>{const r=(0,s.D7)(),{themeVariables:i,handDrawnSeed:n}=r,{nodeBorder:a}=i,o=t.insert("g").attr("class",e.cssClasses).attr("id",e.id).attr("data-look",e.look),l=o.insert("g",":first-child"),c=0*e.padding,u=e.width+c;e.diff=-e.padding;const d=e.height+c,p=e.x-u/2,f=e.y-d/2;let g;if(e.width=u,"handDrawn"===e.look){const t=h.A.svg(o).rectangle(p,f,u,d,{fill:"lightgrey",roughness:.5,strokeLineDash:[5],stroke:a,seed:n});g=o.insert(()=>t,":first-child")}else{g=l.insert("rect",":first-child");const t="divider";g.attr("class",t).attr("x",p).attr("y",f).attr("width",u).attr("height",d).attr("data-look",e.look)}const y=g.node().getBBox();return e.height=y.height,e.offsetX=0,e.offsetY=0,e.intersect=function(t){return x(e,t)},{cluster:o,labelBBox:{}}},"divider"),kanbanSection:T},M=new Map,B=(0,l.K2)(async(t,e)=>{const r=e.shape||"rect",i=await A[r](t,e);return M.set(e.id,i),i},"insertCluster"),L=(0,l.K2)(()=>{M=new Map},"clear");function F(t,e){return t.intersect(e)}(0,l.K2)(F,"intersectNode");var $=F;function E(t,e,r,i){var n=t.x,a=t.y,o=n-i.x,s=a-i.y,l=Math.sqrt(e*e*s*s+r*r*o*o),c=Math.abs(e*r*o/l);i.x<n&&(c=-c);var h=Math.abs(e*r*s/l);return i.y<a&&(h=-h),{x:n+c,y:a+h}}(0,l.K2)(E,"intersectEllipse");var D=E;function O(t,e,r){return D(t,e,e,r)}(0,l.K2)(O,"intersectCircle");var R=O;function K(t,e,r,i){{const n=e.y-t.y,a=t.x-e.x,o=e.x*t.y-t.x*e.y,s=n*r.x+a*r.y+o,l=n*i.x+a*i.y+o,c=1e-6;if(0!==s&&0!==l&&I(s,l))return;const h=i.y-r.y,u=r.x-i.x,d=i.x*r.y-r.x*i.y,p=h*t.x+u*t.y+d,f=h*e.x+u*e.y+d;if(Math.abs(p)<c&&Math.abs(f)<c&&I(p,f))return;const g=n*u-h*a;if(0===g)return;const y=Math.abs(g/2);let m=a*d-u*o;const x=m<0?(m-y)/g:(m+y)/g;m=h*o-n*d;return{x:x,y:m<0?(m-y)/g:(m+y)/g}}}function I(t,e){return t*e>0}(0,l.K2)(K,"intersectLine"),(0,l.K2)(I,"sameSign");var N=K;function z(t,e,r){let i=t.x,n=t.y,a=[],o=Number.POSITIVE_INFINITY,s=Number.POSITIVE_INFINITY;"function"==typeof e.forEach?e.forEach(function(t){o=Math.min(o,t.x),s=Math.min(s,t.y)}):(o=Math.min(o,e.x),s=Math.min(s,e.y));let l=i-t.width/2-o,c=n-t.height/2-s;for(let h=0;h<e.length;h++){let i=e[h],n=e[h<e.length-1?h+1:0],o=N(t,r,{x:l+i.x,y:c+i.y},{x:l+n.x,y:c+n.y});o&&a.push(o)}return a.length?(a.length>1&&a.sort(function(t,e){let i=t.x-r.x,n=t.y-r.y,a=Math.sqrt(i*i+n*n),o=e.x-r.x,s=e.y-r.y,l=Math.sqrt(o*o+s*s);return a<l?-1:a===l?0:1}),a[0]):t}(0,l.K2)(z,"intersectPolygon");var P={node:$,circle:R,ellipse:D,polygon:z,rect:x};function q(t,e){const{labelStyles:r}=(0,n.GX)(e);e.labelStyle=r;const i=f(e);let a=i;i||(a="anchor");const s=t.insert("g").attr("class",a).attr("id",e.domId||e.id),{cssStyles:c}=e,u=h.A.svg(s),d=(0,n.Fr)(e,{fill:"black",stroke:"none",fillStyle:"solid"});"handDrawn"!==e.look&&(d.roughness=0);const g=u.circle(0,0,2,d),y=s.insert(()=>g,":first-child");return y.attr("class","anchor").attr("style",(0,o.KL)(c)),p(e,y),e.intersect=function(t){return l.Rm.info("Circle intersect",e,1,t),P.circle(e,1,t)},s}function j(t,e,r,i,n,a,o){const s=(t+r)/2,l=(e+i)/2,c=Math.atan2(i-e,r-t),h=(r-t)/2/n,u=(i-e)/2/a,d=Math.sqrt(h**2+u**2);if(d>1)throw new Error("The given radii are too small to create an arc between the points.");const p=Math.sqrt(1-d**2),f=s+p*a*Math.sin(c)*(o?-1:1),g=l-p*n*Math.cos(c)*(o?-1:1),y=Math.atan2((e-g)/a,(t-f)/n);let m=Math.atan2((i-g)/a,(r-f)/n)-y;o&&m<0&&(m+=2*Math.PI),!o&&m>0&&(m-=2*Math.PI);const x=[];for(let b=0;b<20;b++){const t=y+b/19*m,e=f+n*Math.cos(t),r=g+a*Math.sin(t);x.push({x:e,y:r})}return x}async function W(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o}=await u(t,e,f(e)),s=o.width+e.padding+20,l=o.height+e.padding,c=l/2,d=c/(2.5+l/50),{cssStyles:y}=e,m=[{x:s/2,y:-l/2},{x:-s/2,y:-l/2},...j(-s/2,-l/2,-s/2,l/2,d,c,!1),{x:s/2,y:l/2},...j(s/2,l/2,s/2,-l/2,d,c,!0)],x=h.A.svg(a),b=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(b.roughness=0,b.fillStyle="solid");const k=g(m),w=x.path(k,b),C=a.insert(()=>w,":first-child");return C.attr("class","basic label-container"),y&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",y),i&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",i),C.attr("transform",`translate(${d/2}, 0)`),p(e,C),e.intersect=function(t){return P.polygon(e,m,t)},a}function H(t,e,r,i){return t.insert("polygon",":first-child").attr("points",i.map(function(t){return t.x+","+t.y}).join(" ")).attr("class","label-container").attr("transform","translate("+-e/2+","+r/2+")")}async function U(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o}=await u(t,e,f(e)),s=o.height+e.padding,l=o.width+e.padding+12,c=-s,d=[{x:12,y:c},{x:l,y:c},{x:l,y:0},{x:0,y:0},{x:0,y:c+12},{x:12,y:c}];let y;const{cssStyles:m}=e;if("handDrawn"===e.look){const t=h.A.svg(a),r=(0,n.Fr)(e,{}),i=g(d),o=t.path(i,r);y=a.insert(()=>o,":first-child").attr("transform",`translate(${-l/2}, ${s/2})`),m&&y.attr("style",m)}else y=H(a,l,s,d);return i&&y.attr("style",i),p(e,y),e.intersect=function(t){return P.polygon(e,d,t)},a}function Y(t,e){const{nodeStyles:r}=(0,n.GX)(e);e.label="";const i=t.insert("g").attr("class",f(e)).attr("id",e.domId??e.id),{cssStyles:a}=e,o=Math.max(28,e.width??0),s=[{x:0,y:o/2},{x:o/2,y:0},{x:0,y:-o/2},{x:-o/2,y:0}],l=h.A.svg(i),c=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(c.roughness=0,c.fillStyle="solid");const u=g(s),d=l.path(u,c),p=i.insert(()=>d,":first-child");return a&&"handDrawn"!==e.look&&p.selectAll("path").attr("style",a),r&&"handDrawn"!==e.look&&p.selectAll("path").attr("style",r),e.width=28,e.height=28,e.intersect=function(t){return P.polygon(e,s,t)},i}async function G(t,e,r){const{labelStyles:i,nodeStyles:a}=(0,n.GX)(e);e.labelStyle=i;const{shapeSvg:s,bbox:c,halfPadding:d}=await u(t,e,f(e)),g=r?.padding??d,y=c.width/2+g;let m;const{cssStyles:x}=e;if("handDrawn"===e.look){const t=h.A.svg(s),r=(0,n.Fr)(e,{}),i=t.circle(0,0,2*y,r);m=s.insert(()=>i,":first-child"),m.attr("class","basic label-container").attr("style",(0,o.KL)(x))}else m=s.insert("circle",":first-child").attr("class","basic label-container").attr("style",a).attr("r",y).attr("cx",0).attr("cy",0);return p(e,m),e.calcIntersect=function(t,e){const r=t.width/2;return P.circle(t,r,e)},e.intersect=function(t){return l.Rm.info("Circle intersect",e,y,t),P.circle(e,y,t)},s}function X(t){const e=Math.cos(Math.PI/4),r=Math.sin(Math.PI/4),i=2*t;return`M ${-i/2*e},${i/2*r} L ${i/2*e},${-i/2*r}\n M ${i/2*e},${i/2*r} L ${-i/2*e},${-i/2*r}`}function V(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r,e.label="";const a=t.insert("g").attr("class",f(e)).attr("id",e.domId??e.id),o=Math.max(30,e?.width??0),{cssStyles:s}=e,c=h.A.svg(a),u=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(u.roughness=0,u.fillStyle="solid");const d=c.circle(0,0,2*o,u),g=X(o),y=c.path(g,u),m=a.insert(()=>d,":first-child");return m.insert(()=>y),s&&"handDrawn"!==e.look&&m.selectAll("path").attr("style",s),i&&"handDrawn"!==e.look&&m.selectAll("path").attr("style",i),p(e,m),e.intersect=function(t){l.Rm.info("crossedCircle intersect",e,{radius:o,point:t});return P.circle(e,o,t)},a}function Z(t,e,r,i=100,n=0,a=180){const o=[],s=n*Math.PI/180,l=(a*Math.PI/180-s)/(i-1);for(let c=0;c<i;c++){const i=s+c*l,n=t+r*Math.cos(i),a=e+r*Math.sin(i);o.push({x:-n,y:-a})}return o}async function Q(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o,label:s}=await u(t,e,f(e)),l=o.width+(e.padding??0),c=o.height+(e.padding??0),d=Math.max(5,.1*c),{cssStyles:y}=e,m=[...Z(l/2,-c/2,d,30,-90,0),{x:-l/2-d,y:d},...Z(l/2+2*d,-d,d,20,-180,-270),...Z(l/2+2*d,d,d,20,-90,-180),{x:-l/2-d,y:-c/2},...Z(l/2,c/2,d,20,0,90)],x=[{x:l/2,y:-c/2-d},{x:-l/2,y:-c/2-d},...Z(l/2,-c/2,d,20,-90,0),{x:-l/2-d,y:-d},...Z(l/2+.1*l,-d,d,20,-180,-270),...Z(l/2+.1*l,d,d,20,-90,-180),{x:-l/2-d,y:c/2},...Z(l/2,c/2,d,20,0,90),{x:-l/2,y:c/2+d},{x:l/2,y:c/2+d}],b=h.A.svg(a),k=(0,n.Fr)(e,{fill:"none"});"handDrawn"!==e.look&&(k.roughness=0,k.fillStyle="solid");const w=g(m).replace("Z",""),C=b.path(w,k),_=g(x),v=b.path(_,{...k}),S=a.insert("g",":first-child");return S.insert(()=>v,":first-child").attr("stroke-opacity",0),S.insert(()=>C,":first-child"),S.attr("class","text"),y&&"handDrawn"!==e.look&&S.selectAll("path").attr("style",y),i&&"handDrawn"!==e.look&&S.selectAll("path").attr("style",i),S.attr("transform",`translate(${d}, 0)`),s.attr("transform",`translate(${-l/2+d-(o.x-(o.left??0))},${-c/2+(e.padding??0)/2-(o.y-(o.top??0))})`),p(e,S),e.intersect=function(t){return P.polygon(e,x,t)},a}function J(t,e,r,i=100,n=0,a=180){const o=[],s=n*Math.PI/180,l=(a*Math.PI/180-s)/(i-1);for(let c=0;c<i;c++){const i=s+c*l,n=t+r*Math.cos(i),a=e+r*Math.sin(i);o.push({x:n,y:a})}return o}async function tt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o,label:s}=await u(t,e,f(e)),l=o.width+(e.padding??0),c=o.height+(e.padding??0),d=Math.max(5,.1*c),{cssStyles:y}=e,m=[...J(l/2,-c/2,d,20,-90,0),{x:l/2+d,y:-d},...J(l/2+2*d,-d,d,20,-180,-270),...J(l/2+2*d,d,d,20,-90,-180),{x:l/2+d,y:c/2},...J(l/2,c/2,d,20,0,90)],x=[{x:-l/2,y:-c/2-d},{x:l/2,y:-c/2-d},...J(l/2,-c/2,d,20,-90,0),{x:l/2+d,y:-d},...J(l/2+2*d,-d,d,20,-180,-270),...J(l/2+2*d,d,d,20,-90,-180),{x:l/2+d,y:c/2},...J(l/2,c/2,d,20,0,90),{x:l/2,y:c/2+d},{x:-l/2,y:c/2+d}],b=h.A.svg(a),k=(0,n.Fr)(e,{fill:"none"});"handDrawn"!==e.look&&(k.roughness=0,k.fillStyle="solid");const w=g(m).replace("Z",""),C=b.path(w,k),_=g(x),v=b.path(_,{...k}),S=a.insert("g",":first-child");return S.insert(()=>v,":first-child").attr("stroke-opacity",0),S.insert(()=>C,":first-child"),S.attr("class","text"),y&&"handDrawn"!==e.look&&S.selectAll("path").attr("style",y),i&&"handDrawn"!==e.look&&S.selectAll("path").attr("style",i),S.attr("transform",`translate(${-d}, 0)`),s.attr("transform",`translate(${-l/2+(e.padding??0)/2-(o.x-(o.left??0))},${-c/2+(e.padding??0)/2-(o.y-(o.top??0))})`),p(e,S),e.intersect=function(t){return P.polygon(e,x,t)},a}function et(t,e,r,i=100,n=0,a=180){const o=[],s=n*Math.PI/180,l=(a*Math.PI/180-s)/(i-1);for(let c=0;c<i;c++){const i=s+c*l,n=t+r*Math.cos(i),a=e+r*Math.sin(i);o.push({x:-n,y:-a})}return o}async function rt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o,label:s}=await u(t,e,f(e)),l=o.width+(e.padding??0),c=o.height+(e.padding??0),d=Math.max(5,.1*c),{cssStyles:y}=e,m=[...et(l/2,-c/2,d,30,-90,0),{x:-l/2-d,y:d},...et(l/2+2*d,-d,d,20,-180,-270),...et(l/2+2*d,d,d,20,-90,-180),{x:-l/2-d,y:-c/2},...et(l/2,c/2,d,20,0,90)],x=[...et(-l/2+d+d/2,-c/2,d,20,-90,-180),{x:l/2-d/2,y:d},...et(-l/2-d/2,-d,d,20,0,90),...et(-l/2-d/2,d,d,20,-90,0),{x:l/2-d/2,y:-d},...et(-l/2+d+d/2,c/2,d,30,-180,-270)],b=[{x:l/2,y:-c/2-d},{x:-l/2,y:-c/2-d},...et(l/2,-c/2,d,20,-90,0),{x:-l/2-d,y:-d},...et(l/2+2*d,-d,d,20,-180,-270),...et(l/2+2*d,d,d,20,-90,-180),{x:-l/2-d,y:c/2},...et(l/2,c/2,d,20,0,90),{x:-l/2,y:c/2+d},{x:l/2-d-d/2,y:c/2+d},...et(-l/2+d+d/2,-c/2,d,20,-90,-180),{x:l/2-d/2,y:d},...et(-l/2-d/2,-d,d,20,0,90),...et(-l/2-d/2,d,d,20,-90,0),{x:l/2-d/2,y:-d},...et(-l/2+d+d/2,c/2,d,30,-180,-270)],k=h.A.svg(a),w=(0,n.Fr)(e,{fill:"none"});"handDrawn"!==e.look&&(w.roughness=0,w.fillStyle="solid");const C=g(m).replace("Z",""),_=k.path(C,w),v=g(x).replace("Z",""),S=k.path(v,w),T=g(b),A=k.path(T,{...w}),M=a.insert("g",":first-child");return M.insert(()=>A,":first-child").attr("stroke-opacity",0),M.insert(()=>_,":first-child"),M.insert(()=>S,":first-child"),M.attr("class","text"),y&&"handDrawn"!==e.look&&M.selectAll("path").attr("style",y),i&&"handDrawn"!==e.look&&M.selectAll("path").attr("style",i),M.attr("transform",`translate(${d-d/4}, 0)`),s.attr("transform",`translate(${-l/2+(e.padding??0)/2-(o.x-(o.left??0))},${-c/2+(e.padding??0)/2-(o.y-(o.top??0))})`),p(e,M),e.intersect=function(t){return P.polygon(e,b,t)},a}async function it(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o}=await u(t,e,f(e)),s=Math.max(80,1.25*(o.width+2*(e.padding??0)),e?.width??0),l=Math.max(20,o.height+2*(e.padding??0),e?.height??0),c=l/2,{cssStyles:d}=e,y=h.A.svg(a),x=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(x.roughness=0,x.fillStyle="solid");const b=s-c,k=l/4,w=[{x:b,y:0},{x:k,y:0},{x:0,y:l/2},{x:k,y:l},{x:b,y:l},...m(-b,-l/2,c,50,270,90)],C=g(w),_=y.path(C,x),v=a.insert(()=>_,":first-child");return v.attr("class","basic label-container"),d&&"handDrawn"!==e.look&&v.selectChildren("path").attr("style",d),i&&"handDrawn"!==e.look&&v.selectChildren("path").attr("style",i),v.attr("transform",`translate(${-s/2}, ${-l/2})`),p(e,v),e.intersect=function(t){return P.polygon(e,w,t)},a}(0,l.K2)(q,"anchor"),(0,l.K2)(j,"generateArcPoints"),(0,l.K2)(W,"bowTieRect"),(0,l.K2)(H,"insertPolygonShape"),(0,l.K2)(U,"card"),(0,l.K2)(Y,"choice"),(0,l.K2)(G,"circle"),(0,l.K2)(X,"createLine"),(0,l.K2)(V,"crossedCircle"),(0,l.K2)(Z,"generateCirclePoints"),(0,l.K2)(Q,"curlyBraceLeft"),(0,l.K2)(J,"generateCirclePoints"),(0,l.K2)(tt,"curlyBraceRight"),(0,l.K2)(et,"generateCirclePoints"),(0,l.K2)(rt,"curlyBraces"),(0,l.K2)(it,"curvedTrapezoid");var nt=(0,l.K2)((t,e,r,i,n,a)=>[`M${t},${e+a}`,`a${n},${a} 0,0,0 ${r},0`,`a${n},${a} 0,0,0 ${-r},0`,`l0,${i}`,`a${n},${a} 0,0,0 ${r},0`,"l0,"+-i].join(" "),"createCylinderPathD"),at=(0,l.K2)((t,e,r,i,n,a)=>[`M${t},${e+a}`,`M${t+r},${e+a}`,`a${n},${a} 0,0,0 ${-r},0`,`l0,${i}`,`a${n},${a} 0,0,0 ${r},0`,"l0,"+-i].join(" "),"createOuterCylinderPathD"),ot=(0,l.K2)((t,e,r,i,n,a)=>[`M${t-r/2},${-i/2}`,`a${n},${a} 0,0,0 ${r},0`].join(" "),"createInnerCylinderPathD");async function st(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:s,label:l}=await u(t,e,f(e)),c=Math.max(s.width+e.padding,e.width??0),d=c/2,g=d/(2.5+c/50),y=Math.max(s.height+g+e.padding,e.height??0);let m;const{cssStyles:x}=e;if("handDrawn"===e.look){const t=h.A.svg(a),r=at(0,0,c,y,d,g),i=ot(0,g,c,y,d,g),o=t.path(r,(0,n.Fr)(e,{})),s=t.path(i,(0,n.Fr)(e,{fill:"none"}));m=a.insert(()=>s,":first-child"),m=a.insert(()=>o,":first-child"),m.attr("class","basic label-container"),x&&m.attr("style",x)}else{const t=nt(0,0,c,y,d,g);m=a.insert("path",":first-child").attr("d",t).attr("class","basic label-container").attr("style",(0,o.KL)(x)).attr("style",i)}return m.attr("label-offset-y",g),m.attr("transform",`translate(${-c/2}, ${-(y/2+g)})`),p(e,m),l.attr("transform",`translate(${-s.width/2-(s.x-(s.left??0))}, ${-s.height/2+(e.padding??0)/1.5-(s.y-(s.top??0))})`),e.intersect=function(t){const r=P.rect(e,t),i=r.x-(e.x??0);if(0!=d&&(Math.abs(i)<(e.width??0)/2||Math.abs(i)==(e.width??0)/2&&Math.abs(r.y-(e.y??0))>(e.height??0)/2-g)){let n=g*g*(1-i*i/(d*d));n>0&&(n=Math.sqrt(n)),n=g-n,t.y-(e.y??0)>0&&(n=-n),r.y+=n}return r},a}async function lt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o,label:s}=await u(t,e,f(e)),l=o.width+e.padding,c=o.height+e.padding,d=.2*c,g=-l/2,y=-c/2-d/2,{cssStyles:m}=e,x=h.A.svg(a),b=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(b.roughness=0,b.fillStyle="solid");const k=[{x:g,y:y+d},{x:-g,y:y+d},{x:-g,y:-y},{x:g,y:-y},{x:g,y:y},{x:-g,y:y},{x:-g,y:y+d}],w=x.polygon(k.map(t=>[t.x,t.y]),b),C=a.insert(()=>w,":first-child");return C.attr("class","basic label-container"),m&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",m),i&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",i),s.attr("transform",`translate(${g+(e.padding??0)/2-(o.x-(o.left??0))}, ${y+d+(e.padding??0)/2-(o.y-(o.top??0))})`),p(e,C),e.intersect=function(t){return P.rect(e,t)},a}async function ct(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:s,halfPadding:c}=await u(t,e,f(e)),d=s.width/2+c+5,g=s.width/2+c;let y;const{cssStyles:m}=e;if("handDrawn"===e.look){const t=h.A.svg(a),r=(0,n.Fr)(e,{roughness:.2,strokeWidth:2.5}),i=(0,n.Fr)(e,{roughness:.2,strokeWidth:1.5}),s=t.circle(0,0,2*d,r),l=t.circle(0,0,2*g,i);y=a.insert("g",":first-child"),y.attr("class",(0,o.KL)(e.cssClasses)).attr("style",(0,o.KL)(m)),y.node()?.appendChild(s),y.node()?.appendChild(l)}else{y=a.insert("g",":first-child");const t=y.insert("circle",":first-child"),e=y.insert("circle");y.attr("class","basic label-container").attr("style",i),t.attr("class","outer-circle").attr("style",i).attr("r",d).attr("cx",0).attr("cy",0),e.attr("class","inner-circle").attr("style",i).attr("r",g).attr("cx",0).attr("cy",0)}return p(e,y),e.intersect=function(t){return l.Rm.info("DoubleCircle intersect",e,d,t),P.circle(e,d,t)},a}function ht(t,e,{config:{themeVariables:r}}){const{labelStyles:i,nodeStyles:a}=(0,n.GX)(e);e.label="",e.labelStyle=i;const o=t.insert("g").attr("class",f(e)).attr("id",e.domId??e.id),{cssStyles:s}=e,c=h.A.svg(o),{nodeBorder:u}=r,d=(0,n.Fr)(e,{fillStyle:"solid"});"handDrawn"!==e.look&&(d.roughness=0);const g=c.circle(0,0,14,d),y=o.insert(()=>g,":first-child");return y.selectAll("path").attr("style",`fill: ${u} !important;`),s&&s.length>0&&"handDrawn"!==e.look&&y.selectAll("path").attr("style",s),a&&"handDrawn"!==e.look&&y.selectAll("path").attr("style",a),p(e,y),e.intersect=function(t){l.Rm.info("filledCircle intersect",e,{radius:7,point:t});return P.circle(e,7,t)},o}async function ut(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o,label:s}=await u(t,e,f(e)),c=o.width+(e.padding??0),d=c+o.height,y=c+o.height,m=[{x:0,y:-d},{x:y,y:-d},{x:y/2,y:0}],{cssStyles:x}=e,b=h.A.svg(a),k=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(k.roughness=0,k.fillStyle="solid");const w=g(m),C=b.path(w,k),_=a.insert(()=>C,":first-child").attr("transform",`translate(${-d/2}, ${d/2})`);return x&&"handDrawn"!==e.look&&_.selectChildren("path").attr("style",x),i&&"handDrawn"!==e.look&&_.selectChildren("path").attr("style",i),e.width=c,e.height=d,p(e,_),s.attr("transform",`translate(${-o.width/2-(o.x-(o.left??0))}, ${-d/2+(e.padding??0)/2+(o.y-(o.top??0))})`),e.intersect=function(t){return l.Rm.info("Triangle intersect",e,m,t),P.polygon(e,m,t)},a}function dt(t,e,{dir:r,config:{state:i,themeVariables:a}}){const{nodeStyles:o}=(0,n.GX)(e);e.label="";const s=t.insert("g").attr("class",f(e)).attr("id",e.domId??e.id),{cssStyles:l}=e;let c=Math.max(70,e?.width??0),u=Math.max(10,e?.height??0);"LR"===r&&(c=Math.max(10,e?.width??0),u=Math.max(70,e?.height??0));const d=-1*c/2,g=-1*u/2,y=h.A.svg(s),m=(0,n.Fr)(e,{stroke:a.lineColor,fill:a.lineColor});"handDrawn"!==e.look&&(m.roughness=0,m.fillStyle="solid");const x=y.rectangle(d,g,c,u,m),b=s.insert(()=>x,":first-child");l&&"handDrawn"!==e.look&&b.selectAll("path").attr("style",l),o&&"handDrawn"!==e.look&&b.selectAll("path").attr("style",o),p(e,b);const k=i?.padding??0;return e.width&&e.height&&(e.width+=k/2||0,e.height+=k/2||0),e.intersect=function(t){return P.rect(e,t)},s}async function pt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o}=await u(t,e,f(e)),s=Math.max(80,o.width+2*(e.padding??0),e?.width??0),c=Math.max(50,o.height+2*(e.padding??0),e?.height??0),d=c/2,{cssStyles:y}=e,x=h.A.svg(a),b=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(b.roughness=0,b.fillStyle="solid");const k=[{x:-s/2,y:-c/2},{x:s/2-d,y:-c/2},...m(-s/2+d,0,d,50,90,270),{x:s/2-d,y:c/2},{x:-s/2,y:c/2}],w=g(k),C=x.path(w,b),_=a.insert(()=>C,":first-child");return _.attr("class","basic label-container"),y&&"handDrawn"!==e.look&&_.selectChildren("path").attr("style",y),i&&"handDrawn"!==e.look&&_.selectChildren("path").attr("style",i),p(e,_),e.intersect=function(t){l.Rm.info("Pill intersect",e,{radius:d,point:t});return P.polygon(e,k,t)},a}async function ft(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o}=await u(t,e,f(e)),s=o.height+(e.padding??0),l=o.width+2.5*(e.padding??0),{cssStyles:c}=e,d=h.A.svg(a),y=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(y.roughness=0,y.fillStyle="solid");let m=l/2;m+=m/6;const x=s/2,b=m-x/2,k=[{x:-b,y:-x},{x:0,y:-x},{x:b,y:-x},{x:m,y:0},{x:b,y:x},{x:0,y:x},{x:-b,y:x},{x:-m,y:0}],w=g(k),C=d.path(w,y),_=a.insert(()=>C,":first-child");return _.attr("class","basic label-container"),c&&"handDrawn"!==e.look&&_.selectChildren("path").attr("style",c),i&&"handDrawn"!==e.look&&_.selectChildren("path").attr("style",i),e.width=l,e.height=s,p(e,_),e.intersect=function(t){return P.polygon(e,k,t)},a}async function gt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.label="",e.labelStyle=r;const{shapeSvg:a}=await u(t,e,f(e)),o=Math.max(30,e?.width??0),s=Math.max(30,e?.height??0),{cssStyles:c}=e,d=h.A.svg(a),y=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(y.roughness=0,y.fillStyle="solid");const m=[{x:0,y:0},{x:o,y:0},{x:0,y:s},{x:o,y:s}],x=g(m),b=d.path(x,y),k=a.insert(()=>b,":first-child");return k.attr("class","basic label-container"),c&&"handDrawn"!==e.look&&k.selectChildren("path").attr("style",c),i&&"handDrawn"!==e.look&&k.selectChildren("path").attr("style",i),k.attr("transform",`translate(${-o/2}, ${-s/2})`),p(e,k),e.intersect=function(t){l.Rm.info("Pill intersect",e,{points:m});return P.polygon(e,m,t)},a}async function yt(t,e,{config:{themeVariables:r,flowchart:i}}){const{labelStyles:o}=(0,n.GX)(e);e.labelStyle=o;const s=e.assetHeight??48,c=e.assetWidth??48,d=Math.max(s,c),f=i?.wrappingWidth;e.width=Math.max(d,f??0);const{shapeSvg:g,bbox:y,label:m}=await u(t,e,"icon-shape default"),x="t"===e.pos,b=d,k=d,{nodeBorder:w}=r,{stylesMap:C}=(0,n.WW)(e),_=-k/2,v=-b/2,S=e.label?8:0,T=h.A.svg(g),A=(0,n.Fr)(e,{stroke:"none",fill:"none"});"handDrawn"!==e.look&&(A.roughness=0,A.fillStyle="solid");const M=T.rectangle(_,v,k,b,A),B=Math.max(k,y.width),L=b+y.height+S,F=T.rectangle(-B/2,-L/2,B,L,{...A,fill:"transparent",stroke:"none"}),$=g.insert(()=>M,":first-child"),E=g.insert(()=>F);if(e.icon){const t=g.append("g");t.html(`<g>${await(0,a.WY)(e.icon,{height:d,width:d,fallbackPrefix:""})}</g>`);const r=t.node().getBBox(),i=r.width,n=r.height,o=r.x,s=r.y;t.attr("transform",`translate(${-i/2-o},${x?y.height/2+S/2-n/2-s:-y.height/2-S/2-n/2-s})`),t.attr("style",`color: ${C.get("stroke")??w};`)}return m.attr("transform",`translate(${-y.width/2-(y.x-(y.left??0))},${x?-L/2:L/2-y.height})`),$.attr("transform",`translate(0,${x?y.height/2+S/2:-y.height/2-S/2})`),p(e,E),e.intersect=function(t){if(l.Rm.info("iconSquare intersect",e,t),!e.label)return P.rect(e,t);const r=e.x??0,i=e.y??0,n=e.height??0;let a=[];a=x?[{x:r-y.width/2,y:i-n/2},{x:r+y.width/2,y:i-n/2},{x:r+y.width/2,y:i-n/2+y.height+S},{x:r+k/2,y:i-n/2+y.height+S},{x:r+k/2,y:i+n/2},{x:r-k/2,y:i+n/2},{x:r-k/2,y:i-n/2+y.height+S},{x:r-y.width/2,y:i-n/2+y.height+S}]:[{x:r-k/2,y:i-n/2},{x:r+k/2,y:i-n/2},{x:r+k/2,y:i-n/2+b},{x:r+y.width/2,y:i-n/2+b},{x:r+y.width/2/2,y:i+n/2},{x:r-y.width/2,y:i+n/2},{x:r-y.width/2,y:i-n/2+b},{x:r-k/2,y:i-n/2+b}];return P.polygon(e,a,t)},g}async function mt(t,e,{config:{themeVariables:r,flowchart:i}}){const{labelStyles:o}=(0,n.GX)(e);e.labelStyle=o;const s=e.assetHeight??48,c=e.assetWidth??48,d=Math.max(s,c),f=i?.wrappingWidth;e.width=Math.max(d,f??0);const{shapeSvg:g,bbox:y,label:m}=await u(t,e,"icon-shape default"),x=e.label?8:0,b="t"===e.pos,{nodeBorder:k,mainBkg:w}=r,{stylesMap:C}=(0,n.WW)(e),_=h.A.svg(g),v=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(v.roughness=0,v.fillStyle="solid");const S=C.get("fill");v.stroke=S??w;const T=g.append("g");e.icon&&T.html(`<g>${await(0,a.WY)(e.icon,{height:d,width:d,fallbackPrefix:""})}</g>`);const A=T.node().getBBox(),M=A.width,B=A.height,L=A.x,F=A.y,$=Math.max(M,B)*Math.SQRT2+40,E=_.circle(0,0,$,v),D=Math.max($,y.width),O=$+y.height+x,R=_.rectangle(-D/2,-O/2,D,O,{...v,fill:"transparent",stroke:"none"}),K=g.insert(()=>E,":first-child"),I=g.insert(()=>R);return T.attr("transform",`translate(${-M/2-L},${b?y.height/2+x/2-B/2-F:-y.height/2-x/2-B/2-F})`),T.attr("style",`color: ${C.get("stroke")??k};`),m.attr("transform",`translate(${-y.width/2-(y.x-(y.left??0))},${b?-O/2:O/2-y.height})`),K.attr("transform",`translate(0,${b?y.height/2+x/2:-y.height/2-x/2})`),p(e,I),e.intersect=function(t){l.Rm.info("iconSquare intersect",e,t);return P.rect(e,t)},g}async function xt(t,e,{config:{themeVariables:r,flowchart:i}}){const{labelStyles:o}=(0,n.GX)(e);e.labelStyle=o;const s=e.assetHeight??48,c=e.assetWidth??48,d=Math.max(s,c),f=i?.wrappingWidth;e.width=Math.max(d,f??0);const{shapeSvg:g,bbox:y,halfPadding:m,label:x}=await u(t,e,"icon-shape default"),b="t"===e.pos,k=d+2*m,w=d+2*m,{nodeBorder:_,mainBkg:v}=r,{stylesMap:S}=(0,n.WW)(e),T=-w/2,A=-k/2,M=e.label?8:0,B=h.A.svg(g),L=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(L.roughness=0,L.fillStyle="solid");const F=S.get("fill");L.stroke=F??v;const $=B.path(C(T,A,w,k,5),L),E=Math.max(w,y.width),D=k+y.height+M,O=B.rectangle(-E/2,-D/2,E,D,{...L,fill:"transparent",stroke:"none"}),R=g.insert(()=>$,":first-child").attr("class","icon-shape2"),K=g.insert(()=>O);if(e.icon){const t=g.append("g");t.html(`<g>${await(0,a.WY)(e.icon,{height:d,width:d,fallbackPrefix:""})}</g>`);const r=t.node().getBBox(),i=r.width,n=r.height,o=r.x,s=r.y;t.attr("transform",`translate(${-i/2-o},${b?y.height/2+M/2-n/2-s:-y.height/2-M/2-n/2-s})`),t.attr("style",`color: ${S.get("stroke")??_};`)}return x.attr("transform",`translate(${-y.width/2-(y.x-(y.left??0))},${b?-D/2:D/2-y.height})`),R.attr("transform",`translate(0,${b?y.height/2+M/2:-y.height/2-M/2})`),p(e,K),e.intersect=function(t){if(l.Rm.info("iconSquare intersect",e,t),!e.label)return P.rect(e,t);const r=e.x??0,i=e.y??0,n=e.height??0;let a=[];a=b?[{x:r-y.width/2,y:i-n/2},{x:r+y.width/2,y:i-n/2},{x:r+y.width/2,y:i-n/2+y.height+M},{x:r+w/2,y:i-n/2+y.height+M},{x:r+w/2,y:i+n/2},{x:r-w/2,y:i+n/2},{x:r-w/2,y:i-n/2+y.height+M},{x:r-y.width/2,y:i-n/2+y.height+M}]:[{x:r-w/2,y:i-n/2},{x:r+w/2,y:i-n/2},{x:r+w/2,y:i-n/2+k},{x:r+y.width/2,y:i-n/2+k},{x:r+y.width/2/2,y:i+n/2},{x:r-y.width/2,y:i+n/2},{x:r-y.width/2,y:i-n/2+k},{x:r-w/2,y:i-n/2+k}];return P.polygon(e,a,t)},g}async function bt(t,e,{config:{themeVariables:r,flowchart:i}}){const{labelStyles:o}=(0,n.GX)(e);e.labelStyle=o;const s=e.assetHeight??48,c=e.assetWidth??48,d=Math.max(s,c),f=i?.wrappingWidth;e.width=Math.max(d,f??0);const{shapeSvg:g,bbox:y,halfPadding:m,label:x}=await u(t,e,"icon-shape default"),b="t"===e.pos,k=d+2*m,w=d+2*m,{nodeBorder:_,mainBkg:v}=r,{stylesMap:S}=(0,n.WW)(e),T=-w/2,A=-k/2,M=e.label?8:0,B=h.A.svg(g),L=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(L.roughness=0,L.fillStyle="solid");const F=S.get("fill");L.stroke=F??v;const $=B.path(C(T,A,w,k,.1),L),E=Math.max(w,y.width),D=k+y.height+M,O=B.rectangle(-E/2,-D/2,E,D,{...L,fill:"transparent",stroke:"none"}),R=g.insert(()=>$,":first-child"),K=g.insert(()=>O);if(e.icon){const t=g.append("g");t.html(`<g>${await(0,a.WY)(e.icon,{height:d,width:d,fallbackPrefix:""})}</g>`);const r=t.node().getBBox(),i=r.width,n=r.height,o=r.x,s=r.y;t.attr("transform",`translate(${-i/2-o},${b?y.height/2+M/2-n/2-s:-y.height/2-M/2-n/2-s})`),t.attr("style",`color: ${S.get("stroke")??_};`)}return x.attr("transform",`translate(${-y.width/2-(y.x-(y.left??0))},${b?-D/2:D/2-y.height})`),R.attr("transform",`translate(0,${b?y.height/2+M/2:-y.height/2-M/2})`),p(e,K),e.intersect=function(t){if(l.Rm.info("iconSquare intersect",e,t),!e.label)return P.rect(e,t);const r=e.x??0,i=e.y??0,n=e.height??0;let a=[];a=b?[{x:r-y.width/2,y:i-n/2},{x:r+y.width/2,y:i-n/2},{x:r+y.width/2,y:i-n/2+y.height+M},{x:r+w/2,y:i-n/2+y.height+M},{x:r+w/2,y:i+n/2},{x:r-w/2,y:i+n/2},{x:r-w/2,y:i-n/2+y.height+M},{x:r-y.width/2,y:i-n/2+y.height+M}]:[{x:r-w/2,y:i-n/2},{x:r+w/2,y:i-n/2},{x:r+w/2,y:i-n/2+k},{x:r+y.width/2,y:i-n/2+k},{x:r+y.width/2/2,y:i+n/2},{x:r-y.width/2,y:i+n/2},{x:r-y.width/2,y:i-n/2+k},{x:r-w/2,y:i-n/2+k}];return P.polygon(e,a,t)},g}async function kt(t,e,{config:{flowchart:r}}){const i=new Image;i.src=e?.img??"",await i.decode();const a=Number(i.naturalWidth.toString().replace("px","")),o=Number(i.naturalHeight.toString().replace("px",""));e.imageAspectRatio=a/o;const{labelStyles:s}=(0,n.GX)(e);e.labelStyle=s;const c=r?.wrappingWidth;e.defaultWidth=r?.wrappingWidth;const d=Math.max(e.label?c??0:0,e?.assetWidth??a),f="on"===e.constraint&&e?.assetHeight?e.assetHeight*e.imageAspectRatio:d,g="on"===e.constraint?f/e.imageAspectRatio:e?.assetHeight??o;e.width=Math.max(f,c??0);const{shapeSvg:y,bbox:m,label:x}=await u(t,e,"image-shape default"),b="t"===e.pos,k=-f/2,w=-g/2,C=e.label?8:0,_=h.A.svg(y),v=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(v.roughness=0,v.fillStyle="solid");const S=_.rectangle(k,w,f,g,v),T=Math.max(f,m.width),A=g+m.height+C,M=_.rectangle(-T/2,-A/2,T,A,{...v,fill:"none",stroke:"none"}),B=y.insert(()=>S,":first-child"),L=y.insert(()=>M);if(e.img){const t=y.append("image");t.attr("href",e.img),t.attr("width",f),t.attr("height",g),t.attr("preserveAspectRatio","none"),t.attr("transform",`translate(${-f/2},${b?A/2-g:-A/2})`)}return x.attr("transform",`translate(${-m.width/2-(m.x-(m.left??0))},${b?-g/2-m.height/2-C/2:g/2-m.height/2+C/2})`),B.attr("transform",`translate(0,${b?m.height/2+C/2:-m.height/2-C/2})`),p(e,L),e.intersect=function(t){if(l.Rm.info("iconSquare intersect",e,t),!e.label)return P.rect(e,t);const r=e.x??0,i=e.y??0,n=e.height??0;let a=[];a=b?[{x:r-m.width/2,y:i-n/2},{x:r+m.width/2,y:i-n/2},{x:r+m.width/2,y:i-n/2+m.height+C},{x:r+f/2,y:i-n/2+m.height+C},{x:r+f/2,y:i+n/2},{x:r-f/2,y:i+n/2},{x:r-f/2,y:i-n/2+m.height+C},{x:r-m.width/2,y:i-n/2+m.height+C}]:[{x:r-f/2,y:i-n/2},{x:r+f/2,y:i-n/2},{x:r+f/2,y:i-n/2+g},{x:r+m.width/2,y:i-n/2+g},{x:r+m.width/2/2,y:i+n/2},{x:r-m.width/2,y:i+n/2},{x:r-m.width/2,y:i-n/2+g},{x:r-f/2,y:i-n/2+g}];return P.polygon(e,a,t)},y}async function wt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o}=await u(t,e,f(e)),s=Math.max(o.width+2*(e.padding??0),e?.width??0),l=Math.max(o.height+2*(e.padding??0),e?.height??0),c=[{x:0,y:0},{x:s,y:0},{x:s+3*l/6,y:-l},{x:-3*l/6,y:-l}];let d;const{cssStyles:y}=e;if("handDrawn"===e.look){const t=h.A.svg(a),r=(0,n.Fr)(e,{}),i=g(c),o=t.path(i,r);d=a.insert(()=>o,":first-child").attr("transform",`translate(${-s/2}, ${l/2})`),y&&d.attr("style",y)}else d=H(a,s,l,c);return i&&d.attr("style",i),e.width=s,e.height=l,p(e,d),e.intersect=function(t){return P.polygon(e,c,t)},a}async function Ct(t,e,r){const{labelStyles:i,nodeStyles:a}=(0,n.GX)(e);e.labelStyle=i;const{shapeSvg:s,bbox:l}=await u(t,e,f(e)),c=Math.max(l.width+2*r.labelPaddingX,e?.width||0),d=Math.max(l.height+2*r.labelPaddingY,e?.height||0),g=-c/2,y=-d/2;let m,{rx:x,ry:b}=e;const{cssStyles:k}=e;if(r?.rx&&r.ry&&(x=r.rx,b=r.ry),"handDrawn"===e.look){const t=h.A.svg(s),r=(0,n.Fr)(e,{}),i=x||b?t.path(C(g,y,c,d,x||0),r):t.rectangle(g,y,c,d,r);m=s.insert(()=>i,":first-child"),m.attr("class","basic label-container").attr("style",(0,o.KL)(k))}else m=s.insert("rect",":first-child"),m.attr("class","basic label-container").attr("style",a).attr("rx",(0,o.KL)(x)).attr("ry",(0,o.KL)(b)).attr("x",g).attr("y",y).attr("width",c).attr("height",d);return p(e,m),e.calcIntersect=function(t,e){return P.rect(t,e)},e.intersect=function(t){return P.rect(e,t)},s}async function _t(t,e){const{shapeSvg:r,bbox:i,label:n}=await u(t,e,"label"),a=r.insert("rect",":first-child");return a.attr("width",.1).attr("height",.1),r.attr("class","label edgeLabel"),n.attr("transform",`translate(${-i.width/2-(i.x-(i.left??0))}, ${-i.height/2-(i.y-(i.top??0))})`),p(e,a),e.intersect=function(t){return P.rect(e,t)},r}async function vt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o}=await u(t,e,f(e)),s=Math.max(o.width+(e.padding??0),e?.width??0),l=Math.max(o.height+(e.padding??0),e?.height??0),c=[{x:0,y:0},{x:s+3*l/6,y:0},{x:s,y:-l},{x:-3*l/6,y:-l}];let d;const{cssStyles:y}=e;if("handDrawn"===e.look){const t=h.A.svg(a),r=(0,n.Fr)(e,{}),i=g(c),o=t.path(i,r);d=a.insert(()=>o,":first-child").attr("transform",`translate(${-s/2}, ${l/2})`),y&&d.attr("style",y)}else d=H(a,s,l,c);return i&&d.attr("style",i),e.width=s,e.height=l,p(e,d),e.intersect=function(t){return P.polygon(e,c,t)},a}async function St(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o}=await u(t,e,f(e)),s=Math.max(o.width+(e.padding??0),e?.width??0),l=Math.max(o.height+(e.padding??0),e?.height??0),c=[{x:-3*l/6,y:0},{x:s,y:0},{x:s+3*l/6,y:-l},{x:0,y:-l}];let d;const{cssStyles:y}=e;if("handDrawn"===e.look){const t=h.A.svg(a),r=(0,n.Fr)(e,{}),i=g(c),o=t.path(i,r);d=a.insert(()=>o,":first-child").attr("transform",`translate(${-s/2}, ${l/2})`),y&&d.attr("style",y)}else d=H(a,s,l,c);return i&&d.attr("style",i),e.width=s,e.height=l,p(e,d),e.intersect=function(t){return P.polygon(e,c,t)},a}function Tt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.label="",e.labelStyle=r;const a=t.insert("g").attr("class",f(e)).attr("id",e.domId??e.id),{cssStyles:o}=e,s=Math.max(35,e?.width??0),c=Math.max(35,e?.height??0),u=[{x:s,y:0},{x:0,y:c+3.5},{x:s-14,y:c+3.5},{x:0,y:2*c},{x:s,y:c-3.5},{x:14,y:c-3.5}],d=h.A.svg(a),y=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(y.roughness=0,y.fillStyle="solid");const m=g(u),x=d.path(m,y),b=a.insert(()=>x,":first-child");return o&&"handDrawn"!==e.look&&b.selectAll("path").attr("style",o),i&&"handDrawn"!==e.look&&b.selectAll("path").attr("style",i),b.attr("transform",`translate(-${s/2},${-c})`),p(e,b),e.intersect=function(t){l.Rm.info("lightningBolt intersect",e,t);return P.polygon(e,u,t)},a}(0,l.K2)(st,"cylinder"),(0,l.K2)(lt,"dividedRectangle"),(0,l.K2)(ct,"doublecircle"),(0,l.K2)(ht,"filledCircle"),(0,l.K2)(ut,"flippedTriangle"),(0,l.K2)(dt,"forkJoin"),(0,l.K2)(pt,"halfRoundedRectangle"),(0,l.K2)(ft,"hexagon"),(0,l.K2)(gt,"hourglass"),(0,l.K2)(yt,"icon"),(0,l.K2)(mt,"iconCircle"),(0,l.K2)(xt,"iconRounded"),(0,l.K2)(bt,"iconSquare"),(0,l.K2)(kt,"imageSquare"),(0,l.K2)(wt,"inv_trapezoid"),(0,l.K2)(Ct,"drawRect"),(0,l.K2)(_t,"labelRect"),(0,l.K2)(vt,"lean_left"),(0,l.K2)(St,"lean_right"),(0,l.K2)(Tt,"lightningBolt");var At=(0,l.K2)((t,e,r,i,n,a,o)=>[`M${t},${e+a}`,`a${n},${a} 0,0,0 ${r},0`,`a${n},${a} 0,0,0 ${-r},0`,`l0,${i}`,`a${n},${a} 0,0,0 ${r},0`,"l0,"+-i,`M${t},${e+a+o}`,`a${n},${a} 0,0,0 ${r},0`].join(" "),"createCylinderPathD"),Mt=(0,l.K2)((t,e,r,i,n,a,o)=>[`M${t},${e+a}`,`M${t+r},${e+a}`,`a${n},${a} 0,0,0 ${-r},0`,`l0,${i}`,`a${n},${a} 0,0,0 ${r},0`,"l0,"+-i,`M${t},${e+a+o}`,`a${n},${a} 0,0,0 ${r},0`].join(" "),"createOuterCylinderPathD"),Bt=(0,l.K2)((t,e,r,i,n,a)=>[`M${t-r/2},${-i/2}`,`a${n},${a} 0,0,0 ${r},0`].join(" "),"createInnerCylinderPathD");async function Lt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:s,label:l}=await u(t,e,f(e)),c=Math.max(s.width+(e.padding??0),e.width??0),d=c/2,g=d/(2.5+c/50),y=Math.max(s.height+g+(e.padding??0),e.height??0),m=.1*y;let x;const{cssStyles:b}=e;if("handDrawn"===e.look){const t=h.A.svg(a),r=Mt(0,0,c,y,d,g,m),i=Bt(0,g,c,y,d,g),o=(0,n.Fr)(e,{}),s=t.path(r,o),l=t.path(i,o);a.insert(()=>l,":first-child").attr("class","line"),x=a.insert(()=>s,":first-child"),x.attr("class","basic label-container"),b&&x.attr("style",b)}else{const t=At(0,0,c,y,d,g,m);x=a.insert("path",":first-child").attr("d",t).attr("class","basic label-container").attr("style",(0,o.KL)(b)).attr("style",i)}return x.attr("label-offset-y",g),x.attr("transform",`translate(${-c/2}, ${-(y/2+g)})`),p(e,x),l.attr("transform",`translate(${-s.width/2-(s.x-(s.left??0))}, ${-s.height/2+g-(s.y-(s.top??0))})`),e.intersect=function(t){const r=P.rect(e,t),i=r.x-(e.x??0);if(0!=d&&(Math.abs(i)<(e.width??0)/2||Math.abs(i)==(e.width??0)/2&&Math.abs(r.y-(e.y??0))>(e.height??0)/2-g)){let n=g*g*(1-i*i/(d*d));n>0&&(n=Math.sqrt(n)),n=g-n,t.y-(e.y??0)>0&&(n=-n),r.y+=n}return r},a}async function Ft(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o,label:s}=await u(t,e,f(e)),l=Math.max(o.width+2*(e.padding??0),e?.width??0),c=Math.max(o.height+2*(e.padding??0),e?.height??0),d=c/4,g=c+d,{cssStyles:m}=e,x=h.A.svg(a),b=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(b.roughness=0,b.fillStyle="solid");const k=[{x:-l/2-l/2*.1,y:-g/2},{x:-l/2-l/2*.1,y:g/2},...y(-l/2-l/2*.1,g/2,l/2+l/2*.1,g/2,d,.8),{x:l/2+l/2*.1,y:-g/2},{x:-l/2-l/2*.1,y:-g/2},{x:-l/2,y:-g/2},{x:-l/2,y:g/2*1.1},{x:-l/2,y:-g/2}],w=x.polygon(k.map(t=>[t.x,t.y]),b),C=a.insert(()=>w,":first-child");return C.attr("class","basic label-container"),m&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",m),i&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",i),C.attr("transform",`translate(0,${-d/2})`),s.attr("transform",`translate(${-l/2+(e.padding??0)+l/2*.1/2-(o.x-(o.left??0))},${-c/2+(e.padding??0)-d/2-(o.y-(o.top??0))})`),p(e,C),e.intersect=function(t){return P.polygon(e,k,t)},a}async function $t(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o,label:s}=await u(t,e,f(e)),l=Math.max(o.width+2*(e.padding??0),e?.width??0),c=Math.max(o.height+2*(e.padding??0),e?.height??0),d=-l/2,y=-c/2,{cssStyles:m}=e,x=h.A.svg(a),b=(0,n.Fr)(e,{}),k=[{x:d-5,y:y+5},{x:d-5,y:y+c+5},{x:d+l-5,y:y+c+5},{x:d+l-5,y:y+c},{x:d+l,y:y+c},{x:d+l,y:y+c-5},{x:d+l+5,y:y+c-5},{x:d+l+5,y:y-5},{x:d+5,y:y-5},{x:d+5,y:y},{x:d,y:y},{x:d,y:y+5}],w=[{x:d,y:y+5},{x:d+l-5,y:y+5},{x:d+l-5,y:y+c},{x:d+l,y:y+c},{x:d+l,y:y},{x:d,y:y}];"handDrawn"!==e.look&&(b.roughness=0,b.fillStyle="solid");const C=g(k),_=x.path(C,b),v=g(w),S=x.path(v,{...b,fill:"none"}),T=a.insert(()=>S,":first-child");return T.insert(()=>_,":first-child"),T.attr("class","basic label-container"),m&&"handDrawn"!==e.look&&T.selectAll("path").attr("style",m),i&&"handDrawn"!==e.look&&T.selectAll("path").attr("style",i),s.attr("transform",`translate(${-o.width/2-5-(o.x-(o.left??0))}, ${-o.height/2+5-(o.y-(o.top??0))})`),p(e,T),e.intersect=function(t){return P.polygon(e,k,t)},a}async function Et(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o,label:s}=await u(t,e,f(e)),l=Math.max(o.width+2*(e.padding??0),e?.width??0),c=Math.max(o.height+2*(e.padding??0),e?.height??0),d=c/4,m=c+d,x=-l/2,b=-m/2,{cssStyles:k}=e,w=y(x-5,b+m+5,x+l-5,b+m+5,d,.8),C=w?.[w.length-1],_=[{x:x-5,y:b+5},{x:x-5,y:b+m+5},...w,{x:x+l-5,y:C.y-5},{x:x+l,y:C.y-5},{x:x+l,y:C.y-10},{x:x+l+5,y:C.y-10},{x:x+l+5,y:b-5},{x:x+5,y:b-5},{x:x+5,y:b},{x:x,y:b},{x:x,y:b+5}],v=[{x:x,y:b+5},{x:x+l-5,y:b+5},{x:x+l-5,y:C.y-5},{x:x+l,y:C.y-5},{x:x+l,y:b},{x:x,y:b}],S=h.A.svg(a),T=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(T.roughness=0,T.fillStyle="solid");const A=g(_),M=S.path(A,T),B=g(v),L=S.path(B,T),F=a.insert(()=>M,":first-child");return F.insert(()=>L),F.attr("class","basic label-container"),k&&"handDrawn"!==e.look&&F.selectAll("path").attr("style",k),i&&"handDrawn"!==e.look&&F.selectAll("path").attr("style",i),F.attr("transform",`translate(0,${-d/2})`),s.attr("transform",`translate(${-o.width/2-5-(o.x-(o.left??0))}, ${-o.height/2+5-d/2-(o.y-(o.top??0))})`),p(e,F),e.intersect=function(t){return P.polygon(e,_,t)},a}async function Dt(t,e,{config:{themeVariables:r}}){const{labelStyles:i,nodeStyles:a}=(0,n.GX)(e);e.labelStyle=i;e.useHtmlLabels||!1!==(0,s.zj)().flowchart?.htmlLabels||(e.centerLabel=!0);const{shapeSvg:o,bbox:l,label:c}=await u(t,e,f(e)),d=Math.max(l.width+2*(e.padding??0),e?.width??0),g=Math.max(l.height+2*(e.padding??0),e?.height??0),y=-d/2,m=-g/2,{cssStyles:x}=e,b=h.A.svg(o),k=(0,n.Fr)(e,{fill:r.noteBkgColor,stroke:r.noteBorderColor});"handDrawn"!==e.look&&(k.roughness=0,k.fillStyle="solid");const w=b.rectangle(y,m,d,g,k),C=o.insert(()=>w,":first-child");return C.attr("class","basic label-container"),x&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",x),a&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",a),c.attr("transform",`translate(${-l.width/2-(l.x-(l.left??0))}, ${-l.height/2-(l.y-(l.top??0))})`),p(e,C),e.intersect=function(t){return P.rect(e,t)},o}(0,l.K2)(Lt,"linedCylinder"),(0,l.K2)(Ft,"linedWaveEdgedRect"),(0,l.K2)($t,"multiRect"),(0,l.K2)(Et,"multiWaveEdgedRectangle"),(0,l.K2)(Dt,"note");var Ot=(0,l.K2)((t,e,r)=>[`M${t+r/2},${e}`,`L${t+r},${e-r/2}`,`L${t+r/2},${e-r}`,`L${t},${e-r/2}`,"Z"].join(" "),"createDecisionBoxPathD");async function Rt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o}=await u(t,e,f(e)),s=o.width+e.padding+(o.height+e.padding),l=[{x:s/2,y:0},{x:s,y:-s/2},{x:s/2,y:-s},{x:0,y:-s/2}];let c;const{cssStyles:d}=e;if("handDrawn"===e.look){const t=h.A.svg(a),r=(0,n.Fr)(e,{}),i=Ot(0,0,s),o=t.path(i,r);c=a.insert(()=>o,":first-child").attr("transform",`translate(${-s/2+.5}, ${s/2})`),d&&c.attr("style",d)}else c=H(a,s,s,l),c.attr("transform",`translate(${-s/2+.5}, ${s/2})`);return i&&c.attr("style",i),p(e,c),e.calcIntersect=function(t,e){const r=t.width,i=[{x:r/2,y:0},{x:r,y:-r/2},{x:r/2,y:-r},{x:0,y:-r/2}],n=P.polygon(t,i,e);return{x:n.x-.5,y:n.y-.5}},e.intersect=function(t){return this.calcIntersect(e,t)},a}async function Kt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o,label:s}=await u(t,e,f(e)),l=-Math.max(o.width+(e.padding??0),e?.width??0)/2,c=-Math.max(o.height+(e.padding??0),e?.height??0)/2,d=c/2,y=[{x:l+d,y:c},{x:l,y:0},{x:l+d,y:-c},{x:-l,y:-c},{x:-l,y:c}],{cssStyles:m}=e,x=h.A.svg(a),b=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(b.roughness=0,b.fillStyle="solid");const k=g(y),w=x.path(k,b),C=a.insert(()=>w,":first-child");return C.attr("class","basic label-container"),m&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",m),i&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",i),C.attr("transform",`translate(${-d/2},0)`),s.attr("transform",`translate(${-d/2-o.width/2-(o.x-(o.left??0))}, ${-o.height/2-(o.y-(o.top??0))})`),p(e,C),e.intersect=function(t){return P.polygon(e,y,t)},a}async function It(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);let a;e.labelStyle=r,a=e.cssClasses?"node "+e.cssClasses:"node default";const o=t.insert("g").attr("class",a).attr("id",e.domId||e.id),u=o.insert("g"),d=o.insert("g").attr("class","label").attr("style",i),f=e.description,g=e.label,y=d.node().appendChild(await w(g,e.labelStyle,!0,!0));let m={width:0,height:0};if((0,s._3)((0,s.D7)()?.flowchart?.htmlLabels)){const t=y.children[0],e=(0,c.Ltv)(y);m=t.getBoundingClientRect(),e.attr("width",m.width),e.attr("height",m.height)}l.Rm.info("Text 2",f);const x=f||[],b=y.getBBox(),k=d.node().appendChild(await w(x.join?x.join("<br/>"):x,e.labelStyle,!0,!0)),_=k.children[0],v=(0,c.Ltv)(k);m=_.getBoundingClientRect(),v.attr("width",m.width),v.attr("height",m.height);const S=(e.padding||0)/2;(0,c.Ltv)(k).attr("transform","translate( "+(m.width>b.width?0:(b.width-m.width)/2)+", "+(b.height+S+5)+")"),(0,c.Ltv)(y).attr("transform","translate( "+(m.width<b.width?0:-(b.width-m.width)/2)+", 0)"),m=d.node().getBBox(),d.attr("transform","translate("+-m.width/2+", "+(-m.height/2-S+3)+")");const T=m.width+(e.padding||0),A=m.height+(e.padding||0),M=-m.width/2-S,B=-m.height/2-S;let L,F;if("handDrawn"===e.look){const t=h.A.svg(o),r=(0,n.Fr)(e,{}),i=t.path(C(M,B,T,A,e.rx||0),r),a=t.line(-m.width/2-S,-m.height/2-S+b.height+S,m.width/2+S,-m.height/2-S+b.height+S,r);F=o.insert(()=>(l.Rm.debug("Rough node insert CXC",i),a),":first-child"),L=o.insert(()=>(l.Rm.debug("Rough node insert CXC",i),i),":first-child")}else L=u.insert("rect",":first-child"),F=u.insert("line"),L.attr("class","outer title-state").attr("style",i).attr("x",-m.width/2-S).attr("y",-m.height/2-S).attr("width",m.width+(e.padding||0)).attr("height",m.height+(e.padding||0)),F.attr("class","divider").attr("x1",-m.width/2-S).attr("x2",m.width/2+S).attr("y1",-m.height/2-S+b.height+S).attr("y2",-m.height/2-S+b.height+S);return p(e,L),e.intersect=function(t){return P.rect(e,t)},o}function Nt(t,e,r,i,n,a,o){const s=(t+r)/2,l=(e+i)/2,c=Math.atan2(i-e,r-t),h=(r-t)/2/n,u=(i-e)/2/a,d=Math.sqrt(h**2+u**2);if(d>1)throw new Error("The given radii are too small to create an arc between the points.");const p=Math.sqrt(1-d**2),f=s+p*a*Math.sin(c)*(o?-1:1),g=l-p*n*Math.cos(c)*(o?-1:1),y=Math.atan2((e-g)/a,(t-f)/n);let m=Math.atan2((i-g)/a,(r-f)/n)-y;o&&m<0&&(m+=2*Math.PI),!o&&m>0&&(m-=2*Math.PI);const x=[];for(let b=0;b<20;b++){const t=y+b/19*m,e=f+n*Math.cos(t),r=g+a*Math.sin(t);x.push({x:e,y:r})}return x}async function zt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o}=await u(t,e,f(e)),s=e?.padding??0,l=e?.padding??0,c=(e?.width?e?.width:o.width)+2*s,d=(e?.height?e?.height:o.height)+2*l,y=e.radius||5,m=e.taper||5,{cssStyles:x}=e,b=h.A.svg(a),k=(0,n.Fr)(e,{});e.stroke&&(k.stroke=e.stroke),"handDrawn"!==e.look&&(k.roughness=0,k.fillStyle="solid");const w=[{x:-c/2+m,y:-d/2},{x:c/2-m,y:-d/2},...Nt(c/2-m,-d/2,c/2,-d/2+m,y,y,!0),{x:c/2,y:-d/2+m},{x:c/2,y:d/2-m},...Nt(c/2,d/2-m,c/2-m,d/2,y,y,!0),{x:c/2-m,y:d/2},{x:-c/2+m,y:d/2},...Nt(-c/2+m,d/2,-c/2,d/2-m,y,y,!0),{x:-c/2,y:d/2-m},{x:-c/2,y:-d/2+m},...Nt(-c/2,-d/2+m,-c/2+m,-d/2,y,y,!0)],C=g(w),_=b.path(C,k),v=a.insert(()=>_,":first-child");return v.attr("class","basic label-container outer-path"),x&&"handDrawn"!==e.look&&v.selectChildren("path").attr("style",x),i&&"handDrawn"!==e.look&&v.selectChildren("path").attr("style",i),p(e,v),e.intersect=function(t){return P.polygon(e,w,t)},a}async function Pt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:s,label:l}=await u(t,e,f(e)),c=e?.padding??0,d=Math.max(s.width+2*(e.padding??0),e?.width??0),g=Math.max(s.height+2*(e.padding??0),e?.height??0),y=-s.width/2-c,m=-s.height/2-c,{cssStyles:x}=e,b=h.A.svg(a),k=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(k.roughness=0,k.fillStyle="solid");const w=[{x:y,y:m},{x:y+d+8,y:m},{x:y+d+8,y:m+g},{x:y-8,y:m+g},{x:y-8,y:m},{x:y,y:m},{x:y,y:m+g}],C=b.polygon(w.map(t=>[t.x,t.y]),k),_=a.insert(()=>C,":first-child");return _.attr("class","basic label-container").attr("style",(0,o.KL)(x)),i&&"handDrawn"!==e.look&&_.selectAll("path").attr("style",i),x&&"handDrawn"!==e.look&&_.selectAll("path").attr("style",i),l.attr("transform",`translate(${-d/2+4+(e.padding??0)-(s.x-(s.left??0))},${-g/2+(e.padding??0)-(s.y-(s.top??0))})`),p(e,_),e.intersect=function(t){return P.rect(e,t)},a}async function qt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o,label:s}=await u(t,e,f(e)),l=Math.max(o.width+2*(e.padding??0),e?.width??0),c=Math.max(o.height+2*(e.padding??0),e?.height??0),d=-l/2,y=-c/2,{cssStyles:m}=e,x=h.A.svg(a),b=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(b.roughness=0,b.fillStyle="solid");const k=[{x:d,y:y},{x:d,y:y+c},{x:d+l,y:y+c},{x:d+l,y:y-c/2}],w=g(k),C=x.path(w,b),_=a.insert(()=>C,":first-child");return _.attr("class","basic label-container"),m&&"handDrawn"!==e.look&&_.selectChildren("path").attr("style",m),i&&"handDrawn"!==e.look&&_.selectChildren("path").attr("style",i),_.attr("transform",`translate(0, ${c/4})`),s.attr("transform",`translate(${-l/2+(e.padding??0)-(o.x-(o.left??0))}, ${-c/4+(e.padding??0)-(o.y-(o.top??0))})`),p(e,_),e.intersect=function(t){return P.polygon(e,k,t)},a}async function jt(t,e){return Ct(t,e,{rx:0,ry:0,classes:"",labelPaddingX:e.labelPaddingX??2*(e?.padding||0),labelPaddingY:1*(e?.padding||0)})}async function Wt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o}=await u(t,e,f(e)),s=o.height+e.padding,l=o.width+s/4+e.padding,c=s/2,{cssStyles:d}=e,y=h.A.svg(a),x=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(x.roughness=0,x.fillStyle="solid");const b=[{x:-l/2+c,y:-s/2},{x:l/2-c,y:-s/2},...m(-l/2+c,0,c,50,90,270),{x:l/2-c,y:s/2},...m(l/2-c,0,c,50,270,450)],k=g(b),w=y.path(k,x),C=a.insert(()=>w,":first-child");return C.attr("class","basic label-container outer-path"),d&&"handDrawn"!==e.look&&C.selectChildren("path").attr("style",d),i&&"handDrawn"!==e.look&&C.selectChildren("path").attr("style",i),p(e,C),e.intersect=function(t){return P.polygon(e,b,t)},a}async function Ht(t,e){return Ct(t,e,{rx:5,ry:5,classes:"flowchart-node"})}function Ut(t,e,{config:{themeVariables:r}}){const{labelStyles:i,nodeStyles:a}=(0,n.GX)(e);e.labelStyle=i;const{cssStyles:o}=e,{lineColor:s,stateBorder:l,nodeBorder:c}=r,u=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),d=h.A.svg(u),f=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(f.roughness=0,f.fillStyle="solid");const g=d.circle(0,0,14,{...f,stroke:s,strokeWidth:2}),y=l??c,m=d.circle(0,0,5,{...f,fill:y,stroke:y,strokeWidth:2,fillStyle:"solid"}),x=u.insert(()=>g,":first-child");return x.insert(()=>m),o&&x.selectAll("path").attr("style",o),a&&x.selectAll("path").attr("style",a),p(e,x),e.intersect=function(t){return P.circle(e,7,t)},u}function Yt(t,e,{config:{themeVariables:r}}){const{lineColor:i}=r,a=t.insert("g").attr("class","node default").attr("id",e.domId||e.id);let o;if("handDrawn"===e.look){const t=h.A.svg(a).circle(0,0,14,(0,n.ue)(i));o=a.insert(()=>t),o.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14)}else o=a.insert("circle",":first-child"),o.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14);return p(e,o),e.intersect=function(t){return P.circle(e,7,t)},a}async function Gt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:s}=await u(t,e,f(e)),l=(e?.padding||0)/2,c=s.width+e.padding,d=s.height+e.padding,g=-s.width/2-l,y=-s.height/2-l,m=[{x:0,y:0},{x:c,y:0},{x:c,y:-d},{x:0,y:-d},{x:0,y:0},{x:-8,y:0},{x:c+8,y:0},{x:c+8,y:-d},{x:-8,y:-d},{x:-8,y:0}];if("handDrawn"===e.look){const t=h.A.svg(a),r=(0,n.Fr)(e,{}),i=t.rectangle(g-8,y,c+16,d,r),s=t.line(g,y,g,y+d,r),l=t.line(g+c,y,g+c,y+d,r);a.insert(()=>s,":first-child"),a.insert(()=>l,":first-child");const u=a.insert(()=>i,":first-child"),{cssStyles:f}=e;u.attr("class","basic label-container").attr("style",(0,o.KL)(f)),p(e,u)}else{const t=H(a,c,d,m);i&&t.attr("style",i),p(e,t)}return e.intersect=function(t){return P.polygon(e,m,t)},a}async function Xt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o}=await u(t,e,f(e)),s=Math.max(o.width+2*(e.padding??0),e?.width??0),l=Math.max(o.height+2*(e.padding??0),e?.height??0),c=-s/2,d=-l/2,y=.2*l,m=.2*l,{cssStyles:x}=e,b=h.A.svg(a),k=(0,n.Fr)(e,{}),w=[{x:c-y/2,y:d},{x:c+s+y/2,y:d},{x:c+s+y/2,y:d+l},{x:c-y/2,y:d+l}],C=[{x:c+s-y/2,y:d+l},{x:c+s+y/2,y:d+l},{x:c+s+y/2,y:d+l-m}];"handDrawn"!==e.look&&(k.roughness=0,k.fillStyle="solid");const _=g(w),v=b.path(_,k),S=g(C),T=b.path(S,{...k,fillStyle:"solid"}),A=a.insert(()=>T,":first-child");return A.insert(()=>v,":first-child"),A.attr("class","basic label-container"),x&&"handDrawn"!==e.look&&A.selectAll("path").attr("style",x),i&&"handDrawn"!==e.look&&A.selectAll("path").attr("style",i),p(e,A),e.intersect=function(t){return P.polygon(e,w,t)},a}async function Vt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o,label:s}=await u(t,e,f(e)),l=Math.max(o.width+2*(e.padding??0),e?.width??0),c=Math.max(o.height+2*(e.padding??0),e?.height??0),d=c/4,m=.2*l,x=.2*c,b=c+d,{cssStyles:k}=e,w=h.A.svg(a),C=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(C.roughness=0,C.fillStyle="solid");const _=[{x:-l/2-l/2*.1,y:b/2},...y(-l/2-l/2*.1,b/2,l/2+l/2*.1,b/2,d,.8),{x:l/2+l/2*.1,y:-b/2},{x:-l/2-l/2*.1,y:-b/2}],v=-l/2+l/2*.1,S=-b/2-.4*x,T=[{x:v+l-m,y:1.4*(S+c)},{x:v+l,y:S+c-x},{x:v+l,y:.9*(S+c)},...y(v+l,1.3*(S+c),v+l-m,1.5*(S+c),.03*-c,.5)],A=g(_),M=w.path(A,C),B=g(T),L=w.path(B,{...C,fillStyle:"solid"}),F=a.insert(()=>L,":first-child");return F.insert(()=>M,":first-child"),F.attr("class","basic label-container"),k&&"handDrawn"!==e.look&&F.selectAll("path").attr("style",k),i&&"handDrawn"!==e.look&&F.selectAll("path").attr("style",i),F.attr("transform",`translate(0,${-d/2})`),s.attr("transform",`translate(${-l/2+(e.padding??0)-(o.x-(o.left??0))},${-c/2+(e.padding??0)-d/2-(o.y-(o.top??0))})`),p(e,F),e.intersect=function(t){return P.polygon(e,_,t)},a}async function Zt(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o}=await u(t,e,f(e)),s=Math.max(o.width+e.padding,e?.width||0),l=Math.max(o.height+e.padding,e?.height||0),c=-s/2,h=-l/2,d=a.insert("rect",":first-child");return d.attr("class","text").attr("style",i).attr("rx",0).attr("ry",0).attr("x",c).attr("y",h).attr("width",s).attr("height",l),p(e,d),e.intersect=function(t){return P.rect(e,t)},a}(0,l.K2)(Rt,"question"),(0,l.K2)(Kt,"rect_left_inv_arrow"),(0,l.K2)(It,"rectWithTitle"),(0,l.K2)(Nt,"generateArcPoints"),(0,l.K2)(zt,"roundedRect"),(0,l.K2)(Pt,"shadedProcess"),(0,l.K2)(qt,"slopedRect"),(0,l.K2)(jt,"squareRect"),(0,l.K2)(Wt,"stadium"),(0,l.K2)(Ht,"state"),(0,l.K2)(Ut,"stateEnd"),(0,l.K2)(Yt,"stateStart"),(0,l.K2)(Gt,"subroutine"),(0,l.K2)(Xt,"taggedRect"),(0,l.K2)(Vt,"taggedWaveEdgedRectangle"),(0,l.K2)(Zt,"text");var Qt=(0,l.K2)((t,e,r,i,n,a)=>`M${t},${e}\n a${n},${a} 0,0,1 0,${-i}\n l${r},0\n a${n},${a} 0,0,1 0,${i}\n M${r},${-i}\n a${n},${a} 0,0,0 0,${i}\n l${-r},0`,"createCylinderPathD"),Jt=(0,l.K2)((t,e,r,i,n,a)=>[`M${t},${e}`,`M${t+r},${e}`,`a${n},${a} 0,0,0 0,${-i}`,`l${-r},0`,`a${n},${a} 0,0,0 0,${i}`,`l${r},0`].join(" "),"createOuterCylinderPathD"),te=(0,l.K2)((t,e,r,i,n,a)=>[`M${t+r/2},${-i/2}`,`a${n},${a} 0,0,0 0,${i}`].join(" "),"createInnerCylinderPathD");async function ee(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:s,label:l,halfPadding:c}=await u(t,e,f(e)),d="neo"===e.look?2*c:c,g=s.height+d,y=g/2,m=y/(2.5+g/50),x=s.width+m+d,{cssStyles:b}=e;let k;if("handDrawn"===e.look){const t=h.A.svg(a),r=Jt(0,0,x,g,m,y),i=te(0,0,x,g,m,y),o=t.path(r,(0,n.Fr)(e,{})),s=t.path(i,(0,n.Fr)(e,{fill:"none"}));k=a.insert(()=>s,":first-child"),k=a.insert(()=>o,":first-child"),k.attr("class","basic label-container"),b&&k.attr("style",b)}else{const t=Qt(0,0,x,g,m,y);k=a.insert("path",":first-child").attr("d",t).attr("class","basic label-container").attr("style",(0,o.KL)(b)).attr("style",i),k.attr("class","basic label-container"),b&&k.selectAll("path").attr("style",b),i&&k.selectAll("path").attr("style",i)}return k.attr("label-offset-x",m),k.attr("transform",`translate(${-x/2}, ${g/2} )`),l.attr("transform",`translate(${-s.width/2-m-(s.x-(s.left??0))}, ${-s.height/2-(s.y-(s.top??0))})`),p(e,k),e.intersect=function(t){const r=P.rect(e,t),i=r.y-(e.y??0);if(0!=y&&(Math.abs(i)<(e.height??0)/2||Math.abs(i)==(e.height??0)/2&&Math.abs(r.x-(e.x??0))>(e.width??0)/2-m)){let n=m*m*(1-i*i/(y*y));0!=n&&(n=Math.sqrt(Math.abs(n))),n=m-n,t.x-(e.x??0)>0&&(n=-n),r.x+=n}return r},a}async function re(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o}=await u(t,e,f(e)),s=o.width+e.padding,l=o.height+e.padding,c=[{x:-3*l/6,y:0},{x:s+3*l/6,y:0},{x:s,y:-l},{x:0,y:-l}];let d;const{cssStyles:y}=e;if("handDrawn"===e.look){const t=h.A.svg(a),r=(0,n.Fr)(e,{}),i=g(c),o=t.path(i,r);d=a.insert(()=>o,":first-child").attr("transform",`translate(${-s/2}, ${l/2})`),y&&d.attr("style",y)}else d=H(a,s,l,c);return i&&d.attr("style",i),e.width=s,e.height=l,p(e,d),e.intersect=function(t){return P.polygon(e,c,t)},a}async function ie(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o}=await u(t,e,f(e)),s=Math.max(60,o.width+2*(e.padding??0),e?.width??0),l=Math.max(20,o.height+2*(e.padding??0),e?.height??0),{cssStyles:c}=e,d=h.A.svg(a),y=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(y.roughness=0,y.fillStyle="solid");const m=[{x:-s/2*.8,y:-l/2},{x:s/2*.8,y:-l/2},{x:s/2,y:-l/2*.6},{x:s/2,y:l/2},{x:-s/2,y:l/2},{x:-s/2,y:-l/2*.6}],x=g(m),b=d.path(x,y),k=a.insert(()=>b,":first-child");return k.attr("class","basic label-container"),c&&"handDrawn"!==e.look&&k.selectChildren("path").attr("style",c),i&&"handDrawn"!==e.look&&k.selectChildren("path").attr("style",i),p(e,k),e.intersect=function(t){return P.polygon(e,m,t)},a}async function ne(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o,label:c}=await u(t,e,f(e)),d=(0,s._3)((0,s.D7)().flowchart?.htmlLabels),y=o.width+(e.padding??0),m=y+o.height,x=y+o.height,b=[{x:0,y:0},{x:x,y:0},{x:x/2,y:-m}],{cssStyles:k}=e,w=h.A.svg(a),C=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(C.roughness=0,C.fillStyle="solid");const _=g(b),v=w.path(_,C),S=a.insert(()=>v,":first-child").attr("transform",`translate(${-m/2}, ${m/2})`);return k&&"handDrawn"!==e.look&&S.selectChildren("path").attr("style",k),i&&"handDrawn"!==e.look&&S.selectChildren("path").attr("style",i),e.width=y,e.height=m,p(e,S),c.attr("transform",`translate(${-o.width/2-(o.x-(o.left??0))}, ${m/2-(o.height+(e.padding??0)/(d?2:1)-(o.y-(o.top??0)))})`),e.intersect=function(t){return l.Rm.info("Triangle intersect",e,b,t),P.polygon(e,b,t)},a}async function ae(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o,label:s}=await u(t,e,f(e)),l=Math.max(o.width+2*(e.padding??0),e?.width??0),c=Math.max(o.height+2*(e.padding??0),e?.height??0),d=c/8,m=c+d,{cssStyles:x}=e,b=70-l,k=b>0?b/2:0,w=h.A.svg(a),C=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(C.roughness=0,C.fillStyle="solid");const _=[{x:-l/2-k,y:m/2},...y(-l/2-k,m/2,l/2+k,m/2,d,.8),{x:l/2+k,y:-m/2},{x:-l/2-k,y:-m/2}],v=g(_),S=w.path(v,C),T=a.insert(()=>S,":first-child");return T.attr("class","basic label-container"),x&&"handDrawn"!==e.look&&T.selectAll("path").attr("style",x),i&&"handDrawn"!==e.look&&T.selectAll("path").attr("style",i),T.attr("transform",`translate(0,${-d/2})`),s.attr("transform",`translate(${-l/2+(e.padding??0)-(o.x-(o.left??0))},${-c/2+(e.padding??0)-d-(o.y-(o.top??0))})`),p(e,T),e.intersect=function(t){return P.polygon(e,_,t)},a}async function oe(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o}=await u(t,e,f(e)),s=Math.max(o.width+2*(e.padding??0),e?.width??0),l=Math.max(o.height+2*(e.padding??0),e?.height??0),c=s/l;let d=s,m=l;d>m*c?m=d/c:d=m*c,d=Math.max(d,100),m=Math.max(m,50);const x=Math.min(.2*m,m/4),b=m+2*x,{cssStyles:k}=e,w=h.A.svg(a),C=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(C.roughness=0,C.fillStyle="solid");const _=[{x:-d/2,y:b/2},...y(-d/2,b/2,d/2,b/2,x,1),{x:d/2,y:-b/2},...y(d/2,-b/2,-d/2,-b/2,x,-1)],v=g(_),S=w.path(v,C),T=a.insert(()=>S,":first-child");return T.attr("class","basic label-container"),k&&"handDrawn"!==e.look&&T.selectAll("path").attr("style",k),i&&"handDrawn"!==e.look&&T.selectAll("path").attr("style",i),p(e,T),e.intersect=function(t){return P.polygon(e,_,t)},a}async function se(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o,label:s}=await u(t,e,f(e)),l=Math.max(o.width+2*(e.padding??0),e?.width??0),c=Math.max(o.height+2*(e.padding??0),e?.height??0),d=-l/2,g=-c/2,{cssStyles:y}=e,m=h.A.svg(a),x=(0,n.Fr)(e,{}),b=[{x:d-5,y:g-5},{x:d-5,y:g+c},{x:d+l,y:g+c},{x:d+l,y:g-5}],k=`M${d-5},${g-5} L${d+l},${g-5} L${d+l},${g+c} L${d-5},${g+c} L${d-5},${g-5}\n M${d-5},${g} L${d+l},${g}\n M${d},${g-5} L${d},${g+c}`;"handDrawn"!==e.look&&(x.roughness=0,x.fillStyle="solid");const w=m.path(k,x),C=a.insert(()=>w,":first-child");return C.attr("transform","translate(2.5, 2.5)"),C.attr("class","basic label-container"),y&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",y),i&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",i),s.attr("transform",`translate(${-o.width/2+2.5-(o.x-(o.left??0))}, ${-o.height/2+2.5-(o.y-(o.top??0))})`),p(e,C),e.intersect=function(t){return P.polygon(e,b,t)},a}async function le(t,e){const r=e;if(r.alias&&(e.label=r.alias),"handDrawn"===e.look){const{themeVariables:r}=(0,s.zj)(),{background:i}=r,n={...e,id:e.id+"-background",look:"default",cssStyles:["stroke: none",`fill: ${i}`]};await le(t,n)}const i=(0,s.zj)();e.useHtmlLabels=i.htmlLabels;let a=i.er?.diagramPadding??10,l=i.er?.entityPadding??6;const{cssStyles:u}=e,{labelStyles:d,nodeStyles:g}=(0,n.GX)(e);if(0===r.attributes.length&&e.label){const r={rx:0,ry:0,labelPaddingX:a,labelPaddingY:1.5*a,classes:""};(0,o.Un)(e.label,i)+2*r.labelPaddingX<i.er.minEntityWidth&&(e.width=i.er.minEntityWidth);const n=await Ct(t,e,r);if(!(0,s._3)(i.htmlLabels)){const t=n.select("text"),e=t.node()?.getBBox();t.attr("transform",`translate(${-e.width/2}, 0)`)}return n}i.htmlLabels||(a*=1.25,l*=1.25);let y=f(e);y||(y="node default");const m=t.insert("g").attr("class",y).attr("id",e.domId||e.id),x=await ce(m,e.label??"",i,0,0,["name"],d);x.height+=l;let b=0;const k=[],w=[];let C=0,_=0,v=0,S=0,T=!0,A=!0;for(const n of r.attributes){const t=await ce(m,n.type,i,0,b,["attribute-type"],d);C=Math.max(C,t.width+a);const e=await ce(m,n.name,i,0,b,["attribute-name"],d);_=Math.max(_,e.width+a);const r=await ce(m,n.keys.join(),i,0,b,["attribute-keys"],d);v=Math.max(v,r.width+a);const o=await ce(m,n.comment,i,0,b,["attribute-comment"],d);S=Math.max(S,o.width+a);const s=Math.max(t.height,e.height,r.height,o.height)+l;w.push({yOffset:b,rowHeight:s}),b+=s}let M=4;v<=a&&(T=!1,v=0,M--),S<=a&&(A=!1,S=0,M--);const B=m.node().getBBox();if(x.width+2*a-(C+_+v+S)>0){const t=x.width+2*a-(C+_+v+S);C+=t/M,_+=t/M,v>0&&(v+=t/M),S>0&&(S+=t/M)}const L=C+_+v+S,F=h.A.svg(m),$=(0,n.Fr)(e,{});"handDrawn"!==e.look&&($.roughness=0,$.fillStyle="solid");let E=0;w.length>0&&(E=w.reduce((t,e)=>t+(e?.rowHeight??0),0));const D=Math.max(B.width+2*a,e?.width||0,L),O=Math.max((E??0)+x.height,e?.height||0),R=-D/2,K=-O/2;m.selectAll("g:not(:first-child)").each((t,e,r)=>{const i=(0,c.Ltv)(r[e]),n=i.attr("transform");let o=0,s=0;if(n){const t=RegExp(/translate\(([^,]+),([^)]+)\)/).exec(n);t&&(o=parseFloat(t[1]),s=parseFloat(t[2]),i.attr("class").includes("attribute-name")?o+=C:i.attr("class").includes("attribute-keys")?o+=C+_:i.attr("class").includes("attribute-comment")&&(o+=C+_+v))}i.attr("transform",`translate(${R+a/2+o}, ${s+K+x.height+l/2})`)}),m.select(".name").attr("transform","translate("+-x.width/2+", "+(K+l/2)+")");const I=F.rectangle(R,K,D,O,$),N=m.insert(()=>I,":first-child").attr("style",u.join("")),{themeVariables:z}=(0,s.zj)(),{rowEven:q,rowOdd:j,nodeBorder:W}=z;k.push(0);for(const[n,o]of w.entries()){const t=(n+1)%2==0&&0!==o.yOffset,e=F.rectangle(R,x.height+K+o?.yOffset,D,o?.rowHeight,{...$,fill:t?q:j,stroke:W});m.insert(()=>e,"g.label").attr("style",u.join("")).attr("class","row-rect-"+(t?"even":"odd"))}let H=F.line(R,x.height+K,D+R,x.height+K,$);m.insert(()=>H).attr("class","divider"),H=F.line(C+R,x.height+K,C+R,O+K,$),m.insert(()=>H).attr("class","divider"),T&&(H=F.line(C+_+R,x.height+K,C+_+R,O+K,$),m.insert(()=>H).attr("class","divider")),A&&(H=F.line(C+_+v+R,x.height+K,C+_+v+R,O+K,$),m.insert(()=>H).attr("class","divider"));for(const n of k)H=F.line(R,x.height+K+n,D+R,x.height+K+n,$),m.insert(()=>H).attr("class","divider");if(p(e,N),g&&"handDrawn"!==e.look){const t=g.split(";"),e=t?.filter(t=>t.includes("stroke"))?.map(t=>`${t}`).join("; ");m.selectAll("path").attr("style",e??""),m.selectAll(".row-rect-even path").attr("style",g)}return e.intersect=function(t){return P.rect(e,t)},m}async function ce(t,e,r,i=0,n=0,l=[],h=""){const u=t.insert("g").attr("class",`label ${l.join(" ")}`).attr("transform",`translate(${i}, ${n})`).attr("style",h);e!==(0,s.QO)(e)&&(e=(e=(0,s.QO)(e)).replaceAll("<","<").replaceAll(">",">"));const d=u.node().appendChild(await(0,a.GZ)(u,e,{width:(0,o.Un)(e,r)+100,style:h,useHtmlLabels:r.htmlLabels},r));if(e.includes("<")||e.includes(">")){let t=d.children[0];for(t.textContent=t.textContent.replaceAll("<","<").replaceAll(">",">");t.childNodes[0];)t=t.childNodes[0],t.textContent=t.textContent.replaceAll("<","<").replaceAll(">",">")}let p=d.getBBox();if((0,s._3)(r.htmlLabels)){const t=d.children[0];t.style.textAlign="start";const e=(0,c.Ltv)(d);p=t.getBoundingClientRect(),e.attr("width",p.width),e.attr("height",p.height)}return p}async function he(t,e,r,i,n=r.class.padding??12){const a=i?0:3,o=t.insert("g").attr("class",f(e)).attr("id",e.domId||e.id);let s=null,l=null,c=null,h=null,u=0,d=0,p=0;if(s=o.insert("g").attr("class","annotation-group text"),e.annotations.length>0){const t=e.annotations[0];await ue(s,{text:`\xab${t}\xbb`},0);u=s.node().getBBox().height}l=o.insert("g").attr("class","label-group text"),await ue(l,e,0,["font-weight: bolder"]);const g=l.node().getBBox();d=g.height,c=o.insert("g").attr("class","members-group text");let y=0;for(const f of e.members){y+=await ue(c,f,y,[f.parseClassifier()])+a}p=c.node().getBBox().height,p<=0&&(p=n/2),h=o.insert("g").attr("class","methods-group text");let m=0;for(const f of e.methods){m+=await ue(h,f,m,[f.parseClassifier()])+a}let x=o.node().getBBox();if(null!==s){const t=s.node().getBBox();s.attr("transform",`translate(${-t.width/2})`)}return l.attr("transform",`translate(${-g.width/2}, ${u})`),x=o.node().getBBox(),c.attr("transform",`translate(0, ${u+d+2*n})`),x=o.node().getBBox(),h.attr("transform",`translate(0, ${u+d+(p?p+4*n:2*n)})`),x=o.node().getBBox(),{shapeSvg:o,bbox:x}}async function ue(t,e,r,i=[]){const n=t.insert("g").attr("class","label").attr("style",i.join("; ")),h=(0,s.zj)();let u="useHtmlLabels"in e?e.useHtmlLabels:(0,s._3)(h.htmlLabels)??!0,d="";d="text"in e?e.text:e.label,!u&&d.startsWith("\\")&&(d=d.substring(1)),(0,s.Wi)(d)&&(u=!0);const p=await(0,a.GZ)(n,(0,s.oB)((0,o.Sm)(d)),{width:(0,o.Un)(d,h)+50,classes:"markdown-node-label",useHtmlLabels:u},h);let f,g=1;if(u){const t=p.children[0],e=(0,c.Ltv)(p);g=t.innerHTML.split("<br>").length,t.innerHTML.includes("</math>")&&(g+=t.innerHTML.split("<mrow>").length-1);const r=t.getElementsByTagName("img");if(r){const t=""===d.replace(/<img[^>]*>/g,"").trim();await Promise.all([...r].map(e=>new Promise(r=>{function i(){if(e.style.display="flex",e.style.flexDirection="column",t){const t=h.fontSize?.toString()??window.getComputedStyle(document.body).fontSize,r=5,i=parseInt(t,10)*r+"px";e.style.minWidth=i,e.style.maxWidth=i}else e.style.width="100%";r(e)}(0,l.K2)(i,"setupImage"),setTimeout(()=>{e.complete&&i()}),e.addEventListener("error",i),e.addEventListener("load",i)})))}f=t.getBoundingClientRect(),e.attr("width",f.width),e.attr("height",f.height)}else{i.includes("font-weight: bolder")&&(0,c.Ltv)(p).selectAll("tspan").attr("font-weight",""),g=p.children.length;const t=p.children[0];if(""===p.textContent||p.textContent.includes(">")){t.textContent=d[0]+d.substring(1).replaceAll(">",">").replaceAll("<","<").trim();" "===d[1]&&(t.textContent=t.textContent[0]+" "+t.textContent.substring(1))}"undefined"===t.textContent&&(t.textContent=""),f=p.getBBox()}return n.attr("transform","translate(0,"+(-f.height/(2*g)+r)+")"),f.height}async function de(t,e){const r=(0,s.D7)(),i=r.class.padding??12,a=i,o=e.useHtmlLabels??(0,s._3)(r.htmlLabels)??!0,l=e;l.annotations=l.annotations??[],l.members=l.members??[],l.methods=l.methods??[];const{shapeSvg:u,bbox:d}=await he(t,e,r,o,a),{labelStyles:f,nodeStyles:g}=(0,n.GX)(e);e.labelStyle=f,e.cssStyles=l.styles||"";const y=l.styles?.join(";")||g||"";e.cssStyles||(e.cssStyles=y.replaceAll("!important","").split(";"));const m=0===l.members.length&&0===l.methods.length&&!r.class?.hideEmptyMembersBox,x=h.A.svg(u),b=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(b.roughness=0,b.fillStyle="solid");const k=d.width;let w=d.height;0===l.members.length&&0===l.methods.length?w+=a:l.members.length>0&&0===l.methods.length&&(w+=2*a);const C=-k/2,_=-w/2,v=x.rectangle(C-i,_-i-(m?i:0===l.members.length&&0===l.methods.length?-i/2:0),k+2*i,w+2*i+(m?2*i:0===l.members.length&&0===l.methods.length?-i:0),b),S=u.insert(()=>v,":first-child");S.attr("class","basic label-container");const T=S.node().getBBox();u.selectAll(".text").each((t,e,r)=>{const n=(0,c.Ltv)(r[e]),a=n.attr("transform");let s=0;if(a){const t=RegExp(/translate\(([^,]+),([^)]+)\)/).exec(a);t&&(s=parseFloat(t[2]))}let h=s+_+i-(m?i:0===l.members.length&&0===l.methods.length?-i/2:0);o||(h-=4);let d=C;(n.attr("class").includes("label-group")||n.attr("class").includes("annotation-group"))&&(d=-n.node()?.getBBox().width/2||0,u.selectAll("text").each(function(t,e,r){"middle"===window.getComputedStyle(r[e]).textAnchor&&(d=0)})),n.attr("transform",`translate(${d}, ${h})`)});const A=u.select(".annotation-group").node().getBBox().height-(m?i/2:0)||0,M=u.select(".label-group").node().getBBox().height-(m?i/2:0)||0,B=u.select(".members-group").node().getBBox().height-(m?i/2:0)||0;if(l.members.length>0||l.methods.length>0||m){const t=x.line(T.x,A+M+_+i,T.x+T.width,A+M+_+i,b);u.insert(()=>t).attr("class","divider").attr("style",y)}if(m||l.members.length>0||l.methods.length>0){const t=x.line(T.x,A+M+B+_+2*a+i,T.x+T.width,A+M+B+_+i+2*a,b);u.insert(()=>t).attr("class","divider").attr("style",y)}if("handDrawn"!==l.look&&u.selectAll("path").attr("style",y),S.select(":nth-child(2)").attr("style",y),u.selectAll(".divider").select("path").attr("style",y),e.labelStyle?u.selectAll("span").attr("style",e.labelStyle):u.selectAll("span").attr("style",y),!o){const t=RegExp(/color\s*:\s*([^;]*)/),e=t.exec(y);if(e){const t=e[0].replace("color","fill");u.selectAll("tspan").attr("style",t)}else if(f){const e=t.exec(f);if(e){const t=e[0].replace("color","fill");u.selectAll("tspan").attr("style",t)}}}return p(e,S),e.intersect=function(t){return P.rect(e,t)},u}async function pe(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const a=e,o=e,s="verifyMethod"in e,l=f(e),u=t.insert("g").attr("class",l).attr("id",e.domId??e.id);let d;d=s?await fe(u,`<<${a.type}>>`,0,e.labelStyle):await fe(u,"<<Element>>",0,e.labelStyle);let g=d;const y=await fe(u,a.name,g,e.labelStyle+"; font-weight: bold;");if(g+=y+20,s){g+=await fe(u,""+(a.requirementId?`ID: ${a.requirementId}`:""),g,e.labelStyle);g+=await fe(u,""+(a.text?`Text: ${a.text}`:""),g,e.labelStyle);g+=await fe(u,""+(a.risk?`Risk: ${a.risk}`:""),g,e.labelStyle),await fe(u,""+(a.verifyMethod?`Verification: ${a.verifyMethod}`:""),g,e.labelStyle)}else{g+=await fe(u,""+(o.type?`Type: ${o.type}`:""),g,e.labelStyle),await fe(u,""+(o.docRef?`Doc Ref: ${o.docRef}`:""),g,e.labelStyle)}const m=(u.node()?.getBBox().width??200)+20,x=(u.node()?.getBBox().height??200)+20,b=-m/2,k=-x/2,w=h.A.svg(u),C=(0,n.Fr)(e,{});"handDrawn"!==e.look&&(C.roughness=0,C.fillStyle="solid");const _=w.rectangle(b,k,m,x,C),v=u.insert(()=>_,":first-child");if(v.attr("class","basic label-container").attr("style",i),u.selectAll(".label").each((t,e,r)=>{const i=(0,c.Ltv)(r[e]),n=i.attr("transform");let a=0,o=0;if(n){const t=RegExp(/translate\(([^,]+),([^)]+)\)/).exec(n);t&&(a=parseFloat(t[1]),o=parseFloat(t[2]))}const s=o-x/2;let l=b+10;0!==e&&1!==e||(l=a),i.attr("transform",`translate(${l}, ${s+20})`)}),g>d+y+20){const t=w.line(b,k+d+y+20,b+m,k+d+y+20,C);u.insert(()=>t).attr("style",i)}return p(e,v),e.intersect=function(t){return P.rect(e,t)},u}async function fe(t,e,r,i=""){if(""===e)return 0;const n=t.insert("g").attr("class","label").attr("style",i),l=(0,s.D7)(),h=l.htmlLabels??!0,u=await(0,a.GZ)(n,(0,s.oB)((0,o.Sm)(e)),{width:(0,o.Un)(e,l)+50,classes:"markdown-node-label",useHtmlLabels:h,style:i},l);let d;if(h){const t=u.children[0],e=(0,c.Ltv)(u);d=t.getBoundingClientRect(),e.attr("width",d.width),e.attr("height",d.height)}else{const t=u.children[0];for(const e of t.children)e.textContent=e.textContent.replaceAll(">",">").replaceAll("<","<"),i&&e.setAttribute("style",i);d=u.getBBox(),d.height+=6}return n.attr("transform",`translate(${-d.width/2},${-d.height/2+r})`),d.height}(0,l.K2)(ee,"tiltedCylinder"),(0,l.K2)(re,"trapezoid"),(0,l.K2)(ie,"trapezoidalPentagon"),(0,l.K2)(ne,"triangle"),(0,l.K2)(ae,"waveEdgedRectangle"),(0,l.K2)(oe,"waveRectangle"),(0,l.K2)(se,"windowPane"),(0,l.K2)(le,"erBox"),(0,l.K2)(ce,"addText"),(0,l.K2)(he,"textHelper"),(0,l.K2)(ue,"addText"),(0,l.K2)(de,"classBox"),(0,l.K2)(pe,"requirementBox"),(0,l.K2)(fe,"addText");var ge=(0,l.K2)(t=>{switch(t){case"Very High":return"red";case"High":return"orange";case"Medium":return null;case"Low":return"blue";case"Very Low":return"lightblue"}},"colorFromPriority");async function ye(t,e,{config:r}){const{labelStyles:i,nodeStyles:a}=(0,n.GX)(e);e.labelStyle=i||"";const o=e.width;e.width=(e.width??200)-10;const{shapeSvg:s,bbox:l,label:c}=await u(t,e,f(e)),g=e.padding||10;let y,m="";"ticket"in e&&e.ticket&&r?.kanban?.ticketBaseUrl&&(m=r?.kanban?.ticketBaseUrl.replace("#TICKET#",e.ticket),y=s.insert("svg:a",":first-child").attr("class","kanban-ticket-link").attr("xlink:href",m).attr("target","_blank"));const x={useHtmlLabels:e.useHtmlLabels,labelStyle:e.labelStyle||"",width:e.width,img:e.img,padding:e.padding||8,centerLabel:!1};let b,k;({label:b,bbox:k}=y?await d(y,"ticket"in e&&e.ticket||"",x):await d(s,"ticket"in e&&e.ticket||"",x));const{label:w,bbox:_}=await d(s,"assigned"in e&&e.assigned||"",x);e.width=o;const v=e?.width||0,S=Math.max(k.height,_.height)/2,T=Math.max(l.height+20,e?.height||0)+S,A=-v/2,M=-T/2;let B;c.attr("transform","translate("+(g-v/2)+", "+(-S-l.height/2)+")"),b.attr("transform","translate("+(g-v/2)+", "+(-S+l.height/2)+")"),w.attr("transform","translate("+(g+v/2-_.width-20)+", "+(-S+l.height/2)+")");const{rx:L,ry:F}=e,{cssStyles:$}=e;if("handDrawn"===e.look){const t=h.A.svg(s),r=(0,n.Fr)(e,{}),i=L||F?t.path(C(A,M,v,T,L||0),r):t.rectangle(A,M,v,T,r);B=s.insert(()=>i,":first-child"),B.attr("class","basic label-container").attr("style",$||null)}else{B=s.insert("rect",":first-child"),B.attr("class","basic label-container __APA__").attr("style",a).attr("rx",L??5).attr("ry",F??5).attr("x",A).attr("y",M).attr("width",v).attr("height",T);const t="priority"in e&&e.priority;if(t){const e=s.append("line"),r=A+2,i=M+Math.floor((L??0)/2),n=M+T-Math.floor((L??0)/2);e.attr("x1",r).attr("y1",i).attr("x2",r).attr("y2",n).attr("stroke-width","4").attr("stroke",ge(t))}}return p(e,B),e.height=T,e.intersect=function(t){return P.rect(e,t)},s}async function me(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:s,halfPadding:c,label:d}=await u(t,e,f(e)),g=s.width+10*c,y=s.height+8*c,m=.15*g,{cssStyles:x}=e,b=s.width+20,k=s.height+20,w=Math.max(g,b),C=Math.max(y,k);let _;d.attr("transform",`translate(${-s.width/2}, ${-s.height/2})`);const v=`M0 0 \n a${m},${m} 1 0,0 ${.25*w},${-1*C*.1}\n a${m},${m} 1 0,0 ${.25*w},0\n a${m},${m} 1 0,0 ${.25*w},0\n a${m},${m} 1 0,0 ${.25*w},${.1*C}\n\n a${m},${m} 1 0,0 ${.15*w},${.33*C}\n a${.8*m},${.8*m} 1 0,0 0,${.34*C}\n a${m},${m} 1 0,0 ${-1*w*.15},${.33*C}\n\n a${m},${m} 1 0,0 ${-1*w*.25},${.15*C}\n a${m},${m} 1 0,0 ${-1*w*.25},0\n a${m},${m} 1 0,0 ${-1*w*.25},0\n a${m},${m} 1 0,0 ${-1*w*.25},${-1*C*.15}\n\n a${m},${m} 1 0,0 ${-1*w*.1},${-1*C*.33}\n a${.8*m},${.8*m} 1 0,0 0,${-1*C*.34}\n a${m},${m} 1 0,0 ${.1*w},${-1*C*.33}\n H0 V0 Z`;if("handDrawn"===e.look){const t=h.A.svg(a),r=(0,n.Fr)(e,{}),i=t.path(v,r);_=a.insert(()=>i,":first-child"),_.attr("class","basic label-container").attr("style",(0,o.KL)(x))}else _=a.insert("path",":first-child").attr("class","basic label-container").attr("style",i).attr("d",v);return _.attr("transform",`translate(${-w/2}, ${-C/2})`),p(e,_),e.calcIntersect=function(t,e){return P.rect(t,e)},e.intersect=function(t){return l.Rm.info("Bang intersect",e,t),P.rect(e,t)},a}async function xe(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:s,halfPadding:c,label:d}=await u(t,e,f(e)),g=s.width+2*c,y=s.height+2*c,m=.15*g,x=.25*g,b=.35*g,k=.2*g,{cssStyles:w}=e;let C;const _=`M0 0 \n a${m},${m} 0 0,1 ${.25*g},${-1*g*.1}\n a${b},${b} 1 0,1 ${.4*g},${-1*g*.1}\n a${x},${x} 1 0,1 ${.35*g},${.2*g}\n\n a${m},${m} 1 0,1 ${.15*g},${.35*y}\n a${k},${k} 1 0,1 ${-1*g*.15},${.65*y}\n\n a${x},${m} 1 0,1 ${-1*g*.25},${.15*g}\n a${b},${b} 1 0,1 ${-1*g*.5},0\n a${m},${m} 1 0,1 ${-1*g*.25},${-1*g*.15}\n\n a${m},${m} 1 0,1 ${-1*g*.1},${-1*y*.35}\n a${k},${k} 1 0,1 ${.1*g},${-1*y*.65}\n H0 V0 Z`;if("handDrawn"===e.look){const t=h.A.svg(a),r=(0,n.Fr)(e,{}),i=t.path(_,r);C=a.insert(()=>i,":first-child"),C.attr("class","basic label-container").attr("style",(0,o.KL)(w))}else C=a.insert("path",":first-child").attr("class","basic label-container").attr("style",i).attr("d",_);return d.attr("transform",`translate(${-s.width/2}, ${-s.height/2})`),C.attr("transform",`translate(${-g/2}, ${-y/2})`),p(e,C),e.calcIntersect=function(t,e){return P.rect(t,e)},e.intersect=function(t){return l.Rm.info("Cloud intersect",e,t),P.rect(e,t)},a}async function be(t,e){const{labelStyles:r,nodeStyles:i}=(0,n.GX)(e);e.labelStyle=r;const{shapeSvg:a,bbox:o,halfPadding:s,label:l}=await u(t,e,f(e)),c=o.width+8*s,h=o.height+2*s,d=`\n M${-c/2} ${h/2-5}\n v${10-h}\n q0,-5 5,-5\n h${c-10}\n q5,0 5,5\n v${h-10}\n q0,5 -5,5\n h${10-c}\n q-5,0 -5,-5\n Z\n `,g=a.append("path").attr("id","node-"+e.id).attr("class","node-bkg node-"+e.type).attr("style",i).attr("d",d);return a.append("line").attr("class","node-line-").attr("x1",-c/2).attr("y1",h/2).attr("x2",c/2).attr("y2",h/2),l.attr("transform",`translate(${-o.width/2}, ${-o.height/2})`),a.append(()=>l.node()),p(e,g),e.calcIntersect=function(t,e){return P.rect(t,e)},e.intersect=function(t){return P.rect(e,t)},a}async function ke(t,e){return G(t,e,{padding:e.padding??0})}(0,l.K2)(ye,"kanbanItem"),(0,l.K2)(me,"bang"),(0,l.K2)(xe,"cloud"),(0,l.K2)(be,"defaultMindmapNode"),(0,l.K2)(ke,"mindmapCircle");var we=[{semanticName:"Process",name:"Rectangle",shortName:"rect",description:"Standard process shape",aliases:["proc","process","rectangle"],internalAliases:["squareRect"],handler:jt},{semanticName:"Event",name:"Rounded Rectangle",shortName:"rounded",description:"Represents an event",aliases:["event"],internalAliases:["roundedRect"],handler:zt},{semanticName:"Terminal Point",name:"Stadium",shortName:"stadium",description:"Terminal point",aliases:["terminal","pill"],handler:Wt},{semanticName:"Subprocess",name:"Framed Rectangle",shortName:"fr-rect",description:"Subprocess",aliases:["subprocess","subproc","framed-rectangle","subroutine"],handler:Gt},{semanticName:"Database",name:"Cylinder",shortName:"cyl",description:"Database storage",aliases:["db","database","cylinder"],handler:st},{semanticName:"Start",name:"Circle",shortName:"circle",description:"Starting point",aliases:["circ"],handler:G},{semanticName:"Bang",name:"Bang",shortName:"bang",description:"Bang",aliases:["bang"],handler:me},{semanticName:"Cloud",name:"Cloud",shortName:"cloud",description:"cloud",aliases:["cloud"],handler:xe},{semanticName:"Decision",name:"Diamond",shortName:"diam",description:"Decision-making step",aliases:["decision","diamond","question"],handler:Rt},{semanticName:"Prepare Conditional",name:"Hexagon",shortName:"hex",description:"Preparation or condition step",aliases:["hexagon","prepare"],handler:ft},{semanticName:"Data Input/Output",name:"Lean Right",shortName:"lean-r",description:"Represents input or output",aliases:["lean-right","in-out"],internalAliases:["lean_right"],handler:St},{semanticName:"Data Input/Output",name:"Lean Left",shortName:"lean-l",description:"Represents output or input",aliases:["lean-left","out-in"],internalAliases:["lean_left"],handler:vt},{semanticName:"Priority Action",name:"Trapezoid Base Bottom",shortName:"trap-b",description:"Priority action",aliases:["priority","trapezoid-bottom","trapezoid"],handler:re},{semanticName:"Manual Operation",name:"Trapezoid Base Top",shortName:"trap-t",description:"Represents a manual task",aliases:["manual","trapezoid-top","inv-trapezoid"],internalAliases:["inv_trapezoid"],handler:wt},{semanticName:"Stop",name:"Double Circle",shortName:"dbl-circ",description:"Represents a stop point",aliases:["double-circle"],internalAliases:["doublecircle"],handler:ct},{semanticName:"Text Block",name:"Text Block",shortName:"text",description:"Text block",handler:Zt},{semanticName:"Card",name:"Notched Rectangle",shortName:"notch-rect",description:"Represents a card",aliases:["card","notched-rectangle"],handler:U},{semanticName:"Lined/Shaded Process",name:"Lined Rectangle",shortName:"lin-rect",description:"Lined process shape",aliases:["lined-rectangle","lined-process","lin-proc","shaded-process"],handler:Pt},{semanticName:"Start",name:"Small Circle",shortName:"sm-circ",description:"Small starting point",aliases:["start","small-circle"],internalAliases:["stateStart"],handler:Yt},{semanticName:"Stop",name:"Framed Circle",shortName:"fr-circ",description:"Stop point",aliases:["stop","framed-circle"],internalAliases:["stateEnd"],handler:Ut},{semanticName:"Fork/Join",name:"Filled Rectangle",shortName:"fork",description:"Fork or join in process flow",aliases:["join"],internalAliases:["forkJoin"],handler:dt},{semanticName:"Collate",name:"Hourglass",shortName:"hourglass",description:"Represents a collate operation",aliases:["hourglass","collate"],handler:gt},{semanticName:"Comment",name:"Curly Brace",shortName:"brace",description:"Adds a comment",aliases:["comment","brace-l"],handler:Q},{semanticName:"Comment Right",name:"Curly Brace",shortName:"brace-r",description:"Adds a comment",handler:tt},{semanticName:"Comment with braces on both sides",name:"Curly Braces",shortName:"braces",description:"Adds a comment",handler:rt},{semanticName:"Com Link",name:"Lightning Bolt",shortName:"bolt",description:"Communication link",aliases:["com-link","lightning-bolt"],handler:Tt},{semanticName:"Document",name:"Document",shortName:"doc",description:"Represents a document",aliases:["doc","document"],handler:ae},{semanticName:"Delay",name:"Half-Rounded Rectangle",shortName:"delay",description:"Represents a delay",aliases:["half-rounded-rectangle"],handler:pt},{semanticName:"Direct Access Storage",name:"Horizontal Cylinder",shortName:"h-cyl",description:"Direct access storage",aliases:["das","horizontal-cylinder"],handler:ee},{semanticName:"Disk Storage",name:"Lined Cylinder",shortName:"lin-cyl",description:"Disk storage",aliases:["disk","lined-cylinder"],handler:Lt},{semanticName:"Display",name:"Curved Trapezoid",shortName:"curv-trap",description:"Represents a display",aliases:["curved-trapezoid","display"],handler:it},{semanticName:"Divided Process",name:"Divided Rectangle",shortName:"div-rect",description:"Divided process shape",aliases:["div-proc","divided-rectangle","divided-process"],handler:lt},{semanticName:"Extract",name:"Triangle",shortName:"tri",description:"Extraction process",aliases:["extract","triangle"],handler:ne},{semanticName:"Internal Storage",name:"Window Pane",shortName:"win-pane",description:"Internal storage",aliases:["internal-storage","window-pane"],handler:se},{semanticName:"Junction",name:"Filled Circle",shortName:"f-circ",description:"Junction point",aliases:["junction","filled-circle"],handler:ht},{semanticName:"Loop Limit",name:"Trapezoidal Pentagon",shortName:"notch-pent",description:"Loop limit step",aliases:["loop-limit","notched-pentagon"],handler:ie},{semanticName:"Manual File",name:"Flipped Triangle",shortName:"flip-tri",description:"Manual file operation",aliases:["manual-file","flipped-triangle"],handler:ut},{semanticName:"Manual Input",name:"Sloped Rectangle",shortName:"sl-rect",description:"Manual input step",aliases:["manual-input","sloped-rectangle"],handler:qt},{semanticName:"Multi-Document",name:"Stacked Document",shortName:"docs",description:"Multiple documents",aliases:["documents","st-doc","stacked-document"],handler:Et},{semanticName:"Multi-Process",name:"Stacked Rectangle",shortName:"st-rect",description:"Multiple processes",aliases:["procs","processes","stacked-rectangle"],handler:$t},{semanticName:"Stored Data",name:"Bow Tie Rectangle",shortName:"bow-rect",description:"Stored data",aliases:["stored-data","bow-tie-rectangle"],handler:W},{semanticName:"Summary",name:"Crossed Circle",shortName:"cross-circ",description:"Summary",aliases:["summary","crossed-circle"],handler:V},{semanticName:"Tagged Document",name:"Tagged Document",shortName:"tag-doc",description:"Tagged document",aliases:["tag-doc","tagged-document"],handler:Vt},{semanticName:"Tagged Process",name:"Tagged Rectangle",shortName:"tag-rect",description:"Tagged process",aliases:["tagged-rectangle","tag-proc","tagged-process"],handler:Xt},{semanticName:"Paper Tape",name:"Flag",shortName:"flag",description:"Paper tape",aliases:["paper-tape"],handler:oe},{semanticName:"Odd",name:"Odd",shortName:"odd",description:"Odd shape",internalAliases:["rect_left_inv_arrow"],handler:Kt},{semanticName:"Lined Document",name:"Lined Document",shortName:"lin-doc",description:"Lined document",aliases:["lined-document"],handler:Ft}],Ce=(0,l.K2)(()=>{const t={state:Ht,choice:Y,note:Dt,rectWithTitle:It,labelRect:_t,iconSquare:bt,iconCircle:mt,icon:yt,iconRounded:xt,imageSquare:kt,anchor:q,kanbanItem:ye,mindmapCircle:ke,defaultMindmapNode:be,classBox:de,erBox:le,requirementBox:pe},e=[...Object.entries(t),...we.flatMap(t=>[t.shortName,..."aliases"in t?t.aliases:[],..."internalAliases"in t?t.internalAliases:[]].map(e=>[e,t.handler]))];return Object.fromEntries(e)},"generateShapeMap")();function _e(t){return t in Ce}(0,l.K2)(_e,"isValidShape");var ve=new Map;async function Se(t,e,r){let i,n;"rect"===e.shape&&(e.rx&&e.ry?e.shape="roundedRect":e.shape="squareRect");const a=e.shape?Ce[e.shape]:void 0;if(!a)throw new Error(`No such shape: ${e.shape}. Please check your syntax.`);if(e.link){let o;"sandbox"===r.config.securityLevel?o="_top":e.linkTarget&&(o=e.linkTarget||"_blank"),i=t.insert("svg:a").attr("xlink:href",e.link).attr("target",o??null),n=await a(i,e,r)}else n=await a(t,e,r),i=n;return e.tooltip&&n.attr("title",e.tooltip),ve.set(e.id,i),e.haveCallback&&i.attr("class",i.attr("class")+" clickable"),i}(0,l.K2)(Se,"insertNode");var Te=(0,l.K2)((t,e)=>{ve.set(e.id,t)},"setNodeElem"),Ae=(0,l.K2)(()=>{ve.clear()},"clear"),Me=(0,l.K2)(t=>{const e=ve.get(t.id);l.Rm.trace("Transforming node",t.diff,t,"translate("+(t.x-t.width/2-5)+", "+t.width/2+")");const r=t.diff||0;return t.clusterNode?e.attr("transform","translate("+(t.x+r-t.width/2)+", "+(t.y-t.height/2-8)+")"):e.attr("transform","translate("+t.x+", "+t.y+")"),r},"positionNode")},6832:(t,e,r)=>{"use strict";r.d(e,{A:()=>s});var i=r(66984),n=r(38446),a=r(25353),o=r(23149);const s=function(t,e,r){if(!(0,o.A)(r))return!1;var s=typeof e;return!!("number"==s?(0,n.A)(r)&&(0,a.A)(e,r.length):"string"==s&&e in r)&&(0,i.A)(r[e],t)}},8232:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var i=r(72453),n=r(74886);const a=(t,e)=>{const r=n.A.parse(t);for(const n in e)r[n]=i.A.channel.clamp[n](e[n]);return n.A.stringify(r)}},9779:(t,e,r)=>{"use strict";r.d(e,{A:()=>_});var i=r(18744),n=r(41917);const a=(0,i.A)(n.A,"DataView");var o=r(68335);const s=(0,i.A)(n.A,"Promise");var l=r(39857);const c=(0,i.A)(n.A,"WeakMap");var h=r(88496),u=r(81121),d="[object Map]",p="[object Promise]",f="[object Set]",g="[object WeakMap]",y="[object DataView]",m=(0,u.A)(a),x=(0,u.A)(o.A),b=(0,u.A)(s),k=(0,u.A)(l.A),w=(0,u.A)(c),C=h.A;(a&&C(new a(new ArrayBuffer(1)))!=y||o.A&&C(new o.A)!=d||s&&C(s.resolve())!=p||l.A&&C(new l.A)!=f||c&&C(new c)!=g)&&(C=function(t){var e=(0,h.A)(t),r="[object Object]"==e?t.constructor:void 0,i=r?(0,u.A)(r):"";if(i)switch(i){case m:return y;case x:return d;case b:return p;case k:return f;case w:return g}return e});const _=C},10045:(t,e,r)=>{"use strict";r.d(e,{XX:()=>u,q7:()=>d,sO:()=>h});var i=r(5164),n=r(5894),a=r(13226),o=r(67633),s=r(40797),l={common:o.Y2,getConfig:o.zj,insertCluster:n.U,insertEdge:i.Jo,insertEdgeLabel:i.jP,insertMarkers:i.g0,insertNode:n.on,interpolateToCurve:a.Ib,labelHelper:n.Zk,log:s.Rm,positionEdgeLabel:i.T_},c={},h=(0,s.K2)(t=>{for(const e of t)c[e.name]=e},"registerLayoutLoaders");(0,s.K2)(()=>{h([{name:"dagre",loader:(0,s.K2)(async()=>await Promise.all([r.e(3624),r.e(2334),r.e(7873)]).then(r.bind(r,57873)),"loader")},{name:"cose-bilkent",loader:(0,s.K2)(async()=>await Promise.all([r.e(165),r.e(7928)]).then(r.bind(r,77928)),"loader")}])},"registerDefaultLayoutLoaders")();var u=(0,s.K2)(async(t,e)=>{if(!(t.layoutAlgorithm in c))throw new Error(`Unknown layout algorithm: ${t.layoutAlgorithm}`);const r=c[t.layoutAlgorithm];return(await r.loader()).render(t,e,l,{algorithm:r.algorithm})},"render"),d=(0,s.K2)((t="",{fallback:e="dagre"}={})=>{if(t in c)return t;if(e in c)return s.Rm.warn(`Layout algorithm ${t} is not registered. Using ${e} as fallback.`),e;throw new Error(`Both layout algorithms ${t} and ${e} are not registered.`)},"getRegisteredLayoutAlgorithm")},11754:(t,e,r)=>{"use strict";r.d(e,{A:()=>d});var i=r(80127);const n=function(){this.__data__=new i.A,this.size=0};const a=function(t){var e=this.__data__,r=e.delete(t);return this.size=e.size,r};const o=function(t){return this.__data__.get(t)};const s=function(t){return this.__data__.has(t)};var l=r(68335),c=r(29471);const h=function(t,e){var r=this.__data__;if(r instanceof i.A){var n=r.__data__;if(!l.A||n.length<199)return n.push([t,e]),this.size=++r.size,this;r=this.__data__=new c.A(n)}return r.set(t,e),this.size=r.size,this};function u(t){var e=this.__data__=new i.A(t);this.size=e.size}u.prototype.clear=n,u.prototype.delete=a,u.prototype.get=o,u.prototype.has=s,u.prototype.set=h;const d=u},13226:(t,e,r)=>{"use strict";r.d(e,{$C:()=>M,$t:()=>W,C4:()=>U,I5:()=>j,Ib:()=>y,KL:()=>X,Sm:()=>Y,Un:()=>R,_K:()=>H,bH:()=>E,dq:()=>P,pe:()=>c,rY:()=>G,ru:()=>O,sM:()=>T,vU:()=>f,yT:()=>L});var i=r(67633),n=r(40797),a=r(16750),o=r(70451),s=r(46632),l=r(42837),c="\u200b",h={curveBasis:o.qrM,curveBasisClosed:o.Yu4,curveBasisOpen:o.IA3,curveBumpX:o.Wi0,curveBumpY:o.PGM,curveBundle:o.OEq,curveCardinalClosed:o.olC,curveCardinalOpen:o.IrU,curveCardinal:o.y8u,curveCatmullRomClosed:o.Q7f,curveCatmullRomOpen:o.cVp,curveCatmullRom:o.oDi,curveLinear:o.lUB,curveLinearClosed:o.Lx9,curveMonotoneX:o.nVG,curveMonotoneY:o.uxU,curveNatural:o.Xf2,curveStep:o.GZz,curveStepAfter:o.UPb,curveStepBefore:o.dyv},u=/\s*(?:(\w+)(?=:):|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,d=(0,n.K2)(function(t,e){const r=p(t,/(?:init\b)|(?:initialize\b)/);let n={};if(Array.isArray(r)){const t=r.map(t=>t.args);(0,i.$i)(t),n=(0,i.hH)(n,[...t])}else n=r.args;if(!n)return;let a=(0,i.Ch)(t,e);const o="config";return void 0!==n[o]&&("flowchart-v2"===a&&(a="flowchart"),n[a]=n[o],delete n[o]),n},"detectInit"),p=(0,n.K2)(function(t,e=null){try{const r=new RegExp(`[%]{2}(?![{]${u.source})(?=[}][%]{2}).*\n`,"ig");let a;t=t.trim().replace(r,"").replace(/'/gm,'"'),n.Rm.debug(`Detecting diagram directive${null!==e?" type:"+e:""} based on the text:${t}`);const o=[];for(;null!==(a=i.DB.exec(t));)if(a.index===i.DB.lastIndex&&i.DB.lastIndex++,a&&!e||e&&a[1]?.match(e)||e&&a[2]?.match(e)){const t=a[1]?a[1]:a[2],e=a[3]?a[3].trim():a[4]?JSON.parse(a[4].trim()):null;o.push({type:t,args:e})}return 0===o.length?{type:t,args:null}:1===o.length?o[0]:o}catch(r){return n.Rm.error(`ERROR: ${r.message} - Unable to parse directive type: '${e}' based on the text: '${t}'`),{type:void 0,args:null}}},"detectDirective"),f=(0,n.K2)(function(t){return t.replace(i.DB,"")},"removeDirectives"),g=(0,n.K2)(function(t,e){for(const[r,i]of e.entries())if(i.match(t))return r;return-1},"isSubstringInArray");function y(t,e){if(!t)return e;const r=`curve${t.charAt(0).toUpperCase()+t.slice(1)}`;return h[r]??e}function m(t,e){const r=t.trim();if(r)return"loose"!==e.securityLevel?(0,a.J)(r):r}(0,n.K2)(y,"interpolateToCurve"),(0,n.K2)(m,"formatUrl");var x=(0,n.K2)((t,...e)=>{const r=t.split("."),i=r.length-1,a=r[i];let o=window;for(let s=0;s<i;s++)if(o=o[r[s]],!o)return void n.Rm.error(`Function name: ${t} not found in window`);o[a](...e)},"runFunc");function b(t,e){return t&&e?Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2)):0}function k(t){let e,r=0;t.forEach(t=>{r+=b(t,e),e=t});return _(t,r/2)}function w(t){return 1===t.length?t[0]:k(t)}(0,n.K2)(b,"distance"),(0,n.K2)(k,"traverseEdge"),(0,n.K2)(w,"calcLabelPosition");var C=(0,n.K2)((t,e=2)=>{const r=Math.pow(10,e);return Math.round(t*r)/r},"roundNumber"),_=(0,n.K2)((t,e)=>{let r,i=e;for(const n of t){if(r){const t=b(n,r);if(0===t)return r;if(t<i)i-=t;else{const e=i/t;if(e<=0)return r;if(e>=1)return{x:n.x,y:n.y};if(e>0&&e<1)return{x:C((1-e)*r.x+e*n.x,5),y:C((1-e)*r.y+e*n.y,5)}}}r=n}throw new Error("Could not find a suitable point for the given distance")},"calculatePoint"),v=(0,n.K2)((t,e,r)=>{n.Rm.info(`our points ${JSON.stringify(e)}`),e[0]!==r&&(e=e.reverse());const i=_(e,25),a=t?10:5,o=Math.atan2(e[0].y-i.y,e[0].x-i.x),s={x:0,y:0};return s.x=Math.sin(o)*a+(e[0].x+i.x)/2,s.y=-Math.cos(o)*a+(e[0].y+i.y)/2,s},"calcCardinalityPosition");function S(t,e,r){const i=structuredClone(r);n.Rm.info("our points",i),"start_left"!==e&&"start_right"!==e&&i.reverse();const a=_(i,25+t),o=10+.5*t,s=Math.atan2(i[0].y-a.y,i[0].x-a.x),l={x:0,y:0};return"start_left"===e?(l.x=Math.sin(s+Math.PI)*o+(i[0].x+a.x)/2,l.y=-Math.cos(s+Math.PI)*o+(i[0].y+a.y)/2):"end_right"===e?(l.x=Math.sin(s-Math.PI)*o+(i[0].x+a.x)/2-5,l.y=-Math.cos(s-Math.PI)*o+(i[0].y+a.y)/2-5):"end_left"===e?(l.x=Math.sin(s)*o+(i[0].x+a.x)/2-5,l.y=-Math.cos(s)*o+(i[0].y+a.y)/2-5):(l.x=Math.sin(s)*o+(i[0].x+a.x)/2,l.y=-Math.cos(s)*o+(i[0].y+a.y)/2),l}function T(t){let e="",r="";for(const i of t)void 0!==i&&(i.startsWith("color:")||i.startsWith("text-align:")?r=r+i+";":e=e+i+";");return{style:e,labelStyle:r}}(0,n.K2)(S,"calcTerminalLabelPosition"),(0,n.K2)(T,"getStylesFromArray");var A=0,M=(0,n.K2)(()=>(A++,"id-"+Math.random().toString(36).substr(2,12)+"-"+A),"generateId");function B(t){let e="";const r="0123456789abcdef";for(let i=0;i<t;i++)e+=r.charAt(Math.floor(16*Math.random()));return e}(0,n.K2)(B,"makeRandomHex");var L=(0,n.K2)(t=>B(t.length),"random"),F=(0,n.K2)(function(){return{x:0,y:0,fill:void 0,anchor:"start",style:"#666",width:100,height:100,textMargin:0,rx:0,ry:0,valign:void 0,text:""}},"getTextObj"),$=(0,n.K2)(function(t,e){const r=e.text.replace(i.Y2.lineBreakRegex," "),[,n]=j(e.fontSize),a=t.append("text");a.attr("x",e.x),a.attr("y",e.y),a.style("text-anchor",e.anchor),a.style("font-family",e.fontFamily),a.style("font-size",n),a.style("font-weight",e.fontWeight),a.attr("fill",e.fill),void 0!==e.class&&a.attr("class",e.class);const o=a.append("tspan");return o.attr("x",e.x+2*e.textMargin),o.attr("fill",e.fill),o.text(r),a},"drawSimpleText"),E=(0,s.A)((t,e,r)=>{if(!t)return t;if(r=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",joinWith:"<br/>"},r),i.Y2.lineBreakRegex.test(t))return t;const n=t.split(" ").filter(Boolean),a=[];let o="";return n.forEach((t,i)=>{const s=R(`${t} `,r),l=R(o,r);if(s>e){const{hyphenatedStrings:i,remainingWord:n}=D(t,e,"-",r);a.push(o,...i),o=n}else l+s>=e?(a.push(o),o=t):o=[o,t].filter(Boolean).join(" ");i+1===n.length&&a.push(o)}),a.filter(t=>""!==t).join(r.joinWith)},(t,e,r)=>`${t}${e}${r.fontSize}${r.fontWeight}${r.fontFamily}${r.joinWith}`),D=(0,s.A)((t,e,r="-",i)=>{i=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:0},i);const n=[...t],a=[];let o="";return n.forEach((t,s)=>{const l=`${o}${t}`;if(R(l,i)>=e){const t=s+1,e=n.length===t,i=`${l}${r}`;a.push(e?l:i),o=""}else o=l}),{hyphenatedStrings:a,remainingWord:o}},(t,e,r="-",i)=>`${t}${e}${r}${i.fontSize}${i.fontWeight}${i.fontFamily}`);function O(t,e){return I(t,e).height}function R(t,e){return I(t,e).width}(0,n.K2)(O,"calculateTextHeight"),(0,n.K2)(R,"calculateTextWidth");var K,I=(0,s.A)((t,e)=>{const{fontSize:r=12,fontFamily:n="Arial",fontWeight:a=400}=e;if(!t)return{width:0,height:0};const[,s]=j(r),l=["sans-serif",n],h=t.split(i.Y2.lineBreakRegex),u=[],d=(0,o.Ltv)("body");if(!d.remove)return{width:0,height:0,lineHeight:0};const p=d.append("svg");for(const i of l){let t=0;const e={width:0,height:0,lineHeight:0};for(const r of h){const n=F();n.text=r||c;const o=$(p,n).style("font-size",s).style("font-weight",a).style("font-family",i),l=(o._groups||o)[0][0].getBBox();if(0===l.width&&0===l.height)throw new Error("svg element not in render tree");e.width=Math.round(Math.max(e.width,l.width)),t=Math.round(l.height),e.height+=t,e.lineHeight=Math.round(Math.max(e.lineHeight,t))}u.push(e)}p.remove();return u[isNaN(u[1].height)||isNaN(u[1].width)||isNaN(u[1].lineHeight)||u[0].height>u[1].height&&u[0].width>u[1].width&&u[0].lineHeight>u[1].lineHeight?0:1]},(t,e)=>`${t}${e.fontSize}${e.fontWeight}${e.fontFamily}`),N=class{constructor(t=!1,e){this.count=0,this.count=e?e.length:0,this.next=t?()=>this.count++:()=>Date.now()}static{(0,n.K2)(this,"InitIDGenerator")}},z=(0,n.K2)(function(t){return K=K||document.createElement("div"),t=escape(t).replace(/%26/g,"&").replace(/%23/g,"#").replace(/%3B/g,";"),K.innerHTML=t,unescape(K.textContent)},"entityDecode");function P(t){return"str"in t}(0,n.K2)(P,"isDetailedError");var q=(0,n.K2)((t,e,r,i)=>{if(!i)return;const n=t.node()?.getBBox();n&&t.append("text").text(i).attr("text-anchor","middle").attr("x",n.x+n.width/2).attr("y",-r).attr("class",e)},"insertTitle"),j=(0,n.K2)(t=>{if("number"==typeof t)return[t,t+"px"];const e=parseInt(t??"",10);return Number.isNaN(e)?[void 0,void 0]:t===String(e)?[e,t+"px"]:[e,t]},"parseFontSize");function W(t,e){return(0,l.A)({},t,e)}(0,n.K2)(W,"cleanAndMerge");var H={assignWithDepth:i.hH,wrapLabel:E,calculateTextHeight:O,calculateTextWidth:R,calculateTextDimensions:I,cleanAndMerge:W,detectInit:d,detectDirective:p,isSubstringInArray:g,interpolateToCurve:y,calcLabelPosition:w,calcCardinalityPosition:v,calcTerminalLabelPosition:S,formatUrl:m,getStylesFromArray:T,generateId:M,random:L,runFunc:x,entityDecode:z,insertTitle:q,isLabelCoordinateInPath:V,parseFontSize:j,InitIDGenerator:N},U=(0,n.K2)(function(t){let e=t;return e=e.replace(/style.*:\S*#.*;/g,function(t){return t.substring(0,t.length-1)}),e=e.replace(/classDef.*:\S*#.*;/g,function(t){return t.substring(0,t.length-1)}),e=e.replace(/#\w+;/g,function(t){const e=t.substring(1,t.length-1);return/^\+?\d+$/.test(e)?"\ufb02\xb0\xb0"+e+"\xb6\xdf":"\ufb02\xb0"+e+"\xb6\xdf"}),e},"encodeEntities"),Y=(0,n.K2)(function(t){return t.replace(/\ufb02\xb0\xb0/g,"&#").replace(/\ufb02\xb0/g,"&").replace(/\xb6\xdf/g,";")},"decodeEntities"),G=(0,n.K2)((t,e,{counter:r=0,prefix:i,suffix:n},a)=>a||`${i?`${i}_`:""}${t}_${e}_${r}${n?`_${n}`:""}`,"getEdgeId");function X(t){return t??null}function V(t,e){const r=Math.round(t.x),i=Math.round(t.y),n=e.replace(/(\d+\.\d+)/g,t=>Math.round(parseFloat(t)).toString());return n.includes(r.toString())||n.includes(i.toString())}(0,n.K2)(X,"handleUndefinedAttr"),(0,n.K2)(V,"isLabelCoordinateInPath")},15647:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});const i=(0,r(40367).A)(Object.getPrototypeOf,Object)},16750:(t,e,r)=>{"use strict";e.J=void 0;var i=r(69119);function n(t){return t.replace(i.ctrlCharactersRegex,"").replace(i.htmlEntitiesRegex,function(t,e){return String.fromCharCode(e)})}function a(t){try{return decodeURIComponent(t)}catch(e){return t}}e.J=function(t){if(!t)return i.BLANK_URL;var e,r=a(t.trim());do{e=(r=a(r=n(r).replace(i.htmlCtrlEntityRegex,"").replace(i.ctrlCharactersRegex,"").replace(i.whitespaceEscapeCharsRegex,"").trim())).match(i.ctrlCharactersRegex)||r.match(i.htmlEntitiesRegex)||r.match(i.htmlCtrlEntityRegex)||r.match(i.whitespaceEscapeCharsRegex)}while(e&&e.length>0);var o=r;if(!o)return i.BLANK_URL;if(function(t){return i.relativeFirstCharacters.indexOf(t[0])>-1}(o))return o;var s=o.trimStart(),l=s.match(i.urlSchemeRegex);if(!l)return o;var c=l[0].toLowerCase().trim();if(i.invalidProtocolRegex.test(c))return i.BLANK_URL;var h=s.replace(/\\/g,"/");if("mailto:"===c||c.includes("://"))return h;if("http:"===c||"https:"===c){if(!function(t){return URL.canParse(t)}(h))return i.BLANK_URL;var u=new URL(h);return u.protocol=u.protocol.toLowerCase(),u.hostname=u.hostname.toLowerCase(),u.toString()}return h}},18598:(t,e,r)=>{"use strict";r.d(e,{A:()=>l});var i=r(23149),n=Object.create;const a=function(){function t(){}return function(e){if(!(0,i.A)(e))return{};if(n)return n(e);t.prototype=e;var r=new t;return t.prototype=void 0,r}}();var o=r(15647),s=r(97271);const l=function(t){return"function"!=typeof t.constructor||(0,s.A)(t)?{}:a((0,o.A)(t))}},18744:(t,e,r)=>{"use strict";r.d(e,{A:()=>x});var i=r(89610);const n=r(41917).A["__core-js_shared__"];var a,o=(a=/[^.]+$/.exec(n&&n.keys&&n.keys.IE_PROTO||""))?"Symbol(src)_1."+a:"";const s=function(t){return!!o&&o in t};var l=r(23149),c=r(81121),h=/^\[object .+?Constructor\]$/,u=Function.prototype,d=Object.prototype,p=u.toString,f=d.hasOwnProperty,g=RegExp("^"+p.call(f).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");const y=function(t){return!(!(0,l.A)(t)||s(t))&&((0,i.A)(t)?g:h).test((0,c.A)(t))};const m=function(t,e){return null==t?void 0:t[e]};const x=function(t,e){var r=m(t,e);return y(r)?r:void 0}},22031:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var i=r(52851),n=r(52528);const a=function(t,e,r,a){var o=!r;r||(r={});for(var s=-1,l=e.length;++s<l;){var c=e[s],h=a?a(r[c],t[c],c,r,t):void 0;void 0===h&&(h=t[c]),o?(0,n.A)(r,c,h):(0,i.A)(r,c,h)}return r}},22279:(t,e,r)=>{"use strict";r.r(e),r.d(e,{default:()=>Ge});var i=r(42467),n=r(73590),a=r(73981),o=r(10045),s=(r(5164),r(28698),r(5894),r(63245),r(32387),r(30092)),l=r(13226),c=r(67633),h=r(40797),u=r(60513),d=r(70451),p="comm",f="rule",g="decl",y=Math.abs,m=String.fromCharCode;Object.assign;function x(t){return t.trim()}function b(t,e,r){return t.replace(e,r)}function k(t,e,r){return t.indexOf(e,r)}function w(t,e){return 0|t.charCodeAt(e)}function C(t,e,r){return t.slice(e,r)}function _(t){return t.length}function v(t,e){return e.push(t),t}function S(t,e){for(var r="",i=0;i<t.length;i++)r+=e(t[i],i,t,e)||"";return r}function T(t,e,r,i){switch(t.type){case"@layer":if(t.children.length)break;case"@import":case"@namespace":case g:return t.return=t.return||t.value;case p:return"";case"@keyframes":return t.return=t.value+"{"+S(t.children,i)+"}";case f:if(!_(t.value=t.props.join(",")))return""}return _(r=S(t.children,i))?t.return=t.value+"{"+r+"}":""}var A=1,M=1,B=0,L=0,F=0,$="";function E(t,e,r,i,n,a,o,s){return{value:t,root:e,parent:r,type:i,props:n,children:a,line:A,column:M,length:o,return:"",siblings:s}}function D(){return F=L>0?w($,--L):0,M--,10===F&&(M=1,A--),F}function O(){return F=L<B?w($,L++):0,M++,10===F&&(M=1,A++),F}function R(){return w($,L)}function K(){return L}function I(t,e){return C($,t,e)}function N(t){switch(t){case 0:case 9:case 10:case 13:case 32:return 5;case 33:case 43:case 44:case 47:case 62:case 64:case 126:case 59:case 123:case 125:return 4;case 58:return 3;case 34:case 39:case 40:case 91:return 2;case 41:case 93:return 1}return 0}function z(t){return A=M=1,B=_($=t),L=0,[]}function P(t){return $="",t}function q(t){return x(I(L-1,H(91===t?t+2:40===t?t+1:t)))}function j(t){for(;(F=R())&&F<33;)O();return N(t)>2||N(F)>3?"":" "}function W(t,e){for(;--e&&O()&&!(F<48||F>102||F>57&&F<65||F>70&&F<97););return I(t,K()+(e<6&&32==R()&&32==O()))}function H(t){for(;O();)switch(F){case t:return L;case 34:case 39:34!==t&&39!==t&&H(F);break;case 40:41===t&&H(t);break;case 92:O()}return L}function U(t,e){for(;O()&&t+F!==57&&(t+F!==84||47!==R()););return"/*"+I(e,L-1)+"*"+m(47===t?t:O())}function Y(t){for(;!N(R());)O();return I(t,L)}function G(t){return P(X("",null,null,null,[""],t=z(t),0,[0],t))}function X(t,e,r,i,n,a,o,s,l){for(var c=0,h=0,u=o,d=0,p=0,f=0,g=1,x=1,S=1,T=0,A="",M=n,B=a,L=i,F=A;x;)switch(f=T,T=O()){case 40:if(108!=f&&58==w(F,u-1)){-1!=k(F+=b(q(T),"&","&\f"),"&\f",y(c?s[c-1]:0))&&(S=-1);break}case 34:case 39:case 91:F+=q(T);break;case 9:case 10:case 13:case 32:F+=j(f);break;case 92:F+=W(K()-1,7);continue;case 47:switch(R()){case 42:case 47:v(Z(U(O(),K()),e,r,l),l),5!=N(f||1)&&5!=N(R()||1)||!_(F)||" "===C(F,-1,void 0)||(F+=" ");break;default:F+="/"}break;case 123*g:s[c++]=_(F)*S;case 125*g:case 59:case 0:switch(T){case 0:case 125:x=0;case 59+h:-1==S&&(F=b(F,/\f/g,"")),p>0&&(_(F)-u||0===g&&47===f)&&v(p>32?Q(F+";",i,r,u-1,l):Q(b(F," ","")+";",i,r,u-2,l),l);break;case 59:F+=";";default:if(v(L=V(F,e,r,c,h,n,s,A,M=[],B=[],u,a),a),123===T)if(0===h)X(F,e,L,L,M,a,u,s,B);else{switch(d){case 99:if(110===w(F,3))break;case 108:if(97===w(F,2))break;default:h=0;case 100:case 109:case 115:}h?X(t,L,L,i&&v(V(t,L,L,0,0,n,s,A,n,M=[],u,B),B),n,B,u,s,i?M:B):X(F,L,L,L,[""],B,0,s,B)}}c=h=p=0,g=S=1,A=F="",u=o;break;case 58:u=1+_(F),p=f;default:if(g<1)if(123==T)--g;else if(125==T&&0==g++&&125==D())continue;switch(F+=m(T),T*g){case 38:S=h>0?1:(F+="\f",-1);break;case 44:s[c++]=(_(F)-1)*S,S=1;break;case 64:45===R()&&(F+=q(O())),d=R(),h=u=_(A=F+=Y(K())),T++;break;case 45:45===f&&2==_(F)&&(g=0)}}return a}function V(t,e,r,i,n,a,o,s,l,c,h,u){for(var d=n-1,p=0===n?a:[""],g=function(t){return t.length}(p),m=0,k=0,w=0;m<i;++m)for(var _=0,v=C(t,d+1,d=y(k=o[m])),S=t;_<g;++_)(S=x(k>0?p[_]+" "+v:b(v,/&\f/g,p[_])))&&(l[w++]=S);return E(t,e,r,0===n?f:s,l,c,h,u)}function Z(t,e,r,i){return E(t,e,r,p,m(F),C(t,2,-2),0,i)}function Q(t,e,r,i,n){return E(t,e,r,g,C(t,0,i),C(t,i+1,-1),i,n)}var J=r(99418),tt=r(66401),et={id:"c4",detector:(0,h.K2)(t=>/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await r.e(4981).then(r.bind(r,54981));return{id:"c4",diagram:t}},"loader")},rt="flowchart",it={id:rt,detector:(0,h.K2)((t,e)=>"dagre-wrapper"!==e?.flowchart?.defaultRenderer&&"elk"!==e?.flowchart?.defaultRenderer&&/^\s*graph/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await r.e(2291).then(r.bind(r,22291));return{id:rt,diagram:t}},"loader")},nt="flowchart-v2",at={id:nt,detector:(0,h.K2)((t,e)=>"dagre-d3"!==e?.flowchart?.defaultRenderer&&("elk"===e?.flowchart?.defaultRenderer&&(e.layout="elk"),!(!/^\s*graph/.test(t)||"dagre-wrapper"!==e?.flowchart?.defaultRenderer)||/^\s*flowchart/.test(t)),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await r.e(2291).then(r.bind(r,22291));return{id:nt,diagram:t}},"loader")},ot={id:"er",detector:(0,h.K2)(t=>/^\s*erDiagram/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await r.e(8756).then(r.bind(r,8756));return{id:"er",diagram:t}},"loader")},st="gitGraph",lt={id:st,detector:(0,h.K2)(t=>/^\s*gitGraph/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(8731),r.e(6319)]).then(r.bind(r,66319));return{id:st,diagram:t}},"loader")},ct="gantt",ht={id:ct,detector:(0,h.K2)(t=>/^\s*gantt/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await r.e(4379).then(r.bind(r,64379));return{id:ct,diagram:t}},"loader")},ut="info",dt={id:ut,detector:(0,h.K2)(t=>/^\s*info/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(8731),r.e(3488)]).then(r.bind(r,93488));return{id:ut,diagram:t}},"loader")},pt={id:"pie",detector:(0,h.K2)(t=>/^\s*pie/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(8731),r.e(9412)]).then(r.bind(r,69412));return{id:"pie",diagram:t}},"loader")},ft="quadrantChart",gt={id:ft,detector:(0,h.K2)(t=>/^\s*quadrantChart/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await r.e(1203).then(r.bind(r,51203));return{id:ft,diagram:t}},"loader")},yt="xychart",mt={id:yt,detector:(0,h.K2)(t=>/^\s*xychart(-beta)?/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await r.e(5955).then(r.bind(r,45955));return{id:yt,diagram:t}},"loader")},xt="requirement",bt={id:xt,detector:(0,h.K2)(t=>/^\s*requirement(Diagram)?/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await r.e(3003).then(r.bind(r,29032));return{id:xt,diagram:t}},"loader")},kt="sequence",wt={id:kt,detector:(0,h.K2)(t=>/^\s*sequenceDiagram/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await r.e(7592).then(r.bind(r,17592));return{id:kt,diagram:t}},"loader")},Ct="class",_t={id:Ct,detector:(0,h.K2)((t,e)=>"dagre-wrapper"!==e?.class?.defaultRenderer&&/^\s*classDiagram/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await Promise.all([r.e(1746),r.e(9510)]).then(r.bind(r,29510));return{id:Ct,diagram:t}},"loader")},vt="classDiagram",St={id:vt,detector:(0,h.K2)((t,e)=>!(!/^\s*classDiagram/.test(t)||"dagre-wrapper"!==e?.class?.defaultRenderer)||/^\s*classDiagram-v2/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await Promise.all([r.e(1746),r.e(3815)]).then(r.bind(r,53815));return{id:vt,diagram:t}},"loader")},Tt="state",At={id:Tt,detector:(0,h.K2)((t,e)=>"dagre-wrapper"!==e?.state?.defaultRenderer&&/^\s*stateDiagram/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(2334),r.e(2235),r.e(8142)]).then(r.bind(r,88142));return{id:Tt,diagram:t}},"loader")},Mt="stateDiagram",Bt={id:Mt,detector:(0,h.K2)((t,e)=>!!/^\s*stateDiagram-v2/.test(t)||!(!/^\s*stateDiagram/.test(t)||"dagre-wrapper"!==e?.state?.defaultRenderer),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await Promise.all([r.e(2235),r.e(4802)]).then(r.bind(r,84802));return{id:Mt,diagram:t}},"loader")},Lt="journey",Ft={id:Lt,detector:(0,h.K2)(t=>/^\s*journey/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await r.e(5480).then(r.bind(r,45480));return{id:Lt,diagram:t}},"loader")},$t={draw:(0,h.K2)((t,e,r)=>{h.Rm.debug("rendering svg for syntax error\n");const i=(0,n.D)(e),a=i.append("g");i.attr("viewBox","0 0 2412 512"),(0,c.a$)(i,100,512,!0),a.append("path").attr("class","error-icon").attr("d","m411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z"),a.append("path").attr("class","error-icon").attr("d","m459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z"),a.append("path").attr("class","error-icon").attr("d","m340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z"),a.append("path").attr("class","error-icon").attr("d","m400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z"),a.append("path").attr("class","error-icon").attr("d","m496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z"),a.append("path").attr("class","error-icon").attr("d","m436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z"),a.append("text").attr("class","error-text").attr("x",1440).attr("y",250).attr("font-size","150px").style("text-anchor","middle").text("Syntax error in text"),a.append("text").attr("class","error-text").attr("x",1250).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text(`mermaid version ${r}`)},"draw")},Et=$t,Dt={db:{},renderer:$t,parser:{parse:(0,h.K2)(()=>{},"parse")}},Ot="flowchart-elk",Rt={id:Ot,detector:(0,h.K2)((t,e={})=>!!(/^\s*flowchart-elk/.test(t)||/^\s*(flowchart|graph)/.test(t)&&"elk"===e?.flowchart?.defaultRenderer)&&(e.layout="elk",!0),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await r.e(2291).then(r.bind(r,22291));return{id:Ot,diagram:t}},"loader")},Kt="timeline",It={id:Kt,detector:(0,h.K2)(t=>/^\s*timeline/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await r.e(291).then(r.bind(r,50291));return{id:Kt,diagram:t}},"loader")},Nt="mindmap",zt={id:Nt,detector:(0,h.K2)(t=>/^\s*mindmap/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await r.e(8565).then(r.bind(r,78565));return{id:Nt,diagram:t}},"loader")},Pt="kanban",qt={id:Pt,detector:(0,h.K2)(t=>/^\s*kanban/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await r.e(6241).then(r.bind(r,16241));return{id:Pt,diagram:t}},"loader")},jt="sankey",Wt={id:jt,detector:(0,h.K2)(t=>/^\s*sankey(-beta)?/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await r.e(1741).then(r.bind(r,11741));return{id:jt,diagram:t}},"loader")},Ht="packet",Ut={id:Ht,detector:(0,h.K2)(t=>/^\s*packet(-beta)?/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(8731),r.e(8948)]).then(r.bind(r,16567));return{id:Ht,diagram:t}},"loader")},Yt="radar",Gt={id:Yt,detector:(0,h.K2)(t=>/^\s*radar-beta/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(8731),r.e(6992)]).then(r.bind(r,16992));return{id:Yt,diagram:t}},"loader")},Xt="block",Vt={id:Xt,detector:(0,h.K2)(t=>/^\s*block(-beta)?/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(5996)]).then(r.bind(r,65996));return{id:Xt,diagram:t}},"loader")},Zt="architecture",Qt={id:Zt,detector:(0,h.K2)(t=>/^\s*architecture/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(8731),r.e(165),r.e(8249)]).then(r.bind(r,8249));return{id:Zt,diagram:t}},"loader")},Jt="treemap",te={id:Jt,detector:(0,h.K2)(t=>/^\s*treemap/.test(t),"detector"),loader:(0,h.K2)(async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(8731),r.e(2821)]).then(r.bind(r,82821));return{id:Jt,diagram:t}},"loader")},ee=!1,re=(0,h.K2)(()=>{ee||(ee=!0,(0,c.Js)("error",Dt,t=>"error"===t.toLowerCase().trim()),(0,c.Js)("---",{db:{clear:(0,h.K2)(()=>{},"clear")},styles:{},renderer:{draw:(0,h.K2)(()=>{},"draw")},parser:{parse:(0,h.K2)(()=>{throw new Error("Diagrams beginning with --- are not valid. If you were trying to use a YAML front-matter, please ensure that you've correctly opened and closed the YAML front-matter with un-indented `---` blocks")},"parse")},init:(0,h.K2)(()=>null,"init")},t=>t.toLowerCase().trimStart().startsWith("---")),(0,c.Xd)(Rt,zt,Qt),(0,c.Xd)(et,qt,St,_t,ot,ht,dt,pt,bt,wt,at,it,It,lt,Bt,At,Ft,gt,Wt,Ut,mt,Vt,Gt,te))},"addDiagrams"),ie=(0,h.K2)(async()=>{h.Rm.debug("Loading registered diagrams");const t=(await Promise.allSettled(Object.entries(c.mW).map(async([t,{detector:e,loader:r}])=>{if(r)try{(0,c.Gs)(t)}catch{try{const{diagram:t,id:i}=await r();(0,c.Js)(i,t,e)}catch(i){throw h.Rm.error(`Failed to load external diagram with key ${t}. Removing from detectors.`),delete c.mW[t],i}}}))).filter(t=>"rejected"===t.status);if(t.length>0){h.Rm.error(`Failed to load ${t.length} external diagrams`);for(const e of t)h.Rm.error(e);throw new Error(`Failed to load ${t.length} external diagrams`)}},"loadRegisteredDiagrams");function ne(t,e){t.attr("role","graphics-document document"),""!==e&&t.attr("aria-roledescription",e)}function ae(t,e,r,i){if(void 0!==t.insert){if(r){const e=`chart-desc-${i}`;t.attr("aria-describedby",e),t.insert("desc",":first-child").attr("id",e).text(r)}if(e){const r=`chart-title-${i}`;t.attr("aria-labelledby",r),t.insert("title",":first-child").attr("id",r).text(e)}}}(0,h.K2)(ne,"setA11yDiagramInfo"),(0,h.K2)(ae,"addSVGa11yTitleDescription");var oe=class t{constructor(t,e,r,i,n){this.type=t,this.text=e,this.db=r,this.parser=i,this.renderer=n}static{(0,h.K2)(this,"Diagram")}static async fromText(e,r={}){const i=(0,c.zj)(),n=(0,c.Ch)(e,i);e=(0,l.C4)(e)+"\n";try{(0,c.Gs)(n)}catch{const t=(0,c.J$)(n);if(!t)throw new c.C0(`Diagram ${n} not found.`);const{id:e,diagram:r}=await t();(0,c.Js)(e,r)}const{db:a,parser:o,renderer:s,init:h}=(0,c.Gs)(n);return o.parser&&(o.parser.yy=a),a.clear?.(),h?.(i),r.title&&a.setDiagramTitle?.(r.title),await o.parse(e),new t(n,e,a,o,s)}async render(t,e){await this.renderer.draw(this.text,t,e,this)}getParser(){return this.parser}getType(){return this.type}},se=[],le=(0,h.K2)(()=>{se.forEach(t=>{t()}),se=[]},"attachFunctions"),ce=(0,h.K2)(t=>t.replace(/^\s*%%(?!{)[^\n]+\n?/gm,"").trimStart(),"cleanupComments");function he(t){const e=t.match(c.EJ);if(!e)return{text:t,metadata:{}};let r=(0,a.H)(e[1],{schema:a.r})??{};r="object"!=typeof r||Array.isArray(r)?{}:r;const i={};return r.displayMode&&(i.displayMode=r.displayMode.toString()),r.title&&(i.title=r.title.toString()),r.config&&(i.config=r.config),{text:t.slice(e[0].length),metadata:i}}(0,h.K2)(he,"extractFrontMatter");var ue=(0,h.K2)(t=>t.replace(/\r\n?/g,"\n").replace(/<(\w+)([^>]*)>/g,(t,e,r)=>"<"+e+r.replace(/="([^"]*)"/g,"='$1'")+">"),"cleanupText"),de=(0,h.K2)(t=>{const{text:e,metadata:r}=he(t),{displayMode:i,title:n,config:a={}}=r;return i&&(a.gantt||(a.gantt={}),a.gantt.displayMode=i),{title:n,config:a,text:e}},"processFrontmatter"),pe=(0,h.K2)(t=>{const e=l._K.detectInit(t)??{},r=l._K.detectDirective(t,"wrap");return Array.isArray(r)?e.wrap=r.some(({type:t})=>"wrap"===t):"wrap"===r?.type&&(e.wrap=!0),{text:(0,l.vU)(t),directive:e}},"processDirectives");function fe(t){const e=ue(t),r=de(e),i=pe(r.text),n=(0,l.$t)(r.config,i.directive);return{code:t=ce(i.text),title:r.title,config:n}}function ge(t){const e=(new TextEncoder).encode(t),r=Array.from(e,t=>String.fromCodePoint(t)).join("");return btoa(r)}(0,h.K2)(fe,"preprocessDiagram"),(0,h.K2)(ge,"toBase64");var ye=["foreignobject"],me=["dominant-baseline"];function xe(t){const e=fe(t);return(0,c.cL)(),(0,c.xA)(e.config??{}),e}async function be(t,e){re();try{const{code:e,config:r}=xe(t);return{diagramType:(await Le(e)).type,config:r}}catch(r){if(e?.suppressErrors)return!1;throw r}}(0,h.K2)(xe,"processAndSetConfigs"),(0,h.K2)(be,"parse");var ke=(0,h.K2)((t,e,r=[])=>`\n.${t} ${e} { ${r.join(" !important; ")} !important; }`,"cssImportantStyles"),we=(0,h.K2)((t,e=new Map)=>{let r="";if(void 0!==t.themeCSS&&(r+=`\n${t.themeCSS}`),void 0!==t.fontFamily&&(r+=`\n:root { --mermaid-font-family: ${t.fontFamily}}`),void 0!==t.altFontFamily&&(r+=`\n:root { --mermaid-alt-font-family: ${t.altFontFamily}}`),e instanceof Map){const i=t.htmlLabels??t.flowchart?.htmlLabels?["> *","span"]:["rect","polygon","ellipse","circle","path"];e.forEach(t=>{(0,tt.A)(t.styles)||i.forEach(e=>{r+=ke(t.id,e,t.styles)}),(0,tt.A)(t.textStyles)||(r+=ke(t.id,"tspan",(t?.textStyles||[]).map(t=>t.replace("color","fill"))))})}return r},"createCssStyles"),Ce=(0,h.K2)((t,e,r,i)=>{const n=we(t,r);return S(G(`${i}{${(0,c.tM)(e,n,t.themeVariables)}}`),T)},"createUserStyles"),_e=(0,h.K2)((t="",e,r)=>{let i=t;return r||e||(i=i.replace(/marker-end="url\([\d+./:=?A-Za-z-]*?#/g,'marker-end="url(#')),i=(0,l.Sm)(i),i=i.replace(/<br>/g,"<br/>"),i},"cleanUpSvgCode"),ve=(0,h.K2)((t="",e)=>`<iframe style="width:100%;height:${e?.viewBox?.baseVal?.height?e.viewBox.baseVal.height+"px":"100%"};border:0;margin:0;" src="data:text/html;charset=UTF-8;base64,${ge(`<body style="margin:0">${t}</body>`)}" sandbox="allow-top-navigation-by-user-activation allow-popups">\n The "iframe" tag is not supported by your browser.\n</iframe>`,"putIntoIFrame"),Se=(0,h.K2)((t,e,r,i,n)=>{const a=t.append("div");a.attr("id",r),i&&a.attr("style",i);const o=a.append("svg").attr("id",e).attr("width","100%").attr("xmlns","http://www.w3.org/2000/svg");return n&&o.attr("xmlns:xlink",n),o.append("g"),t},"appendDivSvgG");function Te(t,e){return t.append("iframe").attr("id",e).attr("style","width: 100%; height: 100%;").attr("sandbox","")}(0,h.K2)(Te,"sandboxedIframe");var Ae=(0,h.K2)((t,e,r,i)=>{t.getElementById(e)?.remove(),t.getElementById(r)?.remove(),t.getElementById(i)?.remove()},"removeExistingElements"),Me=(0,h.K2)(async function(t,e,r){re();const n=xe(e);e=n.code;const a=(0,c.zj)();h.Rm.debug(a),e.length>(a?.maxTextSize??5e4)&&(e="graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa");const o="#"+t,s="i"+t,l="#"+s,u="d"+t,p="#"+u,f=(0,h.K2)(()=>{const t=y?l:p,e=(0,d.Ltv)(t).node();e&&"remove"in e&&e.remove()},"removeTempElements");let g=(0,d.Ltv)("body");const y="sandbox"===a.securityLevel,m="loose"===a.securityLevel,x=a.fontFamily;if(void 0!==r){if(r&&(r.innerHTML=""),y){const t=Te((0,d.Ltv)(r),s);g=(0,d.Ltv)(t.nodes()[0].contentDocument.body),g.node().style.margin=0}else g=(0,d.Ltv)(r);Se(g,t,u,`font-family: ${x}`,"http://www.w3.org/1999/xlink")}else{if(Ae(document,t,u,s),y){const t=Te((0,d.Ltv)("body"),s);g=(0,d.Ltv)(t.nodes()[0].contentDocument.body),g.node().style.margin=0}else g=(0,d.Ltv)("body");Se(g,t,u)}let b,k;try{b=await oe.fromText(e,{title:n.title})}catch($){if(a.suppressErrorRendering)throw f(),$;b=await oe.fromText("error"),k=$}const w=g.select(p).node(),C=b.type,_=w.firstChild,v=_.firstChild,S=b.renderer.getClasses?.(e,b),T=Ce(a,C,S,o),A=document.createElement("style");A.innerHTML=T,_.insertBefore(A,v);try{await b.renderer.draw(e,t,i.n.version,b)}catch(E){throw a.suppressErrorRendering?f():Et.draw(e,t,i.n.version),E}const M=g.select(`${p} svg`),B=b.db.getAccTitle?.(),L=b.db.getAccDescription?.();Fe(C,M,B,L),g.select(`[id="${t}"]`).selectAll("foreignobject > *").attr("xmlns","http://www.w3.org/1999/xhtml");let F=g.select(p).node().innerHTML;if(h.Rm.debug("config.arrowMarkerAbsolute",a.arrowMarkerAbsolute),F=_e(F,y,(0,c._3)(a.arrowMarkerAbsolute)),y){const t=g.select(p+" svg").node();F=ve(F,t)}else m||(F=J.A.sanitize(F,{ADD_TAGS:ye,ADD_ATTR:me,HTML_INTEGRATION_POINTS:{foreignobject:!0}}));if(le(),k)throw k;return f(),{diagramType:C,svg:F,bindFunctions:b.db.bindFunctions}},"render");function Be(t={}){const e=(0,c.hH)({},t);e?.fontFamily&&!e.themeVariables?.fontFamily&&(e.themeVariables||(e.themeVariables={}),e.themeVariables.fontFamily=e.fontFamily),(0,c.wZ)(e),e?.theme&&e.theme in c.H$?e.themeVariables=c.H$[e.theme].getThemeVariables(e.themeVariables):e&&(e.themeVariables=c.H$.default.getThemeVariables(e.themeVariables));const r="object"==typeof e?(0,c.UU)(e):(0,c.Q2)();(0,h.He)(r.logLevel),re()}(0,h.K2)(Be,"initialize");var Le=(0,h.K2)((t,e={})=>{const{code:r}=fe(t);return oe.fromText(r,e)},"getDiagramFromText");function Fe(t,e,r,i){ne(e,t),ae(e,r,i,e.attr("id"))}(0,h.K2)(Fe,"addA11yInfo");var $e=Object.freeze({render:Me,parse:be,getDiagramFromText:Le,initialize:Be,getConfig:c.zj,setConfig:c.Nk,getSiteConfig:c.Q2,updateSiteConfig:c.B6,reset:(0,h.K2)(()=>{(0,c.cL)()},"reset"),globalReset:(0,h.K2)(()=>{(0,c.cL)(c.sb)},"globalReset"),defaultConfig:c.sb});(0,h.He)((0,c.zj)().logLevel),(0,c.cL)((0,c.zj)());var Ee=(0,h.K2)((t,e,r)=>{h.Rm.warn(t),(0,l.dq)(t)?(r&&r(t.str,t.hash),e.push({...t,message:t.str,error:t})):(r&&r(t),t instanceof Error&&e.push({str:t.message,message:t.message,hash:t.name,error:t}))},"handleError"),De=(0,h.K2)(async function(t={querySelector:".mermaid"}){try{await Oe(t)}catch(e){if((0,l.dq)(e)&&h.Rm.error(e.str),Ye.parseError&&Ye.parseError(e),!t.suppressErrors)throw h.Rm.error("Use the suppressErrors option to suppress these errors"),e}},"run"),Oe=(0,h.K2)(async function({postRenderCallback:t,querySelector:e,nodes:r}={querySelector:".mermaid"}){const i=$e.getConfig();let n;if(h.Rm.debug((t?"":"No ")+"Callback function found"),r)n=r;else{if(!e)throw new Error("Nodes and querySelector are both undefined");n=document.querySelectorAll(e)}h.Rm.debug(`Found ${n.length} diagrams`),void 0!==i?.startOnLoad&&(h.Rm.debug("Start On Load: "+i?.startOnLoad),$e.updateSiteConfig({startOnLoad:i?.startOnLoad}));const a=new l._K.InitIDGenerator(i.deterministicIds,i.deterministicIDSeed);let o;const s=[];for(const d of Array.from(n)){if(h.Rm.info("Rendering diagram: "+d.id),d.getAttribute("data-processed"))continue;d.setAttribute("data-processed","true");const e=`mermaid-${a.next()}`;o=d.innerHTML,o=(0,u.T)(l._K.entityDecode(o)).trim().replace(/<br\s*\/?>/gi,"<br/>");const r=l._K.detectInit(o);r&&h.Rm.debug("Detected early reinit: ",r);try{const{svg:r,bindFunctions:i}=await He(e,o,d);d.innerHTML=r,t&&await t(e),i&&i(d)}catch(c){Ee(c,s,Ye.parseError)}}if(s.length>0)throw s[0]},"runThrowsErrors"),Re=(0,h.K2)(function(t){$e.initialize(t)},"initialize"),Ke=(0,h.K2)(async function(t,e,r){h.Rm.warn("mermaid.init is deprecated. Please use run instead."),t&&Re(t);const i={postRenderCallback:r,querySelector:".mermaid"};"string"==typeof e?i.querySelector=e:e&&(e instanceof HTMLElement?i.nodes=[e]:i.nodes=e),await De(i)},"init"),Ie=(0,h.K2)(async(t,{lazyLoad:e=!0}={})=>{re(),(0,c.Xd)(...t),!1===e&&await ie()},"registerExternalDiagrams"),Ne=(0,h.K2)(function(){if(Ye.startOnLoad){const{startOnLoad:t}=$e.getConfig();t&&Ye.run().catch(t=>h.Rm.error("Mermaid failed to initialize",t))}},"contentLoaded");"undefined"!=typeof document&&window.addEventListener("load",Ne,!1);var ze=(0,h.K2)(function(t){Ye.parseError=t},"setParseErrorHandler"),Pe=[],qe=!1,je=(0,h.K2)(async()=>{if(!qe){for(qe=!0;Pe.length>0;){const e=Pe.shift();if(e)try{await e()}catch(t){h.Rm.error("Error executing queue",t)}}qe=!1}},"executeQueue"),We=(0,h.K2)(async(t,e)=>new Promise((r,i)=>{const n=(0,h.K2)(()=>new Promise((n,a)=>{$e.parse(t,e).then(t=>{n(t),r(t)},t=>{h.Rm.error("Error parsing",t),Ye.parseError?.(t),a(t),i(t)})}),"performCall");Pe.push(n),je().catch(i)}),"parse"),He=(0,h.K2)((t,e,r)=>new Promise((i,n)=>{const a=(0,h.K2)(()=>new Promise((a,o)=>{$e.render(t,e,r).then(t=>{a(t),i(t)},t=>{h.Rm.error("Error parsing",t),Ye.parseError?.(t),o(t),n(t)})}),"performCall");Pe.push(a),je().catch(n)}),"render"),Ue=(0,h.K2)(()=>Object.keys(c.mW).map(t=>({id:t})),"getRegisteredDiagramsMetadata"),Ye={startOnLoad:!0,mermaidAPI:$e,parse:We,render:He,init:Ke,run:De,registerExternalDiagrams:Ie,registerLayoutLoaders:o.sO,initialize:Re,parseError:void 0,contentLoaded:Ne,setParseErrorHandler:ze,detectType:c.Ch,registerIconPacks:s.pC,getRegisteredDiagramsMetadata:Ue},Ge=Ye},23149:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});const i=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}},24326:(t,e,r)=>{"use strict";r.d(e,{A:()=>o});var i=r(29008),n=r(76875),a=r(67525);const o=function(t,e){return(0,a.A)((0,n.A)(t,e,i.A),t+"")}},25353:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});var i=/^(?:0|[1-9]\d*)$/;const n=function(t,e){var r=typeof t;return!!(e=null==e?9007199254740991:e)&&("number"==r||"symbol"!=r&&i.test(t))&&t>-1&&t%1==0&&t<e}},25582:(t,e,r)=>{"use strict";r.d(e,{A:()=>s});var i=r(72453),n=r(93539),a=r(74886),o=r(8232);const s=(t,e,r=0,s=1)=>{if("number"!=typeof t)return(0,o.A)(t,{a:e});const l=n.A.set({r:i.A.channel.clamp.r(t),g:i.A.channel.clamp.g(e),b:i.A.channel.clamp.b(r),a:i.A.channel.clamp.a(s)});return a.A.stringify(l)}},28698:(t,e,r)=>{"use strict";r.d(e,{Nq:()=>a,RI:()=>l,hq:()=>n});var i=r(40797),n={aggregation:17.25,extension:17.25,composition:17.25,dependency:6,lollipop:13.5,arrow_point:4},a={arrow_point:9,arrow_cross:12.5,arrow_circle:12.5};function o(t,e){if(void 0===t||void 0===e)return{angle:0,deltaX:0,deltaY:0};t=s(t),e=s(e);const[r,i]=[t.x,t.y],[n,a]=[e.x,e.y],o=n-r,l=a-i;return{angle:Math.atan(l/o),deltaX:o,deltaY:l}}(0,i.K2)(o,"calculateDeltaAndAngle");var s=(0,i.K2)(t=>Array.isArray(t)?{x:t[0],y:t[1]}:t,"pointTransformer"),l=(0,i.K2)(t=>({x:(0,i.K2)(function(e,r,i){let a=0;const l=s(i[0]).x<s(i[i.length-1]).x?"left":"right";if(0===r&&Object.hasOwn(n,t.arrowTypeStart)){const{angle:e,deltaX:r}=o(i[0],i[1]);a=n[t.arrowTypeStart]*Math.cos(e)*(r>=0?1:-1)}else if(r===i.length-1&&Object.hasOwn(n,t.arrowTypeEnd)){const{angle:e,deltaX:r}=o(i[i.length-1],i[i.length-2]);a=n[t.arrowTypeEnd]*Math.cos(e)*(r>=0?1:-1)}const c=Math.abs(s(e).x-s(i[i.length-1]).x),h=Math.abs(s(e).y-s(i[i.length-1]).y),u=Math.abs(s(e).x-s(i[0]).x),d=Math.abs(s(e).y-s(i[0]).y),p=n[t.arrowTypeStart],f=n[t.arrowTypeEnd];if(c<f&&c>0&&h<f){let t=f+1-c;t*="right"===l?-1:1,a-=t}if(u<p&&u>0&&d<p){let t=p+1-u;t*="right"===l?-1:1,a+=t}return s(e).x+a},"x"),y:(0,i.K2)(function(e,r,i){let a=0;const l=s(i[0]).y<s(i[i.length-1]).y?"down":"up";if(0===r&&Object.hasOwn(n,t.arrowTypeStart)){const{angle:e,deltaY:r}=o(i[0],i[1]);a=n[t.arrowTypeStart]*Math.abs(Math.sin(e))*(r>=0?1:-1)}else if(r===i.length-1&&Object.hasOwn(n,t.arrowTypeEnd)){const{angle:e,deltaY:r}=o(i[i.length-1],i[i.length-2]);a=n[t.arrowTypeEnd]*Math.abs(Math.sin(e))*(r>=0?1:-1)}const c=Math.abs(s(e).y-s(i[i.length-1]).y),h=Math.abs(s(e).x-s(i[i.length-1]).x),u=Math.abs(s(e).y-s(i[0]).y),d=Math.abs(s(e).x-s(i[0]).x),p=n[t.arrowTypeStart],f=n[t.arrowTypeEnd];if(c<f&&c>0&&h<f){let t=f+1-c;t*="up"===l?-1:1,a-=t}if(u<p&&u>0&&d<p){let t=p+1-u;t*="up"===l?-1:1,a+=t}return s(e).y+a},"y")}),"getLineFunctionsWithOffset")},29008:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});const i=function(t){return t}},29471:(t,e,r)=>{"use strict";r.d(e,{A:()=>_});const i=(0,r(18744).A)(Object,"create");const n=function(){this.__data__=i?i(null):{},this.size=0};const a=function(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e};var o=Object.prototype.hasOwnProperty;const s=function(t){var e=this.__data__;if(i){var r=e[t];return"__lodash_hash_undefined__"===r?void 0:r}return o.call(e,t)?e[t]:void 0};var l=Object.prototype.hasOwnProperty;const c=function(t){var e=this.__data__;return i?void 0!==e[t]:l.call(e,t)};const h=function(t,e){var r=this.__data__;return this.size+=this.has(t)?0:1,r[t]=i&&void 0===e?"__lodash_hash_undefined__":e,this};function u(t){var e=-1,r=null==t?0:t.length;for(this.clear();++e<r;){var i=t[e];this.set(i[0],i[1])}}u.prototype.clear=n,u.prototype.delete=a,u.prototype.get=s,u.prototype.has=c,u.prototype.set=h;const d=u;var p=r(80127),f=r(68335);const g=function(){this.size=0,this.__data__={hash:new d,map:new(f.A||p.A),string:new d}};const y=function(t){var e=typeof t;return"string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t};const m=function(t,e){var r=t.__data__;return y(e)?r["string"==typeof e?"string":"hash"]:r.map};const x=function(t){var e=m(this,t).delete(t);return this.size-=e?1:0,e};const b=function(t){return m(this,t).get(t)};const k=function(t){return m(this,t).has(t)};const w=function(t,e){var r=m(this,t),i=r.size;return r.set(t,e),this.size+=r.size==i?0:1,this};function C(t){var e=-1,r=null==t?0:t.length;for(this.clear();++e<r;){var i=t[e];this.set(i[0],i[1])}}C.prototype.clear=g,C.prototype.delete=x,C.prototype.get=b,C.prototype.has=k,C.prototype.set=w;const _=C},29893:(t,e,r)=>{"use strict";function i(t,e,r){if(t&&t.length){const[i,n]=e,a=Math.PI/180*r,o=Math.cos(a),s=Math.sin(a);for(const e of t){const[t,r]=e;e[0]=(t-i)*o-(r-n)*s+i,e[1]=(t-i)*s+(r-n)*o+n}}}function n(t,e){return t[0]===e[0]&&t[1]===e[1]}function a(t,e,r,a=1){const o=r,s=Math.max(e,.1),l=t[0]&&t[0][0]&&"number"==typeof t[0][0]?[t]:t,c=[0,0];if(o)for(const n of l)i(n,c,o);const h=function(t,e,r){const i=[];for(const h of t){const t=[...h];n(t[0],t[t.length-1])||t.push([t[0][0],t[0][1]]),t.length>2&&i.push(t)}const a=[];e=Math.max(e,.1);const o=[];for(const n of i)for(let t=0;t<n.length-1;t++){const e=n[t],r=n[t+1];if(e[1]!==r[1]){const t=Math.min(e[1],r[1]);o.push({ymin:t,ymax:Math.max(e[1],r[1]),x:t===e[1]?e[0]:r[0],islope:(r[0]-e[0])/(r[1]-e[1])})}}if(o.sort((t,e)=>t.ymin<e.ymin?-1:t.ymin>e.ymin?1:t.x<e.x?-1:t.x>e.x?1:t.ymax===e.ymax?0:(t.ymax-e.ymax)/Math.abs(t.ymax-e.ymax)),!o.length)return a;let s=[],l=o[0].ymin,c=0;for(;s.length||o.length;){if(o.length){let t=-1;for(let e=0;e<o.length&&!(o[e].ymin>l);e++)t=e;o.splice(0,t+1).forEach(t=>{s.push({s:l,edge:t})})}if(s=s.filter(t=>!(t.edge.ymax<=l)),s.sort((t,e)=>t.edge.x===e.edge.x?0:(t.edge.x-e.edge.x)/Math.abs(t.edge.x-e.edge.x)),(1!==r||c%e==0)&&s.length>1)for(let t=0;t<s.length;t+=2){const e=t+1;if(e>=s.length)break;const r=s[t].edge,i=s[e].edge;a.push([[Math.round(r.x),l],[Math.round(i.x),l]])}l+=r,s.forEach(t=>{t.edge.x=t.edge.x+r*t.edge.islope}),c++}return a}(l,s,a);if(o){for(const t of l)i(t,c,-o);!function(t,e,r){const n=[];t.forEach(t=>n.push(...t)),i(n,e,r)}(h,c,-o)}return h}function o(t,e){var r;const i=e.hachureAngle+90;let n=e.hachureGap;n<0&&(n=4*e.strokeWidth),n=Math.round(Math.max(n,.1));let o=1;return e.roughness>=1&&((null===(r=e.randomizer)||void 0===r?void 0:r.next())||Math.random())>.7&&(o=n),a(t,n,i,o||1)}r.d(e,{A:()=>nt});class s{constructor(t){this.helper=t}fillPolygons(t,e){return this._fillPolygons(t,e)}_fillPolygons(t,e){const r=o(t,e);return{type:"fillSketch",ops:this.renderLines(r,e)}}renderLines(t,e){const r=[];for(const i of t)r.push(...this.helper.doubleLineOps(i[0][0],i[0][1],i[1][0],i[1][1],e));return r}}function l(t){const e=t[0],r=t[1];return Math.sqrt(Math.pow(e[0]-r[0],2)+Math.pow(e[1]-r[1],2))}class c extends s{fillPolygons(t,e){let r=e.hachureGap;r<0&&(r=4*e.strokeWidth),r=Math.max(r,.1);const i=o(t,Object.assign({},e,{hachureGap:r})),n=Math.PI/180*e.hachureAngle,a=[],s=.5*r*Math.cos(n),c=.5*r*Math.sin(n);for(const[o,h]of i)l([o,h])&&a.push([[o[0]-s,o[1]+c],[...h]],[[o[0]+s,o[1]-c],[...h]]);return{type:"fillSketch",ops:this.renderLines(a,e)}}}class h extends s{fillPolygons(t,e){const r=this._fillPolygons(t,e),i=Object.assign({},e,{hachureAngle:e.hachureAngle+90}),n=this._fillPolygons(t,i);return r.ops=r.ops.concat(n.ops),r}}class u{constructor(t){this.helper=t}fillPolygons(t,e){const r=o(t,e=Object.assign({},e,{hachureAngle:0}));return this.dotsOnLines(r,e)}dotsOnLines(t,e){const r=[];let i=e.hachureGap;i<0&&(i=4*e.strokeWidth),i=Math.max(i,.1);let n=e.fillWeight;n<0&&(n=e.strokeWidth/2);const a=i/4;for(const o of t){const t=l(o),s=t/i,c=Math.ceil(s)-1,h=t-c*i,u=(o[0][0]+o[1][0])/2-i/4,d=Math.min(o[0][1],o[1][1]);for(let o=0;o<c;o++){const t=d+h+o*i,s=u-a+2*Math.random()*a,l=t-a+2*Math.random()*a,c=this.helper.ellipse(s,l,n,n,e);r.push(...c.ops)}}return{type:"fillSketch",ops:r}}}class d{constructor(t){this.helper=t}fillPolygons(t,e){const r=o(t,e);return{type:"fillSketch",ops:this.dashedLine(r,e)}}dashedLine(t,e){const r=e.dashOffset<0?e.hachureGap<0?4*e.strokeWidth:e.hachureGap:e.dashOffset,i=e.dashGap<0?e.hachureGap<0?4*e.strokeWidth:e.hachureGap:e.dashGap,n=[];return t.forEach(t=>{const a=l(t),o=Math.floor(a/(r+i)),s=(a+i-o*(r+i))/2;let c=t[0],h=t[1];c[0]>h[0]&&(c=t[1],h=t[0]);const u=Math.atan((h[1]-c[1])/(h[0]-c[0]));for(let l=0;l<o;l++){const t=l*(r+i),a=t+r,o=[c[0]+t*Math.cos(u)+s*Math.cos(u),c[1]+t*Math.sin(u)+s*Math.sin(u)],h=[c[0]+a*Math.cos(u)+s*Math.cos(u),c[1]+a*Math.sin(u)+s*Math.sin(u)];n.push(...this.helper.doubleLineOps(o[0],o[1],h[0],h[1],e))}}),n}}class p{constructor(t){this.helper=t}fillPolygons(t,e){const r=e.hachureGap<0?4*e.strokeWidth:e.hachureGap,i=e.zigzagOffset<0?r:e.zigzagOffset,n=o(t,e=Object.assign({},e,{hachureGap:r+i}));return{type:"fillSketch",ops:this.zigzagLines(n,i,e)}}zigzagLines(t,e,r){const i=[];return t.forEach(t=>{const n=l(t),a=Math.round(n/(2*e));let o=t[0],s=t[1];o[0]>s[0]&&(o=t[1],s=t[0]);const c=Math.atan((s[1]-o[1])/(s[0]-o[0]));for(let l=0;l<a;l++){const t=2*l*e,n=2*(l+1)*e,a=Math.sqrt(2*Math.pow(e,2)),s=[o[0]+t*Math.cos(c),o[1]+t*Math.sin(c)],h=[o[0]+n*Math.cos(c),o[1]+n*Math.sin(c)],u=[s[0]+a*Math.cos(c+Math.PI/4),s[1]+a*Math.sin(c+Math.PI/4)];i.push(...this.helper.doubleLineOps(s[0],s[1],u[0],u[1],r),...this.helper.doubleLineOps(u[0],u[1],h[0],h[1],r))}}),i}}const f={};class g{constructor(t){this.seed=t}next(){return this.seed?(2**31-1&(this.seed=Math.imul(48271,this.seed)))/2**31:Math.random()}}const y={A:7,a:7,C:6,c:6,H:1,h:1,L:2,l:2,M:2,m:2,Q:4,q:4,S:4,s:4,T:2,t:2,V:1,v:1,Z:0,z:0};function m(t,e){return t.type===e}function x(t){const e=[],r=function(t){const e=new Array;for(;""!==t;)if(t.match(/^([ \t\r\n,]+)/))t=t.substr(RegExp.$1.length);else if(t.match(/^([aAcChHlLmMqQsStTvVzZ])/))e[e.length]={type:0,text:RegExp.$1},t=t.substr(RegExp.$1.length);else{if(!t.match(/^(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)/))return[];e[e.length]={type:1,text:`${parseFloat(RegExp.$1)}`},t=t.substr(RegExp.$1.length)}return e[e.length]={type:2,text:""},e}(t);let i="BOD",n=0,a=r[n];for(;!m(a,2);){let o=0;const s=[];if("BOD"===i){if("M"!==a.text&&"m"!==a.text)return x("M0,0"+t);n++,o=y[a.text],i=a.text}else m(a,1)?o=y[i]:(n++,o=y[a.text],i=a.text);if(!(n+o<r.length))throw new Error("Path data ended short");for(let t=n;t<n+o;t++){const e=r[t];if(!m(e,1))throw new Error("Param not a number: "+i+","+e.text);s[s.length]=+e.text}if("number"!=typeof y[i])throw new Error("Bad segment: "+i);{const t={key:i,data:s};e.push(t),n+=o,a=r[n],"M"===i&&(i="L"),"m"===i&&(i="l")}}return e}function b(t){let e=0,r=0,i=0,n=0;const a=[];for(const{key:o,data:s}of t)switch(o){case"M":a.push({key:"M",data:[...s]}),[e,r]=s,[i,n]=s;break;case"m":e+=s[0],r+=s[1],a.push({key:"M",data:[e,r]}),i=e,n=r;break;case"L":a.push({key:"L",data:[...s]}),[e,r]=s;break;case"l":e+=s[0],r+=s[1],a.push({key:"L",data:[e,r]});break;case"C":a.push({key:"C",data:[...s]}),e=s[4],r=s[5];break;case"c":{const t=s.map((t,i)=>i%2?t+r:t+e);a.push({key:"C",data:t}),e=t[4],r=t[5];break}case"Q":a.push({key:"Q",data:[...s]}),e=s[2],r=s[3];break;case"q":{const t=s.map((t,i)=>i%2?t+r:t+e);a.push({key:"Q",data:t}),e=t[2],r=t[3];break}case"A":a.push({key:"A",data:[...s]}),e=s[5],r=s[6];break;case"a":e+=s[5],r+=s[6],a.push({key:"A",data:[s[0],s[1],s[2],s[3],s[4],e,r]});break;case"H":a.push({key:"H",data:[...s]}),e=s[0];break;case"h":e+=s[0],a.push({key:"H",data:[e]});break;case"V":a.push({key:"V",data:[...s]}),r=s[0];break;case"v":r+=s[0],a.push({key:"V",data:[r]});break;case"S":a.push({key:"S",data:[...s]}),e=s[2],r=s[3];break;case"s":{const t=s.map((t,i)=>i%2?t+r:t+e);a.push({key:"S",data:t}),e=t[2],r=t[3];break}case"T":a.push({key:"T",data:[...s]}),e=s[0],r=s[1];break;case"t":e+=s[0],r+=s[1],a.push({key:"T",data:[e,r]});break;case"Z":case"z":a.push({key:"Z",data:[]}),e=i,r=n}return a}function k(t){const e=[];let r="",i=0,n=0,a=0,o=0,s=0,l=0;for(const{key:c,data:h}of t){switch(c){case"M":e.push({key:"M",data:[...h]}),[i,n]=h,[a,o]=h;break;case"C":e.push({key:"C",data:[...h]}),i=h[4],n=h[5],s=h[2],l=h[3];break;case"L":e.push({key:"L",data:[...h]}),[i,n]=h;break;case"H":i=h[0],e.push({key:"L",data:[i,n]});break;case"V":n=h[0],e.push({key:"L",data:[i,n]});break;case"S":{let t=0,a=0;"C"===r||"S"===r?(t=i+(i-s),a=n+(n-l)):(t=i,a=n),e.push({key:"C",data:[t,a,...h]}),s=h[0],l=h[1],i=h[2],n=h[3];break}case"T":{const[t,a]=h;let o=0,c=0;"Q"===r||"T"===r?(o=i+(i-s),c=n+(n-l)):(o=i,c=n);const u=i+2*(o-i)/3,d=n+2*(c-n)/3,p=t+2*(o-t)/3,f=a+2*(c-a)/3;e.push({key:"C",data:[u,d,p,f,t,a]}),s=o,l=c,i=t,n=a;break}case"Q":{const[t,r,a,o]=h,c=i+2*(t-i)/3,u=n+2*(r-n)/3,d=a+2*(t-a)/3,p=o+2*(r-o)/3;e.push({key:"C",data:[c,u,d,p,a,o]}),s=t,l=r,i=a,n=o;break}case"A":{const t=Math.abs(h[0]),r=Math.abs(h[1]),a=h[2],o=h[3],s=h[4],l=h[5],c=h[6];0===t||0===r?(e.push({key:"C",data:[i,n,l,c,l,c]}),i=l,n=c):i===l&&n===c||(C(i,n,l,c,t,r,a,o,s).forEach(function(t){e.push({key:"C",data:t})}),i=l,n=c);break}case"Z":e.push({key:"Z",data:[]}),i=a,n=o}r=c}return e}function w(t,e,r){return[t*Math.cos(r)-e*Math.sin(r),t*Math.sin(r)+e*Math.cos(r)]}function C(t,e,r,i,n,a,o,s,l,c){const h=(u=o,Math.PI*u/180);var u;let d=[],p=0,f=0,g=0,y=0;if(c)[p,f,g,y]=c;else{[t,e]=w(t,e,-h),[r,i]=w(r,i,-h);const o=(t-r)/2,c=(e-i)/2;let u=o*o/(n*n)+c*c/(a*a);u>1&&(u=Math.sqrt(u),n*=u,a*=u);const d=n*n,m=a*a,x=d*m-d*c*c-m*o*o,b=d*c*c+m*o*o,k=(s===l?-1:1)*Math.sqrt(Math.abs(x/b));g=k*n*c/a+(t+r)/2,y=k*-a*o/n+(e+i)/2,p=Math.asin(parseFloat(((e-y)/a).toFixed(9))),f=Math.asin(parseFloat(((i-y)/a).toFixed(9))),t<g&&(p=Math.PI-p),r<g&&(f=Math.PI-f),p<0&&(p=2*Math.PI+p),f<0&&(f=2*Math.PI+f),l&&p>f&&(p-=2*Math.PI),!l&&f>p&&(f-=2*Math.PI)}let m=f-p;if(Math.abs(m)>120*Math.PI/180){const t=f,e=r,s=i;f=l&&f>p?p+120*Math.PI/180*1:p+120*Math.PI/180*-1,d=C(r=g+n*Math.cos(f),i=y+a*Math.sin(f),e,s,n,a,o,0,l,[f,t,g,y])}m=f-p;const x=Math.cos(p),b=Math.sin(p),k=Math.cos(f),_=Math.sin(f),v=Math.tan(m/4),S=4/3*n*v,T=4/3*a*v,A=[t,e],M=[t+S*b,e-T*x],B=[r+S*_,i-T*k],L=[r,i];if(M[0]=2*A[0]-M[0],M[1]=2*A[1]-M[1],c)return[M,B,L].concat(d);{d=[M,B,L].concat(d);const t=[];for(let e=0;e<d.length;e+=3){const r=w(d[e][0],d[e][1],h),i=w(d[e+1][0],d[e+1][1],h),n=w(d[e+2][0],d[e+2][1],h);t.push([r[0],r[1],i[0],i[1],n[0],n[1]])}return t}}const _={randOffset:function(t,e){return R(t,e)},randOffsetWithRange:function(t,e,r){return O(t,e,r)},ellipse:function(t,e,r,i,n){return M(t,e,n,A(r,i,n)).opset},doubleLineOps:function(t,e,r,i,n){return K(t,e,r,i,n,!0)}};function v(t,e,r,i,n){return{type:"path",ops:K(t,e,r,i,n)}}function S(t,e,r){const i=(t||[]).length;if(i>2){const n=[];for(let e=0;e<i-1;e++)n.push(...K(t[e][0],t[e][1],t[e+1][0],t[e+1][1],r));return e&&n.push(...K(t[i-1][0],t[i-1][1],t[0][0],t[0][1],r)),{type:"path",ops:n}}return 2===i?v(t[0][0],t[0][1],t[1][0],t[1][1],r):{type:"path",ops:[]}}function T(t,e){if(t.length){const r="number"==typeof t[0][0]?[t]:t,i=N(r[0],1*(1+.2*e.roughness),e),n=e.disableMultiStroke?[]:N(r[0],1.5*(1+.22*e.roughness),E(e));for(let t=1;t<r.length;t++){const a=r[t];if(a.length){const t=N(a,1*(1+.2*e.roughness),e),r=e.disableMultiStroke?[]:N(a,1.5*(1+.22*e.roughness),E(e));for(const e of t)"move"!==e.op&&i.push(e);for(const e of r)"move"!==e.op&&n.push(e)}}return{type:"path",ops:i.concat(n)}}return{type:"path",ops:[]}}function A(t,e,r){const i=Math.sqrt(2*Math.PI*Math.sqrt((Math.pow(t/2,2)+Math.pow(e/2,2))/2)),n=Math.ceil(Math.max(r.curveStepCount,r.curveStepCount/Math.sqrt(200)*i)),a=2*Math.PI/n;let o=Math.abs(t/2),s=Math.abs(e/2);const l=1-r.curveFitting;return o+=R(o*l,r),s+=R(s*l,r),{increment:a,rx:o,ry:s}}function M(t,e,r,i){const[n,a]=P(i.increment,t,e,i.rx,i.ry,1,i.increment*O(.1,O(.4,1,r),r),r);let o=z(n,null,r);if(!r.disableMultiStroke&&0!==r.roughness){const[n]=P(i.increment,t,e,i.rx,i.ry,1.5,0,r),a=z(n,null,r);o=o.concat(a)}return{estimatedPoints:a,opset:{type:"path",ops:o}}}function B(t,e,r,i,n,a,o,s,l){const c=t,h=e;let u=Math.abs(r/2),d=Math.abs(i/2);u+=R(.01*u,l),d+=R(.01*d,l);let p=n,f=a;for(;p<0;)p+=2*Math.PI,f+=2*Math.PI;f-p>2*Math.PI&&(p=0,f=2*Math.PI);const g=2*Math.PI/l.curveStepCount,y=Math.min(g/2,(f-p)/2),m=q(y,c,h,u,d,p,f,1,l);if(!l.disableMultiStroke){const t=q(y,c,h,u,d,p,f,1.5,l);m.push(...t)}return o&&(s?m.push(...K(c,h,c+u*Math.cos(p),h+d*Math.sin(p),l),...K(c,h,c+u*Math.cos(f),h+d*Math.sin(f),l)):m.push({op:"lineTo",data:[c,h]},{op:"lineTo",data:[c+u*Math.cos(p),h+d*Math.sin(p)]})),{type:"path",ops:m}}function L(t,e){const r=k(b(x(t))),i=[];let n=[0,0],a=[0,0];for(const{key:o,data:s}of r)switch(o){case"M":a=[s[0],s[1]],n=[s[0],s[1]];break;case"L":i.push(...K(a[0],a[1],s[0],s[1],e)),a=[s[0],s[1]];break;case"C":{const[t,r,n,o,l,c]=s;i.push(...j(t,r,n,o,l,c,a,e)),a=[l,c];break}case"Z":i.push(...K(a[0],a[1],n[0],n[1],e)),a=[n[0],n[1]]}return{type:"path",ops:i}}function F(t,e){const r=[];for(const i of t)if(i.length){const t=e.maxRandomnessOffset||0,n=i.length;if(n>2){r.push({op:"move",data:[i[0][0]+R(t,e),i[0][1]+R(t,e)]});for(let a=1;a<n;a++)r.push({op:"lineTo",data:[i[a][0]+R(t,e),i[a][1]+R(t,e)]})}}return{type:"fillPath",ops:r}}function $(t,e){return function(t,e){let r=t.fillStyle||"hachure";if(!f[r])switch(r){case"zigzag":f[r]||(f[r]=new c(e));break;case"cross-hatch":f[r]||(f[r]=new h(e));break;case"dots":f[r]||(f[r]=new u(e));break;case"dashed":f[r]||(f[r]=new d(e));break;case"zigzag-line":f[r]||(f[r]=new p(e));break;default:r="hachure",f[r]||(f[r]=new s(e))}return f[r]}(e,_).fillPolygons(t,e)}function E(t){const e=Object.assign({},t);return e.randomizer=void 0,t.seed&&(e.seed=t.seed+1),e}function D(t){return t.randomizer||(t.randomizer=new g(t.seed||0)),t.randomizer.next()}function O(t,e,r,i=1){return r.roughness*i*(D(r)*(e-t)+t)}function R(t,e,r=1){return O(-t,t,e,r)}function K(t,e,r,i,n,a=!1){const o=a?n.disableMultiStrokeFill:n.disableMultiStroke,s=I(t,e,r,i,n,!0,!1);if(o)return s;const l=I(t,e,r,i,n,!0,!0);return s.concat(l)}function I(t,e,r,i,n,a,o){const s=Math.pow(t-r,2)+Math.pow(e-i,2),l=Math.sqrt(s);let c=1;c=l<200?1:l>500?.4:-.0016668*l+1.233334;let h=n.maxRandomnessOffset||0;h*h*100>s&&(h=l/10);const u=h/2,d=.2+.2*D(n);let p=n.bowing*n.maxRandomnessOffset*(i-e)/200,f=n.bowing*n.maxRandomnessOffset*(t-r)/200;p=R(p,n,c),f=R(f,n,c);const g=[],y=()=>R(u,n,c),m=()=>R(h,n,c),x=n.preserveVertices;return a&&(o?g.push({op:"move",data:[t+(x?0:y()),e+(x?0:y())]}):g.push({op:"move",data:[t+(x?0:R(h,n,c)),e+(x?0:R(h,n,c))]})),o?g.push({op:"bcurveTo",data:[p+t+(r-t)*d+y(),f+e+(i-e)*d+y(),p+t+2*(r-t)*d+y(),f+e+2*(i-e)*d+y(),r+(x?0:y()),i+(x?0:y())]}):g.push({op:"bcurveTo",data:[p+t+(r-t)*d+m(),f+e+(i-e)*d+m(),p+t+2*(r-t)*d+m(),f+e+2*(i-e)*d+m(),r+(x?0:m()),i+(x?0:m())]}),g}function N(t,e,r){if(!t.length)return[];const i=[];i.push([t[0][0]+R(e,r),t[0][1]+R(e,r)]),i.push([t[0][0]+R(e,r),t[0][1]+R(e,r)]);for(let n=1;n<t.length;n++)i.push([t[n][0]+R(e,r),t[n][1]+R(e,r)]),n===t.length-1&&i.push([t[n][0]+R(e,r),t[n][1]+R(e,r)]);return z(i,null,r)}function z(t,e,r){const i=t.length,n=[];if(i>3){const a=[],o=1-r.curveTightness;n.push({op:"move",data:[t[1][0],t[1][1]]});for(let e=1;e+2<i;e++){const r=t[e];a[0]=[r[0],r[1]],a[1]=[r[0]+(o*t[e+1][0]-o*t[e-1][0])/6,r[1]+(o*t[e+1][1]-o*t[e-1][1])/6],a[2]=[t[e+1][0]+(o*t[e][0]-o*t[e+2][0])/6,t[e+1][1]+(o*t[e][1]-o*t[e+2][1])/6],a[3]=[t[e+1][0],t[e+1][1]],n.push({op:"bcurveTo",data:[a[1][0],a[1][1],a[2][0],a[2][1],a[3][0],a[3][1]]})}if(e&&2===e.length){const t=r.maxRandomnessOffset;n.push({op:"lineTo",data:[e[0]+R(t,r),e[1]+R(t,r)]})}}else 3===i?(n.push({op:"move",data:[t[1][0],t[1][1]]}),n.push({op:"bcurveTo",data:[t[1][0],t[1][1],t[2][0],t[2][1],t[2][0],t[2][1]]})):2===i&&n.push(...I(t[0][0],t[0][1],t[1][0],t[1][1],r,!0,!0));return n}function P(t,e,r,i,n,a,o,s){const l=[],c=[];if(0===s.roughness){t/=4,c.push([e+i*Math.cos(-t),r+n*Math.sin(-t)]);for(let a=0;a<=2*Math.PI;a+=t){const t=[e+i*Math.cos(a),r+n*Math.sin(a)];l.push(t),c.push(t)}c.push([e+i*Math.cos(0),r+n*Math.sin(0)]),c.push([e+i*Math.cos(t),r+n*Math.sin(t)])}else{const h=R(.5,s)-Math.PI/2;c.push([R(a,s)+e+.9*i*Math.cos(h-t),R(a,s)+r+.9*n*Math.sin(h-t)]);const u=2*Math.PI+h-.01;for(let o=h;o<u;o+=t){const t=[R(a,s)+e+i*Math.cos(o),R(a,s)+r+n*Math.sin(o)];l.push(t),c.push(t)}c.push([R(a,s)+e+i*Math.cos(h+2*Math.PI+.5*o),R(a,s)+r+n*Math.sin(h+2*Math.PI+.5*o)]),c.push([R(a,s)+e+.98*i*Math.cos(h+o),R(a,s)+r+.98*n*Math.sin(h+o)]),c.push([R(a,s)+e+.9*i*Math.cos(h+.5*o),R(a,s)+r+.9*n*Math.sin(h+.5*o)])}return[c,l]}function q(t,e,r,i,n,a,o,s,l){const c=a+R(.1,l),h=[];h.push([R(s,l)+e+.9*i*Math.cos(c-t),R(s,l)+r+.9*n*Math.sin(c-t)]);for(let u=c;u<=o;u+=t)h.push([R(s,l)+e+i*Math.cos(u),R(s,l)+r+n*Math.sin(u)]);return h.push([e+i*Math.cos(o),r+n*Math.sin(o)]),h.push([e+i*Math.cos(o),r+n*Math.sin(o)]),z(h,null,l)}function j(t,e,r,i,n,a,o,s){const l=[],c=[s.maxRandomnessOffset||1,(s.maxRandomnessOffset||1)+.3];let h=[0,0];const u=s.disableMultiStroke?1:2,d=s.preserveVertices;for(let p=0;p<u;p++)0===p?l.push({op:"move",data:[o[0],o[1]]}):l.push({op:"move",data:[o[0]+(d?0:R(c[0],s)),o[1]+(d?0:R(c[0],s))]}),h=d?[n,a]:[n+R(c[p],s),a+R(c[p],s)],l.push({op:"bcurveTo",data:[t+R(c[p],s),e+R(c[p],s),r+R(c[p],s),i+R(c[p],s),h[0],h[1]]});return l}function W(t){return[...t]}function H(t,e=0){const r=t.length;if(r<3)throw new Error("A curve must have at least three points.");const i=[];if(3===r)i.push(W(t[0]),W(t[1]),W(t[2]),W(t[2]));else{const r=[];r.push(t[0],t[0]);for(let e=1;e<t.length;e++)r.push(t[e]),e===t.length-1&&r.push(t[e]);const n=[],a=1-e;i.push(W(r[0]));for(let t=1;t+2<r.length;t++){const e=r[t];n[0]=[e[0],e[1]],n[1]=[e[0]+(a*r[t+1][0]-a*r[t-1][0])/6,e[1]+(a*r[t+1][1]-a*r[t-1][1])/6],n[2]=[r[t+1][0]+(a*r[t][0]-a*r[t+2][0])/6,r[t+1][1]+(a*r[t][1]-a*r[t+2][1])/6],n[3]=[r[t+1][0],r[t+1][1]],i.push(n[1],n[2],n[3])}}return i}function U(t,e){return Math.pow(t[0]-e[0],2)+Math.pow(t[1]-e[1],2)}function Y(t,e,r){const i=U(e,r);if(0===i)return U(t,e);let n=((t[0]-e[0])*(r[0]-e[0])+(t[1]-e[1])*(r[1]-e[1]))/i;return n=Math.max(0,Math.min(1,n)),U(t,G(e,r,n))}function G(t,e,r){return[t[0]+(e[0]-t[0])*r,t[1]+(e[1]-t[1])*r]}function X(t,e,r,i){const n=i||[];if(function(t,e){const r=t[e+0],i=t[e+1],n=t[e+2],a=t[e+3];let o=3*i[0]-2*r[0]-a[0];o*=o;let s=3*i[1]-2*r[1]-a[1];s*=s;let l=3*n[0]-2*a[0]-r[0];l*=l;let c=3*n[1]-2*a[1]-r[1];return c*=c,o<l&&(o=l),s<c&&(s=c),o+s}(t,e)<r){const r=t[e+0];n.length?(a=n[n.length-1],o=r,Math.sqrt(U(a,o))>1&&n.push(r)):n.push(r),n.push(t[e+3])}else{const i=.5,a=t[e+0],o=t[e+1],s=t[e+2],l=t[e+3],c=G(a,o,i),h=G(o,s,i),u=G(s,l,i),d=G(c,h,i),p=G(h,u,i),f=G(d,p,i);X([a,c,d,f],0,r,n),X([f,p,u,l],0,r,n)}var a,o;return n}function V(t,e){return Z(t,0,t.length,e)}function Z(t,e,r,i,n){const a=n||[],o=t[e],s=t[r-1];let l=0,c=1;for(let h=e+1;h<r-1;++h){const e=Y(t[h],o,s);e>l&&(l=e,c=h)}return Math.sqrt(l)>i?(Z(t,e,c+1,i,a),Z(t,c,r,i,a)):(a.length||a.push(o),a.push(s)),a}function Q(t,e=.15,r){const i=[],n=(t.length-1)/3;for(let a=0;a<n;a++)X(t,3*a,e,i);return r&&r>0?Z(i,0,i.length,r):i}const J="none";class tt{constructor(t){this.defaultOptions={maxRandomnessOffset:2,roughness:1,bowing:1,stroke:"#000",strokeWidth:1,curveTightness:0,curveFitting:.95,curveStepCount:9,fillStyle:"hachure",fillWeight:-1,hachureAngle:-41,hachureGap:-1,dashOffset:-1,dashGap:-1,zigzagOffset:-1,seed:0,disableMultiStroke:!1,disableMultiStrokeFill:!1,preserveVertices:!1,fillShapeRoughnessGain:.8},this.config=t||{},this.config.options&&(this.defaultOptions=this._o(this.config.options))}static newSeed(){return Math.floor(Math.random()*2**31)}_o(t){return t?Object.assign({},this.defaultOptions,t):this.defaultOptions}_d(t,e,r){return{shape:t,sets:e||[],options:r||this.defaultOptions}}line(t,e,r,i,n){const a=this._o(n);return this._d("line",[v(t,e,r,i,a)],a)}rectangle(t,e,r,i,n){const a=this._o(n),o=[],s=function(t,e,r,i,n){return function(t,e){return S(t,!0,e)}([[t,e],[t+r,e],[t+r,e+i],[t,e+i]],n)}(t,e,r,i,a);if(a.fill){const n=[[t,e],[t+r,e],[t+r,e+i],[t,e+i]];"solid"===a.fillStyle?o.push(F([n],a)):o.push($([n],a))}return a.stroke!==J&&o.push(s),this._d("rectangle",o,a)}ellipse(t,e,r,i,n){const a=this._o(n),o=[],s=A(r,i,a),l=M(t,e,a,s);if(a.fill)if("solid"===a.fillStyle){const r=M(t,e,a,s).opset;r.type="fillPath",o.push(r)}else o.push($([l.estimatedPoints],a));return a.stroke!==J&&o.push(l.opset),this._d("ellipse",o,a)}circle(t,e,r,i){const n=this.ellipse(t,e,r,r,i);return n.shape="circle",n}linearPath(t,e){const r=this._o(e);return this._d("linearPath",[S(t,!1,r)],r)}arc(t,e,r,i,n,a,o=!1,s){const l=this._o(s),c=[],h=B(t,e,r,i,n,a,o,!0,l);if(o&&l.fill)if("solid"===l.fillStyle){const o=Object.assign({},l);o.disableMultiStroke=!0;const s=B(t,e,r,i,n,a,!0,!1,o);s.type="fillPath",c.push(s)}else c.push(function(t,e,r,i,n,a,o){const s=t,l=e;let c=Math.abs(r/2),h=Math.abs(i/2);c+=R(.01*c,o),h+=R(.01*h,o);let u=n,d=a;for(;u<0;)u+=2*Math.PI,d+=2*Math.PI;d-u>2*Math.PI&&(u=0,d=2*Math.PI);const p=(d-u)/o.curveStepCount,f=[];for(let g=u;g<=d;g+=p)f.push([s+c*Math.cos(g),l+h*Math.sin(g)]);return f.push([s+c*Math.cos(d),l+h*Math.sin(d)]),f.push([s,l]),$([f],o)}(t,e,r,i,n,a,l));return l.stroke!==J&&c.push(h),this._d("arc",c,l)}curve(t,e){const r=this._o(e),i=[],n=T(t,r);if(r.fill&&r.fill!==J)if("solid"===r.fillStyle){const e=T(t,Object.assign(Object.assign({},r),{disableMultiStroke:!0,roughness:r.roughness?r.roughness+r.fillShapeRoughnessGain:0}));i.push({type:"fillPath",ops:this._mergedShape(e.ops)})}else{const e=[],n=t;if(n.length){const t="number"==typeof n[0][0]?[n]:n;for(const i of t)i.length<3?e.push(...i):3===i.length?e.push(...Q(H([i[0],i[0],i[1],i[2]]),10,(1+r.roughness)/2)):e.push(...Q(H(i),10,(1+r.roughness)/2))}e.length&&i.push($([e],r))}return r.stroke!==J&&i.push(n),this._d("curve",i,r)}polygon(t,e){const r=this._o(e),i=[],n=S(t,!0,r);return r.fill&&("solid"===r.fillStyle?i.push(F([t],r)):i.push($([t],r))),r.stroke!==J&&i.push(n),this._d("polygon",i,r)}path(t,e){const r=this._o(e),i=[];if(!t)return this._d("path",i,r);t=(t||"").replace(/\n/g," ").replace(/(-\s)/g,"-").replace("/(ss)/g"," ");const n=r.fill&&"transparent"!==r.fill&&r.fill!==J,a=r.stroke!==J,o=!!(r.simplification&&r.simplification<1),s=function(t,e,r){const i=k(b(x(t))),n=[];let a=[],o=[0,0],s=[];const l=()=>{s.length>=4&&a.push(...Q(s,1)),s=[]},c=()=>{l(),a.length&&(n.push(a),a=[])};for(const{key:u,data:d}of i)switch(u){case"M":c(),o=[d[0],d[1]],a.push(o);break;case"L":l(),a.push([d[0],d[1]]);break;case"C":if(!s.length){const t=a.length?a[a.length-1]:o;s.push([t[0],t[1]])}s.push([d[0],d[1]]),s.push([d[2],d[3]]),s.push([d[4],d[5]]);break;case"Z":l(),a.push([o[0],o[1]])}if(c(),!r)return n;const h=[];for(const u of n){const t=V(u,r);t.length&&h.push(t)}return h}(t,0,o?4-4*(r.simplification||1):(1+r.roughness)/2),l=L(t,r);if(n)if("solid"===r.fillStyle)if(1===s.length){const e=L(t,Object.assign(Object.assign({},r),{disableMultiStroke:!0,roughness:r.roughness?r.roughness+r.fillShapeRoughnessGain:0}));i.push({type:"fillPath",ops:this._mergedShape(e.ops)})}else i.push(F(s,r));else i.push($(s,r));return a&&(o?s.forEach(t=>{i.push(S(t,!1,r))}):i.push(l)),this._d("path",i,r)}opsToPath(t,e){let r="";for(const i of t.ops){const t="number"==typeof e&&e>=0?i.data.map(t=>+t.toFixed(e)):i.data;switch(i.op){case"move":r+=`M${t[0]} ${t[1]} `;break;case"bcurveTo":r+=`C${t[0]} ${t[1]}, ${t[2]} ${t[3]}, ${t[4]} ${t[5]} `;break;case"lineTo":r+=`L${t[0]} ${t[1]} `}}return r.trim()}toPaths(t){const e=t.sets||[],r=t.options||this.defaultOptions,i=[];for(const n of e){let t=null;switch(n.type){case"path":t={d:this.opsToPath(n),stroke:r.stroke,strokeWidth:r.strokeWidth,fill:J};break;case"fillPath":t={d:this.opsToPath(n),stroke:J,strokeWidth:0,fill:r.fill||J};break;case"fillSketch":t=this.fillSketch(n,r)}t&&i.push(t)}return i}fillSketch(t,e){let r=e.fillWeight;return r<0&&(r=e.strokeWidth/2),{d:this.opsToPath(t),stroke:e.fill||J,strokeWidth:r,fill:J}}_mergedShape(t){return t.filter((t,e)=>0===e||"move"!==t.op)}}class et{constructor(t,e){this.canvas=t,this.ctx=this.canvas.getContext("2d"),this.gen=new tt(e)}draw(t){const e=t.sets||[],r=t.options||this.getDefaultOptions(),i=this.ctx,n=t.options.fixedDecimalPlaceDigits;for(const a of e)switch(a.type){case"path":i.save(),i.strokeStyle="none"===r.stroke?"transparent":r.stroke,i.lineWidth=r.strokeWidth,r.strokeLineDash&&i.setLineDash(r.strokeLineDash),r.strokeLineDashOffset&&(i.lineDashOffset=r.strokeLineDashOffset),this._drawToContext(i,a,n),i.restore();break;case"fillPath":{i.save(),i.fillStyle=r.fill||"";const e="curve"===t.shape||"polygon"===t.shape||"path"===t.shape?"evenodd":"nonzero";this._drawToContext(i,a,n,e),i.restore();break}case"fillSketch":this.fillSketch(i,a,r)}}fillSketch(t,e,r){let i=r.fillWeight;i<0&&(i=r.strokeWidth/2),t.save(),r.fillLineDash&&t.setLineDash(r.fillLineDash),r.fillLineDashOffset&&(t.lineDashOffset=r.fillLineDashOffset),t.strokeStyle=r.fill||"",t.lineWidth=i,this._drawToContext(t,e,r.fixedDecimalPlaceDigits),t.restore()}_drawToContext(t,e,r,i="nonzero"){t.beginPath();for(const n of e.ops){const e="number"==typeof r&&r>=0?n.data.map(t=>+t.toFixed(r)):n.data;switch(n.op){case"move":t.moveTo(e[0],e[1]);break;case"bcurveTo":t.bezierCurveTo(e[0],e[1],e[2],e[3],e[4],e[5]);break;case"lineTo":t.lineTo(e[0],e[1])}}"fillPath"===e.type?t.fill(i):t.stroke()}get generator(){return this.gen}getDefaultOptions(){return this.gen.defaultOptions}line(t,e,r,i,n){const a=this.gen.line(t,e,r,i,n);return this.draw(a),a}rectangle(t,e,r,i,n){const a=this.gen.rectangle(t,e,r,i,n);return this.draw(a),a}ellipse(t,e,r,i,n){const a=this.gen.ellipse(t,e,r,i,n);return this.draw(a),a}circle(t,e,r,i){const n=this.gen.circle(t,e,r,i);return this.draw(n),n}linearPath(t,e){const r=this.gen.linearPath(t,e);return this.draw(r),r}polygon(t,e){const r=this.gen.polygon(t,e);return this.draw(r),r}arc(t,e,r,i,n,a,o=!1,s){const l=this.gen.arc(t,e,r,i,n,a,o,s);return this.draw(l),l}curve(t,e){const r=this.gen.curve(t,e);return this.draw(r),r}path(t,e){const r=this.gen.path(t,e);return this.draw(r),r}}const rt="http://www.w3.org/2000/svg";class it{constructor(t,e){this.svg=t,this.gen=new tt(e)}draw(t){const e=t.sets||[],r=t.options||this.getDefaultOptions(),i=this.svg.ownerDocument||window.document,n=i.createElementNS(rt,"g"),a=t.options.fixedDecimalPlaceDigits;for(const o of e){let e=null;switch(o.type){case"path":e=i.createElementNS(rt,"path"),e.setAttribute("d",this.opsToPath(o,a)),e.setAttribute("stroke",r.stroke),e.setAttribute("stroke-width",r.strokeWidth+""),e.setAttribute("fill","none"),r.strokeLineDash&&e.setAttribute("stroke-dasharray",r.strokeLineDash.join(" ").trim()),r.strokeLineDashOffset&&e.setAttribute("stroke-dashoffset",`${r.strokeLineDashOffset}`);break;case"fillPath":e=i.createElementNS(rt,"path"),e.setAttribute("d",this.opsToPath(o,a)),e.setAttribute("stroke","none"),e.setAttribute("stroke-width","0"),e.setAttribute("fill",r.fill||""),"curve"!==t.shape&&"polygon"!==t.shape||e.setAttribute("fill-rule","evenodd");break;case"fillSketch":e=this.fillSketch(i,o,r)}e&&n.appendChild(e)}return n}fillSketch(t,e,r){let i=r.fillWeight;i<0&&(i=r.strokeWidth/2);const n=t.createElementNS(rt,"path");return n.setAttribute("d",this.opsToPath(e,r.fixedDecimalPlaceDigits)),n.setAttribute("stroke",r.fill||""),n.setAttribute("stroke-width",i+""),n.setAttribute("fill","none"),r.fillLineDash&&n.setAttribute("stroke-dasharray",r.fillLineDash.join(" ").trim()),r.fillLineDashOffset&&n.setAttribute("stroke-dashoffset",`${r.fillLineDashOffset}`),n}get generator(){return this.gen}getDefaultOptions(){return this.gen.defaultOptions}opsToPath(t,e){return this.gen.opsToPath(t,e)}line(t,e,r,i,n){const a=this.gen.line(t,e,r,i,n);return this.draw(a)}rectangle(t,e,r,i,n){const a=this.gen.rectangle(t,e,r,i,n);return this.draw(a)}ellipse(t,e,r,i,n){const a=this.gen.ellipse(t,e,r,i,n);return this.draw(a)}circle(t,e,r,i){const n=this.gen.circle(t,e,r,i);return this.draw(n)}linearPath(t,e){const r=this.gen.linearPath(t,e);return this.draw(r)}polygon(t,e){const r=this.gen.polygon(t,e);return this.draw(r)}arc(t,e,r,i,n,a,o=!1,s){const l=this.gen.arc(t,e,r,i,n,a,o,s);return this.draw(l)}curve(t,e){const r=this.gen.curve(t,e);return this.draw(r)}path(t,e){const r=this.gen.path(t,e);return this.draw(r)}}var nt={canvas:(t,e)=>new et(t,e),svg:(t,e)=>new it(t,e),generator:t=>new tt(t),newSeed:()=>tt.newSeed()}},30092:(t,e,r)=>{"use strict";r.d(e,{W6:()=>re,GZ:()=>oe,WY:()=>jt,pC:()=>zt,hE:()=>ae,Gc:()=>Kt});var i=r(13226),n=r(67633),a=r(40797);const o=(t,e)=>!!t&&!(!(e&&""===t.prefix||t.prefix)||!t.name),s=Object.freeze({left:0,top:0,width:16,height:16}),l=Object.freeze({rotate:0,vFlip:!1,hFlip:!1}),c=Object.freeze({...s,...l}),h=Object.freeze({...c,body:"",hidden:!1});function u(t,e){const r=function(t,e){const r={};!t.hFlip!=!e.hFlip&&(r.hFlip=!0),!t.vFlip!=!e.vFlip&&(r.vFlip=!0);const i=((t.rotate||0)+(e.rotate||0))%4;return i&&(r.rotate=i),r}(t,e);for(const i in h)i in l?i in t&&!(i in r)&&(r[i]=l[i]):i in e?r[i]=e[i]:i in t&&(r[i]=t[i]);return r}function d(t,e,r){const i=t.icons,n=t.aliases||Object.create(null);let a={};function o(t){a=u(i[t]||n[t],a)}return o(e),r.forEach(o),u(t,a)}function p(t,e){if(t.icons[e])return d(t,e,[]);const r=function(t,e){const r=t.icons,i=t.aliases||Object.create(null),n=Object.create(null);return(e||Object.keys(r).concat(Object.keys(i))).forEach(function t(e){if(r[e])return n[e]=[];if(!(e in n)){n[e]=null;const r=i[e]&&i[e].parent,a=r&&t(r);a&&(n[e]=[r].concat(a))}return n[e]}),n}(t,[e])[e];return r?d(t,e,r):null}const f=Object.freeze({width:null,height:null}),g=Object.freeze({...f,...l}),y=/(-?[0-9.]*[0-9]+[0-9.]*)/g,m=/^-?[0-9.]*[0-9]+[0-9.]*$/g;function x(t,e,r){if(1===e)return t;if(r=r||100,"number"==typeof t)return Math.ceil(t*e*r)/r;if("string"!=typeof t)return t;const i=t.split(y);if(null===i||!i.length)return t;const n=[];let a=i.shift(),o=m.test(a);for(;;){if(o){const t=parseFloat(a);isNaN(t)?n.push(a):n.push(Math.ceil(t*e*r)/r)}else n.push(a);if(a=i.shift(),void 0===a)return n.join("");o=!o}}const b=/\sid="(\S+)"/g,k="IconifyId"+Date.now().toString(16)+(16777216*Math.random()|0).toString(16);let w=0;var C=r(70451);function _(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var v={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null};function S(t){v=t}var T={exec:()=>null};function A(t,e=""){let r="string"==typeof t?t:t.source,i={replace:(t,e)=>{let n="string"==typeof e?e:e.source;return n=n.replace(M.caret,"$1"),r=r.replace(t,n),i},getRegex:()=>new RegExp(r,e)};return i}var M={codeRemoveIndent:/^(?: {1,4}| {0,3}\t)/gm,outputLinkReplace:/\\([\[\]])/g,indentCodeCompensation:/^(\s+)(?:```)/,beginningSpace:/^\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\n/g,tabCharGlobal:/\t/g,multipleSpaceGlobal:/\s+/g,blankLine:/^[ \t]*$/,doubleBlankLine:/\n[ \t]*\n[ \t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \t]?/gm,listReplaceTabs:/^\t+/,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\[[ xX]\] /,listReplaceTask:/^\[[ xX]\] +/,anyLine:/\n.*\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\||\| *$/g,tableRowBlankLine:/\n[ \t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^<a /i,endATag:/^<\/a>/i,startPreScriptTag:/^<(pre|code|kbd|script)(\s|>)/i,endPreScriptTag:/^<\/(pre|code|kbd|script)(\s|>)/i,startAngleBracket:/^</,endAngleBracket:/>$/,pedanticHrefTitle:/^([^'"]*[^\s])\s+(['"])(.*)\2/,unicodeAlphaNumeric:/[\p{L}\p{N}]/u,escapeTest:/[&<>"']/,escapeReplace:/[&<>"']/g,escapeTestNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,escapeReplaceNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,unescapeTest:/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi,caret:/(^|[^\[])\^/g,percentDecode:/%25/g,findPipe:/\|/g,splitPipe:/ \|/,slashPipe:/\\\|/g,carriageReturn:/\r\n|\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\S*/,endingNewline:/\n$/,listItemRegex:t=>new RegExp(`^( {0,3}${t})((?:[\t ][^\\n]*)?(?:\\n|$))`),nextBulletRegex:t=>new RegExp(`^ {0,${Math.min(3,t-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`),hrRegex:t=>new RegExp(`^ {0,${Math.min(3,t-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),fencesBeginRegex:t=>new RegExp(`^ {0,${Math.min(3,t-1)}}(?:\`\`\`|~~~)`),headingBeginRegex:t=>new RegExp(`^ {0,${Math.min(3,t-1)}}#`),htmlBeginRegex:t=>new RegExp(`^ {0,${Math.min(3,t-1)}}<(?:[a-z].*>|!--)`,"i")},B=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,L=/(?:[*+-]|\d{1,9}[.)])/,F=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,$=A(F).replace(/bull/g,L).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/\|table/g,"").getRegex(),E=A(F).replace(/bull/g,L).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/table/g,/ {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(),D=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,O=/(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/,R=A(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label",O).replace("title",/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),K=A(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,L).getRegex(),I="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",N=/<!--(?:-?>|[\s\S]*?(?:-->|$))/,z=A("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$))","i").replace("comment",N).replace("tag",I).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),P=A(D).replace("hr",B).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",I).getRegex(),q={blockquote:A(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph",P).getRegex(),code:/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,def:R,fences:/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,hr:B,html:z,lheading:$,list:K,newline:/^(?:[ \t]*(?:\n|$))+/,paragraph:P,table:T,text:/^[^\n]+/},j=A("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr",B).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("blockquote"," {0,3}>").replace("code","(?: {4}| {0,3}\t)[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",I).getRegex(),W={...q,lheading:E,table:j,paragraph:A(D).replace("hr",B).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("table",j).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",I).getRegex()},H={...q,html:A("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:\"[^\"]*\"|'[^']*'|\\s[^'\"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",N).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:T,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:A(D).replace("hr",B).replace("heading"," *#{1,6} *[^\n]").replace("lheading",$).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},U=/^( {2,}|\\)\n(?!\s*$)/,Y=/[\p{P}\p{S}]/u,G=/[\s\p{P}\p{S}]/u,X=/[^\s\p{P}\p{S}]/u,V=A(/^((?![*_])punctSpace)/,"u").replace(/punctSpace/g,G).getRegex(),Z=/(?!~)[\p{P}\p{S}]/u,Q=A(/link|code|html/,"g").replace("link",/\[(?:[^\[\]`]|(?<!`)(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("code",/(?<!`)(?<b>`+)[^`]+\k<b>(?!`)/).replace("html",/<(?! )[^<>]*?>/).getRegex(),J=/^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/,tt=A(J,"u").replace(/punct/g,Y).getRegex(),et=A(J,"u").replace(/punct/g,Z).getRegex(),rt="^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)",it=A(rt,"gu").replace(/notPunctSpace/g,X).replace(/punctSpace/g,G).replace(/punct/g,Y).getRegex(),nt=A(rt,"gu").replace(/notPunctSpace/g,/(?:[^\s\p{P}\p{S}]|~)/u).replace(/punctSpace/g,/(?!~)[\s\p{P}\p{S}]/u).replace(/punct/g,Z).getRegex(),at=A("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,X).replace(/punctSpace/g,G).replace(/punct/g,Y).getRegex(),ot=A(/\\(punct)/,"gu").replace(/punct/g,Y).getRegex(),st=A(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),lt=A(N).replace("(?:--\x3e|$)","--\x3e").getRegex(),ct=A("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment",lt).replace("attribute",/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),ht=/(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+[^`]*?`+(?!`)|[^\[\]\\`])*?/,ut=A(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]*(?:\n[ \t]*)?)(title))?\s*\)/).replace("label",ht).replace("href",/<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title",/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),dt=A(/^!?\[(label)\]\[(ref)\]/).replace("label",ht).replace("ref",O).getRegex(),pt=A(/^!?\[(ref)\](?:\[\])?/).replace("ref",O).getRegex(),ft=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,gt={_backpedal:T,anyPunctuation:ot,autolink:st,blockSkip:Q,br:U,code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,del:T,emStrongLDelim:tt,emStrongRDelimAst:it,emStrongRDelimUnd:at,escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,link:ut,nolink:pt,punctuation:V,reflink:dt,reflinkSearch:A("reflink|nolink(?!\\()","g").replace("reflink",dt).replace("nolink",pt).getRegex(),tag:ct,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,url:T},yt={...gt,link:A(/^!?\[(label)\]\((.*?)\)/).replace("label",ht).getRegex(),reflink:A(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",ht).getRegex()},mt={...gt,emStrongRDelimAst:nt,emStrongLDelim:et,url:A(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol",ft).replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/,text:A(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace("protocol",ft).getRegex()},xt={...mt,br:A(U).replace("{2,}","*").getRegex(),text:A(mt.text).replace("\\b_","\\b_| {2,}\\n").replace(/\{2,\}/g,"*").getRegex()},bt={normal:q,gfm:W,pedantic:H},kt={normal:gt,gfm:mt,breaks:xt,pedantic:yt},wt={"&":"&","<":"<",">":">",'"':""","'":"'"},Ct=t=>wt[t];function _t(t,e){if(e){if(M.escapeTest.test(t))return t.replace(M.escapeReplace,Ct)}else if(M.escapeTestNoEncode.test(t))return t.replace(M.escapeReplaceNoEncode,Ct);return t}function vt(t){try{t=encodeURI(t).replace(M.percentDecode,"%")}catch{return null}return t}function St(t,e){let r=t.replace(M.findPipe,(t,e,r)=>{let i=!1,n=e;for(;--n>=0&&"\\"===r[n];)i=!i;return i?"|":" |"}).split(M.splitPipe),i=0;if(r[0].trim()||r.shift(),r.length>0&&!r.at(-1)?.trim()&&r.pop(),e)if(r.length>e)r.splice(e);else for(;r.length<e;)r.push("");for(;i<r.length;i++)r[i]=r[i].trim().replace(M.slashPipe,"|");return r}function Tt(t,e,r){let i=t.length;if(0===i)return"";let n=0;for(;n<i;){let a=t.charAt(i-n-1);if(a!==e||r){if(a===e||!r)break;n++}else n++}return t.slice(0,i-n)}function At(t,e,r,i,n){let a=e.href,o=e.title||null,s=t[1].replace(n.other.outputLinkReplace,"$1");i.state.inLink=!0;let l={type:"!"===t[0].charAt(0)?"image":"link",raw:r,href:a,title:o,text:s,tokens:i.inlineTokens(s)};return i.state.inLink=!1,l}var Mt=class{options;rules;lexer;constructor(t){this.options=t||v}space(t){let e=this.rules.block.newline.exec(t);if(e&&e[0].length>0)return{type:"space",raw:e[0]}}code(t){let e=this.rules.block.code.exec(t);if(e){let t=e[0].replace(this.rules.other.codeRemoveIndent,"");return{type:"code",raw:e[0],codeBlockStyle:"indented",text:this.options.pedantic?t:Tt(t,"\n")}}}fences(t){let e=this.rules.block.fences.exec(t);if(e){let t=e[0],r=function(t,e,r){let i=t.match(r.other.indentCodeCompensation);if(null===i)return e;let n=i[1];return e.split("\n").map(t=>{let e=t.match(r.other.beginningSpace);if(null===e)return t;let[i]=e;return i.length>=n.length?t.slice(n.length):t}).join("\n")}(t,e[3]||"",this.rules);return{type:"code",raw:t,lang:e[2]?e[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):e[2],text:r}}}heading(t){let e=this.rules.block.heading.exec(t);if(e){let t=e[2].trim();if(this.rules.other.endingHash.test(t)){let e=Tt(t,"#");(this.options.pedantic||!e||this.rules.other.endingSpaceChar.test(e))&&(t=e.trim())}return{type:"heading",raw:e[0],depth:e[1].length,text:t,tokens:this.lexer.inline(t)}}}hr(t){let e=this.rules.block.hr.exec(t);if(e)return{type:"hr",raw:Tt(e[0],"\n")}}blockquote(t){let e=this.rules.block.blockquote.exec(t);if(e){let t=Tt(e[0],"\n").split("\n"),r="",i="",n=[];for(;t.length>0;){let e,a=!1,o=[];for(e=0;e<t.length;e++)if(this.rules.other.blockquoteStart.test(t[e]))o.push(t[e]),a=!0;else{if(a)break;o.push(t[e])}t=t.slice(e);let s=o.join("\n"),l=s.replace(this.rules.other.blockquoteSetextReplace,"\n $1").replace(this.rules.other.blockquoteSetextReplace2,"");r=r?`${r}\n${s}`:s,i=i?`${i}\n${l}`:l;let c=this.lexer.state.top;if(this.lexer.state.top=!0,this.lexer.blockTokens(l,n,!0),this.lexer.state.top=c,0===t.length)break;let h=n.at(-1);if("code"===h?.type)break;if("blockquote"===h?.type){let e=h,a=e.raw+"\n"+t.join("\n"),o=this.blockquote(a);n[n.length-1]=o,r=r.substring(0,r.length-e.raw.length)+o.raw,i=i.substring(0,i.length-e.text.length)+o.text;break}if("list"===h?.type){let e=h,a=e.raw+"\n"+t.join("\n"),o=this.list(a);n[n.length-1]=o,r=r.substring(0,r.length-h.raw.length)+o.raw,i=i.substring(0,i.length-e.raw.length)+o.raw,t=a.substring(n.at(-1).raw.length).split("\n");continue}}return{type:"blockquote",raw:r,tokens:n,text:i}}}list(t){let e=this.rules.block.list.exec(t);if(e){let r=e[1].trim(),i=r.length>1,n={type:"list",raw:"",ordered:i,start:i?+r.slice(0,-1):"",loose:!1,items:[]};r=i?`\\d{1,9}\\${r.slice(-1)}`:`\\${r}`,this.options.pedantic&&(r=i?r:"[*+-]");let a=this.rules.other.listItemRegex(r),o=!1;for(;t;){let r=!1,i="",s="";if(!(e=a.exec(t))||this.rules.block.hr.test(t))break;i=e[0],t=t.substring(i.length);let l=e[2].split("\n",1)[0].replace(this.rules.other.listReplaceTabs,t=>" ".repeat(3*t.length)),c=t.split("\n",1)[0],h=!l.trim(),u=0;if(this.options.pedantic?(u=2,s=l.trimStart()):h?u=e[1].length+1:(u=e[2].search(this.rules.other.nonSpaceChar),u=u>4?1:u,s=l.slice(u),u+=e[1].length),h&&this.rules.other.blankLine.test(c)&&(i+=c+"\n",t=t.substring(c.length+1),r=!0),!r){let e=this.rules.other.nextBulletRegex(u),r=this.rules.other.hrRegex(u),n=this.rules.other.fencesBeginRegex(u),a=this.rules.other.headingBeginRegex(u),o=this.rules.other.htmlBeginRegex(u);for(;t;){let d,p=t.split("\n",1)[0];if(c=p,this.options.pedantic?(c=c.replace(this.rules.other.listReplaceNesting," "),d=c):d=c.replace(this.rules.other.tabCharGlobal," "),n.test(c)||a.test(c)||o.test(c)||e.test(c)||r.test(c))break;if(d.search(this.rules.other.nonSpaceChar)>=u||!c.trim())s+="\n"+d.slice(u);else{if(h||l.replace(this.rules.other.tabCharGlobal," ").search(this.rules.other.nonSpaceChar)>=4||n.test(l)||a.test(l)||r.test(l))break;s+="\n"+c}!h&&!c.trim()&&(h=!0),i+=p+"\n",t=t.substring(p.length+1),l=d.slice(u)}}n.loose||(o?n.loose=!0:this.rules.other.doubleBlankLine.test(i)&&(o=!0));let d,p=null;this.options.gfm&&(p=this.rules.other.listIsTask.exec(s),p&&(d="[ ] "!==p[0],s=s.replace(this.rules.other.listReplaceTask,""))),n.items.push({type:"list_item",raw:i,task:!!p,checked:d,loose:!1,text:s,tokens:[]}),n.raw+=i}let s=n.items.at(-1);if(!s)return;s.raw=s.raw.trimEnd(),s.text=s.text.trimEnd(),n.raw=n.raw.trimEnd();for(let t=0;t<n.items.length;t++)if(this.lexer.state.top=!1,n.items[t].tokens=this.lexer.blockTokens(n.items[t].text,[]),!n.loose){let e=n.items[t].tokens.filter(t=>"space"===t.type),r=e.length>0&&e.some(t=>this.rules.other.anyLine.test(t.raw));n.loose=r}if(n.loose)for(let t=0;t<n.items.length;t++)n.items[t].loose=!0;return n}}html(t){let e=this.rules.block.html.exec(t);if(e)return{type:"html",block:!0,raw:e[0],pre:"pre"===e[1]||"script"===e[1]||"style"===e[1],text:e[0]}}def(t){let e=this.rules.block.def.exec(t);if(e){let t=e[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal," "),r=e[2]?e[2].replace(this.rules.other.hrefBrackets,"$1").replace(this.rules.inline.anyPunctuation,"$1"):"",i=e[3]?e[3].substring(1,e[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"):e[3];return{type:"def",tag:t,raw:e[0],href:r,title:i}}}table(t){let e=this.rules.block.table.exec(t);if(!e||!this.rules.other.tableDelimiter.test(e[2]))return;let r=St(e[1]),i=e[2].replace(this.rules.other.tableAlignChars,"").split("|"),n=e[3]?.trim()?e[3].replace(this.rules.other.tableRowBlankLine,"").split("\n"):[],a={type:"table",raw:e[0],header:[],align:[],rows:[]};if(r.length===i.length){for(let t of i)this.rules.other.tableAlignRight.test(t)?a.align.push("right"):this.rules.other.tableAlignCenter.test(t)?a.align.push("center"):this.rules.other.tableAlignLeft.test(t)?a.align.push("left"):a.align.push(null);for(let t=0;t<r.length;t++)a.header.push({text:r[t],tokens:this.lexer.inline(r[t]),header:!0,align:a.align[t]});for(let t of n)a.rows.push(St(t,a.header.length).map((t,e)=>({text:t,tokens:this.lexer.inline(t),header:!1,align:a.align[e]})));return a}}lheading(t){let e=this.rules.block.lheading.exec(t);if(e)return{type:"heading",raw:e[0],depth:"="===e[2].charAt(0)?1:2,text:e[1],tokens:this.lexer.inline(e[1])}}paragraph(t){let e=this.rules.block.paragraph.exec(t);if(e){let t="\n"===e[1].charAt(e[1].length-1)?e[1].slice(0,-1):e[1];return{type:"paragraph",raw:e[0],text:t,tokens:this.lexer.inline(t)}}}text(t){let e=this.rules.block.text.exec(t);if(e)return{type:"text",raw:e[0],text:e[0],tokens:this.lexer.inline(e[0])}}escape(t){let e=this.rules.inline.escape.exec(t);if(e)return{type:"escape",raw:e[0],text:e[1]}}tag(t){let e=this.rules.inline.tag.exec(t);if(e)return!this.lexer.state.inLink&&this.rules.other.startATag.test(e[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(e[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(e[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(e[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:e[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:e[0]}}link(t){let e=this.rules.inline.link.exec(t);if(e){let t=e[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(t)){if(!this.rules.other.endAngleBracket.test(t))return;let e=Tt(t.slice(0,-1),"\\");if((t.length-e.length)%2==0)return}else{let t=function(t,e){if(-1===t.indexOf(e[1]))return-1;let r=0;for(let i=0;i<t.length;i++)if("\\"===t[i])i++;else if(t[i]===e[0])r++;else if(t[i]===e[1]&&(r--,r<0))return i;return r>0?-2:-1}(e[2],"()");if(-2===t)return;if(t>-1){let r=(0===e[0].indexOf("!")?5:4)+e[1].length+t;e[2]=e[2].substring(0,t),e[0]=e[0].substring(0,r).trim(),e[3]=""}}let r=e[2],i="";if(this.options.pedantic){let t=this.rules.other.pedanticHrefTitle.exec(r);t&&(r=t[1],i=t[3])}else i=e[3]?e[3].slice(1,-1):"";return r=r.trim(),this.rules.other.startAngleBracket.test(r)&&(r=this.options.pedantic&&!this.rules.other.endAngleBracket.test(t)?r.slice(1):r.slice(1,-1)),At(e,{href:r&&r.replace(this.rules.inline.anyPunctuation,"$1"),title:i&&i.replace(this.rules.inline.anyPunctuation,"$1")},e[0],this.lexer,this.rules)}}reflink(t,e){let r;if((r=this.rules.inline.reflink.exec(t))||(r=this.rules.inline.nolink.exec(t))){let t=e[(r[2]||r[1]).replace(this.rules.other.multipleSpaceGlobal," ").toLowerCase()];if(!t){let t=r[0].charAt(0);return{type:"text",raw:t,text:t}}return At(r,t,r[0],this.lexer,this.rules)}}emStrong(t,e,r=""){let i=this.rules.inline.emStrongLDelim.exec(t);if(!(!i||i[3]&&r.match(this.rules.other.unicodeAlphaNumeric))&&(!i[1]&&!i[2]||!r||this.rules.inline.punctuation.exec(r))){let r,n,a=[...i[0]].length-1,o=a,s=0,l="*"===i[0][0]?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(l.lastIndex=0,e=e.slice(-1*t.length+a);null!=(i=l.exec(e));){if(r=i[1]||i[2]||i[3]||i[4]||i[5]||i[6],!r)continue;if(n=[...r].length,i[3]||i[4]){o+=n;continue}if((i[5]||i[6])&&a%3&&!((a+n)%3)){s+=n;continue}if(o-=n,o>0)continue;n=Math.min(n,n+o+s);let e=[...i[0]][0].length,l=t.slice(0,a+i.index+e+n);if(Math.min(a,n)%2){let t=l.slice(1,-1);return{type:"em",raw:l,text:t,tokens:this.lexer.inlineTokens(t)}}let c=l.slice(2,-2);return{type:"strong",raw:l,text:c,tokens:this.lexer.inlineTokens(c)}}}}codespan(t){let e=this.rules.inline.code.exec(t);if(e){let t=e[2].replace(this.rules.other.newLineCharGlobal," "),r=this.rules.other.nonSpaceChar.test(t),i=this.rules.other.startingSpaceChar.test(t)&&this.rules.other.endingSpaceChar.test(t);return r&&i&&(t=t.substring(1,t.length-1)),{type:"codespan",raw:e[0],text:t}}}br(t){let e=this.rules.inline.br.exec(t);if(e)return{type:"br",raw:e[0]}}del(t){let e=this.rules.inline.del.exec(t);if(e)return{type:"del",raw:e[0],text:e[2],tokens:this.lexer.inlineTokens(e[2])}}autolink(t){let e=this.rules.inline.autolink.exec(t);if(e){let t,r;return"@"===e[2]?(t=e[1],r="mailto:"+t):(t=e[1],r=t),{type:"link",raw:e[0],text:t,href:r,tokens:[{type:"text",raw:t,text:t}]}}}url(t){let e;if(e=this.rules.inline.url.exec(t)){let t,r;if("@"===e[2])t=e[0],r="mailto:"+t;else{let i;do{i=e[0],e[0]=this.rules.inline._backpedal.exec(e[0])?.[0]??""}while(i!==e[0]);t=e[0],r="www."===e[1]?"http://"+e[0]:e[0]}return{type:"link",raw:e[0],text:t,href:r,tokens:[{type:"text",raw:t,text:t}]}}}inlineText(t){let e=this.rules.inline.text.exec(t);if(e){let t=this.lexer.state.inRawBlock;return{type:"text",raw:e[0],text:e[0],escaped:t}}}},Bt=class t{tokens;options;state;tokenizer;inlineQueue;constructor(t){this.tokens=[],this.tokens.links=Object.create(null),this.options=t||v,this.options.tokenizer=this.options.tokenizer||new Mt,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};let e={other:M,block:bt.normal,inline:kt.normal};this.options.pedantic?(e.block=bt.pedantic,e.inline=kt.pedantic):this.options.gfm&&(e.block=bt.gfm,this.options.breaks?e.inline=kt.breaks:e.inline=kt.gfm),this.tokenizer.rules=e}static get rules(){return{block:bt,inline:kt}}static lex(e,r){return new t(r).lex(e)}static lexInline(e,r){return new t(r).inlineTokens(e)}lex(t){t=t.replace(M.carriageReturn,"\n"),this.blockTokens(t,this.tokens);for(let e=0;e<this.inlineQueue.length;e++){let t=this.inlineQueue[e];this.inlineTokens(t.src,t.tokens)}return this.inlineQueue=[],this.tokens}blockTokens(t,e=[],r=!1){for(this.options.pedantic&&(t=t.replace(M.tabCharGlobal," ").replace(M.spaceLine,""));t;){let i;if(this.options.extensions?.block?.some(r=>!!(i=r.call({lexer:this},t,e))&&(t=t.substring(i.raw.length),e.push(i),!0)))continue;if(i=this.tokenizer.space(t)){t=t.substring(i.raw.length);let r=e.at(-1);1===i.raw.length&&void 0!==r?r.raw+="\n":e.push(i);continue}if(i=this.tokenizer.code(t)){t=t.substring(i.raw.length);let r=e.at(-1);"paragraph"===r?.type||"text"===r?.type?(r.raw+=(r.raw.endsWith("\n")?"":"\n")+i.raw,r.text+="\n"+i.text,this.inlineQueue.at(-1).src=r.text):e.push(i);continue}if(i=this.tokenizer.fences(t)){t=t.substring(i.raw.length),e.push(i);continue}if(i=this.tokenizer.heading(t)){t=t.substring(i.raw.length),e.push(i);continue}if(i=this.tokenizer.hr(t)){t=t.substring(i.raw.length),e.push(i);continue}if(i=this.tokenizer.blockquote(t)){t=t.substring(i.raw.length),e.push(i);continue}if(i=this.tokenizer.list(t)){t=t.substring(i.raw.length),e.push(i);continue}if(i=this.tokenizer.html(t)){t=t.substring(i.raw.length),e.push(i);continue}if(i=this.tokenizer.def(t)){t=t.substring(i.raw.length);let r=e.at(-1);"paragraph"===r?.type||"text"===r?.type?(r.raw+=(r.raw.endsWith("\n")?"":"\n")+i.raw,r.text+="\n"+i.raw,this.inlineQueue.at(-1).src=r.text):this.tokens.links[i.tag]||(this.tokens.links[i.tag]={href:i.href,title:i.title},e.push(i));continue}if(i=this.tokenizer.table(t)){t=t.substring(i.raw.length),e.push(i);continue}if(i=this.tokenizer.lheading(t)){t=t.substring(i.raw.length),e.push(i);continue}let n=t;if(this.options.extensions?.startBlock){let e,r=1/0,i=t.slice(1);this.options.extensions.startBlock.forEach(t=>{e=t.call({lexer:this},i),"number"==typeof e&&e>=0&&(r=Math.min(r,e))}),r<1/0&&r>=0&&(n=t.substring(0,r+1))}if(this.state.top&&(i=this.tokenizer.paragraph(n))){let a=e.at(-1);r&&"paragraph"===a?.type?(a.raw+=(a.raw.endsWith("\n")?"":"\n")+i.raw,a.text+="\n"+i.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=a.text):e.push(i),r=n.length!==t.length,t=t.substring(i.raw.length);continue}if(i=this.tokenizer.text(t)){t=t.substring(i.raw.length);let r=e.at(-1);"text"===r?.type?(r.raw+=(r.raw.endsWith("\n")?"":"\n")+i.raw,r.text+="\n"+i.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=r.text):e.push(i);continue}if(t){let e="Infinite loop on byte: "+t.charCodeAt(0);if(this.options.silent){console.error(e);break}throw new Error(e)}}return this.state.top=!0,e}inline(t,e=[]){return this.inlineQueue.push({src:t,tokens:e}),e}inlineTokens(t,e=[]){let r=t,i=null;if(this.tokens.links){let t=Object.keys(this.tokens.links);if(t.length>0)for(;null!=(i=this.tokenizer.rules.inline.reflinkSearch.exec(r));)t.includes(i[0].slice(i[0].lastIndexOf("[")+1,-1))&&(r=r.slice(0,i.index)+"["+"a".repeat(i[0].length-2)+"]"+r.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;null!=(i=this.tokenizer.rules.inline.anyPunctuation.exec(r));)r=r.slice(0,i.index)+"++"+r.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);for(;null!=(i=this.tokenizer.rules.inline.blockSkip.exec(r));)r=r.slice(0,i.index)+"["+"a".repeat(i[0].length-2)+"]"+r.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);r=this.options.hooks?.emStrongMask?.call({lexer:this},r)??r;let n=!1,a="";for(;t;){let i;if(n||(a=""),n=!1,this.options.extensions?.inline?.some(r=>!!(i=r.call({lexer:this},t,e))&&(t=t.substring(i.raw.length),e.push(i),!0)))continue;if(i=this.tokenizer.escape(t)){t=t.substring(i.raw.length),e.push(i);continue}if(i=this.tokenizer.tag(t)){t=t.substring(i.raw.length),e.push(i);continue}if(i=this.tokenizer.link(t)){t=t.substring(i.raw.length),e.push(i);continue}if(i=this.tokenizer.reflink(t,this.tokens.links)){t=t.substring(i.raw.length);let r=e.at(-1);"text"===i.type&&"text"===r?.type?(r.raw+=i.raw,r.text+=i.text):e.push(i);continue}if(i=this.tokenizer.emStrong(t,r,a)){t=t.substring(i.raw.length),e.push(i);continue}if(i=this.tokenizer.codespan(t)){t=t.substring(i.raw.length),e.push(i);continue}if(i=this.tokenizer.br(t)){t=t.substring(i.raw.length),e.push(i);continue}if(i=this.tokenizer.del(t)){t=t.substring(i.raw.length),e.push(i);continue}if(i=this.tokenizer.autolink(t)){t=t.substring(i.raw.length),e.push(i);continue}if(!this.state.inLink&&(i=this.tokenizer.url(t))){t=t.substring(i.raw.length),e.push(i);continue}let o=t;if(this.options.extensions?.startInline){let e,r=1/0,i=t.slice(1);this.options.extensions.startInline.forEach(t=>{e=t.call({lexer:this},i),"number"==typeof e&&e>=0&&(r=Math.min(r,e))}),r<1/0&&r>=0&&(o=t.substring(0,r+1))}if(i=this.tokenizer.inlineText(o)){t=t.substring(i.raw.length),"_"!==i.raw.slice(-1)&&(a=i.raw.slice(-1)),n=!0;let r=e.at(-1);"text"===r?.type?(r.raw+=i.raw,r.text+=i.text):e.push(i);continue}if(t){let e="Infinite loop on byte: "+t.charCodeAt(0);if(this.options.silent){console.error(e);break}throw new Error(e)}}return e}},Lt=class{options;parser;constructor(t){this.options=t||v}space(t){return""}code({text:t,lang:e,escaped:r}){let i=(e||"").match(M.notSpaceStart)?.[0],n=t.replace(M.endingNewline,"")+"\n";return i?'<pre><code class="language-'+_t(i)+'">'+(r?n:_t(n,!0))+"</code></pre>\n":"<pre><code>"+(r?n:_t(n,!0))+"</code></pre>\n"}blockquote({tokens:t}){return`<blockquote>\n${this.parser.parse(t)}</blockquote>\n`}html({text:t}){return t}def(t){return""}heading({tokens:t,depth:e}){return`<h${e}>${this.parser.parseInline(t)}</h${e}>\n`}hr(t){return"<hr>\n"}list(t){let e=t.ordered,r=t.start,i="";for(let a=0;a<t.items.length;a++){let e=t.items[a];i+=this.listitem(e)}let n=e?"ol":"ul";return"<"+n+(e&&1!==r?' start="'+r+'"':"")+">\n"+i+"</"+n+">\n"}listitem(t){let e="";if(t.task){let r=this.checkbox({checked:!!t.checked});t.loose?"paragraph"===t.tokens[0]?.type?(t.tokens[0].text=r+" "+t.tokens[0].text,t.tokens[0].tokens&&t.tokens[0].tokens.length>0&&"text"===t.tokens[0].tokens[0].type&&(t.tokens[0].tokens[0].text=r+" "+_t(t.tokens[0].tokens[0].text),t.tokens[0].tokens[0].escaped=!0)):t.tokens.unshift({type:"text",raw:r+" ",text:r+" ",escaped:!0}):e+=r+" "}return e+=this.parser.parse(t.tokens,!!t.loose),`<li>${e}</li>\n`}checkbox({checked:t}){return"<input "+(t?'checked="" ':"")+'disabled="" type="checkbox">'}paragraph({tokens:t}){return`<p>${this.parser.parseInline(t)}</p>\n`}table(t){let e="",r="";for(let n=0;n<t.header.length;n++)r+=this.tablecell(t.header[n]);e+=this.tablerow({text:r});let i="";for(let n=0;n<t.rows.length;n++){let e=t.rows[n];r="";for(let t=0;t<e.length;t++)r+=this.tablecell(e[t]);i+=this.tablerow({text:r})}return i&&(i=`<tbody>${i}</tbody>`),"<table>\n<thead>\n"+e+"</thead>\n"+i+"</table>\n"}tablerow({text:t}){return`<tr>\n${t}</tr>\n`}tablecell(t){let e=this.parser.parseInline(t.tokens),r=t.header?"th":"td";return(t.align?`<${r} align="${t.align}">`:`<${r}>`)+e+`</${r}>\n`}strong({tokens:t}){return`<strong>${this.parser.parseInline(t)}</strong>`}em({tokens:t}){return`<em>${this.parser.parseInline(t)}</em>`}codespan({text:t}){return`<code>${_t(t,!0)}</code>`}br(t){return"<br>"}del({tokens:t}){return`<del>${this.parser.parseInline(t)}</del>`}link({href:t,title:e,tokens:r}){let i=this.parser.parseInline(r),n=vt(t);if(null===n)return i;let a='<a href="'+(t=n)+'"';return e&&(a+=' title="'+_t(e)+'"'),a+=">"+i+"</a>",a}image({href:t,title:e,text:r,tokens:i}){i&&(r=this.parser.parseInline(i,this.parser.textRenderer));let n=vt(t);if(null===n)return _t(r);let a=`<img src="${t=n}" alt="${r}"`;return e&&(a+=` title="${_t(e)}"`),a+=">",a}text(t){return"tokens"in t&&t.tokens?this.parser.parseInline(t.tokens):"escaped"in t&&t.escaped?t.text:_t(t.text)}},Ft=class{strong({text:t}){return t}em({text:t}){return t}codespan({text:t}){return t}del({text:t}){return t}html({text:t}){return t}text({text:t}){return t}link({text:t}){return""+t}image({text:t}){return""+t}br(){return""}},$t=class t{options;renderer;textRenderer;constructor(t){this.options=t||v,this.options.renderer=this.options.renderer||new Lt,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new Ft}static parse(e,r){return new t(r).parse(e)}static parseInline(e,r){return new t(r).parseInline(e)}parse(t,e=!0){let r="";for(let i=0;i<t.length;i++){let n=t[i];if(this.options.extensions?.renderers?.[n.type]){let t=n,e=this.options.extensions.renderers[t.type].call({parser:this},t);if(!1!==e||!["space","hr","heading","code","table","blockquote","list","html","def","paragraph","text"].includes(t.type)){r+=e||"";continue}}let a=n;switch(a.type){case"space":r+=this.renderer.space(a);continue;case"hr":r+=this.renderer.hr(a);continue;case"heading":r+=this.renderer.heading(a);continue;case"code":r+=this.renderer.code(a);continue;case"table":r+=this.renderer.table(a);continue;case"blockquote":r+=this.renderer.blockquote(a);continue;case"list":r+=this.renderer.list(a);continue;case"html":r+=this.renderer.html(a);continue;case"def":r+=this.renderer.def(a);continue;case"paragraph":r+=this.renderer.paragraph(a);continue;case"text":{let n=a,o=this.renderer.text(n);for(;i+1<t.length&&"text"===t[i+1].type;)n=t[++i],o+="\n"+this.renderer.text(n);r+=e?this.renderer.paragraph({type:"paragraph",raw:o,text:o,tokens:[{type:"text",raw:o,text:o,escaped:!0}]}):o;continue}default:{let t='Token with "'+a.type+'" type was not found.';if(this.options.silent)return console.error(t),"";throw new Error(t)}}}return r}parseInline(t,e=this.renderer){let r="";for(let i=0;i<t.length;i++){let n=t[i];if(this.options.extensions?.renderers?.[n.type]){let t=this.options.extensions.renderers[n.type].call({parser:this},n);if(!1!==t||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(n.type)){r+=t||"";continue}}let a=n;switch(a.type){case"escape":case"text":r+=e.text(a);break;case"html":r+=e.html(a);break;case"link":r+=e.link(a);break;case"image":r+=e.image(a);break;case"strong":r+=e.strong(a);break;case"em":r+=e.em(a);break;case"codespan":r+=e.codespan(a);break;case"br":r+=e.br(a);break;case"del":r+=e.del(a);break;default:{let t='Token with "'+a.type+'" type was not found.';if(this.options.silent)return console.error(t),"";throw new Error(t)}}}return r}},Et=class{options;block;constructor(t){this.options=t||v}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens","emStrongMask"]);static passThroughHooksRespectAsync=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(t){return t}postprocess(t){return t}processAllTokens(t){return t}emStrongMask(t){return t}provideLexer(){return this.block?Bt.lex:Bt.lexInline}provideParser(){return this.block?$t.parse:$t.parseInline}},Dt=new class{defaults={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null};options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=$t;Renderer=Lt;TextRenderer=Ft;Lexer=Bt;Tokenizer=Mt;Hooks=Et;constructor(...t){this.use(...t)}walkTokens(t,e){let r=[];for(let i of t)switch(r=r.concat(e.call(this,i)),i.type){case"table":{let t=i;for(let i of t.header)r=r.concat(this.walkTokens(i.tokens,e));for(let i of t.rows)for(let t of i)r=r.concat(this.walkTokens(t.tokens,e));break}case"list":{let t=i;r=r.concat(this.walkTokens(t.items,e));break}default:{let t=i;this.defaults.extensions?.childTokens?.[t.type]?this.defaults.extensions.childTokens[t.type].forEach(i=>{let n=t[i].flat(1/0);r=r.concat(this.walkTokens(n,e))}):t.tokens&&(r=r.concat(this.walkTokens(t.tokens,e)))}}return r}use(...t){let e=this.defaults.extensions||{renderers:{},childTokens:{}};return t.forEach(t=>{let r={...t};if(r.async=this.defaults.async||r.async||!1,t.extensions&&(t.extensions.forEach(t=>{if(!t.name)throw new Error("extension name required");if("renderer"in t){let r=e.renderers[t.name];e.renderers[t.name]=r?function(...e){let i=t.renderer.apply(this,e);return!1===i&&(i=r.apply(this,e)),i}:t.renderer}if("tokenizer"in t){if(!t.level||"block"!==t.level&&"inline"!==t.level)throw new Error("extension level must be 'block' or 'inline'");let r=e[t.level];r?r.unshift(t.tokenizer):e[t.level]=[t.tokenizer],t.start&&("block"===t.level?e.startBlock?e.startBlock.push(t.start):e.startBlock=[t.start]:"inline"===t.level&&(e.startInline?e.startInline.push(t.start):e.startInline=[t.start]))}"childTokens"in t&&t.childTokens&&(e.childTokens[t.name]=t.childTokens)}),r.extensions=e),t.renderer){let e=this.defaults.renderer||new Lt(this.defaults);for(let r in t.renderer){if(!(r in e))throw new Error(`renderer '${r}' does not exist`);if(["options","parser"].includes(r))continue;let i=r,n=t.renderer[i],a=e[i];e[i]=(...t)=>{let r=n.apply(e,t);return!1===r&&(r=a.apply(e,t)),r||""}}r.renderer=e}if(t.tokenizer){let e=this.defaults.tokenizer||new Mt(this.defaults);for(let r in t.tokenizer){if(!(r in e))throw new Error(`tokenizer '${r}' does not exist`);if(["options","rules","lexer"].includes(r))continue;let i=r,n=t.tokenizer[i],a=e[i];e[i]=(...t)=>{let r=n.apply(e,t);return!1===r&&(r=a.apply(e,t)),r}}r.tokenizer=e}if(t.hooks){let e=this.defaults.hooks||new Et;for(let r in t.hooks){if(!(r in e))throw new Error(`hook '${r}' does not exist`);if(["options","block"].includes(r))continue;let i=r,n=t.hooks[i],a=e[i];Et.passThroughHooks.has(r)?e[i]=t=>{if(this.defaults.async&&Et.passThroughHooksRespectAsync.has(r))return(async()=>{let r=await n.call(e,t);return a.call(e,r)})();let i=n.call(e,t);return a.call(e,i)}:e[i]=(...t)=>{if(this.defaults.async)return(async()=>{let r=await n.apply(e,t);return!1===r&&(r=await a.apply(e,t)),r})();let r=n.apply(e,t);return!1===r&&(r=a.apply(e,t)),r}}r.hooks=e}if(t.walkTokens){let e=this.defaults.walkTokens,i=t.walkTokens;r.walkTokens=function(t){let r=[];return r.push(i.call(this,t)),e&&(r=r.concat(e.call(this,t))),r}}this.defaults={...this.defaults,...r}}),this}setOptions(t){return this.defaults={...this.defaults,...t},this}lexer(t,e){return Bt.lex(t,e??this.defaults)}parser(t,e){return $t.parse(t,e??this.defaults)}parseMarkdown(t){return(e,r)=>{let i={...r},n={...this.defaults,...i},a=this.onError(!!n.silent,!!n.async);if(!0===this.defaults.async&&!1===i.async)return a(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof e>"u"||null===e)return a(new Error("marked(): input parameter is undefined or null"));if("string"!=typeof e)return a(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected"));if(n.hooks&&(n.hooks.options=n,n.hooks.block=t),n.async)return(async()=>{let r=n.hooks?await n.hooks.preprocess(e):e,i=await(n.hooks?await n.hooks.provideLexer():t?Bt.lex:Bt.lexInline)(r,n),a=n.hooks?await n.hooks.processAllTokens(i):i;n.walkTokens&&await Promise.all(this.walkTokens(a,n.walkTokens));let o=await(n.hooks?await n.hooks.provideParser():t?$t.parse:$t.parseInline)(a,n);return n.hooks?await n.hooks.postprocess(o):o})().catch(a);try{n.hooks&&(e=n.hooks.preprocess(e));let r=(n.hooks?n.hooks.provideLexer():t?Bt.lex:Bt.lexInline)(e,n);n.hooks&&(r=n.hooks.processAllTokens(r)),n.walkTokens&&this.walkTokens(r,n.walkTokens);let i=(n.hooks?n.hooks.provideParser():t?$t.parse:$t.parseInline)(r,n);return n.hooks&&(i=n.hooks.postprocess(i)),i}catch(o){return a(o)}}}onError(t,e){return r=>{if(r.message+="\nPlease report this to https://github.com/markedjs/marked.",t){let t="<p>An error occurred:</p><pre>"+_t(r.message+"",!0)+"</pre>";return e?Promise.resolve(t):t}if(e)return Promise.reject(r);throw r}}};function Ot(t,e){return Dt.parse(t,e)}Ot.options=Ot.setOptions=function(t){return Dt.setOptions(t),Ot.defaults=Dt.defaults,S(Ot.defaults),Ot},Ot.getDefaults=_,Ot.defaults=v,Ot.use=function(...t){return Dt.use(...t),Ot.defaults=Dt.defaults,S(Ot.defaults),Ot},Ot.walkTokens=function(t,e){return Dt.walkTokens(t,e)},Ot.parseInline=Dt.parseInline,Ot.Parser=$t,Ot.parser=$t.parse,Ot.Renderer=Lt,Ot.TextRenderer=Ft,Ot.Lexer=Bt,Ot.lexer=Bt.lex,Ot.Tokenizer=Mt,Ot.Hooks=Et,Ot.parse=Ot;Ot.options,Ot.setOptions,Ot.use,Ot.walkTokens,Ot.parseInline,$t.parse,Bt.lex;var Rt=r(60513),Kt={body:'<g><rect width="80" height="80" style="fill: #087ebf; stroke-width: 0px;"/><text transform="translate(21.16 64.67)" style="fill: #fff; font-family: ArialMT, Arial; font-size: 67.75px;"><tspan x="0" y="0">?</tspan></text></g>',height:80,width:80},It=new Map,Nt=new Map,zt=(0,a.K2)(t=>{for(const e of t){if(!e.name)throw new Error('Invalid icon loader. Must have a "name" property with non-empty string value.');if(a.Rm.debug("Registering icon pack:",e.name),"loader"in e)Nt.set(e.name,e.loader);else{if(!("icons"in e))throw a.Rm.error("Invalid icon loader:",e),new Error('Invalid icon loader. Must have either "icons" or "loader" property.');It.set(e.name,e.icons)}}},"registerIconPacks"),Pt=(0,a.K2)(async(t,e)=>{const r=((t,e,r,i="")=>{const n=t.split(":");if("@"===t.slice(0,1)){if(n.length<2||n.length>3)return null;i=n.shift().slice(1)}if(n.length>3||!n.length)return null;if(n.length>1){const t=n.pop(),r=n.pop(),a={provider:n.length>0?n[0]:i,prefix:r,name:t};return e&&!o(a)?null:a}const a=n[0],s=a.split("-");if(s.length>1){const t={provider:i,prefix:s.shift(),name:s.join("-")};return e&&!o(t)?null:t}if(r&&""===i){const t={provider:i,prefix:"",name:a};return e&&!o(t,r)?null:t}return null})(t,!0,void 0!==e);if(!r)throw new Error(`Invalid icon name: ${t}`);const i=r.prefix||e;if(!i)throw new Error(`Icon name must contain a prefix: ${t}`);let n=It.get(i);if(!n){const t=Nt.get(i);if(!t)throw new Error(`Icon set not found: ${r.prefix}`);try{n={...await t(),prefix:i},It.set(i,n)}catch(l){throw a.Rm.error(l),new Error(`Failed to load icon set: ${r.prefix}`)}}const s=p(n,r.name);if(!s)throw new Error(`Icon not found: ${t}`);return s},"getRegisteredIconData"),qt=(0,a.K2)(async t=>{try{return await Pt(t),!0}catch{return!1}},"isIconAvailable"),jt=(0,a.K2)(async(t,e,r)=>{let i;try{i=await Pt(t,e?.fallbackPrefix)}catch(l){a.Rm.error(l),i=Kt}const o=function(t,e){const r={...c,...t},i={...g,...e},n={left:r.left,top:r.top,width:r.width,height:r.height};let a=r.body;[r,i].forEach(t=>{const e=[],r=t.hFlip,i=t.vFlip;let o,s=t.rotate;switch(r?i?s+=2:(e.push("translate("+(n.width+n.left).toString()+" "+(0-n.top).toString()+")"),e.push("scale(-1 1)"),n.top=n.left=0):i&&(e.push("translate("+(0-n.left).toString()+" "+(n.height+n.top).toString()+")"),e.push("scale(1 -1)"),n.top=n.left=0),s<0&&(s-=4*Math.floor(s/4)),s%=4,s){case 1:o=n.height/2+n.top,e.unshift("rotate(90 "+o.toString()+" "+o.toString()+")");break;case 2:e.unshift("rotate(180 "+(n.width/2+n.left).toString()+" "+(n.height/2+n.top).toString()+")");break;case 3:o=n.width/2+n.left,e.unshift("rotate(-90 "+o.toString()+" "+o.toString()+")")}s%2==1&&(n.left!==n.top&&(o=n.left,n.left=n.top,n.top=o),n.width!==n.height&&(o=n.width,n.width=n.height,n.height=o)),e.length&&(a=function(t,e,r){const i=function(t,e="defs"){let r="";const i=t.indexOf("<"+e);for(;i>=0;){const n=t.indexOf(">",i),a=t.indexOf("</"+e);if(-1===n||-1===a)break;const o=t.indexOf(">",a);if(-1===o)break;r+=t.slice(n+1,a).trim(),t=t.slice(0,i).trim()+t.slice(o+1)}return{defs:r,content:t}}(t);return n=i.defs,a=e+i.content+r,n?"<defs>"+n+"</defs>"+a:a;var n,a}(a,'<g transform="'+e.join(" ")+'">',"</g>"))});const o=i.width,s=i.height,l=n.width,h=n.height;let u,d;null===o?(d=null===s?"1em":"auto"===s?h:s,u=x(d,l/h)):(u="auto"===o?l:o,d=null===s?x(u,h/l):"auto"===s?h:s);const p={},f=(t,e)=>{(t=>"unset"===t||"undefined"===t||"none"===t)(e)||(p[t]=e.toString())};f("width",u),f("height",d);const y=[n.left,n.top,l,h];return p.viewBox=y.join(" "),{attributes:p,viewBox:y,body:a}}(i,e),s=function(t,e){let r=-1===t.indexOf("xlink:")?"":' xmlns:xlink="http://www.w3.org/1999/xlink"';for(const i in e)r+=" "+i+'="'+e[i]+'"';return'<svg xmlns="http://www.w3.org/2000/svg"'+r+">"+t+"</svg>"}(function(t,e=k){const r=[];let i;for(;i=b.exec(t);)r.push(i[1]);if(!r.length)return t;const n="suffix"+(16777216*Math.random()|Date.now()).toString(16);return r.forEach(r=>{const i="function"==typeof e?e(r):e+(w++).toString(),a=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");t=t.replace(new RegExp('([#;"])('+a+')([")]|\\.[a-z])',"g"),"$1"+i+n+"$3")}),t=t.replace(new RegExp(n,"g"),"")}(o.body),{...o.attributes,...r});return(0,n.jZ)(s,(0,n.zj)())},"getIconSVG");function Wt(t,{markdownAutoWrap:e}){const r=t.replace(/<br\/>/g,"\n").replace(/\n{2,}/g,"\n"),i=(0,Rt.T)(r);return!1===e?i.replace(/ /g," "):i}function Ht(t,e={}){const r=Wt(t,e),i=Ot.lexer(r),n=[[]];let o=0;function s(t,e="normal"){if("text"===t.type){t.text.split("\n").forEach((t,r)=>{0!==r&&(o++,n.push([])),t.split(" ").forEach(t=>{(t=t.replace(/'/g,"'"))&&n[o].push({content:t,type:e})})})}else"strong"===t.type||"em"===t.type?t.tokens.forEach(e=>{s(e,t.type)}):"html"===t.type&&n[o].push({content:t.text,type:"normal"})}return(0,a.K2)(s,"processNode"),i.forEach(t=>{"paragraph"===t.type?t.tokens?.forEach(t=>{s(t)}):"html"===t.type?n[o].push({content:t.text,type:"normal"}):n[o].push({content:t.raw,type:"normal"})}),n}function Ut(t,{markdownAutoWrap:e}={}){const r=Ot.lexer(t);function i(t){return"text"===t.type?!1===e?t.text.replace(/\n */g,"<br/>").replace(/ /g," "):t.text.replace(/\n */g,"<br/>"):"strong"===t.type?`<strong>${t.tokens?.map(i).join("")}</strong>`:"em"===t.type?`<em>${t.tokens?.map(i).join("")}</em>`:"paragraph"===t.type?`<p>${t.tokens?.map(i).join("")}</p>`:"space"===t.type?"":"html"===t.type?`${t.text}`:"escape"===t.type?t.text:(a.Rm.warn(`Unsupported markdown: ${t.type}`),t.raw)}return(0,a.K2)(i,"output"),r.map(i).join("")}function Yt(t){return Intl.Segmenter?[...(new Intl.Segmenter).segment(t)].map(t=>t.segment):[...t]}function Gt(t,e){return Xt(t,[],Yt(e.content),e.type)}function Xt(t,e,r,i){if(0===r.length)return[{content:e.join(""),type:i},{content:"",type:i}];const[n,...a]=r,o=[...e,n];return t([{content:o.join(""),type:i}])?Xt(t,o,a,i):(0===e.length&&n&&(e.push(n),r.shift()),[{content:e.join(""),type:i},{content:r.join(""),type:i}])}function Vt(t,e){if(t.some(({content:t})=>t.includes("\n")))throw new Error("splitLineToFitWidth does not support newlines in the line");return Zt(t,e)}function Zt(t,e,r=[],i=[]){if(0===t.length)return i.length>0&&r.push(i),r.length>0?r:[];let n="";" "===t[0].content&&(n=" ",t.shift());const a=t.shift()??{content:" ",type:"normal"},o=[...i];if(""!==n&&o.push({content:n,type:"normal"}),o.push(a),e(o))return Zt(t,e,r,o);if(i.length>0)r.push(i),t.unshift(a);else if(a.content){const[i,n]=Gt(e,a);r.push([i]),n.content&&t.unshift(n)}return Zt(t,e,r)}function Qt(t,e){e&&t.attr("style",e)}async function Jt(t,e,r,i,a=!1,o=(0,n.zj)()){const s=t.append("foreignObject");s.attr("width",10*r+"px"),s.attr("height",10*r+"px");const l=s.append("xhtml:div"),c=(0,n.Wi)(e.label)?await(0,n.dj)(e.label.replace(n.Y2.lineBreakRegex,"\n"),o):(0,n.jZ)(e.label,o),h=e.isNode?"nodeLabel":"edgeLabel",u=l.append("span");u.html(c),Qt(u,e.labelStyle),u.attr("class",`${h} ${i}`),Qt(l,e.labelStyle),l.style("display","table-cell"),l.style("white-space","nowrap"),l.style("line-height","1.5"),l.style("max-width",r+"px"),l.style("text-align","center"),l.attr("xmlns","http://www.w3.org/1999/xhtml"),a&&l.attr("class","labelBkg");let d=l.node().getBoundingClientRect();return d.width===r&&(l.style("display","table"),l.style("white-space","break-spaces"),l.style("width",r+"px"),d=l.node().getBoundingClientRect()),s.node()}function te(t,e,r){return t.append("tspan").attr("class","text-outer-tspan").attr("x",0).attr("y",e*r-.1+"em").attr("dy",r+"em")}function ee(t,e,r){const i=t.append("text"),n=te(i,1,e);ne(n,r);const a=n.node().getComputedTextLength();return i.remove(),a}function re(t,e,r){const i=t.append("text"),n=te(i,1,e);ne(n,[{content:r,type:"normal"}]);const a=n.node()?.getBoundingClientRect();return a&&i.remove(),a}function ie(t,e,r,i=!1){const n=e.append("g"),o=n.insert("rect").attr("class","background").attr("style","stroke: none"),s=n.append("text").attr("y","-10.1");let l=0;for(const c of r){const e=(0,a.K2)(e=>ee(n,1.1,e)<=t,"checkWidth"),r=e(c)?[c]:Vt(c,e);for(const t of r){ne(te(s,l,1.1),t),l++}}if(i){const t=s.node().getBBox(),e=2;return o.attr("x",t.x-e).attr("y",t.y-e).attr("width",t.width+2*e).attr("height",t.height+2*e),n.node()}return s.node()}function ne(t,e){t.text(""),e.forEach((e,r)=>{const i=t.append("tspan").attr("font-style","em"===e.type?"italic":"normal").attr("class","text-inner-tspan").attr("font-weight","strong"===e.type?"bold":"normal");0===r?i.text(e.content):i.text(" "+e.content)})}async function ae(t,e={}){const r=[];t.replace(/(fa[bklrs]?):fa-([\w-]+)/g,(t,i,a)=>(r.push((async()=>{const r=`${i}:${a}`;return await qt(r)?await jt(r,void 0,{class:"label-icon"}):`<i class='${(0,n.jZ)(t,e).replace(":"," ")}'></i>`})()),t));const i=await Promise.all(r);return t.replace(/(fa[bklrs]?):fa-([\w-]+)/g,()=>i.shift()??"")}(0,a.K2)(Wt,"preprocessMarkdown"),(0,a.K2)(Ht,"markdownToLines"),(0,a.K2)(Ut,"markdownToHTML"),(0,a.K2)(Yt,"splitTextToChars"),(0,a.K2)(Gt,"splitWordToFitWidth"),(0,a.K2)(Xt,"splitWordToFitWidthRecursion"),(0,a.K2)(Vt,"splitLineToFitWidth"),(0,a.K2)(Zt,"splitLineToFitWidthRecursion"),(0,a.K2)(Qt,"applyStyle"),(0,a.K2)(Jt,"addHtmlSpan"),(0,a.K2)(te,"createTspan"),(0,a.K2)(ee,"computeWidthOfText"),(0,a.K2)(re,"computeDimensionOfText"),(0,a.K2)(ie,"createFormattedText"),(0,a.K2)(ne,"updateTextContentAndStyles"),(0,a.K2)(ae,"replaceIconSubstring");var oe=(0,a.K2)(async(t,e="",{style:r="",isTitle:o=!1,classes:s="",useHtmlLabels:l=!0,isNode:c=!0,width:h=200,addSvgBackground:u=!1}={},d)=>{if(a.Rm.debug("XYZ createText",e,r,o,s,l,c,"addSvgBackground: ",u),l){const a=Ut(e,d),o=await ae((0,i.Sm)(a),d),l=e.replace(/\\\\/g,"\\"),p={isNode:c,label:(0,n.Wi)(e)?l:o,labelStyle:r.replace("fill:","color:")};return await Jt(t,p,h,s,u,d)}{const i=ie(h,t,Ht(e.replace(/<br\s*\/?>/g,"<br/>").replace("<br>","<br/>"),d),!!e&&u);if(c){/stroke:/.exec(r)&&(r=r.replace("stroke:","lineColor:"));const t=r.replace(/stroke:[^;]+;?/g,"").replace(/stroke-width:[^;]+;?/g,"").replace(/fill:[^;]+;?/g,"").replace(/color:/g,"fill:");(0,C.Ltv)(i).attr("style",t)}else{const t=r.replace(/stroke:[^;]+;?/g,"").replace(/stroke-width:[^;]+;?/g,"").replace(/fill:[^;]+;?/g,"").replace(/background:/g,"fill:");(0,C.Ltv)(i).select("rect").attr("style",t.replace(/background:/g,"fill:"));const e=r.replace(/stroke:[^;]+;?/g,"").replace(/stroke-width:[^;]+;?/g,"").replace(/fill:[^;]+;?/g,"").replace(/color:/g,"fill:");(0,C.Ltv)(i).select("text").attr("style",e)}return i}},"createText")},32387:(t,e,r)=>{"use strict";r.d(e,{Fr:()=>h,GX:()=>c,KX:()=>l,WW:()=>o,ue:()=>a});var i=r(67633),n=r(40797),a=(0,n.K2)(t=>{const{handDrawnSeed:e}=(0,i.D7)();return{fill:t,hachureAngle:120,hachureGap:4,fillWeight:2,roughness:.7,stroke:t,seed:e}},"solidStateFill"),o=(0,n.K2)(t=>{const e=s([...t.cssCompiledStyles||[],...t.cssStyles||[],...t.labelStyle||[]]);return{stylesMap:e,stylesArray:[...e]}},"compileStyles"),s=(0,n.K2)(t=>{const e=new Map;return t.forEach(t=>{const[r,i]=t.split(":");e.set(r.trim(),i?.trim())}),e},"styles2Map"),l=(0,n.K2)(t=>"color"===t||"font-size"===t||"font-family"===t||"font-weight"===t||"font-style"===t||"text-decoration"===t||"text-align"===t||"text-transform"===t||"line-height"===t||"letter-spacing"===t||"word-spacing"===t||"text-shadow"===t||"text-overflow"===t||"white-space"===t||"word-wrap"===t||"word-break"===t||"overflow-wrap"===t||"hyphens"===t,"isLabelStyle"),c=(0,n.K2)(t=>{const{stylesArray:e}=o(t),r=[],i=[],n=[],a=[];return e.forEach(t=>{const e=t[0];l(e)?r.push(t.join(":")+" !important"):(i.push(t.join(":")+" !important"),e.includes("stroke")&&n.push(t.join(":")+" !important"),"fill"===e&&a.push(t.join(":")+" !important"))}),{labelStyles:r.join(";"),nodeStyles:i.join(";"),stylesArray:e,borderStyles:n,backgroundStyles:a}},"styles2String"),h=(0,n.K2)((t,e)=>{const{themeVariables:r,handDrawnSeed:n}=(0,i.D7)(),{nodeBorder:a,mainBkg:s}=r,{stylesMap:l}=o(t);return Object.assign({roughness:.7,fill:l.get("fill")||s,fillStyle:"hachure",fillWeight:4,hachureGap:5.2,stroke:l.get("stroke")||a,seed:n,strokeWidth:l.get("stroke-width")?.replace("px","")||1.3,fillLineDash:[0,0],strokeLineDash:u(l.get("stroke-dasharray"))},e)},"userNodeOverrides"),u=(0,n.K2)(t=>{if(!t)return[0,0];const e=t.trim().split(/\s+/).map(Number);if(1===e.length){const t=isNaN(e[0])?0:e[0];return[t,t]}return[isNaN(e[0])?0:e[0],isNaN(e[1])?0:e[1]]},"getStrokeDashArray")},33858:(t,e,r)=>{"use strict";r.d(e,{A:()=>u});var i=r(88496),n=r(5254),a=r(53098),o={};o["[object Float32Array]"]=o["[object Float64Array]"]=o["[object Int8Array]"]=o["[object Int16Array]"]=o["[object Int32Array]"]=o["[object Uint8Array]"]=o["[object Uint8ClampedArray]"]=o["[object Uint16Array]"]=o["[object Uint32Array]"]=!0,o["[object Arguments]"]=o["[object Array]"]=o["[object ArrayBuffer]"]=o["[object Boolean]"]=o["[object DataView]"]=o["[object Date]"]=o["[object Error]"]=o["[object Function]"]=o["[object Map]"]=o["[object Number]"]=o["[object Object]"]=o["[object RegExp]"]=o["[object Set]"]=o["[object String]"]=o["[object WeakMap]"]=!1;const s=function(t){return(0,a.A)(t)&&(0,n.A)(t.length)&&!!o[(0,i.A)(t)]};var l=r(52789),c=r(64841),h=c.A&&c.A.isTypedArray;const u=h?(0,l.A)(h):s},38446:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var i=r(89610),n=r(5254);const a=function(t){return null!=t&&(0,n.A)(t.length)&&!(0,i.A)(t)}},39142:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});const i=function(t){return function(){return t}}},39759:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});const i=function(t,e){var r=-1,i=t.length;for(e||(e=Array(i));++r<i;)e[r]=t[r];return e}},39857:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var i=r(18744),n=r(41917);const a=(0,i.A)(n.A,"Set")},40367:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});const i=function(t,e){return function(r){return t(e(r))}}},40797:(t,e,r)=>{"use strict";r.d(e,{He:()=>c,K2:()=>a,Rm:()=>l,VA:()=>o});var i=r(74353),n=Object.defineProperty,a=(t,e)=>n(t,"name",{value:e,configurable:!0}),o=(t,e)=>{for(var r in e)n(t,r,{get:e[r],enumerable:!0})},s={trace:0,debug:1,info:2,warn:3,error:4,fatal:5},l={trace:a((...t)=>{},"trace"),debug:a((...t)=>{},"debug"),info:a((...t)=>{},"info"),warn:a((...t)=>{},"warn"),error:a((...t)=>{},"error"),fatal:a((...t)=>{},"fatal")},c=a(function(t="fatal"){let e=s.fatal;"string"==typeof t?t.toLowerCase()in s&&(e=s[t]):"number"==typeof t&&(e=t),l.trace=()=>{},l.debug=()=>{},l.info=()=>{},l.warn=()=>{},l.error=()=>{},l.fatal=()=>{},e<=s.fatal&&(l.fatal=console.error?console.error.bind(console,h("FATAL"),"color: orange"):console.log.bind(console,"\x1b[35m",h("FATAL"))),e<=s.error&&(l.error=console.error?console.error.bind(console,h("ERROR"),"color: orange"):console.log.bind(console,"\x1b[31m",h("ERROR"))),e<=s.warn&&(l.warn=console.warn?console.warn.bind(console,h("WARN"),"color: orange"):console.log.bind(console,"\x1b[33m",h("WARN"))),e<=s.info&&(l.info=console.info?console.info.bind(console,h("INFO"),"color: lightblue"):console.log.bind(console,"\x1b[34m",h("INFO"))),e<=s.debug&&(l.debug=console.debug?console.debug.bind(console,h("DEBUG"),"color: lightgreen"):console.log.bind(console,"\x1b[32m",h("DEBUG"))),e<=s.trace&&(l.trace=console.debug?console.debug.bind(console,h("TRACE"),"color: lightgreen"):console.log.bind(console,"\x1b[32m",h("TRACE")))},"setLogLevel"),h=a(t=>`%c${i().format("ss.SSS")} : ${t} : `,"format")},41917:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var i=r(72136),n="object"==typeof self&&self&&self.Object===Object&&self;const a=i.A||n||Function("return this")()},42467:(t,e,r)=>{"use strict";r.d(e,{n:()=>i});var i={name:"mermaid",version:"11.12.0",description:"Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.",type:"module",module:"./dist/mermaid.core.mjs",types:"./dist/mermaid.d.ts",exports:{".":{types:"./dist/mermaid.d.ts",import:"./dist/mermaid.core.mjs",default:"./dist/mermaid.core.mjs"},"./*":"./*"},keywords:["diagram","markdown","flowchart","sequence diagram","gantt","class diagram","git graph","mindmap","packet diagram","c4 diagram","er diagram","pie chart","pie diagram","quadrant chart","requirement diagram","graph"],scripts:{clean:"rimraf dist",dev:"pnpm -w dev","docs:code":"typedoc src/defaultConfig.ts src/config.ts src/mermaid.ts && prettier --write ./src/docs/config/setup","docs:build":"rimraf ../../docs && pnpm docs:code && pnpm docs:spellcheck && tsx scripts/docs.cli.mts","docs:verify":"pnpm docs:code && pnpm docs:spellcheck && tsx scripts/docs.cli.mts --verify","docs:pre:vitepress":"pnpm --filter ./src/docs prefetch && rimraf src/vitepress && pnpm docs:code && tsx scripts/docs.cli.mts --vitepress && pnpm --filter ./src/vitepress install --no-frozen-lockfile --ignore-scripts","docs:build:vitepress":"pnpm docs:pre:vitepress && (cd src/vitepress && pnpm run build) && cpy --flat src/docs/landing/ ./src/vitepress/.vitepress/dist/landing","docs:dev":'pnpm docs:pre:vitepress && concurrently "pnpm --filter ./src/vitepress dev" "tsx scripts/docs.cli.mts --watch --vitepress"',"docs:dev:docker":'pnpm docs:pre:vitepress && concurrently "pnpm --filter ./src/vitepress dev:docker" "tsx scripts/docs.cli.mts --watch --vitepress"',"docs:serve":"pnpm docs:build:vitepress && vitepress serve src/vitepress","docs:spellcheck":'cspell "src/docs/**/*.md"',"docs:release-version":"tsx scripts/update-release-version.mts","docs:verify-version":"tsx scripts/update-release-version.mts --verify","types:build-config":"tsx scripts/create-types-from-json-schema.mts","types:verify-config":"tsx scripts/create-types-from-json-schema.mts --verify",checkCircle:"npx madge --circular ./src",prepublishOnly:"pnpm docs:verify-version"},repository:{type:"git",url:"https://github.com/mermaid-js/mermaid"},author:"Knut Sveidqvist",license:"MIT",standard:{ignore:["**/parser/*.js","dist/**/*.js","cypress/**/*.js"],globals:["page"]},dependencies:{"@braintree/sanitize-url":"^7.1.1","@iconify/utils":"^3.0.1","@mermaid-js/parser":"workspace:^","@types/d3":"^7.4.3",cytoscape:"^3.29.3","cytoscape-cose-bilkent":"^4.1.0","cytoscape-fcose":"^2.2.0",d3:"^7.9.0","d3-sankey":"^0.12.3","dagre-d3-es":"7.0.11",dayjs:"^1.11.18",dompurify:"^3.2.5",katex:"^0.16.22",khroma:"^2.1.0","lodash-es":"^4.17.21",marked:"^16.2.1",roughjs:"^4.6.6",stylis:"^4.3.6","ts-dedent":"^2.2.0",uuid:"^11.1.0"},devDependencies:{"@adobe/jsonschema2md":"^8.0.5","@iconify/types":"^2.0.0","@types/cytoscape":"^3.21.9","@types/cytoscape-fcose":"^2.2.4","@types/d3-sankey":"^0.12.4","@types/d3-scale":"^4.0.9","@types/d3-scale-chromatic":"^3.1.0","@types/d3-selection":"^3.0.11","@types/d3-shape":"^3.1.7","@types/jsdom":"^21.1.7","@types/katex":"^0.16.7","@types/lodash-es":"^4.17.12","@types/micromatch":"^4.0.9","@types/stylis":"^4.2.7","@types/uuid":"^10.0.0",ajv:"^8.17.1",canvas:"^3.1.2",chokidar:"3.6.0",concurrently:"^9.1.2","csstree-validator":"^4.0.1",globby:"^14.1.0",jison:"^0.4.18","js-base64":"^3.7.8",jsdom:"^26.1.0","json-schema-to-typescript":"^15.0.4",micromatch:"^4.0.8","path-browserify":"^1.0.1",prettier:"^3.5.3",remark:"^15.0.1","remark-frontmatter":"^5.0.0","remark-gfm":"^4.0.1",rimraf:"^6.0.1","start-server-and-test":"^2.0.13","type-fest":"^4.35.0",typedoc:"^0.28.12","typedoc-plugin-markdown":"^4.8.1",typescript:"~5.7.3","unist-util-flatmap":"^1.0.0","unist-util-visit":"^5.0.0",vitepress:"^1.6.4","vitepress-plugin-search":"1.0.4-alpha.22"},files:["dist/","README.md"],publishConfig:{access:"public"}}},42837:(t,e,r)=>{"use strict";r.d(e,{A:()=>D});var i=r(11754),n=r(52528),a=r(66984);const o=function(t,e,r){(void 0!==r&&!(0,a.A)(t[e],r)||void 0===r&&!(e in t))&&(0,n.A)(t,e,r)};var s=r(4574),l=r(80154),c=r(1801),h=r(39759),u=r(18598),d=r(52274),p=r(92049),f=r(53533),g=r(99912),y=r(89610),m=r(23149),x=r(88496),b=r(15647),k=r(53098),w=Function.prototype,C=Object.prototype,_=w.toString,v=C.hasOwnProperty,S=_.call(Object);const T=function(t){if(!(0,k.A)(t)||"[object Object]"!=(0,x.A)(t))return!1;var e=(0,b.A)(t);if(null===e)return!0;var r=v.call(e,"constructor")&&e.constructor;return"function"==typeof r&&r instanceof r&&_.call(r)==S};var A=r(33858);const M=function(t,e){if(("constructor"!==e||"function"!=typeof t[e])&&"__proto__"!=e)return t[e]};var B=r(22031),L=r(55615);const F=function(t){return(0,B.A)(t,(0,L.A)(t))};const $=function(t,e,r,i,n,a,s){var x=M(t,r),b=M(e,r),k=s.get(b);if(k)o(t,r,k);else{var w=a?a(x,b,r+"",t,e,s):void 0,C=void 0===w;if(C){var _=(0,p.A)(b),v=!_&&(0,g.A)(b),S=!_&&!v&&(0,A.A)(b);w=b,_||v||S?(0,p.A)(x)?w=x:(0,f.A)(x)?w=(0,h.A)(x):v?(C=!1,w=(0,l.A)(b,!0)):S?(C=!1,w=(0,c.A)(b,!0)):w=[]:T(b)||(0,d.A)(b)?(w=x,(0,d.A)(x)?w=F(x):(0,m.A)(x)&&!(0,y.A)(x)||(w=(0,u.A)(b))):C=!1}C&&(s.set(b,w),n(w,b,i,a,s),s.delete(b)),o(t,r,w)}};const E=function t(e,r,n,a,l){e!==r&&(0,s.A)(r,function(s,c){if(l||(l=new i.A),(0,m.A)(s))$(e,r,c,n,t,a,l);else{var h=a?a(M(e,c),s,c+"",e,r,l):void 0;void 0===h&&(h=s),o(e,c,h)}},L.A)};const D=(0,r(3767).A)(function(t,e,r){E(t,e,r)})},43988:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});const i=r(41917).A.Uint8Array},46632:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var i=r(29471);function n(t,e){if("function"!=typeof t||null!=e&&"function"!=typeof e)throw new TypeError("Expected a function");var r=function(){var i=arguments,n=e?e.apply(this,i):i[0],a=r.cache;if(a.has(n))return a.get(n);var o=t.apply(this,i);return r.cache=a.set(n,o)||a,o};return r.cache=new(n.Cache||i.A),r}n.Cache=i.A;const a=n},52274:(t,e,r)=>{"use strict";r.d(e,{A:()=>c});var i=r(88496),n=r(53098);const a=function(t){return(0,n.A)(t)&&"[object Arguments]"==(0,i.A)(t)};var o=Object.prototype,s=o.hasOwnProperty,l=o.propertyIsEnumerable;const c=a(function(){return arguments}())?a:function(t){return(0,n.A)(t)&&s.call(t,"callee")&&!l.call(t,"callee")}},52528:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});var i=r(84171);const n=function(t,e,r){"__proto__"==e&&i.A?(0,i.A)(t,e,{configurable:!0,enumerable:!0,value:r,writable:!0}):t[e]=r}},52789:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});const i=function(t){return function(e){return t(e)}}},52851:(t,e,r)=>{"use strict";r.d(e,{A:()=>o});var i=r(52528),n=r(66984),a=Object.prototype.hasOwnProperty;const o=function(t,e,r){var o=t[e];a.call(t,e)&&(0,n.A)(o,r)&&(void 0!==r||e in t)||(0,i.A)(t,e,r)}},53098:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});const i=function(t){return null!=t&&"object"==typeof t}},53533:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var i=r(38446),n=r(53098);const a=function(t){return(0,n.A)(t)&&(0,i.A)(t)}},55615:(t,e,r)=>{"use strict";r.d(e,{A:()=>h});var i=r(83607),n=r(23149),a=r(97271);const o=function(t){var e=[];if(null!=t)for(var r in Object(t))e.push(r);return e};var s=Object.prototype.hasOwnProperty;const l=function(t){if(!(0,n.A)(t))return o(t);var e=(0,a.A)(t),r=[];for(var i in t)("constructor"!=i||!e&&s.call(t,i))&&r.push(i);return r};var c=r(38446);const h=function(t){return(0,c.A)(t)?(0,i.A)(t,!0):l(t)}},60513:(t,e,r)=>{"use strict";function i(t){for(var e=[],r=1;r<arguments.length;r++)e[r-1]=arguments[r];var i=Array.from("string"==typeof t?[t]:t);i[i.length-1]=i[i.length-1].replace(/\r?\n([\t ]*)$/,"");var n=i.reduce(function(t,e){var r=e.match(/\n([\t ]+|(?!\s).)/g);return r?t.concat(r.map(function(t){var e,r;return null!==(r=null===(e=t.match(/[\t ]/g))||void 0===e?void 0:e.length)&&void 0!==r?r:0})):t},[]);if(n.length){var a=new RegExp("\n[\t ]{"+Math.min.apply(Math,n)+"}","g");i=i.map(function(t){return t.replace(a,"\n")})}i[0]=i[0].replace(/^\r?\n/,"");var o=i[0];return e.forEach(function(t,e){var r=o.match(/(?:^|\n)( *)$/),n=r?r[1]:"",a=t;"string"==typeof t&&t.includes("\n")&&(a=String(t).split("\n").map(function(t,e){return 0===e?t:""+n+t}).join("\n")),o+=a+i[e+1]}),o}r.d(e,{T:()=>i})},63122:(t,e,r)=>{"use strict";r.d(e,{Y:()=>n,Z:()=>a});var i=r(72453);const n={};for(let o=0;o<=255;o++)n[o]=i.A.unit.dec2hex(o);const a={ALL:0,RGB:1,HSL:2}},63245:(t,e,r)=>{"use strict";r.d(e,{O:()=>i});var i=(0,r(40797).K2)(({flowchart:t})=>{const e=t?.subGraphTitleMargin?.top??0,r=t?.subGraphTitleMargin?.bottom??0;return{subGraphTitleTopMargin:e,subGraphTitleBottomMargin:r,subGraphTitleTotalMargin:e+r}},"getSubGraphTitleMargins")},64841:(t,e,r)=>{"use strict";r.d(e,{A:()=>s});var i=r(72136),n="object"==typeof exports&&exports&&!exports.nodeType&&exports,a=n&&"object"==typeof module&&module&&!module.nodeType&&module,o=a&&a.exports===n&&i.A.process;const s=function(){try{var t=a&&a.require&&a.require("util").types;return t||o&&o.binding&&o.binding("util")}catch(e){}}()},66401:(t,e,r)=>{"use strict";r.d(e,{A:()=>d});var i=r(69471),n=r(9779),a=r(52274),o=r(92049),s=r(38446),l=r(99912),c=r(97271),h=r(33858),u=Object.prototype.hasOwnProperty;const d=function(t){if(null==t)return!0;if((0,s.A)(t)&&((0,o.A)(t)||"string"==typeof t||"function"==typeof t.splice||(0,l.A)(t)||(0,h.A)(t)||(0,a.A)(t)))return!t.length;var e=(0,n.A)(t);if("[object Map]"==e||"[object Set]"==e)return!t.size;if((0,c.A)(t))return!(0,i.A)(t).length;for(var r in t)if(u.call(t,r))return!1;return!0}},66984:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});const i=function(t,e){return t===e||t!=t&&e!=e}},67525:(t,e,r)=>{"use strict";r.d(e,{A:()=>l});var i=r(39142),n=r(84171),a=r(29008);const o=n.A?function(t,e){return(0,n.A)(t,"toString",{configurable:!0,enumerable:!1,value:(0,i.A)(e),writable:!0})}:a.A;var s=Date.now;const l=function(t){var e=0,r=0;return function(){var i=s(),n=16-(i-r);if(r=i,n>0){if(++e>=800)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}(o)},67633:(t,e,r)=>{"use strict";r.d(e,{C0:()=>x,xA:()=>nt,hH:()=>S,Dl:()=>Dt,IU:()=>Zt,Wt:()=>Ut,Y2:()=>Kt,a$:()=>zt,sb:()=>U,ME:()=>le,UI:()=>j,Ch:()=>k,mW:()=>b,DB:()=>y,_3:()=>vt,EJ:()=>g,m7:()=>ee,iN:()=>Jt,zj:()=>rt,D7:()=>oe,Gs:()=>fe,J$:()=>_,ab:()=>ie,Q2:()=>tt,P$:()=>D,ID:()=>_t,TM:()=>ht,Wi:()=>Et,H1:()=>ut,QO:()=>At,Js:()=>pe,Xd:()=>w,dj:()=>Rt,cL:()=>at,$i:()=>W,jZ:()=>mt,oB:()=>ce,wZ:()=>Q,EI:()=>te,SV:()=>Qt,Nk:()=>et,XV:()=>se,ke:()=>re,UU:()=>Z,ot:()=>Pt,mj:()=>he,tM:()=>Ht,H$:()=>I,B6:()=>J});var i=r(40797),n=r(74886),a=r(8232);const o=(t,e)=>{const r=n.A.parse(t),i={};for(const n in e)e[n]&&(i[n]=r[n]+e[n]);return(0,a.A)(t,i)};var s=r(25582);const l=(t,e,r=50)=>{const{r:i,g:a,b:o,a:l}=n.A.parse(t),{r:c,g:h,b:u,a:d}=n.A.parse(e),p=r/100,f=2*p-1,g=l-d,y=((f*g===-1?f:(f+g)/(1+f*g))+1)/2,m=1-y,x=i*y+c*m,b=a*y+h*m,k=o*y+u*m,w=l*p+d*(1-p);return(0,s.A)(x,b,k,w)},c=(t,e=100)=>{const r=n.A.parse(t);return r.r=255-r.r,r.g=255-r.g,r.b=255-r.b,l(r,t,e)};var h,u=r(75263),d=r(78041),p=r(3219),f=r(99418),g=/^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s,y=/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,m=/\s*%%.*\n/gm,x=class extends Error{static{(0,i.K2)(this,"UnknownDiagramError")}constructor(t){super(t),this.name="UnknownDiagramError"}},b={},k=(0,i.K2)(function(t,e){t=t.replace(g,"").replace(y,"").replace(m,"\n");for(const[r,{detector:i}]of Object.entries(b)){if(i(t,e))return r}throw new x(`No diagram type detected matching given configuration for text: ${t}`)},"detectType"),w=(0,i.K2)((...t)=>{for(const{id:e,detector:r,loader:i}of t)C(e,r,i)},"registerLazyLoadedDiagrams"),C=(0,i.K2)((t,e,r)=>{b[t]&&i.Rm.warn(`Detector with key ${t} already exists. Overwriting.`),b[t]={detector:e,loader:r},i.Rm.debug(`Detector with key ${t} added${r?" with loader":""}`)},"addDetector"),_=(0,i.K2)(t=>b[t].loader,"getDiagramLoader"),v=(0,i.K2)((t,e,{depth:r=2,clobber:i=!1}={})=>{const n={depth:r,clobber:i};return Array.isArray(e)&&!Array.isArray(t)?(e.forEach(e=>v(t,e,n)),t):Array.isArray(e)&&Array.isArray(t)?(e.forEach(e=>{t.includes(e)||t.push(e)}),t):void 0===t||r<=0?null!=t&&"object"==typeof t&&"object"==typeof e?Object.assign(t,e):e:(void 0!==e&&"object"==typeof t&&"object"==typeof e&&Object.keys(e).forEach(n=>{"object"!=typeof e[n]||void 0!==t[n]&&"object"!=typeof t[n]?(i||"object"!=typeof t[n]&&"object"!=typeof e[n])&&(t[n]=e[n]):(void 0===t[n]&&(t[n]=Array.isArray(e[n])?[]:{}),t[n]=v(t[n],e[n],{depth:r-1,clobber:i}))}),t)},"assignWithDepth"),S=v,T="#ffffff",A="#f2f2f2",M=(0,i.K2)((t,e)=>o(t,e?{s:-40,l:10}:{s:-40,l:-10}),"mkBorder"),B=class{static{(0,i.K2)(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#fff4dd",this.noteBkgColor="#fff5ad",this.noteTextColor="#333",this.THEME_COLOR_LIMIT=12,this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px"}updateColors(){if(this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#333"),this.secondaryColor=this.secondaryColor||o(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||o(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||M(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||M(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||M(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||M(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#333",this.secondaryTextColor=this.secondaryTextColor||c(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||c(this.tertiaryColor),this.lineColor=this.lineColor||c(this.background),this.arrowheadColor=this.arrowheadColor||c(this.background),this.textColor=this.textColor||this.primaryTextColor,this.border2=this.border2||this.tertiaryBorderColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.primaryBorderColor,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?(0,u.A)(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||this.actorBorder,this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||(0,u.A)(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||c(this.lineColor),this.sectionBkgColor=this.sectionBkgColor||this.tertiaryColor,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||this.secondaryColor,this.sectionBkgColor2=this.sectionBkgColor2||this.primaryColor,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||this.primaryColor,this.activeTaskBorderColor=this.activeTaskBorderColor||this.primaryColor,this.activeTaskBkgColor=this.activeTaskBkgColor||(0,d.A)(this.primaryColor,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.vertLineColor=this.vertLineColor||"navy",this.taskTextColor=this.taskTextColor||this.textColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.darkMode?(this.rowOdd=this.rowOdd||(0,u.A)(this.mainBkg,5)||"#ffffff",this.rowEven=this.rowEven||(0,u.A)(this.mainBkg,10)):(this.rowOdd=this.rowOdd||(0,d.A)(this.mainBkg,75)||"#ffffff",this.rowEven=this.rowEven||(0,d.A)(this.mainBkg,5)),this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||this.tertiaryColor,this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||o(this.primaryColor,{h:30}),this.cScale4=this.cScale4||o(this.primaryColor,{h:60}),this.cScale5=this.cScale5||o(this.primaryColor,{h:90}),this.cScale6=this.cScale6||o(this.primaryColor,{h:120}),this.cScale7=this.cScale7||o(this.primaryColor,{h:150}),this.cScale8=this.cScale8||o(this.primaryColor,{h:210,l:150}),this.cScale9=this.cScale9||o(this.primaryColor,{h:270}),this.cScale10=this.cScale10||o(this.primaryColor,{h:300}),this.cScale11=this.cScale11||o(this.primaryColor,{h:330}),this.darkMode)for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScale"+e]=(0,u.A)(this["cScale"+e],75);else for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScale"+e]=(0,u.A)(this["cScale"+e],25);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleInv"+e]=this["cScaleInv"+e]||c(this["cScale"+e]);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this.darkMode?this["cScalePeer"+e]=this["cScalePeer"+e]||(0,d.A)(this["cScale"+e],10):this["cScalePeer"+e]=this["cScalePeer"+e]||(0,u.A)(this["cScale"+e],10);this.scaleLabelColor=this.scaleLabelColor||this.labelTextColor;for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleLabel"+e]=this["cScaleLabel"+e]||this.scaleLabelColor;const t=this.darkMode?-4:-1;for(let e=0;e<5;e++)this["surface"+e]=this["surface"+e]||o(this.mainBkg,{h:180,s:-15,l:t*(5+3*e)}),this["surfacePeer"+e]=this["surfacePeer"+e]||o(this.mainBkg,{h:180,s:-15,l:t*(8+3*e)});this.classText=this.classText||this.textColor,this.fillType0=this.fillType0||this.primaryColor,this.fillType1=this.fillType1||this.secondaryColor,this.fillType2=this.fillType2||o(this.primaryColor,{h:64}),this.fillType3=this.fillType3||o(this.secondaryColor,{h:64}),this.fillType4=this.fillType4||o(this.primaryColor,{h:-64}),this.fillType5=this.fillType5||o(this.secondaryColor,{h:-64}),this.fillType6=this.fillType6||o(this.primaryColor,{h:128}),this.fillType7=this.fillType7||o(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||o(this.primaryColor,{l:-10}),this.pie5=this.pie5||o(this.secondaryColor,{l:-10}),this.pie6=this.pie6||o(this.tertiaryColor,{l:-10}),this.pie7=this.pie7||o(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||o(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||o(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||o(this.primaryColor,{h:60,l:-20}),this.pie11=this.pie11||o(this.primaryColor,{h:-60,l:-20}),this.pie12=this.pie12||o(this.primaryColor,{h:120,l:-10}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.radar={axisColor:this.radar?.axisColor||this.lineColor,axisStrokeWidth:this.radar?.axisStrokeWidth||2,axisLabelFontSize:this.radar?.axisLabelFontSize||12,curveOpacity:this.radar?.curveOpacity||.5,curveStrokeWidth:this.radar?.curveStrokeWidth||2,graticuleColor:this.radar?.graticuleColor||"#DEDEDE",graticuleStrokeWidth:this.radar?.graticuleStrokeWidth||1,graticuleOpacity:this.radar?.graticuleOpacity||.3,legendBoxSize:this.radar?.legendBoxSize||12,legendFontSize:this.radar?.legendFontSize||12},this.archEdgeColor=this.archEdgeColor||"#777",this.archEdgeArrowColor=this.archEdgeArrowColor||"#777",this.archEdgeWidth=this.archEdgeWidth||"3",this.archGroupBorderColor=this.archGroupBorderColor||"#000",this.archGroupBorderWidth=this.archGroupBorderWidth||"2px",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||o(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||o(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||o(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||o(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||o(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||o(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,p.A)(this.quadrant1Fill)?(0,d.A)(this.quadrant1Fill):(0,u.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#FFF4DD,#FFD8B1,#FFA07A,#ECEFF1,#D6DBDF,#C3E0A8,#FFB6A4,#FFD74D,#738FA7,#FFFFF0"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?(0,u.A)(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||o(this.primaryColor,{h:-30}),this.git4=this.git4||o(this.primaryColor,{h:-60}),this.git5=this.git5||o(this.primaryColor,{h:-90}),this.git6=this.git6||o(this.primaryColor,{h:60}),this.git7=this.git7||o(this.primaryColor,{h:120}),this.darkMode?(this.git0=(0,d.A)(this.git0,25),this.git1=(0,d.A)(this.git1,25),this.git2=(0,d.A)(this.git2,25),this.git3=(0,d.A)(this.git3,25),this.git4=(0,d.A)(this.git4,25),this.git5=(0,d.A)(this.git5,25),this.git6=(0,d.A)(this.git6,25),this.git7=(0,d.A)(this.git7,25)):(this.git0=(0,u.A)(this.git0,25),this.git1=(0,u.A)(this.git1,25),this.git2=(0,u.A)(this.git2,25),this.git3=(0,u.A)(this.git3,25),this.git4=(0,u.A)(this.git4,25),this.git5=(0,u.A)(this.git5,25),this.git6=(0,u.A)(this.git6,25),this.git7=(0,u.A)(this.git7,25)),this.gitInv0=this.gitInv0||c(this.git0),this.gitInv1=this.gitInv1||c(this.git1),this.gitInv2=this.gitInv2||c(this.git2),this.gitInv3=this.gitInv3||c(this.git3),this.gitInv4=this.gitInv4||c(this.git4),this.gitInv5=this.gitInv5||c(this.git5),this.gitInv6=this.gitInv6||c(this.git6),this.gitInv7=this.gitInv7||c(this.git7),this.branchLabelColor=this.branchLabelColor||(this.darkMode?"black":this.labelTextColor),this.gitBranchLabel0=this.gitBranchLabel0||this.branchLabelColor,this.gitBranchLabel1=this.gitBranchLabel1||this.branchLabelColor,this.gitBranchLabel2=this.gitBranchLabel2||this.branchLabelColor,this.gitBranchLabel3=this.gitBranchLabel3||this.branchLabelColor,this.gitBranchLabel4=this.gitBranchLabel4||this.branchLabelColor,this.gitBranchLabel5=this.gitBranchLabel5||this.branchLabelColor,this.gitBranchLabel6=this.gitBranchLabel6||this.branchLabelColor,this.gitBranchLabel7=this.gitBranchLabel7||this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||T,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||A}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach(e=>{this[e]=t[e]}),this.updateColors(),e.forEach(e=>{this[e]=t[e]})}},L=(0,i.K2)(t=>{const e=new B;return e.calculate(t),e},"getThemeVariables"),F=class{static{(0,i.K2)(this,"Theme")}constructor(){this.background="#333",this.primaryColor="#1f2020",this.secondaryColor=(0,d.A)(this.primaryColor,16),this.tertiaryColor=o(this.primaryColor,{h:-160}),this.primaryBorderColor=c(this.background),this.secondaryBorderColor=M(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=M(this.tertiaryColor,this.darkMode),this.primaryTextColor=c(this.primaryColor),this.secondaryTextColor=c(this.secondaryColor),this.tertiaryTextColor=c(this.tertiaryColor),this.lineColor=c(this.background),this.textColor=c(this.background),this.mainBkg="#1f2020",this.secondBkg="calculated",this.mainContrastColor="lightgrey",this.darkTextColor=(0,d.A)(c("#323D47"),10),this.lineColor="calculated",this.border1="#ccc",this.border2=(0,s.A)(255,255,255,.25),this.arrowheadColor="calculated",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#181818",this.textColor="#ccc",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#F9FFFE",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="calculated",this.activationBkgColor="calculated",this.sequenceNumberColor="black",this.sectionBkgColor=(0,u.A)("#EAE8D9",30),this.altSectionBkgColor="calculated",this.sectionBkgColor2="#EAE8D9",this.excludeBkgColor=(0,u.A)(this.sectionBkgColor,10),this.taskBorderColor=(0,s.A)(255,255,255,70),this.taskBkgColor="calculated",this.taskTextColor="calculated",this.taskTextLightColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor=(0,s.A)(255,255,255,50),this.activeTaskBkgColor="#81B1DB",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="grey",this.critBorderColor="#E83737",this.critBkgColor="#E83737",this.taskTextDarkColor="calculated",this.todayLineColor="#DB5757",this.vertLineColor="#00BFFF",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.rowOdd=this.rowOdd||(0,d.A)(this.mainBkg,5)||"#ffffff",this.rowEven=this.rowEven||(0,u.A)(this.mainBkg,10),this.labelColor="calculated",this.errorBkgColor="#a44141",this.errorTextColor="#ddd"}updateColors(){this.secondBkg=(0,d.A)(this.mainBkg,16),this.lineColor=this.mainContrastColor,this.arrowheadColor=this.mainContrastColor,this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.edgeLabelBackground=(0,d.A)(this.labelBackground,25),this.actorBorder=this.border1,this.actorBkg=this.mainBkg,this.actorTextColor=this.mainContrastColor,this.actorLineColor=this.actorBorder,this.signalColor=this.mainContrastColor,this.signalTextColor=this.mainContrastColor,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.mainContrastColor,this.loopTextColor=this.mainContrastColor,this.noteBorderColor=this.secondaryBorderColor,this.noteBkgColor=this.secondBkg,this.noteTextColor=this.secondaryTextColor,this.activationBorderColor=this.border1,this.activationBkgColor=this.secondBkg,this.altSectionBkgColor=this.background,this.taskBkgColor=(0,d.A)(this.mainBkg,23),this.taskTextColor=this.darkTextColor,this.taskTextLightColor=this.mainContrastColor,this.taskTextOutsideColor=this.taskTextLightColor,this.gridColor=this.mainContrastColor,this.doneTaskBkgColor=this.mainContrastColor,this.taskTextDarkColor=this.darkTextColor,this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#555",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#f4f4f4",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=o(this.primaryColor,{h:64}),this.fillType3=o(this.secondaryColor,{h:64}),this.fillType4=o(this.primaryColor,{h:-64}),this.fillType5=o(this.secondaryColor,{h:-64}),this.fillType6=o(this.primaryColor,{h:128}),this.fillType7=o(this.secondaryColor,{h:128}),this.cScale1=this.cScale1||"#0b0000",this.cScale2=this.cScale2||"#4d1037",this.cScale3=this.cScale3||"#3f5258",this.cScale4=this.cScale4||"#4f2f1b",this.cScale5=this.cScale5||"#6e0a0a",this.cScale6=this.cScale6||"#3b0048",this.cScale7=this.cScale7||"#995a01",this.cScale8=this.cScale8||"#154706",this.cScale9=this.cScale9||"#161722",this.cScale10=this.cScale10||"#00296f",this.cScale11=this.cScale11||"#01629c",this.cScale12=this.cScale12||"#010029",this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||o(this.primaryColor,{h:30}),this.cScale4=this.cScale4||o(this.primaryColor,{h:60}),this.cScale5=this.cScale5||o(this.primaryColor,{h:90}),this.cScale6=this.cScale6||o(this.primaryColor,{h:120}),this.cScale7=this.cScale7||o(this.primaryColor,{h:150}),this.cScale8=this.cScale8||o(this.primaryColor,{h:210}),this.cScale9=this.cScale9||o(this.primaryColor,{h:270}),this.cScale10=this.cScale10||o(this.primaryColor,{h:300}),this.cScale11=this.cScale11||o(this.primaryColor,{h:330});for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleInv"+t]=this["cScaleInv"+t]||c(this["cScale"+t]);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScalePeer"+t]=this["cScalePeer"+t]||(0,d.A)(this["cScale"+t],10);for(let t=0;t<5;t++)this["surface"+t]=this["surface"+t]||o(this.mainBkg,{h:30,s:-30,l:-(4*t-10)}),this["surfacePeer"+t]=this["surfacePeer"+t]||o(this.mainBkg,{h:30,s:-30,l:-(4*t-7)});this.scaleLabelColor=this.scaleLabelColor||(this.darkMode?"black":this.labelTextColor);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.scaleLabelColor;for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["pie"+t]=this["cScale"+t];this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||o(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||o(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||o(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||o(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||o(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||o(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,p.A)(this.quadrant1Fill)?(0,d.A)(this.quadrant1Fill):(0,u.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#3498db,#2ecc71,#e74c3c,#f1c40f,#bdc3c7,#ffffff,#34495e,#9b59b6,#1abc9c,#e67e22"},this.packet={startByteColor:this.primaryTextColor,endByteColor:this.primaryTextColor,labelColor:this.primaryTextColor,titleColor:this.primaryTextColor,blockStrokeColor:this.primaryTextColor,blockFillColor:this.background},this.radar={axisColor:this.radar?.axisColor||this.lineColor,axisStrokeWidth:this.radar?.axisStrokeWidth||2,axisLabelFontSize:this.radar?.axisLabelFontSize||12,curveOpacity:this.radar?.curveOpacity||.5,curveStrokeWidth:this.radar?.curveStrokeWidth||2,graticuleColor:this.radar?.graticuleColor||"#DEDEDE",graticuleStrokeWidth:this.radar?.graticuleStrokeWidth||1,graticuleOpacity:this.radar?.graticuleOpacity||.3,legendBoxSize:this.radar?.legendBoxSize||12,legendFontSize:this.radar?.legendFontSize||12},this.classText=this.primaryTextColor,this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?(0,u.A)(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=(0,d.A)(this.secondaryColor,20),this.git1=(0,d.A)(this.pie2||this.secondaryColor,20),this.git2=(0,d.A)(this.pie3||this.tertiaryColor,20),this.git3=(0,d.A)(this.pie4||o(this.primaryColor,{h:-30}),20),this.git4=(0,d.A)(this.pie5||o(this.primaryColor,{h:-60}),20),this.git5=(0,d.A)(this.pie6||o(this.primaryColor,{h:-90}),10),this.git6=(0,d.A)(this.pie7||o(this.primaryColor,{h:60}),10),this.git7=(0,d.A)(this.pie8||o(this.primaryColor,{h:120}),20),this.gitInv0=this.gitInv0||c(this.git0),this.gitInv1=this.gitInv1||c(this.git1),this.gitInv2=this.gitInv2||c(this.git2),this.gitInv3=this.gitInv3||c(this.git3),this.gitInv4=this.gitInv4||c(this.git4),this.gitInv5=this.gitInv5||c(this.git5),this.gitInv6=this.gitInv6||c(this.git6),this.gitInv7=this.gitInv7||c(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||c(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||c(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||(0,d.A)(this.background,12),this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||(0,d.A)(this.background,2),this.nodeBorder=this.nodeBorder||"#999"}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach(e=>{this[e]=t[e]}),this.updateColors(),e.forEach(e=>{this[e]=t[e]})}},$=(0,i.K2)(t=>{const e=new F;return e.calculate(t),e},"getThemeVariables"),E=class{static{(0,i.K2)(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#ECECFF",this.secondaryColor=o(this.primaryColor,{h:120}),this.secondaryColor="#ffffde",this.tertiaryColor=o(this.primaryColor,{h:-160}),this.primaryBorderColor=M(this.primaryColor,this.darkMode),this.secondaryBorderColor=M(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=M(this.tertiaryColor,this.darkMode),this.primaryTextColor=c(this.primaryColor),this.secondaryTextColor=c(this.secondaryColor),this.tertiaryTextColor=c(this.tertiaryColor),this.lineColor=c(this.background),this.textColor=c(this.background),this.background="white",this.mainBkg="#ECECFF",this.secondBkg="#ffffde",this.lineColor="#333333",this.border1="#9370DB",this.border2="#aaaa33",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="rgba(232,232,232, 0.8)",this.textColor="#333",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="calculated",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="calculated",this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor="calculated",this.taskTextOutsideColor=this.taskTextDarkColor,this.taskTextClickableColor="calculated",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBorderColor="calculated",this.critBkgColor="calculated",this.todayLineColor="calculated",this.vertLineColor="calculated",this.sectionBkgColor=(0,s.A)(102,102,255,.49),this.altSectionBkgColor="white",this.sectionBkgColor2="#fff400",this.taskBorderColor="#534fbc",this.taskBkgColor="#8a90dd",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="#534fbc",this.activeTaskBkgColor="#bfc7ff",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.vertLineColor="navy",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.rowOdd="calculated",this.rowEven="calculated",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222",this.updateColors()}updateColors(){this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||o(this.primaryColor,{h:30}),this.cScale4=this.cScale4||o(this.primaryColor,{h:60}),this.cScale5=this.cScale5||o(this.primaryColor,{h:90}),this.cScale6=this.cScale6||o(this.primaryColor,{h:120}),this.cScale7=this.cScale7||o(this.primaryColor,{h:150}),this.cScale8=this.cScale8||o(this.primaryColor,{h:210}),this.cScale9=this.cScale9||o(this.primaryColor,{h:270}),this.cScale10=this.cScale10||o(this.primaryColor,{h:300}),this.cScale11=this.cScale11||o(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||(0,u.A)(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||(0,u.A)(this.tertiaryColor,40);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScale"+t]=(0,u.A)(this["cScale"+t],10),this["cScalePeer"+t]=this["cScalePeer"+t]||(0,u.A)(this["cScale"+t],25);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleInv"+t]=this["cScaleInv"+t]||o(this["cScale"+t],{h:180});for(let t=0;t<5;t++)this["surface"+t]=this["surface"+t]||o(this.mainBkg,{h:30,l:-(5+5*t)}),this["surfacePeer"+t]=this["surfacePeer"+t]||o(this.mainBkg,{h:30,l:-(7+5*t)});if(this.scaleLabelColor="calculated"!==this.scaleLabelColor&&this.scaleLabelColor?this.scaleLabelColor:this.labelTextColor,"calculated"!==this.labelTextColor){this.cScaleLabel0=this.cScaleLabel0||c(this.labelTextColor),this.cScaleLabel3=this.cScaleLabel3||c(this.labelTextColor);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.labelTextColor}this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.titleColor=this.textColor,this.edgeLabelBackground=this.labelBackground,this.actorBorder=(0,d.A)(this.border1,23),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.signalColor=this.textColor,this.signalTextColor=this.textColor,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.actorLineColor=this.actorBorder,this.taskTextColor=this.taskTextLightColor,this.taskTextOutsideColor=this.taskTextDarkColor,this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.rowOdd=this.rowOdd||(0,d.A)(this.primaryColor,75)||"#ffffff",this.rowEven=this.rowEven||(0,d.A)(this.primaryColor,1),this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.specialStateColor=this.lineColor,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=o(this.primaryColor,{h:64}),this.fillType3=o(this.secondaryColor,{h:64}),this.fillType4=o(this.primaryColor,{h:-64}),this.fillType5=o(this.secondaryColor,{h:-64}),this.fillType6=o(this.primaryColor,{h:128}),this.fillType7=o(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||o(this.tertiaryColor,{l:-40}),this.pie4=this.pie4||o(this.primaryColor,{l:-10}),this.pie5=this.pie5||o(this.secondaryColor,{l:-30}),this.pie6=this.pie6||o(this.tertiaryColor,{l:-20}),this.pie7=this.pie7||o(this.primaryColor,{h:60,l:-20}),this.pie8=this.pie8||o(this.primaryColor,{h:-60,l:-40}),this.pie9=this.pie9||o(this.primaryColor,{h:120,l:-40}),this.pie10=this.pie10||o(this.primaryColor,{h:60,l:-40}),this.pie11=this.pie11||o(this.primaryColor,{h:-90,l:-40}),this.pie12=this.pie12||o(this.primaryColor,{h:120,l:-30}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||o(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||o(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||o(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||o(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||o(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||o(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,p.A)(this.quadrant1Fill)?(0,d.A)(this.quadrant1Fill):(0,u.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.radar={axisColor:this.radar?.axisColor||this.lineColor,axisStrokeWidth:this.radar?.axisStrokeWidth||2,axisLabelFontSize:this.radar?.axisLabelFontSize||12,curveOpacity:this.radar?.curveOpacity||.5,curveStrokeWidth:this.radar?.curveStrokeWidth||2,graticuleColor:this.radar?.graticuleColor||"#DEDEDE",graticuleStrokeWidth:this.radar?.graticuleStrokeWidth||1,graticuleOpacity:this.radar?.graticuleOpacity||.3,legendBoxSize:this.radar?.legendBoxSize||12,legendFontSize:this.radar?.legendFontSize||12},this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#ECECFF,#8493A6,#FFC3A0,#DCDDE1,#B8E994,#D1A36F,#C3CDE6,#FFB6C1,#496078,#F8F3E3"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.labelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||o(this.primaryColor,{h:-30}),this.git4=this.git4||o(this.primaryColor,{h:-60}),this.git5=this.git5||o(this.primaryColor,{h:-90}),this.git6=this.git6||o(this.primaryColor,{h:60}),this.git7=this.git7||o(this.primaryColor,{h:120}),this.darkMode?(this.git0=(0,d.A)(this.git0,25),this.git1=(0,d.A)(this.git1,25),this.git2=(0,d.A)(this.git2,25),this.git3=(0,d.A)(this.git3,25),this.git4=(0,d.A)(this.git4,25),this.git5=(0,d.A)(this.git5,25),this.git6=(0,d.A)(this.git6,25),this.git7=(0,d.A)(this.git7,25)):(this.git0=(0,u.A)(this.git0,25),this.git1=(0,u.A)(this.git1,25),this.git2=(0,u.A)(this.git2,25),this.git3=(0,u.A)(this.git3,25),this.git4=(0,u.A)(this.git4,25),this.git5=(0,u.A)(this.git5,25),this.git6=(0,u.A)(this.git6,25),this.git7=(0,u.A)(this.git7,25)),this.gitInv0=this.gitInv0||(0,u.A)(c(this.git0),25),this.gitInv1=this.gitInv1||c(this.git1),this.gitInv2=this.gitInv2||c(this.git2),this.gitInv3=this.gitInv3||c(this.git3),this.gitInv4=this.gitInv4||c(this.git4),this.gitInv5=this.gitInv5||c(this.git5),this.gitInv6=this.gitInv6||c(this.git6),this.gitInv7=this.gitInv7||c(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||c(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||c(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||T,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||A}calculate(t){if(Object.keys(this).forEach(t=>{"calculated"===this[t]&&(this[t]=void 0)}),"object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach(e=>{this[e]=t[e]}),this.updateColors(),e.forEach(e=>{this[e]=t[e]})}},D=(0,i.K2)(t=>{const e=new E;return e.calculate(t),e},"getThemeVariables"),O=class{static{(0,i.K2)(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#cde498",this.secondaryColor="#cdffb2",this.background="white",this.mainBkg="#cde498",this.secondBkg="#cdffb2",this.lineColor="green",this.border1="#13540c",this.border2="#6eaa49",this.arrowheadColor="green",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.tertiaryColor=(0,d.A)("#cde498",10),this.primaryBorderColor=M(this.primaryColor,this.darkMode),this.secondaryBorderColor=M(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=M(this.tertiaryColor,this.darkMode),this.primaryTextColor=c(this.primaryColor),this.secondaryTextColor=c(this.secondaryColor),this.tertiaryTextColor=c(this.primaryColor),this.lineColor=c(this.background),this.textColor=c(this.background),this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#333",this.edgeLabelBackground="#e8e8e8",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="calculated",this.signalColor="#333",this.signalTextColor="#333",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="#326932",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="#6eaa49",this.altSectionBkgColor="white",this.sectionBkgColor2="#6eaa49",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="#487e3a",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.vertLineColor="#00BFFF",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){this.actorBorder=(0,u.A)(this.mainBkg,20),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.actorLineColor=this.actorBorder,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||o(this.primaryColor,{h:30}),this.cScale4=this.cScale4||o(this.primaryColor,{h:60}),this.cScale5=this.cScale5||o(this.primaryColor,{h:90}),this.cScale6=this.cScale6||o(this.primaryColor,{h:120}),this.cScale7=this.cScale7||o(this.primaryColor,{h:150}),this.cScale8=this.cScale8||o(this.primaryColor,{h:210}),this.cScale9=this.cScale9||o(this.primaryColor,{h:270}),this.cScale10=this.cScale10||o(this.primaryColor,{h:300}),this.cScale11=this.cScale11||o(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||(0,u.A)(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||(0,u.A)(this.tertiaryColor,40);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScale"+t]=(0,u.A)(this["cScale"+t],10),this["cScalePeer"+t]=this["cScalePeer"+t]||(0,u.A)(this["cScale"+t],25);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleInv"+t]=this["cScaleInv"+t]||o(this["cScale"+t],{h:180});this.scaleLabelColor="calculated"!==this.scaleLabelColor&&this.scaleLabelColor?this.scaleLabelColor:this.labelTextColor;for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.scaleLabelColor;for(let t=0;t<5;t++)this["surface"+t]=this["surface"+t]||o(this.mainBkg,{h:30,s:-30,l:-(5+5*t)}),this["surfacePeer"+t]=this["surfacePeer"+t]||o(this.mainBkg,{h:30,s:-30,l:-(8+5*t)});this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.taskBorderColor=this.border1,this.taskTextColor=this.taskTextLightColor,this.taskTextOutsideColor=this.taskTextDarkColor,this.activeTaskBorderColor=this.taskBorderColor,this.activeTaskBkgColor=this.mainBkg,this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.rowOdd=this.rowOdd||(0,d.A)(this.mainBkg,75)||"#ffffff",this.rowEven=this.rowEven||(0,d.A)(this.mainBkg,20),this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor=this.lineColor,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=o(this.primaryColor,{h:64}),this.fillType3=o(this.secondaryColor,{h:64}),this.fillType4=o(this.primaryColor,{h:-64}),this.fillType5=o(this.secondaryColor,{h:-64}),this.fillType6=o(this.primaryColor,{h:128}),this.fillType7=o(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||o(this.primaryColor,{l:-30}),this.pie5=this.pie5||o(this.secondaryColor,{l:-30}),this.pie6=this.pie6||o(this.tertiaryColor,{h:40,l:-40}),this.pie7=this.pie7||o(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||o(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||o(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||o(this.primaryColor,{h:60,l:-50}),this.pie11=this.pie11||o(this.primaryColor,{h:-60,l:-50}),this.pie12=this.pie12||o(this.primaryColor,{h:120,l:-50}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||o(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||o(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||o(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||o(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||o(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||o(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,p.A)(this.quadrant1Fill)?(0,d.A)(this.quadrant1Fill):(0,u.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.packet={startByteColor:this.primaryTextColor,endByteColor:this.primaryTextColor,labelColor:this.primaryTextColor,titleColor:this.primaryTextColor,blockStrokeColor:this.primaryTextColor,blockFillColor:this.mainBkg},this.radar={axisColor:this.radar?.axisColor||this.lineColor,axisStrokeWidth:this.radar?.axisStrokeWidth||2,axisLabelFontSize:this.radar?.axisLabelFontSize||12,curveOpacity:this.radar?.curveOpacity||.5,curveStrokeWidth:this.radar?.curveStrokeWidth||2,graticuleColor:this.radar?.graticuleColor||"#DEDEDE",graticuleStrokeWidth:this.radar?.graticuleStrokeWidth||1,graticuleOpacity:this.radar?.graticuleOpacity||.3,legendBoxSize:this.radar?.legendBoxSize||12,legendFontSize:this.radar?.legendFontSize||12},this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#CDE498,#FF6B6B,#A0D2DB,#D7BDE2,#F0F0F0,#FFC3A0,#7FD8BE,#FF9A8B,#FAF3E0,#FFF176"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.edgeLabelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||o(this.primaryColor,{h:-30}),this.git4=this.git4||o(this.primaryColor,{h:-60}),this.git5=this.git5||o(this.primaryColor,{h:-90}),this.git6=this.git6||o(this.primaryColor,{h:60}),this.git7=this.git7||o(this.primaryColor,{h:120}),this.darkMode?(this.git0=(0,d.A)(this.git0,25),this.git1=(0,d.A)(this.git1,25),this.git2=(0,d.A)(this.git2,25),this.git3=(0,d.A)(this.git3,25),this.git4=(0,d.A)(this.git4,25),this.git5=(0,d.A)(this.git5,25),this.git6=(0,d.A)(this.git6,25),this.git7=(0,d.A)(this.git7,25)):(this.git0=(0,u.A)(this.git0,25),this.git1=(0,u.A)(this.git1,25),this.git2=(0,u.A)(this.git2,25),this.git3=(0,u.A)(this.git3,25),this.git4=(0,u.A)(this.git4,25),this.git5=(0,u.A)(this.git5,25),this.git6=(0,u.A)(this.git6,25),this.git7=(0,u.A)(this.git7,25)),this.gitInv0=this.gitInv0||c(this.git0),this.gitInv1=this.gitInv1||c(this.git1),this.gitInv2=this.gitInv2||c(this.git2),this.gitInv3=this.gitInv3||c(this.git3),this.gitInv4=this.gitInv4||c(this.git4),this.gitInv5=this.gitInv5||c(this.git5),this.gitInv6=this.gitInv6||c(this.git6),this.gitInv7=this.gitInv7||c(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||c(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||c(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||T,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||A}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach(e=>{this[e]=t[e]}),this.updateColors(),e.forEach(e=>{this[e]=t[e]})}},R=(0,i.K2)(t=>{const e=new O;return e.calculate(t),e},"getThemeVariables"),K=class{static{(0,i.K2)(this,"Theme")}constructor(){this.primaryColor="#eee",this.contrast="#707070",this.secondaryColor=(0,d.A)(this.contrast,55),this.background="#ffffff",this.tertiaryColor=o(this.primaryColor,{h:-160}),this.primaryBorderColor=M(this.primaryColor,this.darkMode),this.secondaryBorderColor=M(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=M(this.tertiaryColor,this.darkMode),this.primaryTextColor=c(this.primaryColor),this.secondaryTextColor=c(this.secondaryColor),this.tertiaryTextColor=c(this.tertiaryColor),this.lineColor=c(this.background),this.textColor=c(this.background),this.mainBkg="#eee",this.secondBkg="calculated",this.lineColor="#666",this.border1="#999",this.border2="calculated",this.note="#ffa",this.text="#333",this.critical="#d42",this.done="#bbb",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="white",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor=this.actorBorder,this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="calculated",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="white",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBkgColor="calculated",this.critBorderColor="calculated",this.todayLineColor="calculated",this.vertLineColor="calculated",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.rowOdd=this.rowOdd||(0,d.A)(this.mainBkg,75)||"#ffffff",this.rowEven=this.rowEven||"#f4f4f4",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){this.secondBkg=(0,d.A)(this.contrast,55),this.border2=this.contrast,this.actorBorder=(0,d.A)(this.border1,23),this.actorBkg=this.mainBkg,this.actorTextColor=this.text,this.actorLineColor=this.actorBorder,this.signalColor=this.text,this.signalTextColor=this.text,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.text,this.loopTextColor=this.text,this.noteBorderColor="#999",this.noteBkgColor="#666",this.noteTextColor="#fff",this.cScale0=this.cScale0||"#555",this.cScale1=this.cScale1||"#F4F4F4",this.cScale2=this.cScale2||"#555",this.cScale3=this.cScale3||"#BBB",this.cScale4=this.cScale4||"#777",this.cScale5=this.cScale5||"#999",this.cScale6=this.cScale6||"#DDD",this.cScale7=this.cScale7||"#FFF",this.cScale8=this.cScale8||"#DDD",this.cScale9=this.cScale9||"#BBB",this.cScale10=this.cScale10||"#999",this.cScale11=this.cScale11||"#777";for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleInv"+t]=this["cScaleInv"+t]||c(this["cScale"+t]);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this.darkMode?this["cScalePeer"+t]=this["cScalePeer"+t]||(0,d.A)(this["cScale"+t],10):this["cScalePeer"+t]=this["cScalePeer"+t]||(0,u.A)(this["cScale"+t],10);this.scaleLabelColor=this.scaleLabelColor||(this.darkMode?"black":this.labelTextColor),this.cScaleLabel0=this.cScaleLabel0||this.cScale1,this.cScaleLabel2=this.cScaleLabel2||this.cScale1;for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.scaleLabelColor;for(let t=0;t<5;t++)this["surface"+t]=this["surface"+t]||o(this.mainBkg,{l:-(5+5*t)}),this["surfacePeer"+t]=this["surfacePeer"+t]||o(this.mainBkg,{l:-(8+5*t)});this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.titleColor=this.text,this.sectionBkgColor=(0,d.A)(this.contrast,30),this.sectionBkgColor2=(0,d.A)(this.contrast,30),this.taskBorderColor=(0,u.A)(this.contrast,10),this.taskBkgColor=this.contrast,this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor=this.text,this.taskTextOutsideColor=this.taskTextDarkColor,this.activeTaskBorderColor=this.taskBorderColor,this.activeTaskBkgColor=this.mainBkg,this.gridColor=(0,d.A)(this.border1,30),this.doneTaskBkgColor=this.done,this.doneTaskBorderColor=this.lineColor,this.critBkgColor=this.critical,this.critBorderColor=(0,u.A)(this.critBkgColor,10),this.todayLineColor=this.critBkgColor,this.vertLineColor=this.critBkgColor,this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.transitionColor=this.transitionColor||"#000",this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f4f4f4",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.stateBorder=this.stateBorder||"#000",this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#222",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=o(this.primaryColor,{h:64}),this.fillType3=o(this.secondaryColor,{h:64}),this.fillType4=o(this.primaryColor,{h:-64}),this.fillType5=o(this.secondaryColor,{h:-64}),this.fillType6=o(this.primaryColor,{h:128}),this.fillType7=o(this.secondaryColor,{h:128});for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["pie"+t]=this["cScale"+t];this.pie12=this.pie0,this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||o(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||o(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||o(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||o(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||o(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||o(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,p.A)(this.quadrant1Fill)?(0,d.A)(this.quadrant1Fill):(0,u.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#EEE,#6BB8E4,#8ACB88,#C7ACD6,#E8DCC2,#FFB2A8,#FFF380,#7E8D91,#FFD8B1,#FAF3E0"},this.radar={axisColor:this.radar?.axisColor||this.lineColor,axisStrokeWidth:this.radar?.axisStrokeWidth||2,axisLabelFontSize:this.radar?.axisLabelFontSize||12,curveOpacity:this.radar?.curveOpacity||.5,curveStrokeWidth:this.radar?.curveStrokeWidth||2,graticuleColor:this.radar?.graticuleColor||"#DEDEDE",graticuleStrokeWidth:this.radar?.graticuleStrokeWidth||1,graticuleOpacity:this.radar?.graticuleOpacity||.3,legendBoxSize:this.radar?.legendBoxSize||12,legendFontSize:this.radar?.legendFontSize||12},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.edgeLabelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=(0,u.A)(this.pie1,25)||this.primaryColor,this.git1=this.pie2||this.secondaryColor,this.git2=this.pie3||this.tertiaryColor,this.git3=this.pie4||o(this.primaryColor,{h:-30}),this.git4=this.pie5||o(this.primaryColor,{h:-60}),this.git5=this.pie6||o(this.primaryColor,{h:-90}),this.git6=this.pie7||o(this.primaryColor,{h:60}),this.git7=this.pie8||o(this.primaryColor,{h:120}),this.gitInv0=this.gitInv0||c(this.git0),this.gitInv1=this.gitInv1||c(this.git1),this.gitInv2=this.gitInv2||c(this.git2),this.gitInv3=this.gitInv3||c(this.git3),this.gitInv4=this.gitInv4||c(this.git4),this.gitInv5=this.gitInv5||c(this.git5),this.gitInv6=this.gitInv6||c(this.git6),this.gitInv7=this.gitInv7||c(this.git7),this.branchLabelColor=this.branchLabelColor||this.labelTextColor,this.gitBranchLabel0=this.branchLabelColor,this.gitBranchLabel1="white",this.gitBranchLabel2=this.branchLabelColor,this.gitBranchLabel3="white",this.gitBranchLabel4=this.branchLabelColor,this.gitBranchLabel5=this.branchLabelColor,this.gitBranchLabel6=this.branchLabelColor,this.gitBranchLabel7=this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||T,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||A}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach(e=>{this[e]=t[e]}),this.updateColors(),e.forEach(e=>{this[e]=t[e]})}},I={base:{getThemeVariables:L},dark:{getThemeVariables:$},default:{getThemeVariables:D},forest:{getThemeVariables:R},neutral:{getThemeVariables:(0,i.K2)(t=>{const e=new K;return e.calculate(t),e},"getThemeVariables")}},N={flowchart:{useMaxWidth:!0,titleTopMargin:25,subGraphTitleMargin:{top:0,bottom:0},diagramPadding:8,htmlLabels:!0,nodeSpacing:50,rankSpacing:50,curve:"basis",padding:15,defaultRenderer:"dagre-wrapper",wrappingWidth:200,inheritDir:!1},sequence:{useMaxWidth:!0,hideUnusedParticipants:!1,activationWidth:10,diagramMarginX:50,diagramMarginY:10,actorMargin:50,width:150,height:65,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",mirrorActors:!0,forceMenus:!1,bottomMarginAdj:1,rightAngles:!1,showSequenceNumbers:!1,actorFontSize:14,actorFontFamily:'"Open Sans", sans-serif',actorFontWeight:400,noteFontSize:14,noteFontFamily:'"trebuchet ms", verdana, arial, sans-serif',noteFontWeight:400,noteAlign:"center",messageFontSize:16,messageFontFamily:'"trebuchet ms", verdana, arial, sans-serif',messageFontWeight:400,wrap:!1,wrapPadding:10,labelBoxWidth:50,labelBoxHeight:20},gantt:{useMaxWidth:!0,titleTopMargin:25,barHeight:20,barGap:4,topPadding:50,rightPadding:75,leftPadding:75,gridLineStartPadding:35,fontSize:11,sectionFontSize:11,numberSectionStyles:4,axisFormat:"%Y-%m-%d",topAxis:!1,displayMode:"",weekday:"sunday"},journey:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,maxLabelWidth:360,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"],titleColor:"",titleFontFamily:'"trebuchet ms", verdana, arial, sans-serif',titleFontSize:"4ex"},class:{useMaxWidth:!0,titleTopMargin:25,arrowMarkerAbsolute:!1,dividerMargin:10,padding:5,textHeight:10,defaultRenderer:"dagre-wrapper",htmlLabels:!1,hideEmptyMembersBox:!1},state:{useMaxWidth:!0,titleTopMargin:25,dividerMargin:10,sizeUnit:5,padding:8,textHeight:10,titleShift:-15,noteMargin:10,forkWidth:70,forkHeight:7,miniPadding:2,fontSizeFactor:5.02,fontSize:24,labelHeight:16,edgeLengthFactor:"20",compositTitleSize:35,radius:5,defaultRenderer:"dagre-wrapper"},er:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:20,layoutDirection:"TB",minEntityWidth:100,minEntityHeight:75,entityPadding:15,nodeSpacing:140,rankSpacing:80,stroke:"gray",fill:"honeydew",fontSize:12},pie:{useMaxWidth:!0,textPosition:.75},quadrantChart:{useMaxWidth:!0,chartWidth:500,chartHeight:500,titleFontSize:20,titlePadding:10,quadrantPadding:5,xAxisLabelPadding:5,yAxisLabelPadding:5,xAxisLabelFontSize:16,yAxisLabelFontSize:16,quadrantLabelFontSize:16,quadrantTextTopPadding:5,pointTextPadding:5,pointLabelFontSize:12,pointRadius:5,xAxisPosition:"top",yAxisPosition:"left",quadrantInternalBorderStrokeWidth:1,quadrantExternalBorderStrokeWidth:2},xyChart:{useMaxWidth:!0,width:700,height:500,titleFontSize:20,titlePadding:10,showDataLabel:!1,showTitle:!0,xAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},yAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},chartOrientation:"vertical",plotReservedSpacePercent:50},requirement:{useMaxWidth:!0,rect_fill:"#f9f9f9",text_color:"#333",rect_border_size:"0.5px",rect_border_color:"#bbb",rect_min_width:200,rect_min_height:200,fontSize:14,rect_padding:10,line_height:20},mindmap:{useMaxWidth:!0,padding:10,maxNodeWidth:200,layoutAlgorithm:"cose-bilkent"},kanban:{useMaxWidth:!0,padding:8,sectionWidth:200,ticketBaseUrl:""},timeline:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"],disableMulticolor:!1},gitGraph:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:8,nodeLabel:{width:75,height:100,x:-25,y:0},mainBranchName:"main",mainBranchOrder:0,showCommitLabel:!0,showBranches:!0,rotateCommitLabel:!0,parallelCommits:!1,arrowMarkerAbsolute:!1},c4:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,c4ShapeMargin:50,c4ShapePadding:20,width:216,height:60,boxMargin:10,c4ShapeInRow:4,nextLinePaddingX:0,c4BoundaryInRow:2,personFontSize:14,personFontFamily:'"Open Sans", sans-serif',personFontWeight:"normal",external_personFontSize:14,external_personFontFamily:'"Open Sans", sans-serif',external_personFontWeight:"normal",systemFontSize:14,systemFontFamily:'"Open Sans", sans-serif',systemFontWeight:"normal",external_systemFontSize:14,external_systemFontFamily:'"Open Sans", sans-serif',external_systemFontWeight:"normal",system_dbFontSize:14,system_dbFontFamily:'"Open Sans", sans-serif',system_dbFontWeight:"normal",external_system_dbFontSize:14,external_system_dbFontFamily:'"Open Sans", sans-serif',external_system_dbFontWeight:"normal",system_queueFontSize:14,system_queueFontFamily:'"Open Sans", sans-serif',system_queueFontWeight:"normal",external_system_queueFontSize:14,external_system_queueFontFamily:'"Open Sans", sans-serif',external_system_queueFontWeight:"normal",boundaryFontSize:14,boundaryFontFamily:'"Open Sans", sans-serif',boundaryFontWeight:"normal",messageFontSize:12,messageFontFamily:'"Open Sans", sans-serif',messageFontWeight:"normal",containerFontSize:14,containerFontFamily:'"Open Sans", sans-serif',containerFontWeight:"normal",external_containerFontSize:14,external_containerFontFamily:'"Open Sans", sans-serif',external_containerFontWeight:"normal",container_dbFontSize:14,container_dbFontFamily:'"Open Sans", sans-serif',container_dbFontWeight:"normal",external_container_dbFontSize:14,external_container_dbFontFamily:'"Open Sans", sans-serif',external_container_dbFontWeight:"normal",container_queueFontSize:14,container_queueFontFamily:'"Open Sans", sans-serif',container_queueFontWeight:"normal",external_container_queueFontSize:14,external_container_queueFontFamily:'"Open Sans", sans-serif',external_container_queueFontWeight:"normal",componentFontSize:14,componentFontFamily:'"Open Sans", sans-serif',componentFontWeight:"normal",external_componentFontSize:14,external_componentFontFamily:'"Open Sans", sans-serif',external_componentFontWeight:"normal",component_dbFontSize:14,component_dbFontFamily:'"Open Sans", sans-serif',component_dbFontWeight:"normal",external_component_dbFontSize:14,external_component_dbFontFamily:'"Open Sans", sans-serif',external_component_dbFontWeight:"normal",component_queueFontSize:14,component_queueFontFamily:'"Open Sans", sans-serif',component_queueFontWeight:"normal",external_component_queueFontSize:14,external_component_queueFontFamily:'"Open Sans", sans-serif',external_component_queueFontWeight:"normal",wrap:!0,wrapPadding:10,person_bg_color:"#08427B",person_border_color:"#073B6F",external_person_bg_color:"#686868",external_person_border_color:"#8A8A8A",system_bg_color:"#1168BD",system_border_color:"#3C7FC0",system_db_bg_color:"#1168BD",system_db_border_color:"#3C7FC0",system_queue_bg_color:"#1168BD",system_queue_border_color:"#3C7FC0",external_system_bg_color:"#999999",external_system_border_color:"#8A8A8A",external_system_db_bg_color:"#999999",external_system_db_border_color:"#8A8A8A",external_system_queue_bg_color:"#999999",external_system_queue_border_color:"#8A8A8A",container_bg_color:"#438DD5",container_border_color:"#3C7FC0",container_db_bg_color:"#438DD5",container_db_border_color:"#3C7FC0",container_queue_bg_color:"#438DD5",container_queue_border_color:"#3C7FC0",external_container_bg_color:"#B3B3B3",external_container_border_color:"#A6A6A6",external_container_db_bg_color:"#B3B3B3",external_container_db_border_color:"#A6A6A6",external_container_queue_bg_color:"#B3B3B3",external_container_queue_border_color:"#A6A6A6",component_bg_color:"#85BBF0",component_border_color:"#78A8D8",component_db_bg_color:"#85BBF0",component_db_border_color:"#78A8D8",component_queue_bg_color:"#85BBF0",component_queue_border_color:"#78A8D8",external_component_bg_color:"#CCCCCC",external_component_border_color:"#BFBFBF",external_component_db_bg_color:"#CCCCCC",external_component_db_border_color:"#BFBFBF",external_component_queue_bg_color:"#CCCCCC",external_component_queue_border_color:"#BFBFBF"},sankey:{useMaxWidth:!0,width:600,height:400,linkColor:"gradient",nodeAlignment:"justify",showValues:!0,prefix:"",suffix:""},block:{useMaxWidth:!0,padding:8},packet:{useMaxWidth:!0,rowHeight:32,bitWidth:32,bitsPerRow:32,showBits:!0,paddingX:5,paddingY:5},architecture:{useMaxWidth:!0,padding:40,iconSize:80,fontSize:16},radar:{useMaxWidth:!0,width:600,height:600,marginTop:50,marginRight:50,marginBottom:50,marginLeft:50,axisScaleFactor:1,axisLabelFactor:1.05,curveTension:.17},theme:"default",look:"classic",handDrawnSeed:0,layout:"dagre",maxTextSize:5e4,maxEdges:500,darkMode:!1,fontFamily:'"trebuchet ms", verdana, arial, sans-serif;',logLevel:5,securityLevel:"strict",startOnLoad:!0,arrowMarkerAbsolute:!1,secure:["secure","securityLevel","startOnLoad","maxTextSize","suppressErrorRendering","maxEdges"],legacyMathML:!1,forceLegacyMathML:!1,deterministicIds:!1,fontSize:16,markdownAutoWrap:!0,suppressErrorRendering:!1},z={...N,deterministicIDSeed:void 0,elk:{mergeEdges:!1,nodePlacementStrategy:"BRANDES_KOEPF",forceNodeModelOrder:!1,considerModelOrder:"NODES_AND_EDGES"},themeCSS:void 0,themeVariables:I.default.getThemeVariables(),sequence:{...N.sequence,messageFont:(0,i.K2)(function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},"messageFont"),noteFont:(0,i.K2)(function(){return{fontFamily:this.noteFontFamily,fontSize:this.noteFontSize,fontWeight:this.noteFontWeight}},"noteFont"),actorFont:(0,i.K2)(function(){return{fontFamily:this.actorFontFamily,fontSize:this.actorFontSize,fontWeight:this.actorFontWeight}},"actorFont")},class:{hideEmptyMembersBox:!1},gantt:{...N.gantt,tickInterval:void 0,useWidth:void 0},c4:{...N.c4,useWidth:void 0,personFont:(0,i.K2)(function(){return{fontFamily:this.personFontFamily,fontSize:this.personFontSize,fontWeight:this.personFontWeight}},"personFont"),flowchart:{...N.flowchart,inheritDir:!1},external_personFont:(0,i.K2)(function(){return{fontFamily:this.external_personFontFamily,fontSize:this.external_personFontSize,fontWeight:this.external_personFontWeight}},"external_personFont"),systemFont:(0,i.K2)(function(){return{fontFamily:this.systemFontFamily,fontSize:this.systemFontSize,fontWeight:this.systemFontWeight}},"systemFont"),external_systemFont:(0,i.K2)(function(){return{fontFamily:this.external_systemFontFamily,fontSize:this.external_systemFontSize,fontWeight:this.external_systemFontWeight}},"external_systemFont"),system_dbFont:(0,i.K2)(function(){return{fontFamily:this.system_dbFontFamily,fontSize:this.system_dbFontSize,fontWeight:this.system_dbFontWeight}},"system_dbFont"),external_system_dbFont:(0,i.K2)(function(){return{fontFamily:this.external_system_dbFontFamily,fontSize:this.external_system_dbFontSize,fontWeight:this.external_system_dbFontWeight}},"external_system_dbFont"),system_queueFont:(0,i.K2)(function(){return{fontFamily:this.system_queueFontFamily,fontSize:this.system_queueFontSize,fontWeight:this.system_queueFontWeight}},"system_queueFont"),external_system_queueFont:(0,i.K2)(function(){return{fontFamily:this.external_system_queueFontFamily,fontSize:this.external_system_queueFontSize,fontWeight:this.external_system_queueFontWeight}},"external_system_queueFont"),containerFont:(0,i.K2)(function(){return{fontFamily:this.containerFontFamily,fontSize:this.containerFontSize,fontWeight:this.containerFontWeight}},"containerFont"),external_containerFont:(0,i.K2)(function(){return{fontFamily:this.external_containerFontFamily,fontSize:this.external_containerFontSize,fontWeight:this.external_containerFontWeight}},"external_containerFont"),container_dbFont:(0,i.K2)(function(){return{fontFamily:this.container_dbFontFamily,fontSize:this.container_dbFontSize,fontWeight:this.container_dbFontWeight}},"container_dbFont"),external_container_dbFont:(0,i.K2)(function(){return{fontFamily:this.external_container_dbFontFamily,fontSize:this.external_container_dbFontSize,fontWeight:this.external_container_dbFontWeight}},"external_container_dbFont"),container_queueFont:(0,i.K2)(function(){return{fontFamily:this.container_queueFontFamily,fontSize:this.container_queueFontSize,fontWeight:this.container_queueFontWeight}},"container_queueFont"),external_container_queueFont:(0,i.K2)(function(){return{fontFamily:this.external_container_queueFontFamily,fontSize:this.external_container_queueFontSize,fontWeight:this.external_container_queueFontWeight}},"external_container_queueFont"),componentFont:(0,i.K2)(function(){return{fontFamily:this.componentFontFamily,fontSize:this.componentFontSize,fontWeight:this.componentFontWeight}},"componentFont"),external_componentFont:(0,i.K2)(function(){return{fontFamily:this.external_componentFontFamily,fontSize:this.external_componentFontSize,fontWeight:this.external_componentFontWeight}},"external_componentFont"),component_dbFont:(0,i.K2)(function(){return{fontFamily:this.component_dbFontFamily,fontSize:this.component_dbFontSize,fontWeight:this.component_dbFontWeight}},"component_dbFont"),external_component_dbFont:(0,i.K2)(function(){return{fontFamily:this.external_component_dbFontFamily,fontSize:this.external_component_dbFontSize,fontWeight:this.external_component_dbFontWeight}},"external_component_dbFont"),component_queueFont:(0,i.K2)(function(){return{fontFamily:this.component_queueFontFamily,fontSize:this.component_queueFontSize,fontWeight:this.component_queueFontWeight}},"component_queueFont"),external_component_queueFont:(0,i.K2)(function(){return{fontFamily:this.external_component_queueFontFamily,fontSize:this.external_component_queueFontSize,fontWeight:this.external_component_queueFontWeight}},"external_component_queueFont"),boundaryFont:(0,i.K2)(function(){return{fontFamily:this.boundaryFontFamily,fontSize:this.boundaryFontSize,fontWeight:this.boundaryFontWeight}},"boundaryFont"),messageFont:(0,i.K2)(function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},"messageFont")},pie:{...N.pie,useWidth:984},xyChart:{...N.xyChart,useWidth:void 0},requirement:{...N.requirement,useWidth:void 0},packet:{...N.packet},radar:{...N.radar},treemap:{useMaxWidth:!0,padding:10,diagramPadding:8,showValues:!0,nodeWidth:100,nodeHeight:40,borderWidth:1,valueFontSize:12,labelFontSize:14,valueFormat:","}},P=(0,i.K2)((t,e="")=>Object.keys(t).reduce((r,i)=>Array.isArray(t[i])?r:"object"==typeof t[i]&&null!==t[i]?[...r,e+i,...P(t[i],"")]:[...r,e+i],[]),"keyify"),q=new Set(P(z,"")),j=z,W=(0,i.K2)(t=>{if(i.Rm.debug("sanitizeDirective called with",t),"object"==typeof t&&null!=t)if(Array.isArray(t))t.forEach(t=>W(t));else{for(const e of Object.keys(t)){if(i.Rm.debug("Checking key",e),e.startsWith("__")||e.includes("proto")||e.includes("constr")||!q.has(e)||null==t[e]){i.Rm.debug("sanitize deleting key: ",e),delete t[e];continue}if("object"==typeof t[e]){i.Rm.debug("sanitizing object",e),W(t[e]);continue}const r=["themeCSS","fontFamily","altFontFamily"];for(const n of r)e.includes(n)&&(i.Rm.debug("sanitizing css option",e),t[e]=H(t[e]))}if(t.themeVariables)for(const e of Object.keys(t.themeVariables)){const r=t.themeVariables[e];r?.match&&!r.match(/^[\d "#%(),.;A-Za-z]+$/)&&(t.themeVariables[e]="")}i.Rm.debug("After sanitization",t)}},"sanitizeDirective"),H=(0,i.K2)(t=>{let e=0,r=0;for(const i of t){if(e<r)return"{ /* ERROR: Unbalanced CSS */ }";"{"===i?e++:"}"===i&&r++}return e!==r?"{ /* ERROR: Unbalanced CSS */ }":t},"sanitizeCss"),U=Object.freeze(j),Y=S({},U),G=[],X=S({},U),V=(0,i.K2)((t,e)=>{let r=S({},t),i={};for(const n of e)it(n),i=S(i,n);if(r=S(r,i),i.theme&&i.theme in I){const t=S({},h),e=S(t.themeVariables||{},i.themeVariables);r.theme&&r.theme in I&&(r.themeVariables=I[r.theme].getThemeVariables(e))}return ct(X=r),X},"updateCurrentConfig"),Z=(0,i.K2)(t=>(Y=S({},U),Y=S(Y,t),t.theme&&I[t.theme]&&(Y.themeVariables=I[t.theme].getThemeVariables(t.themeVariables)),V(Y,G),Y),"setSiteConfig"),Q=(0,i.K2)(t=>{h=S({},t)},"saveConfigFromInitialize"),J=(0,i.K2)(t=>(Y=S(Y,t),V(Y,G),Y),"updateSiteConfig"),tt=(0,i.K2)(()=>S({},Y),"getSiteConfig"),et=(0,i.K2)(t=>(ct(t),S(X,t),rt()),"setConfig"),rt=(0,i.K2)(()=>S({},X),"getConfig"),it=(0,i.K2)(t=>{t&&(["secure",...Y.secure??[]].forEach(e=>{Object.hasOwn(t,e)&&(i.Rm.debug(`Denied attempt to modify a secure key ${e}`,t[e]),delete t[e])}),Object.keys(t).forEach(e=>{e.startsWith("__")&&delete t[e]}),Object.keys(t).forEach(e=>{"string"==typeof t[e]&&(t[e].includes("<")||t[e].includes(">")||t[e].includes("url(data:"))&&delete t[e],"object"==typeof t[e]&&it(t[e])}))},"sanitize"),nt=(0,i.K2)(t=>{W(t),t.fontFamily&&!t.themeVariables?.fontFamily&&(t.themeVariables={...t.themeVariables,fontFamily:t.fontFamily}),G.push(t),V(Y,G)},"addDirective"),at=(0,i.K2)((t=Y)=>{V(t,G=[])},"reset"),ot={LAZY_LOAD_DEPRECATED:"The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead."},st={},lt=(0,i.K2)(t=>{st[t]||(i.Rm.warn(ot[t]),st[t]=!0)},"issueWarning"),ct=(0,i.K2)(t=>{t&&(t.lazyLoadedDiagrams||t.loadExternalDiagramsAtStartup)&<("LAZY_LOAD_DEPRECATED")},"checkConfig"),ht=(0,i.K2)(()=>{let t={};h&&(t=S(t,h));for(const e of G)t=S(t,e);return t},"getUserDefinedConfig"),ut=/<br\s*\/?>/gi,dt=(0,i.K2)(t=>{if(!t)return[""];return Ct(t).replace(/\\n/g,"#br#").split("#br#")},"getRows"),pt=(()=>{let t=!1;return()=>{t||(ft(),t=!0)}})();function ft(){const t="data-temp-href-target";f.A.addHook("beforeSanitizeAttributes",e=>{"A"===e.tagName&&e.hasAttribute("target")&&e.setAttribute(t,e.getAttribute("target")??"")}),f.A.addHook("afterSanitizeAttributes",e=>{"A"===e.tagName&&e.hasAttribute(t)&&(e.setAttribute("target",e.getAttribute(t)??""),e.removeAttribute(t),"_blank"===e.getAttribute("target")&&e.setAttribute("rel","noopener"))})}(0,i.K2)(ft,"setupDompurifyHooks");var gt=(0,i.K2)(t=>{pt();return f.A.sanitize(t)},"removeScript"),yt=(0,i.K2)((t,e)=>{if(!1!==e.flowchart?.htmlLabels){const r=e.securityLevel;"antiscript"===r||"strict"===r?t=gt(t):"loose"!==r&&(t=(t=(t=Ct(t)).replace(/</g,"<").replace(/>/g,">")).replace(/=/g,"="),t=wt(t))}return t},"sanitizeMore"),mt=(0,i.K2)((t,e)=>t?t=e.dompurifyConfig?f.A.sanitize(yt(t,e),e.dompurifyConfig).toString():f.A.sanitize(yt(t,e),{FORBID_TAGS:["style"]}).toString():t,"sanitizeText"),xt=(0,i.K2)((t,e)=>"string"==typeof t?mt(t,e):t.flat().map(t=>mt(t,e)),"sanitizeTextOrArray"),bt=(0,i.K2)(t=>ut.test(t),"hasBreaks"),kt=(0,i.K2)(t=>t.split(ut),"splitBreaks"),wt=(0,i.K2)(t=>t.replace(/#br#/g,"<br/>"),"placeholderToBreak"),Ct=(0,i.K2)(t=>t.replace(ut,"#br#"),"breakToPlaceholder"),_t=(0,i.K2)(t=>{let e="";return t&&(e=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,e=CSS.escape(e)),e},"getUrl"),vt=(0,i.K2)(t=>!1!==t&&!["false","null","0"].includes(String(t).trim().toLowerCase()),"evaluate"),St=(0,i.K2)(function(...t){const e=t.filter(t=>!isNaN(t));return Math.max(...e)},"getMax"),Tt=(0,i.K2)(function(...t){const e=t.filter(t=>!isNaN(t));return Math.min(...e)},"getMin"),At=(0,i.K2)(function(t){const e=t.split(/(,)/),r=[];for(let i=0;i<e.length;i++){let t=e[i];if(","===t&&i>0&&i+1<e.length){const n=e[i-1],a=e[i+1];Bt(n,a)&&(t=n+","+a,i++,r.pop())}r.push(Lt(t))}return r.join("")},"parseGenericTypes"),Mt=(0,i.K2)((t,e)=>Math.max(0,t.split(e).length-1),"countOccurrence"),Bt=(0,i.K2)((t,e)=>{const r=Mt(t,"~"),i=Mt(e,"~");return 1===r&&1===i},"shouldCombineSets"),Lt=(0,i.K2)(t=>{const e=Mt(t,"~");let r=!1;if(e<=1)return t;e%2!=0&&t.startsWith("~")&&(t=t.substring(1),r=!0);const i=[...t];let n=i.indexOf("~"),a=i.lastIndexOf("~");for(;-1!==n&&-1!==a&&n!==a;)i[n]="<",i[a]=">",n=i.indexOf("~"),a=i.lastIndexOf("~");return r&&i.unshift("~"),i.join("")},"processSet"),Ft=(0,i.K2)(()=>void 0!==window.MathMLElement,"isMathMLSupported"),$t=/\$\$(.*)\$\$/g,Et=(0,i.K2)(t=>(t.match($t)?.length??0)>0,"hasKatex"),Dt=(0,i.K2)(async(t,e)=>{const r=document.createElement("div");r.innerHTML=await Rt(t,e),r.id="katex-temp",r.style.visibility="hidden",r.style.position="absolute",r.style.top="0";const i=document.querySelector("body");i?.insertAdjacentElement("beforeend",r);const n={width:r.clientWidth,height:r.clientHeight};return r.remove(),n},"calculateMathMLDimensions"),Ot=(0,i.K2)(async(t,e)=>{if(!Et(t))return t;if(!(Ft()||e.legacyMathML||e.forceLegacyMathML))return t.replace($t,"MathML is unsupported in this environment.");{const{default:i}=await r.e(2130).then(r.bind(r,22130)),n=e.forceLegacyMathML||!Ft()&&e.legacyMathML?"htmlAndMathml":"mathml";return t.split(ut).map(t=>Et(t)?`<div style="display: flex; align-items: center; justify-content: center; white-space: nowrap;">${t}</div>`:`<div>${t}</div>`).join("").replace($t,(t,e)=>i.renderToString(e,{throwOnError:!0,displayMode:!0,output:n}).replace(/\n/g," ").replace(/<annotation.*<\/annotation>/g,""))}},"renderKatexUnsanitized"),Rt=(0,i.K2)(async(t,e)=>mt(await Ot(t,e),e),"renderKatexSanitized"),Kt={getRows:dt,sanitizeText:mt,sanitizeTextOrArray:xt,hasBreaks:bt,splitBreaks:kt,lineBreakRegex:ut,removeScript:gt,getUrl:_t,evaluate:vt,getMax:St,getMin:Tt},It=(0,i.K2)(function(t,e){for(let r of e)t.attr(r[0],r[1])},"d3Attrs"),Nt=(0,i.K2)(function(t,e,r){let i=new Map;return r?(i.set("width","100%"),i.set("style",`max-width: ${e}px;`)):(i.set("height",t),i.set("width",e)),i},"calculateSvgSizeAttrs"),zt=(0,i.K2)(function(t,e,r,i){const n=Nt(e,r,i);It(t,n)},"configureSvgSize"),Pt=(0,i.K2)(function(t,e,r,n){const a=e.node().getBBox(),o=a.width,s=a.height;i.Rm.info(`SVG bounds: ${o}x${s}`,a);let l=0,c=0;i.Rm.info(`Graph bounds: ${l}x${c}`,t),l=o+2*r,c=s+2*r,i.Rm.info(`Calculated bounds: ${l}x${c}`),zt(e,c,l,n);const h=`${a.x-r} ${a.y-r} ${a.width+2*r} ${a.height+2*r}`;e.attr("viewBox",h)},"setupGraphViewbox"),qt={},jt=(0,i.K2)((t,e,r)=>{let n="";return t in qt&&qt[t]?n=qt[t](r):i.Rm.warn(`No theme found for ${t}`),` & {\n font-family: ${r.fontFamily};\n font-size: ${r.fontSize};\n fill: ${r.textColor}\n }\n @keyframes edge-animation-frame {\n from {\n stroke-dashoffset: 0;\n }\n }\n @keyframes dash {\n to {\n stroke-dashoffset: 0;\n }\n }\n & .edge-animation-slow {\n stroke-dasharray: 9,5 !important;\n stroke-dashoffset: 900;\n animation: dash 50s linear infinite;\n stroke-linecap: round;\n }\n & .edge-animation-fast {\n stroke-dasharray: 9,5 !important;\n stroke-dashoffset: 900;\n animation: dash 20s linear infinite;\n stroke-linecap: round;\n }\n /* Classes common for multiple diagrams */\n\n & .error-icon {\n fill: ${r.errorBkgColor};\n }\n & .error-text {\n fill: ${r.errorTextColor};\n stroke: ${r.errorTextColor};\n }\n\n & .edge-thickness-normal {\n stroke-width: 1px;\n }\n & .edge-thickness-thick {\n stroke-width: 3.5px\n }\n & .edge-pattern-solid {\n stroke-dasharray: 0;\n }\n & .edge-thickness-invisible {\n stroke-width: 0;\n fill: none;\n }\n & .edge-pattern-dashed{\n stroke-dasharray: 3;\n }\n .edge-pattern-dotted {\n stroke-dasharray: 2;\n }\n\n & .marker {\n fill: ${r.lineColor};\n stroke: ${r.lineColor};\n }\n & .marker.cross {\n stroke: ${r.lineColor};\n }\n\n & svg {\n font-family: ${r.fontFamily};\n font-size: ${r.fontSize};\n }\n & p {\n margin: 0\n }\n\n ${n}\n\n ${e}\n`},"getStyles"),Wt=(0,i.K2)((t,e)=>{void 0!==e&&(qt[t]=e)},"addStylesForDiagram"),Ht=jt,Ut={};(0,i.VA)(Ut,{clear:()=>Zt,getAccDescription:()=>ee,getAccTitle:()=>Jt,getDiagramTitle:()=>ie,setAccDescription:()=>te,setAccTitle:()=>Qt,setDiagramTitle:()=>re});var Yt="",Gt="",Xt="",Vt=(0,i.K2)(t=>mt(t,rt()),"sanitizeText"),Zt=(0,i.K2)(()=>{Yt="",Xt="",Gt=""},"clear"),Qt=(0,i.K2)(t=>{Yt=Vt(t).replace(/^\s+/g,"")},"setAccTitle"),Jt=(0,i.K2)(()=>Yt,"getAccTitle"),te=(0,i.K2)(t=>{Xt=Vt(t).replace(/\n\s+/g,"\n")},"setAccDescription"),ee=(0,i.K2)(()=>Xt,"getAccDescription"),re=(0,i.K2)(t=>{Gt=Vt(t)},"setDiagramTitle"),ie=(0,i.K2)(()=>Gt,"getDiagramTitle"),ne=i.Rm,ae=i.He,oe=rt,se=et,le=U,ce=(0,i.K2)(t=>mt(t,oe()),"sanitizeText"),he=Pt,ue=(0,i.K2)(()=>Ut,"getCommonDb"),de={},pe=(0,i.K2)((t,e,r)=>{de[t]&&ne.warn(`Diagram with id ${t} already registered. Overwriting.`),de[t]=e,r&&C(t,r),Wt(t,e.styles),e.injectUtils?.(ne,ae,oe,ce,he,ue(),()=>{})},"registerDiagram"),fe=(0,i.K2)(t=>{if(t in de)return de[t];throw new ge(t)},"getDiagram"),ge=class extends Error{static{(0,i.K2)(this,"DiagramNotFoundError")}constructor(t){super(`Diagram ${t} not found.`)}}},68335:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var i=r(18744),n=r(41917);const a=(0,i.A)(n.A,"Map")},69119:(t,e)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.BLANK_URL=e.relativeFirstCharacters=e.whitespaceEscapeCharsRegex=e.urlSchemeRegex=e.ctrlCharactersRegex=e.htmlCtrlEntityRegex=e.htmlEntitiesRegex=e.invalidProtocolRegex=void 0,e.invalidProtocolRegex=/^([^\w]*)(javascript|data|vbscript)/im,e.htmlEntitiesRegex=/&#(\w+)(^\w|;)?/g,e.htmlCtrlEntityRegex=/&(newline|tab);/gi,e.ctrlCharactersRegex=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,e.urlSchemeRegex=/^.+(:|:)/gim,e.whitespaceEscapeCharsRegex=/(\\|%5[cC])((%(6[eE]|72|74))|[nrt])/g,e.relativeFirstCharacters=[".","/"],e.BLANK_URL="about:blank"},69471:(t,e,r)=>{"use strict";r.d(e,{A:()=>o});var i=r(97271);const n=(0,r(40367).A)(Object.keys,Object);var a=Object.prototype.hasOwnProperty;const o=function(t){if(!(0,i.A)(t))return n(t);var e=[];for(var r in Object(t))a.call(t,r)&&"constructor"!=r&&e.push(r);return e}},70451:(t,e,r)=>{"use strict";function i(t,e){let r;if(void 0===e)for(const i of t)null!=i&&(r<i||void 0===r&&i>=i)&&(r=i);else{let i=-1;for(let n of t)null!=(n=e(n,++i,t))&&(r<n||void 0===r&&n>=n)&&(r=n)}return r}function n(t,e){let r;if(void 0===e)for(const i of t)null!=i&&(r>i||void 0===r&&i>=i)&&(r=i);else{let i=-1;for(let n of t)null!=(n=e(n,++i,t))&&(r>n||void 0===r&&n>=n)&&(r=n)}return r}function a(t){return t}r.d(e,{JLW:()=>us,l78:()=>x,tlR:()=>m,qrM:()=>vs,Yu4:()=>Ts,IA3:()=>Ms,Wi0:()=>Ls,PGM:()=>Fs,OEq:()=>Es,y8u:()=>Rs,olC:()=>Is,IrU:()=>zs,oDi:()=>js,Q7f:()=>Hs,cVp:()=>Ys,lUB:()=>fs,Lx9:()=>Xs,nVG:()=>il,uxU:()=>nl,Xf2:()=>sl,GZz:()=>cl,UPb:()=>ul,dyv:()=>hl,GPZ:()=>Yr,Sk5:()=>Jr,bEH:()=>$i,n8j:()=>ms,T9B:()=>i,jkA:()=>n,rLf:()=>ks,WH:()=>Pi,m4Y:()=>bn,UMr:()=>zi,w7C:()=>Ro,zt:()=>Ko,Ltv:()=>Io,UAC:()=>Rn,DCK:()=>fa,TUC:()=>Hn,Agd:()=>Dn,t6C:()=>Ln,wXd:()=>$n,ABi:()=>Pn,Ui6:()=>ea,rGn:()=>Un,ucG:()=>Fn,YPH:()=>zn,Mol:()=>Wn,PGu:()=>qn,GuW:()=>jn,hkb:()=>di});var o=1,s=2,l=3,c=4,h=1e-6;function u(t){return"translate("+t+",0)"}function d(t){return"translate(0,"+t+")"}function p(t){return e=>+t(e)}function f(t,e){return e=Math.max(0,t.bandwidth()-2*e)/2,t.round()&&(e=Math.round(e)),r=>+t(r)+e}function g(){return!this.__axis}function y(t,e){var r=[],i=null,n=null,y=6,m=6,x=3,b="undefined"!=typeof window&&window.devicePixelRatio>1?0:.5,k=t===o||t===c?-1:1,w=t===c||t===s?"x":"y",C=t===o||t===l?u:d;function _(u){var d=null==i?e.ticks?e.ticks.apply(e,r):e.domain():i,_=null==n?e.tickFormat?e.tickFormat.apply(e,r):a:n,v=Math.max(y,0)+x,S=e.range(),T=+S[0]+b,A=+S[S.length-1]+b,M=(e.bandwidth?f:p)(e.copy(),b),B=u.selection?u.selection():u,L=B.selectAll(".domain").data([null]),F=B.selectAll(".tick").data(d,e).order(),$=F.exit(),E=F.enter().append("g").attr("class","tick"),D=F.select("line"),O=F.select("text");L=L.merge(L.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),F=F.merge(E),D=D.merge(E.append("line").attr("stroke","currentColor").attr(w+"2",k*y)),O=O.merge(E.append("text").attr("fill","currentColor").attr(w,k*v).attr("dy",t===o?"0em":t===l?"0.71em":"0.32em")),u!==B&&(L=L.transition(u),F=F.transition(u),D=D.transition(u),O=O.transition(u),$=$.transition(u).attr("opacity",h).attr("transform",function(t){return isFinite(t=M(t))?C(t+b):this.getAttribute("transform")}),E.attr("opacity",h).attr("transform",function(t){var e=this.parentNode.__axis;return C((e&&isFinite(e=e(t))?e:M(t))+b)})),$.remove(),L.attr("d",t===c||t===s?m?"M"+k*m+","+T+"H"+b+"V"+A+"H"+k*m:"M"+b+","+T+"V"+A:m?"M"+T+","+k*m+"V"+b+"H"+A+"V"+k*m:"M"+T+","+b+"H"+A),F.attr("opacity",1).attr("transform",function(t){return C(M(t)+b)}),D.attr(w+"2",k*y),O.attr(w,k*v).text(_),B.filter(g).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",t===s?"start":t===c?"end":"middle"),B.each(function(){this.__axis=M})}return _.scale=function(t){return arguments.length?(e=t,_):e},_.ticks=function(){return r=Array.from(arguments),_},_.tickArguments=function(t){return arguments.length?(r=null==t?[]:Array.from(t),_):r.slice()},_.tickValues=function(t){return arguments.length?(i=null==t?null:Array.from(t),_):i&&i.slice()},_.tickFormat=function(t){return arguments.length?(n=t,_):n},_.tickSize=function(t){return arguments.length?(y=m=+t,_):y},_.tickSizeInner=function(t){return arguments.length?(y=+t,_):y},_.tickSizeOuter=function(t){return arguments.length?(m=+t,_):m},_.tickPadding=function(t){return arguments.length?(x=+t,_):x},_.offset=function(t){return arguments.length?(b=+t,_):b},_}function m(t){return y(o,t)}function x(t){return y(l,t)}function b(){}function k(t){return null==t?b:function(){return this.querySelector(t)}}function w(){return[]}function C(t){return null==t?w:function(){return this.querySelectorAll(t)}}function _(t){return function(){return null==(e=t.apply(this,arguments))?[]:Array.isArray(e)?e:Array.from(e);var e}}function v(t){return function(){return this.matches(t)}}function S(t){return function(e){return e.matches(t)}}var T=Array.prototype.find;function A(){return this.firstElementChild}var M=Array.prototype.filter;function B(){return Array.from(this.children)}function L(t){return new Array(t.length)}function F(t,e){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=e}function $(t,e,r,i,n,a){for(var o,s=0,l=e.length,c=a.length;s<c;++s)(o=e[s])?(o.__data__=a[s],i[s]=o):r[s]=new F(t,a[s]);for(;s<l;++s)(o=e[s])&&(n[s]=o)}function E(t,e,r,i,n,a,o){var s,l,c,h=new Map,u=e.length,d=a.length,p=new Array(u);for(s=0;s<u;++s)(l=e[s])&&(p[s]=c=o.call(l,l.__data__,s,e)+"",h.has(c)?n[s]=l:h.set(c,l));for(s=0;s<d;++s)c=o.call(t,a[s],s,a)+"",(l=h.get(c))?(i[s]=l,l.__data__=a[s],h.delete(c)):r[s]=new F(t,a[s]);for(s=0;s<u;++s)(l=e[s])&&h.get(p[s])===l&&(n[s]=l)}function D(t){return t.__data__}function O(t){return"object"==typeof t&&"length"in t?t:Array.from(t)}function R(t,e){return t<e?-1:t>e?1:t>=e?0:NaN}F.prototype={constructor:F,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,e){return this._parent.insertBefore(t,e)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var K="http://www.w3.org/1999/xhtml";const I={svg:"http://www.w3.org/2000/svg",xhtml:K,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function N(t){var e=t+="",r=e.indexOf(":");return r>=0&&"xmlns"!==(e=t.slice(0,r))&&(t=t.slice(r+1)),I.hasOwnProperty(e)?{space:I[e],local:t}:t}function z(t){return function(){this.removeAttribute(t)}}function P(t){return function(){this.removeAttributeNS(t.space,t.local)}}function q(t,e){return function(){this.setAttribute(t,e)}}function j(t,e){return function(){this.setAttributeNS(t.space,t.local,e)}}function W(t,e){return function(){var r=e.apply(this,arguments);null==r?this.removeAttribute(t):this.setAttribute(t,r)}}function H(t,e){return function(){var r=e.apply(this,arguments);null==r?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,r)}}function U(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function Y(t){return function(){this.style.removeProperty(t)}}function G(t,e,r){return function(){this.style.setProperty(t,e,r)}}function X(t,e,r){return function(){var i=e.apply(this,arguments);null==i?this.style.removeProperty(t):this.style.setProperty(t,i,r)}}function V(t,e){return t.style.getPropertyValue(e)||U(t).getComputedStyle(t,null).getPropertyValue(e)}function Z(t){return function(){delete this[t]}}function Q(t,e){return function(){this[t]=e}}function J(t,e){return function(){var r=e.apply(this,arguments);null==r?delete this[t]:this[t]=r}}function tt(t){return t.trim().split(/^|\s+/)}function et(t){return t.classList||new rt(t)}function rt(t){this._node=t,this._names=tt(t.getAttribute("class")||"")}function it(t,e){for(var r=et(t),i=-1,n=e.length;++i<n;)r.add(e[i])}function nt(t,e){for(var r=et(t),i=-1,n=e.length;++i<n;)r.remove(e[i])}function at(t){return function(){it(this,t)}}function ot(t){return function(){nt(this,t)}}function st(t,e){return function(){(e.apply(this,arguments)?it:nt)(this,t)}}function lt(){this.textContent=""}function ct(t){return function(){this.textContent=t}}function ht(t){return function(){var e=t.apply(this,arguments);this.textContent=null==e?"":e}}function ut(){this.innerHTML=""}function dt(t){return function(){this.innerHTML=t}}function pt(t){return function(){var e=t.apply(this,arguments);this.innerHTML=null==e?"":e}}function ft(){this.nextSibling&&this.parentNode.appendChild(this)}function gt(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function yt(t){return function(){var e=this.ownerDocument,r=this.namespaceURI;return r===K&&e.documentElement.namespaceURI===K?e.createElement(t):e.createElementNS(r,t)}}function mt(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function xt(t){var e=N(t);return(e.local?mt:yt)(e)}function bt(){return null}function kt(){var t=this.parentNode;t&&t.removeChild(this)}function wt(){var t=this.cloneNode(!1),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function Ct(){var t=this.cloneNode(!0),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function _t(t){return function(){var e=this.__on;if(e){for(var r,i=0,n=-1,a=e.length;i<a;++i)r=e[i],t.type&&r.type!==t.type||r.name!==t.name?e[++n]=r:this.removeEventListener(r.type,r.listener,r.options);++n?e.length=n:delete this.__on}}}function vt(t,e,r){return function(){var i,n=this.__on,a=function(t){return function(e){t.call(this,e,this.__data__)}}(e);if(n)for(var o=0,s=n.length;o<s;++o)if((i=n[o]).type===t.type&&i.name===t.name)return this.removeEventListener(i.type,i.listener,i.options),this.addEventListener(i.type,i.listener=a,i.options=r),void(i.value=e);this.addEventListener(t.type,a,r),i={type:t.type,name:t.name,value:e,listener:a,options:r},n?n.push(i):this.__on=[i]}}function St(t,e,r){var i=U(t),n=i.CustomEvent;"function"==typeof n?n=new n(e,r):(n=i.document.createEvent("Event"),r?(n.initEvent(e,r.bubbles,r.cancelable),n.detail=r.detail):n.initEvent(e,!1,!1)),t.dispatchEvent(n)}function Tt(t,e){return function(){return St(this,t,e)}}function At(t,e){return function(){return St(this,t,e.apply(this,arguments))}}rt.prototype={add:function(t){this._names.indexOf(t)<0&&(this._names.push(t),this._node.setAttribute("class",this._names.join(" ")))},remove:function(t){var e=this._names.indexOf(t);e>=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var Mt=[null];function Bt(t,e){this._groups=t,this._parents=e}function Lt(){return new Bt([[document.documentElement]],Mt)}Bt.prototype=Lt.prototype={constructor:Bt,select:function(t){"function"!=typeof t&&(t=k(t));for(var e=this._groups,r=e.length,i=new Array(r),n=0;n<r;++n)for(var a,o,s=e[n],l=s.length,c=i[n]=new Array(l),h=0;h<l;++h)(a=s[h])&&(o=t.call(a,a.__data__,h,s))&&("__data__"in a&&(o.__data__=a.__data__),c[h]=o);return new Bt(i,this._parents)},selectAll:function(t){t="function"==typeof t?_(t):C(t);for(var e=this._groups,r=e.length,i=[],n=[],a=0;a<r;++a)for(var o,s=e[a],l=s.length,c=0;c<l;++c)(o=s[c])&&(i.push(t.call(o,o.__data__,c,s)),n.push(o));return new Bt(i,n)},selectChild:function(t){return this.select(null==t?A:function(t){return function(){return T.call(this.children,t)}}("function"==typeof t?t:S(t)))},selectChildren:function(t){return this.selectAll(null==t?B:function(t){return function(){return M.call(this.children,t)}}("function"==typeof t?t:S(t)))},filter:function(t){"function"!=typeof t&&(t=v(t));for(var e=this._groups,r=e.length,i=new Array(r),n=0;n<r;++n)for(var a,o=e[n],s=o.length,l=i[n]=[],c=0;c<s;++c)(a=o[c])&&t.call(a,a.__data__,c,o)&&l.push(a);return new Bt(i,this._parents)},data:function(t,e){if(!arguments.length)return Array.from(this,D);var r,i=e?E:$,n=this._parents,a=this._groups;"function"!=typeof t&&(r=t,t=function(){return r});for(var o=a.length,s=new Array(o),l=new Array(o),c=new Array(o),h=0;h<o;++h){var u=n[h],d=a[h],p=d.length,f=O(t.call(u,u&&u.__data__,h,n)),g=f.length,y=l[h]=new Array(g),m=s[h]=new Array(g);i(u,d,y,m,c[h]=new Array(p),f,e);for(var x,b,k=0,w=0;k<g;++k)if(x=y[k]){for(k>=w&&(w=k+1);!(b=m[w])&&++w<g;);x._next=b||null}}return(s=new Bt(s,n))._enter=l,s._exit=c,s},enter:function(){return new Bt(this._enter||this._groups.map(L),this._parents)},exit:function(){return new Bt(this._exit||this._groups.map(L),this._parents)},join:function(t,e,r){var i=this.enter(),n=this,a=this.exit();return"function"==typeof t?(i=t(i))&&(i=i.selection()):i=i.append(t+""),null!=e&&(n=e(n))&&(n=n.selection()),null==r?a.remove():r(a),i&&n?i.merge(n).order():n},merge:function(t){for(var e=t.selection?t.selection():t,r=this._groups,i=e._groups,n=r.length,a=i.length,o=Math.min(n,a),s=new Array(n),l=0;l<o;++l)for(var c,h=r[l],u=i[l],d=h.length,p=s[l]=new Array(d),f=0;f<d;++f)(c=h[f]||u[f])&&(p[f]=c);for(;l<n;++l)s[l]=r[l];return new Bt(s,this._parents)},selection:function(){return this},order:function(){for(var t=this._groups,e=-1,r=t.length;++e<r;)for(var i,n=t[e],a=n.length-1,o=n[a];--a>=0;)(i=n[a])&&(o&&4^i.compareDocumentPosition(o)&&o.parentNode.insertBefore(i,o),o=i);return this},sort:function(t){function e(e,r){return e&&r?t(e.__data__,r.__data__):!e-!r}t||(t=R);for(var r=this._groups,i=r.length,n=new Array(i),a=0;a<i;++a){for(var o,s=r[a],l=s.length,c=n[a]=new Array(l),h=0;h<l;++h)(o=s[h])&&(c[h]=o);c.sort(e)}return new Bt(n,this._parents).order()},call:function(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this},nodes:function(){return Array.from(this)},node:function(){for(var t=this._groups,e=0,r=t.length;e<r;++e)for(var i=t[e],n=0,a=i.length;n<a;++n){var o=i[n];if(o)return o}return null},size:function(){let t=0;for(const e of this)++t;return t},empty:function(){return!this.node()},each:function(t){for(var e=this._groups,r=0,i=e.length;r<i;++r)for(var n,a=e[r],o=0,s=a.length;o<s;++o)(n=a[o])&&t.call(n,n.__data__,o,a);return this},attr:function(t,e){var r=N(t);if(arguments.length<2){var i=this.node();return r.local?i.getAttributeNS(r.space,r.local):i.getAttribute(r)}return this.each((null==e?r.local?P:z:"function"==typeof e?r.local?H:W:r.local?j:q)(r,e))},style:function(t,e,r){return arguments.length>1?this.each((null==e?Y:"function"==typeof e?X:G)(t,e,null==r?"":r)):V(this.node(),t)},property:function(t,e){return arguments.length>1?this.each((null==e?Z:"function"==typeof e?J:Q)(t,e)):this.node()[t]},classed:function(t,e){var r=tt(t+"");if(arguments.length<2){for(var i=et(this.node()),n=-1,a=r.length;++n<a;)if(!i.contains(r[n]))return!1;return!0}return this.each(("function"==typeof e?st:e?at:ot)(r,e))},text:function(t){return arguments.length?this.each(null==t?lt:("function"==typeof t?ht:ct)(t)):this.node().textContent},html:function(t){return arguments.length?this.each(null==t?ut:("function"==typeof t?pt:dt)(t)):this.node().innerHTML},raise:function(){return this.each(ft)},lower:function(){return this.each(gt)},append:function(t){var e="function"==typeof t?t:xt(t);return this.select(function(){return this.appendChild(e.apply(this,arguments))})},insert:function(t,e){var r="function"==typeof t?t:xt(t),i=null==e?bt:"function"==typeof e?e:k(e);return this.select(function(){return this.insertBefore(r.apply(this,arguments),i.apply(this,arguments)||null)})},remove:function(){return this.each(kt)},clone:function(t){return this.select(t?Ct:wt)},datum:function(t){return arguments.length?this.property("__data__",t):this.node().__data__},on:function(t,e,r){var i,n,a=function(t){return t.trim().split(/^|\s+/).map(function(t){var e="",r=t.indexOf(".");return r>=0&&(e=t.slice(r+1),t=t.slice(0,r)),{type:t,name:e}})}(t+""),o=a.length;if(!(arguments.length<2)){for(s=e?vt:_t,i=0;i<o;++i)this.each(s(a[i],e,r));return this}var s=this.node().__on;if(s)for(var l,c=0,h=s.length;c<h;++c)for(i=0,l=s[c];i<o;++i)if((n=a[i]).type===l.type&&n.name===l.name)return l.value},dispatch:function(t,e){return this.each(("function"==typeof e?At:Tt)(t,e))},[Symbol.iterator]:function*(){for(var t=this._groups,e=0,r=t.length;e<r;++e)for(var i,n=t[e],a=0,o=n.length;a<o;++a)(i=n[a])&&(yield i)}};const Ft=Lt;var $t={value:()=>{}};function Et(){for(var t,e=0,r=arguments.length,i={};e<r;++e){if(!(t=arguments[e]+"")||t in i||/[\s.]/.test(t))throw new Error("illegal type: "+t);i[t]=[]}return new Dt(i)}function Dt(t){this._=t}function Ot(t,e){for(var r,i=0,n=t.length;i<n;++i)if((r=t[i]).name===e)return r.value}function Rt(t,e,r){for(var i=0,n=t.length;i<n;++i)if(t[i].name===e){t[i]=$t,t=t.slice(0,i).concat(t.slice(i+1));break}return null!=r&&t.push({name:e,value:r}),t}Dt.prototype=Et.prototype={constructor:Dt,on:function(t,e){var r,i,n=this._,a=(i=n,(t+"").trim().split(/^|\s+/).map(function(t){var e="",r=t.indexOf(".");if(r>=0&&(e=t.slice(r+1),t=t.slice(0,r)),t&&!i.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:e}})),o=-1,s=a.length;if(!(arguments.length<2)){if(null!=e&&"function"!=typeof e)throw new Error("invalid callback: "+e);for(;++o<s;)if(r=(t=a[o]).type)n[r]=Rt(n[r],t.name,e);else if(null==e)for(r in n)n[r]=Rt(n[r],t.name,null);return this}for(;++o<s;)if((r=(t=a[o]).type)&&(r=Ot(n[r],t.name)))return r},copy:function(){var t={},e=this._;for(var r in e)t[r]=e[r].slice();return new Dt(t)},call:function(t,e){if((r=arguments.length-2)>0)for(var r,i,n=new Array(r),a=0;a<r;++a)n[a]=arguments[a+2];if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(a=0,r=(i=this._[t]).length;a<r;++a)i[a].value.apply(e,n)},apply:function(t,e,r){if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(var i=this._[t],n=0,a=i.length;n<a;++n)i[n].value.apply(e,r)}};const Kt=Et;var It,Nt,zt=0,Pt=0,qt=0,jt=0,Wt=0,Ht=0,Ut="object"==typeof performance&&performance.now?performance:Date,Yt="object"==typeof window&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(t){setTimeout(t,17)};function Gt(){return Wt||(Yt(Xt),Wt=Ut.now()+Ht)}function Xt(){Wt=0}function Vt(){this._call=this._time=this._next=null}function Zt(t,e,r){var i=new Vt;return i.restart(t,e,r),i}function Qt(){Wt=(jt=Ut.now())+Ht,zt=Pt=0;try{!function(){Gt(),++zt;for(var t,e=It;e;)(t=Wt-e._time)>=0&&e._call.call(void 0,t),e=e._next;--zt}()}finally{zt=0,function(){var t,e,r=It,i=1/0;for(;r;)r._call?(i>r._time&&(i=r._time),t=r,r=r._next):(e=r._next,r._next=null,r=t?t._next=e:It=e);Nt=t,te(i)}(),Wt=0}}function Jt(){var t=Ut.now(),e=t-jt;e>1e3&&(Ht-=e,jt=t)}function te(t){zt||(Pt&&(Pt=clearTimeout(Pt)),t-Wt>24?(t<1/0&&(Pt=setTimeout(Qt,t-Ut.now()-Ht)),qt&&(qt=clearInterval(qt))):(qt||(jt=Ut.now(),qt=setInterval(Jt,1e3)),zt=1,Yt(Qt)))}function ee(t,e,r){var i=new Vt;return e=null==e?0:+e,i.restart(r=>{i.stop(),t(r+e)},e,r),i}Vt.prototype=Zt.prototype={constructor:Vt,restart:function(t,e,r){if("function"!=typeof t)throw new TypeError("callback is not a function");r=(null==r?Gt():+r)+(null==e?0:+e),this._next||Nt===this||(Nt?Nt._next=this:It=this,Nt=this),this._call=t,this._time=r,te()},stop:function(){this._call&&(this._call=null,this._time=1/0,te())}};var re=Kt("start","end","cancel","interrupt"),ie=[];function ne(t,e,r,i,n,a){var o=t.__transition;if(o){if(r in o)return}else t.__transition={};!function(t,e,r){var i,n=t.__transition;function a(t){r.state=1,r.timer.restart(o,r.delay,r.time),r.delay<=t&&o(t-r.delay)}function o(a){var c,h,u,d;if(1!==r.state)return l();for(c in n)if((d=n[c]).name===r.name){if(3===d.state)return ee(o);4===d.state?(d.state=6,d.timer.stop(),d.on.call("interrupt",t,t.__data__,d.index,d.group),delete n[c]):+c<e&&(d.state=6,d.timer.stop(),d.on.call("cancel",t,t.__data__,d.index,d.group),delete n[c])}if(ee(function(){3===r.state&&(r.state=4,r.timer.restart(s,r.delay,r.time),s(a))}),r.state=2,r.on.call("start",t,t.__data__,r.index,r.group),2===r.state){for(r.state=3,i=new Array(u=r.tween.length),c=0,h=-1;c<u;++c)(d=r.tween[c].value.call(t,t.__data__,r.index,r.group))&&(i[++h]=d);i.length=h+1}}function s(e){for(var n=e<r.duration?r.ease.call(null,e/r.duration):(r.timer.restart(l),r.state=5,1),a=-1,o=i.length;++a<o;)i[a].call(t,n);5===r.state&&(r.on.call("end",t,t.__data__,r.index,r.group),l())}function l(){for(var i in r.state=6,r.timer.stop(),delete n[e],n)return;delete t.__transition}n[e]=r,r.timer=Zt(a,0,r.time)}(t,r,{name:e,index:i,group:n,on:re,tween:ie,time:a.time,delay:a.delay,duration:a.duration,ease:a.ease,timer:null,state:0})}function ae(t,e){var r=se(t,e);if(r.state>0)throw new Error("too late; already scheduled");return r}function oe(t,e){var r=se(t,e);if(r.state>3)throw new Error("too late; already running");return r}function se(t,e){var r=t.__transition;if(!r||!(r=r[e]))throw new Error("transition not found");return r}function le(t,e){return t=+t,e=+e,function(r){return t*(1-r)+e*r}}var ce,he=180/Math.PI,ue={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function de(t,e,r,i,n,a){var o,s,l;return(o=Math.sqrt(t*t+e*e))&&(t/=o,e/=o),(l=t*r+e*i)&&(r-=t*l,i-=e*l),(s=Math.sqrt(r*r+i*i))&&(r/=s,i/=s,l/=s),t*i<e*r&&(t=-t,e=-e,l=-l,o=-o),{translateX:n,translateY:a,rotate:Math.atan2(e,t)*he,skewX:Math.atan(l)*he,scaleX:o,scaleY:s}}function pe(t,e,r,i){function n(t){return t.length?t.pop()+" ":""}return function(a,o){var s=[],l=[];return a=t(a),o=t(o),function(t,i,n,a,o,s){if(t!==n||i!==a){var l=o.push("translate(",null,e,null,r);s.push({i:l-4,x:le(t,n)},{i:l-2,x:le(i,a)})}else(n||a)&&o.push("translate("+n+e+a+r)}(a.translateX,a.translateY,o.translateX,o.translateY,s,l),function(t,e,r,a){t!==e?(t-e>180?e+=360:e-t>180&&(t+=360),a.push({i:r.push(n(r)+"rotate(",null,i)-2,x:le(t,e)})):e&&r.push(n(r)+"rotate("+e+i)}(a.rotate,o.rotate,s,l),function(t,e,r,a){t!==e?a.push({i:r.push(n(r)+"skewX(",null,i)-2,x:le(t,e)}):e&&r.push(n(r)+"skewX("+e+i)}(a.skewX,o.skewX,s,l),function(t,e,r,i,a,o){if(t!==r||e!==i){var s=a.push(n(a)+"scale(",null,",",null,")");o.push({i:s-4,x:le(t,r)},{i:s-2,x:le(e,i)})}else 1===r&&1===i||a.push(n(a)+"scale("+r+","+i+")")}(a.scaleX,a.scaleY,o.scaleX,o.scaleY,s,l),a=o=null,function(t){for(var e,r=-1,i=l.length;++r<i;)s[(e=l[r]).i]=e.x(t);return s.join("")}}}var fe=pe(function(t){const e=new("function"==typeof DOMMatrix?DOMMatrix:WebKitCSSMatrix)(t+"");return e.isIdentity?ue:de(e.a,e.b,e.c,e.d,e.e,e.f)},"px, ","px)","deg)"),ge=pe(function(t){return null==t?ue:(ce||(ce=document.createElementNS("http://www.w3.org/2000/svg","g")),ce.setAttribute("transform",t),(t=ce.transform.baseVal.consolidate())?de((t=t.matrix).a,t.b,t.c,t.d,t.e,t.f):ue)},", ",")",")");function ye(t,e){var r,i;return function(){var n=oe(this,t),a=n.tween;if(a!==r)for(var o=0,s=(i=r=a).length;o<s;++o)if(i[o].name===e){(i=i.slice()).splice(o,1);break}n.tween=i}}function me(t,e,r){var i,n;if("function"!=typeof r)throw new Error;return function(){var a=oe(this,t),o=a.tween;if(o!==i){n=(i=o).slice();for(var s={name:e,value:r},l=0,c=n.length;l<c;++l)if(n[l].name===e){n[l]=s;break}l===c&&n.push(s)}a.tween=n}}function xe(t,e,r){var i=t._id;return t.each(function(){var t=oe(this,i);(t.value||(t.value={}))[e]=r.apply(this,arguments)}),function(t){return se(t,i).value[e]}}function be(t,e,r){t.prototype=e.prototype=r,r.constructor=t}function ke(t,e){var r=Object.create(t.prototype);for(var i in e)r[i]=e[i];return r}function we(){}var Ce=.7,_e=1/Ce,ve="\\s*([+-]?\\d+)\\s*",Se="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",Te="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",Ae=/^#([0-9a-f]{3,8})$/,Me=new RegExp(`^rgb\\(${ve},${ve},${ve}\\)$`),Be=new RegExp(`^rgb\\(${Te},${Te},${Te}\\)$`),Le=new RegExp(`^rgba\\(${ve},${ve},${ve},${Se}\\)$`),Fe=new RegExp(`^rgba\\(${Te},${Te},${Te},${Se}\\)$`),$e=new RegExp(`^hsl\\(${Se},${Te},${Te}\\)$`),Ee=new RegExp(`^hsla\\(${Se},${Te},${Te},${Se}\\)$`),De={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};function Oe(){return this.rgb().formatHex()}function Re(){return this.rgb().formatRgb()}function Ke(t){var e,r;return t=(t+"").trim().toLowerCase(),(e=Ae.exec(t))?(r=e[1].length,e=parseInt(e[1],16),6===r?Ie(e):3===r?new qe(e>>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===r?Ne(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===r?Ne(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=Me.exec(t))?new qe(e[1],e[2],e[3],1):(e=Be.exec(t))?new qe(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=Le.exec(t))?Ne(e[1],e[2],e[3],e[4]):(e=Fe.exec(t))?Ne(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=$e.exec(t))?Ge(e[1],e[2]/100,e[3]/100,1):(e=Ee.exec(t))?Ge(e[1],e[2]/100,e[3]/100,e[4]):De.hasOwnProperty(t)?Ie(De[t]):"transparent"===t?new qe(NaN,NaN,NaN,0):null}function Ie(t){return new qe(t>>16&255,t>>8&255,255&t,1)}function Ne(t,e,r,i){return i<=0&&(t=e=r=NaN),new qe(t,e,r,i)}function ze(t){return t instanceof we||(t=Ke(t)),t?new qe((t=t.rgb()).r,t.g,t.b,t.opacity):new qe}function Pe(t,e,r,i){return 1===arguments.length?ze(t):new qe(t,e,r,null==i?1:i)}function qe(t,e,r,i){this.r=+t,this.g=+e,this.b=+r,this.opacity=+i}function je(){return`#${Ye(this.r)}${Ye(this.g)}${Ye(this.b)}`}function We(){const t=He(this.opacity);return`${1===t?"rgb(":"rgba("}${Ue(this.r)}, ${Ue(this.g)}, ${Ue(this.b)}${1===t?")":`, ${t})`}`}function He(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function Ue(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function Ye(t){return((t=Ue(t))<16?"0":"")+t.toString(16)}function Ge(t,e,r,i){return i<=0?t=e=r=NaN:r<=0||r>=1?t=e=NaN:e<=0&&(t=NaN),new Ve(t,e,r,i)}function Xe(t){if(t instanceof Ve)return new Ve(t.h,t.s,t.l,t.opacity);if(t instanceof we||(t=Ke(t)),!t)return new Ve;if(t instanceof Ve)return t;var e=(t=t.rgb()).r/255,r=t.g/255,i=t.b/255,n=Math.min(e,r,i),a=Math.max(e,r,i),o=NaN,s=a-n,l=(a+n)/2;return s?(o=e===a?(r-i)/s+6*(r<i):r===a?(i-e)/s+2:(e-r)/s+4,s/=l<.5?a+n:2-a-n,o*=60):s=l>0&&l<1?0:o,new Ve(o,s,l,t.opacity)}function Ve(t,e,r,i){this.h=+t,this.s=+e,this.l=+r,this.opacity=+i}function Ze(t){return(t=(t||0)%360)<0?t+360:t}function Qe(t){return Math.max(0,Math.min(1,t||0))}function Je(t,e,r){return 255*(t<60?e+(r-e)*t/60:t<180?r:t<240?e+(r-e)*(240-t)/60:e)}function tr(t,e,r,i,n){var a=t*t,o=a*t;return((1-3*t+3*a-o)*e+(4-6*a+3*o)*r+(1+3*t+3*a-3*o)*i+o*n)/6}be(we,Ke,{copy(t){return Object.assign(new this.constructor,this,t)},displayable(){return this.rgb().displayable()},hex:Oe,formatHex:Oe,formatHex8:function(){return this.rgb().formatHex8()},formatHsl:function(){return Xe(this).formatHsl()},formatRgb:Re,toString:Re}),be(qe,Pe,ke(we,{brighter(t){return t=null==t?_e:Math.pow(_e,t),new qe(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=null==t?Ce:Math.pow(Ce,t),new qe(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new qe(Ue(this.r),Ue(this.g),Ue(this.b),He(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:je,formatHex:je,formatHex8:function(){return`#${Ye(this.r)}${Ye(this.g)}${Ye(this.b)}${Ye(255*(isNaN(this.opacity)?1:this.opacity))}`},formatRgb:We,toString:We})),be(Ve,function(t,e,r,i){return 1===arguments.length?Xe(t):new Ve(t,e,r,null==i?1:i)},ke(we,{brighter(t){return t=null==t?_e:Math.pow(_e,t),new Ve(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=null==t?Ce:Math.pow(Ce,t),new Ve(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+360*(this.h<0),e=isNaN(t)||isNaN(this.s)?0:this.s,r=this.l,i=r+(r<.5?r:1-r)*e,n=2*r-i;return new qe(Je(t>=240?t-240:t+120,n,i),Je(t,n,i),Je(t<120?t+240:t-120,n,i),this.opacity)},clamp(){return new Ve(Ze(this.h),Qe(this.s),Qe(this.l),He(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const t=He(this.opacity);return`${1===t?"hsl(":"hsla("}${Ze(this.h)}, ${100*Qe(this.s)}%, ${100*Qe(this.l)}%${1===t?")":`, ${t})`}`}}));const er=t=>()=>t;function rr(t,e){return function(r){return t+r*e}}function ir(t){return 1===(t=+t)?nr:function(e,r){return r-e?function(t,e,r){return t=Math.pow(t,r),e=Math.pow(e,r)-t,r=1/r,function(i){return Math.pow(t+i*e,r)}}(e,r,t):er(isNaN(e)?r:e)}}function nr(t,e){var r=e-t;return r?rr(t,r):er(isNaN(t)?e:t)}const ar=function t(e){var r=ir(e);function i(t,e){var i=r((t=Pe(t)).r,(e=Pe(e)).r),n=r(t.g,e.g),a=r(t.b,e.b),o=nr(t.opacity,e.opacity);return function(e){return t.r=i(e),t.g=n(e),t.b=a(e),t.opacity=o(e),t+""}}return i.gamma=t,i}(1);function or(t){return function(e){var r,i,n=e.length,a=new Array(n),o=new Array(n),s=new Array(n);for(r=0;r<n;++r)i=Pe(e[r]),a[r]=i.r||0,o[r]=i.g||0,s[r]=i.b||0;return a=t(a),o=t(o),s=t(s),i.opacity=1,function(t){return i.r=a(t),i.g=o(t),i.b=s(t),i+""}}}or(function(t){var e=t.length-1;return function(r){var i=r<=0?r=0:r>=1?(r=1,e-1):Math.floor(r*e),n=t[i],a=t[i+1],o=i>0?t[i-1]:2*n-a,s=i<e-1?t[i+2]:2*a-n;return tr((r-i/e)*e,o,n,a,s)}}),or(function(t){var e=t.length;return function(r){var i=Math.floor(((r%=1)<0?++r:r)*e),n=t[(i+e-1)%e],a=t[i%e],o=t[(i+1)%e],s=t[(i+2)%e];return tr((r-i/e)*e,n,a,o,s)}});var sr=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,lr=new RegExp(sr.source,"g");function cr(t,e){var r,i,n,a=sr.lastIndex=lr.lastIndex=0,o=-1,s=[],l=[];for(t+="",e+="";(r=sr.exec(t))&&(i=lr.exec(e));)(n=i.index)>a&&(n=e.slice(a,n),s[o]?s[o]+=n:s[++o]=n),(r=r[0])===(i=i[0])?s[o]?s[o]+=i:s[++o]=i:(s[++o]=null,l.push({i:o,x:le(r,i)})),a=lr.lastIndex;return a<e.length&&(n=e.slice(a),s[o]?s[o]+=n:s[++o]=n),s.length<2?l[0]?function(t){return function(e){return t(e)+""}}(l[0].x):function(t){return function(){return t}}(e):(e=l.length,function(t){for(var r,i=0;i<e;++i)s[(r=l[i]).i]=r.x(t);return s.join("")})}function hr(t,e){var r;return("number"==typeof e?le:e instanceof Ke?ar:(r=Ke(e))?(e=r,ar):cr)(t,e)}function ur(t){return function(){this.removeAttribute(t)}}function dr(t){return function(){this.removeAttributeNS(t.space,t.local)}}function pr(t,e,r){var i,n,a=r+"";return function(){var o=this.getAttribute(t);return o===a?null:o===i?n:n=e(i=o,r)}}function fr(t,e,r){var i,n,a=r+"";return function(){var o=this.getAttributeNS(t.space,t.local);return o===a?null:o===i?n:n=e(i=o,r)}}function gr(t,e,r){var i,n,a;return function(){var o,s,l=r(this);if(null!=l)return(o=this.getAttribute(t))===(s=l+"")?null:o===i&&s===n?a:(n=s,a=e(i=o,l));this.removeAttribute(t)}}function yr(t,e,r){var i,n,a;return function(){var o,s,l=r(this);if(null!=l)return(o=this.getAttributeNS(t.space,t.local))===(s=l+"")?null:o===i&&s===n?a:(n=s,a=e(i=o,l));this.removeAttributeNS(t.space,t.local)}}function mr(t,e){var r,i;function n(){var n=e.apply(this,arguments);return n!==i&&(r=(i=n)&&function(t,e){return function(r){this.setAttributeNS(t.space,t.local,e.call(this,r))}}(t,n)),r}return n._value=e,n}function xr(t,e){var r,i;function n(){var n=e.apply(this,arguments);return n!==i&&(r=(i=n)&&function(t,e){return function(r){this.setAttribute(t,e.call(this,r))}}(t,n)),r}return n._value=e,n}function br(t,e){return function(){ae(this,t).delay=+e.apply(this,arguments)}}function kr(t,e){return e=+e,function(){ae(this,t).delay=e}}function wr(t,e){return function(){oe(this,t).duration=+e.apply(this,arguments)}}function Cr(t,e){return e=+e,function(){oe(this,t).duration=e}}var _r=Ft.prototype.constructor;function vr(t){return function(){this.style.removeProperty(t)}}var Sr=0;function Tr(t,e,r,i){this._groups=t,this._parents=e,this._name=r,this._id=i}function Ar(){return++Sr}var Mr=Ft.prototype;Tr.prototype=function(t){return Ft().transition(t)}.prototype={constructor:Tr,select:function(t){var e=this._name,r=this._id;"function"!=typeof t&&(t=k(t));for(var i=this._groups,n=i.length,a=new Array(n),o=0;o<n;++o)for(var s,l,c=i[o],h=c.length,u=a[o]=new Array(h),d=0;d<h;++d)(s=c[d])&&(l=t.call(s,s.__data__,d,c))&&("__data__"in s&&(l.__data__=s.__data__),u[d]=l,ne(u[d],e,r,d,u,se(s,r)));return new Tr(a,this._parents,e,r)},selectAll:function(t){var e=this._name,r=this._id;"function"!=typeof t&&(t=C(t));for(var i=this._groups,n=i.length,a=[],o=[],s=0;s<n;++s)for(var l,c=i[s],h=c.length,u=0;u<h;++u)if(l=c[u]){for(var d,p=t.call(l,l.__data__,u,c),f=se(l,r),g=0,y=p.length;g<y;++g)(d=p[g])&&ne(d,e,r,g,p,f);a.push(p),o.push(l)}return new Tr(a,o,e,r)},selectChild:Mr.selectChild,selectChildren:Mr.selectChildren,filter:function(t){"function"!=typeof t&&(t=v(t));for(var e=this._groups,r=e.length,i=new Array(r),n=0;n<r;++n)for(var a,o=e[n],s=o.length,l=i[n]=[],c=0;c<s;++c)(a=o[c])&&t.call(a,a.__data__,c,o)&&l.push(a);return new Tr(i,this._parents,this._name,this._id)},merge:function(t){if(t._id!==this._id)throw new Error;for(var e=this._groups,r=t._groups,i=e.length,n=r.length,a=Math.min(i,n),o=new Array(i),s=0;s<a;++s)for(var l,c=e[s],h=r[s],u=c.length,d=o[s]=new Array(u),p=0;p<u;++p)(l=c[p]||h[p])&&(d[p]=l);for(;s<i;++s)o[s]=e[s];return new Tr(o,this._parents,this._name,this._id)},selection:function(){return new _r(this._groups,this._parents)},transition:function(){for(var t=this._name,e=this._id,r=Ar(),i=this._groups,n=i.length,a=0;a<n;++a)for(var o,s=i[a],l=s.length,c=0;c<l;++c)if(o=s[c]){var h=se(o,e);ne(o,t,r,c,s,{time:h.time+h.delay+h.duration,delay:0,duration:h.duration,ease:h.ease})}return new Tr(i,this._parents,t,r)},call:Mr.call,nodes:Mr.nodes,node:Mr.node,size:Mr.size,empty:Mr.empty,each:Mr.each,on:function(t,e){var r=this._id;return arguments.length<2?se(this.node(),r).on.on(t):this.each(function(t,e,r){var i,n,a=function(t){return(t+"").trim().split(/^|\s+/).every(function(t){var e=t.indexOf(".");return e>=0&&(t=t.slice(0,e)),!t||"start"===t})}(e)?ae:oe;return function(){var o=a(this,t),s=o.on;s!==i&&(n=(i=s).copy()).on(e,r),o.on=n}}(r,t,e))},attr:function(t,e){var r=N(t),i="transform"===r?ge:hr;return this.attrTween(t,"function"==typeof e?(r.local?yr:gr)(r,i,xe(this,"attr."+t,e)):null==e?(r.local?dr:ur)(r):(r.local?fr:pr)(r,i,e))},attrTween:function(t,e){var r="attr."+t;if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==e)return this.tween(r,null);if("function"!=typeof e)throw new Error;var i=N(t);return this.tween(r,(i.local?mr:xr)(i,e))},style:function(t,e,r){var i="transform"==(t+="")?fe:hr;return null==e?this.styleTween(t,function(t,e){var r,i,n;return function(){var a=V(this,t),o=(this.style.removeProperty(t),V(this,t));return a===o?null:a===r&&o===i?n:n=e(r=a,i=o)}}(t,i)).on("end.style."+t,vr(t)):"function"==typeof e?this.styleTween(t,function(t,e,r){var i,n,a;return function(){var o=V(this,t),s=r(this),l=s+"";return null==s&&(this.style.removeProperty(t),l=s=V(this,t)),o===l?null:o===i&&l===n?a:(n=l,a=e(i=o,s))}}(t,i,xe(this,"style."+t,e))).each(function(t,e){var r,i,n,a,o="style."+e,s="end."+o;return function(){var l=oe(this,t),c=l.on,h=null==l.value[o]?a||(a=vr(e)):void 0;c===r&&n===h||(i=(r=c).copy()).on(s,n=h),l.on=i}}(this._id,t)):this.styleTween(t,function(t,e,r){var i,n,a=r+"";return function(){var o=V(this,t);return o===a?null:o===i?n:n=e(i=o,r)}}(t,i,e),r).on("end.style."+t,null)},styleTween:function(t,e,r){var i="style."+(t+="");if(arguments.length<2)return(i=this.tween(i))&&i._value;if(null==e)return this.tween(i,null);if("function"!=typeof e)throw new Error;return this.tween(i,function(t,e,r){var i,n;function a(){var a=e.apply(this,arguments);return a!==n&&(i=(n=a)&&function(t,e,r){return function(i){this.style.setProperty(t,e.call(this,i),r)}}(t,a,r)),i}return a._value=e,a}(t,e,null==r?"":r))},text:function(t){return this.tween("text","function"==typeof t?function(t){return function(){var e=t(this);this.textContent=null==e?"":e}}(xe(this,"text",t)):function(t){return function(){this.textContent=t}}(null==t?"":t+""))},textTween:function(t){var e="text";if(arguments.length<1)return(e=this.tween(e))&&e._value;if(null==t)return this.tween(e,null);if("function"!=typeof t)throw new Error;return this.tween(e,function(t){var e,r;function i(){var i=t.apply(this,arguments);return i!==r&&(e=(r=i)&&function(t){return function(e){this.textContent=t.call(this,e)}}(i)),e}return i._value=t,i}(t))},remove:function(){return this.on("end.remove",function(t){return function(){var e=this.parentNode;for(var r in this.__transition)if(+r!==t)return;e&&e.removeChild(this)}}(this._id))},tween:function(t,e){var r=this._id;if(t+="",arguments.length<2){for(var i,n=se(this.node(),r).tween,a=0,o=n.length;a<o;++a)if((i=n[a]).name===t)return i.value;return null}return this.each((null==e?ye:me)(r,t,e))},delay:function(t){var e=this._id;return arguments.length?this.each(("function"==typeof t?br:kr)(e,t)):se(this.node(),e).delay},duration:function(t){var e=this._id;return arguments.length?this.each(("function"==typeof t?wr:Cr)(e,t)):se(this.node(),e).duration},ease:function(t){var e=this._id;return arguments.length?this.each(function(t,e){if("function"!=typeof e)throw new Error;return function(){oe(this,t).ease=e}}(e,t)):se(this.node(),e).ease},easeVarying:function(t){if("function"!=typeof t)throw new Error;return this.each(function(t,e){return function(){var r=e.apply(this,arguments);if("function"!=typeof r)throw new Error;oe(this,t).ease=r}}(this._id,t))},end:function(){var t,e,r=this,i=r._id,n=r.size();return new Promise(function(a,o){var s={value:o},l={value:function(){0===--n&&a()}};r.each(function(){var r=oe(this,i),n=r.on;n!==t&&((e=(t=n).copy())._.cancel.push(s),e._.interrupt.push(s),e._.end.push(l)),r.on=e}),0===n&&a()})},[Symbol.iterator]:Mr[Symbol.iterator]};var Br={time:null,delay:0,duration:250,ease:function(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}};function Lr(t,e){for(var r;!(r=t.__transition)||!(r=r[e]);)if(!(t=t.parentNode))throw new Error(`transition ${e} not found`);return r}Ft.prototype.interrupt=function(t){return this.each(function(){!function(t,e){var r,i,n,a=t.__transition,o=!0;if(a){for(n in e=null==e?null:e+"",a)(r=a[n]).name===e?(i=r.state>2&&r.state<5,r.state=6,r.timer.stop(),r.on.call(i?"interrupt":"cancel",t,t.__data__,r.index,r.group),delete a[n]):o=!1;o&&delete t.__transition}}(this,t)})},Ft.prototype.transition=function(t){var e,r;t instanceof Tr?(e=t._id,t=t._name):(e=Ar(),(r=Br).time=Gt(),t=null==t?null:t+"");for(var i=this._groups,n=i.length,a=0;a<n;++a)for(var o,s=i[a],l=s.length,c=0;c<l;++c)(o=s[c])&&ne(o,t,e,c,s,r||Lr(o,e));return new Tr(i,this._parents,t,e)};const{abs:Fr,max:$r,min:Er}=Math;function Dr(t){return[+t[0],+t[1]]}function Or(t){return[Dr(t[0]),Dr(t[1])]}["w","e"].map(Rr),["n","s"].map(Rr),["n","w","e","s","nw","ne","sw","se"].map(Rr);function Rr(t){return{type:t}}function Kr(t,e){if((r=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var r,i=t.slice(0,r);return[i.length>1?i[0]+i.slice(2):i,+t.slice(r+1)]}function Ir(t){return(t=Kr(Math.abs(t)))?t[1]:NaN}var Nr,zr=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Pr(t){if(!(e=zr.exec(t)))throw new Error("invalid format: "+t);var e;return new qr({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}function qr(t){this.fill=void 0===t.fill?" ":t.fill+"",this.align=void 0===t.align?">":t.align+"",this.sign=void 0===t.sign?"-":t.sign+"",this.symbol=void 0===t.symbol?"":t.symbol+"",this.zero=!!t.zero,this.width=void 0===t.width?void 0:+t.width,this.comma=!!t.comma,this.precision=void 0===t.precision?void 0:+t.precision,this.trim=!!t.trim,this.type=void 0===t.type?"":t.type+""}function jr(t,e){var r=Kr(t,e);if(!r)return t+"";var i=r[0],n=r[1];return n<0?"0."+new Array(-n).join("0")+i:i.length>n+1?i.slice(0,n+1)+"."+i.slice(n+1):i+new Array(n-i.length+2).join("0")}Pr.prototype=qr.prototype,qr.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const Wr={"%":(t,e)=>(100*t).toFixed(e),b:t=>Math.round(t).toString(2),c:t=>t+"",d:function(t){return Math.abs(t=Math.round(t))>=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)},e:(t,e)=>t.toExponential(e),f:(t,e)=>t.toFixed(e),g:(t,e)=>t.toPrecision(e),o:t=>Math.round(t).toString(8),p:(t,e)=>jr(100*t,e),r:jr,s:function(t,e){var r=Kr(t,e);if(!r)return t+"";var i=r[0],n=r[1],a=n-(Nr=3*Math.max(-8,Math.min(8,Math.floor(n/3))))+1,o=i.length;return a===o?i:a>o?i+new Array(a-o+1).join("0"):a>0?i.slice(0,a)+"."+i.slice(a):"0."+new Array(1-a).join("0")+Kr(t,Math.max(0,e+a-1))[0]},X:t=>Math.round(t).toString(16).toUpperCase(),x:t=>Math.round(t).toString(16)};function Hr(t){return t}var Ur,Yr,Gr,Xr=Array.prototype.map,Vr=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"];function Zr(t){var e,r,i=void 0===t.grouping||void 0===t.thousands?Hr:(e=Xr.call(t.grouping,Number),r=t.thousands+"",function(t,i){for(var n=t.length,a=[],o=0,s=e[0],l=0;n>0&&s>0&&(l+s+1>i&&(s=Math.max(1,i-l)),a.push(t.substring(n-=s,n+s)),!((l+=s+1)>i));)s=e[o=(o+1)%e.length];return a.reverse().join(r)}),n=void 0===t.currency?"":t.currency[0]+"",a=void 0===t.currency?"":t.currency[1]+"",o=void 0===t.decimal?".":t.decimal+"",s=void 0===t.numerals?Hr:function(t){return function(e){return e.replace(/[0-9]/g,function(e){return t[+e]})}}(Xr.call(t.numerals,String)),l=void 0===t.percent?"%":t.percent+"",c=void 0===t.minus?"\u2212":t.minus+"",h=void 0===t.nan?"NaN":t.nan+"";function u(t){var e=(t=Pr(t)).fill,r=t.align,u=t.sign,d=t.symbol,p=t.zero,f=t.width,g=t.comma,y=t.precision,m=t.trim,x=t.type;"n"===x?(g=!0,x="g"):Wr[x]||(void 0===y&&(y=12),m=!0,x="g"),(p||"0"===e&&"="===r)&&(p=!0,e="0",r="=");var b="$"===d?n:"#"===d&&/[boxX]/.test(x)?"0"+x.toLowerCase():"",k="$"===d?a:/[%p]/.test(x)?l:"",w=Wr[x],C=/[defgprs%]/.test(x);function _(t){var n,a,l,d=b,_=k;if("c"===x)_=w(t)+_,t="";else{var v=(t=+t)<0||1/t<0;if(t=isNaN(t)?h:w(Math.abs(t),y),m&&(t=function(t){t:for(var e,r=t.length,i=1,n=-1;i<r;++i)switch(t[i]){case".":n=e=i;break;case"0":0===n&&(n=i),e=i;break;default:if(!+t[i])break t;n>0&&(n=0)}return n>0?t.slice(0,n)+t.slice(e+1):t}(t)),v&&0===+t&&"+"!==u&&(v=!1),d=(v?"("===u?u:c:"-"===u||"("===u?"":u)+d,_=("s"===x?Vr[8+Nr/3]:"")+_+(v&&"("===u?")":""),C)for(n=-1,a=t.length;++n<a;)if(48>(l=t.charCodeAt(n))||l>57){_=(46===l?o+t.slice(n+1):t.slice(n))+_,t=t.slice(0,n);break}}g&&!p&&(t=i(t,1/0));var S=d.length+t.length+_.length,T=S<f?new Array(f-S+1).join(e):"";switch(g&&p&&(t=i(T+t,T.length?f-_.length:1/0),T=""),r){case"<":t=d+t+_+T;break;case"=":t=d+T+t+_;break;case"^":t=T.slice(0,S=T.length>>1)+d+t+_+T.slice(S);break;default:t=T+d+t+_}return s(t)}return y=void 0===y?6:/[gprs]/.test(x)?Math.max(1,Math.min(21,y)):Math.max(0,Math.min(20,y)),_.toString=function(){return t+""},_}return{format:u,formatPrefix:function(t,e){var r=u(((t=Pr(t)).type="f",t)),i=3*Math.max(-8,Math.min(8,Math.floor(Ir(e)/3))),n=Math.pow(10,-i),a=Vr[8+i/3];return function(t){return r(n*t)+a}}}}function Qr(t){var e=0,r=t.children,i=r&&r.length;if(i)for(;--i>=0;)e+=r[i].value;else e=1;t.value=e}function Jr(t,e){t instanceof Map?(t=[void 0,t],void 0===e&&(e=ei)):void 0===e&&(e=ti);for(var r,i,n,a,o,s=new ni(t),l=[s];r=l.pop();)if((n=e(r.data))&&(o=(n=Array.from(n)).length))for(r.children=n,a=o-1;a>=0;--a)l.push(i=n[a]=new ni(n[a])),i.parent=r,i.depth=r.depth+1;return s.eachBefore(ii)}function ti(t){return t.children}function ei(t){return Array.isArray(t)?t[1]:null}function ri(t){void 0!==t.data.value&&(t.value=t.data.value),t.data=t.data.data}function ii(t){var e=0;do{t.height=e}while((t=t.parent)&&t.height<++e)}function ni(t){this.data=t,this.depth=this.height=0,this.parent=null}function ai(t){t.x0=Math.round(t.x0),t.y0=Math.round(t.y0),t.x1=Math.round(t.x1),t.y1=Math.round(t.y1)}function oi(t,e,r,i,n){for(var a,o=t.children,s=-1,l=o.length,c=t.value&&(i-e)/t.value;++s<l;)(a=o[s]).y0=r,a.y1=n,a.x0=e,a.x1=e+=a.value*c}function si(t,e,r,i,n){for(var a,o=t.children,s=-1,l=o.length,c=t.value&&(n-r)/t.value;++s<l;)(a=o[s]).x0=e,a.x1=i,a.y0=r,a.y1=r+=a.value*c}Ur=Zr({thousands:",",grouping:[3],currency:["$",""]}),Yr=Ur.format,Gr=Ur.formatPrefix,ni.prototype=Jr.prototype={constructor:ni,count:function(){return this.eachAfter(Qr)},each:function(t,e){let r=-1;for(const i of this)t.call(e,i,++r,this);return this},eachAfter:function(t,e){for(var r,i,n,a=this,o=[a],s=[],l=-1;a=o.pop();)if(s.push(a),r=a.children)for(i=0,n=r.length;i<n;++i)o.push(r[i]);for(;a=s.pop();)t.call(e,a,++l,this);return this},eachBefore:function(t,e){for(var r,i,n=this,a=[n],o=-1;n=a.pop();)if(t.call(e,n,++o,this),r=n.children)for(i=r.length-1;i>=0;--i)a.push(r[i]);return this},find:function(t,e){let r=-1;for(const i of this)if(t.call(e,i,++r,this))return i},sum:function(t){return this.eachAfter(function(e){for(var r=+t(e.data)||0,i=e.children,n=i&&i.length;--n>=0;)r+=i[n].value;e.value=r})},sort:function(t){return this.eachBefore(function(e){e.children&&e.children.sort(t)})},path:function(t){for(var e=this,r=function(t,e){if(t===e)return t;var r=t.ancestors(),i=e.ancestors(),n=null;t=r.pop(),e=i.pop();for(;t===e;)n=t,t=r.pop(),e=i.pop();return n}(e,t),i=[e];e!==r;)e=e.parent,i.push(e);for(var n=i.length;t!==r;)i.splice(n,0,t),t=t.parent;return i},ancestors:function(){for(var t=this,e=[t];t=t.parent;)e.push(t);return e},descendants:function(){return Array.from(this)},leaves:function(){var t=[];return this.eachBefore(function(e){e.children||t.push(e)}),t},links:function(){var t=this,e=[];return t.each(function(r){r!==t&&e.push({source:r.parent,target:r})}),e},copy:function(){return Jr(this).eachBefore(ri)},[Symbol.iterator]:function*(){var t,e,r,i,n=this,a=[n];do{for(t=a.reverse(),a=[];n=t.pop();)if(yield n,e=n.children)for(r=0,i=e.length;r<i;++r)a.push(e[r])}while(a.length)}};const li=function t(e){function r(t,r,i,n,a){!function(t,e,r,i,n,a){for(var o,s,l,c,h,u,d,p,f,g,y,m=[],x=e.children,b=0,k=0,w=x.length,C=e.value;b<w;){l=n-r,c=a-i;do{h=x[k++].value}while(!h&&k<w);for(u=d=h,y=h*h*(g=Math.max(c/l,l/c)/(C*t)),f=Math.max(d/y,y/u);k<w;++k){if(h+=s=x[k].value,s<u&&(u=s),s>d&&(d=s),y=h*h*g,(p=Math.max(d/y,y/u))>f){h-=s;break}f=p}m.push(o={value:h,dice:l<c,children:x.slice(b,k)}),o.dice?oi(o,r,i,n,C?i+=c*h/C:a):si(o,r,i,C?r+=l*h/C:n,a),C-=h,b=k}}(e,t,r,i,n,a)}return r.ratio=function(e){return t((e=+e)>1?e:1)},r}((1+Math.sqrt(5))/2);function ci(t){if("function"!=typeof t)throw new Error;return t}function hi(){return 0}function ui(t){return function(){return t}}function di(){var t=li,e=!1,r=1,i=1,n=[0],a=hi,o=hi,s=hi,l=hi,c=hi;function h(t){return t.x0=t.y0=0,t.x1=r,t.y1=i,t.eachBefore(u),n=[0],e&&t.eachBefore(ai),t}function u(e){var r=n[e.depth],i=e.x0+r,h=e.y0+r,u=e.x1-r,d=e.y1-r;u<i&&(i=u=(i+u)/2),d<h&&(h=d=(h+d)/2),e.x0=i,e.y0=h,e.x1=u,e.y1=d,e.children&&(r=n[e.depth+1]=a(e)/2,i+=c(e)-r,h+=o(e)-r,(u-=s(e)-r)<i&&(i=u=(i+u)/2),(d-=l(e)-r)<h&&(h=d=(h+d)/2),t(e,i,h,u,d))}return h.round=function(t){return arguments.length?(e=!!t,h):e},h.size=function(t){return arguments.length?(r=+t[0],i=+t[1],h):[r,i]},h.tile=function(e){return arguments.length?(t=ci(e),h):t},h.padding=function(t){return arguments.length?h.paddingInner(t).paddingOuter(t):h.paddingInner()},h.paddingInner=function(t){return arguments.length?(a="function"==typeof t?t:ui(+t),h):a},h.paddingOuter=function(t){return arguments.length?h.paddingTop(t).paddingRight(t).paddingBottom(t).paddingLeft(t):h.paddingTop()},h.paddingTop=function(t){return arguments.length?(o="function"==typeof t?t:ui(+t),h):o},h.paddingRight=function(t){return arguments.length?(s="function"==typeof t?t:ui(+t),h):s},h.paddingBottom=function(t){return arguments.length?(l="function"==typeof t?t:ui(+t),h):l},h.paddingLeft=function(t){return arguments.length?(c="function"==typeof t?t:ui(+t),h):c},h}const pi=Math.PI/180,fi=180/Math.PI,gi=.96422,yi=.82521,mi=4/29,xi=6/29,bi=3*xi*xi,ki=xi*xi*xi;function wi(t){if(t instanceof Ci)return new Ci(t.l,t.a,t.b,t.opacity);if(t instanceof Bi)return Li(t);t instanceof qe||(t=ze(t));var e,r,i=Ti(t.r),n=Ti(t.g),a=Ti(t.b),o=_i((.2225045*i+.7168786*n+.0606169*a)/1);return i===n&&n===a?e=r=o:(e=_i((.4360747*i+.3850649*n+.1430804*a)/gi),r=_i((.0139322*i+.0971045*n+.7141733*a)/yi)),new Ci(116*o-16,500*(e-o),200*(o-r),t.opacity)}function Ci(t,e,r,i){this.l=+t,this.a=+e,this.b=+r,this.opacity=+i}function _i(t){return t>ki?Math.pow(t,1/3):t/bi+mi}function vi(t){return t>xi?t*t*t:bi*(t-mi)}function Si(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function Ti(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function Ai(t){if(t instanceof Bi)return new Bi(t.h,t.c,t.l,t.opacity);if(t instanceof Ci||(t=wi(t)),0===t.a&&0===t.b)return new Bi(NaN,0<t.l&&t.l<100?0:NaN,t.l,t.opacity);var e=Math.atan2(t.b,t.a)*fi;return new Bi(e<0?e+360:e,Math.sqrt(t.a*t.a+t.b*t.b),t.l,t.opacity)}function Mi(t,e,r,i){return 1===arguments.length?Ai(t):new Bi(t,e,r,null==i?1:i)}function Bi(t,e,r,i){this.h=+t,this.c=+e,this.l=+r,this.opacity=+i}function Li(t){if(isNaN(t.h))return new Ci(t.l,0,0,t.opacity);var e=t.h*pi;return new Ci(t.l,Math.cos(e)*t.c,Math.sin(e)*t.c,t.opacity)}function Fi(t){return function(e,r){var i=t((e=Mi(e)).h,(r=Mi(r)).h),n=nr(e.c,r.c),a=nr(e.l,r.l),o=nr(e.opacity,r.opacity);return function(t){return e.h=i(t),e.c=n(t),e.l=a(t),e.opacity=o(t),e+""}}}be(Ci,function(t,e,r,i){return 1===arguments.length?wi(t):new Ci(t,e,r,null==i?1:i)},ke(we,{brighter(t){return new Ci(this.l+18*(null==t?1:t),this.a,this.b,this.opacity)},darker(t){return new Ci(this.l-18*(null==t?1:t),this.a,this.b,this.opacity)},rgb(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,r=isNaN(this.b)?t:t-this.b/200;return new qe(Si(3.1338561*(e=gi*vi(e))-1.6168667*(t=1*vi(t))-.4906146*(r=yi*vi(r))),Si(-.9787684*e+1.9161415*t+.033454*r),Si(.0719453*e-.2289914*t+1.4052427*r),this.opacity)}})),be(Bi,Mi,ke(we,{brighter(t){return new Bi(this.h,this.c,this.l+18*(null==t?1:t),this.opacity)},darker(t){return new Bi(this.h,this.c,this.l-18*(null==t?1:t),this.opacity)},rgb(){return Li(this).rgb()}}));const $i=Fi(function(t,e){var r=e-t;return r?rr(t,r>180||r<-180?r-360*Math.round(r/360):r):er(isNaN(t)?e:t)});Fi(nr);function Ei(t,e){switch(arguments.length){case 0:break;case 1:this.range(t);break;default:this.range(e).domain(t)}return this}class Di extends Map{constructor(t,e=Ii){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:e}}),null!=t)for(const[r,i]of t)this.set(r,i)}get(t){return super.get(Oi(this,t))}has(t){return super.has(Oi(this,t))}set(t,e){return super.set(Ri(this,t),e)}delete(t){return super.delete(Ki(this,t))}}Set;function Oi({_intern:t,_key:e},r){const i=e(r);return t.has(i)?t.get(i):r}function Ri({_intern:t,_key:e},r){const i=e(r);return t.has(i)?t.get(i):(t.set(i,r),r)}function Ki({_intern:t,_key:e},r){const i=e(r);return t.has(i)&&(r=t.get(i),t.delete(i)),r}function Ii(t){return null!==t&&"object"==typeof t?t.valueOf():t}const Ni=Symbol("implicit");function zi(){var t=new Di,e=[],r=[],i=Ni;function n(n){let a=t.get(n);if(void 0===a){if(i!==Ni)return i;t.set(n,a=e.push(n)-1)}return r[a%r.length]}return n.domain=function(r){if(!arguments.length)return e.slice();e=[],t=new Di;for(const i of r)t.has(i)||t.set(i,e.push(i)-1);return n},n.range=function(t){return arguments.length?(r=Array.from(t),n):r.slice()},n.unknown=function(t){return arguments.length?(i=t,n):i},n.copy=function(){return zi(e,r).unknown(i)},Ei.apply(n,arguments),n}function Pi(){var t,e,r=zi().unknown(void 0),i=r.domain,n=r.range,a=0,o=1,s=!1,l=0,c=0,h=.5;function u(){var r=i().length,u=o<a,d=u?o:a,p=u?a:o;t=(p-d)/Math.max(1,r-l+2*c),s&&(t=Math.floor(t)),d+=(p-d-t*(r-l))*h,e=t*(1-l),s&&(d=Math.round(d),e=Math.round(e));var f=function(t,e,r){t=+t,e=+e,r=(n=arguments.length)<2?(e=t,t=0,1):n<3?1:+r;for(var i=-1,n=0|Math.max(0,Math.ceil((e-t)/r)),a=new Array(n);++i<n;)a[i]=t+i*r;return a}(r).map(function(e){return d+t*e});return n(u?f.reverse():f)}return delete r.unknown,r.domain=function(t){return arguments.length?(i(t),u()):i()},r.range=function(t){return arguments.length?([a,o]=t,a=+a,o=+o,u()):[a,o]},r.rangeRound=function(t){return[a,o]=t,a=+a,o=+o,s=!0,u()},r.bandwidth=function(){return e},r.step=function(){return t},r.round=function(t){return arguments.length?(s=!!t,u()):s},r.padding=function(t){return arguments.length?(l=Math.min(1,c=+t),u()):l},r.paddingInner=function(t){return arguments.length?(l=Math.min(1,t),u()):l},r.paddingOuter=function(t){return arguments.length?(c=+t,u()):c},r.align=function(t){return arguments.length?(h=Math.max(0,Math.min(1,t)),u()):h},r.copy=function(){return Pi(i(),[a,o]).round(s).paddingInner(l).paddingOuter(c).align(h)},Ei.apply(u(),arguments)}const qi=Math.sqrt(50),ji=Math.sqrt(10),Wi=Math.sqrt(2);function Hi(t,e,r){const i=(e-t)/Math.max(0,r),n=Math.floor(Math.log10(i)),a=i/Math.pow(10,n),o=a>=qi?10:a>=ji?5:a>=Wi?2:1;let s,l,c;return n<0?(c=Math.pow(10,-n)/o,s=Math.round(t*c),l=Math.round(e*c),s/c<t&&++s,l/c>e&&--l,c=-c):(c=Math.pow(10,n)*o,s=Math.round(t/c),l=Math.round(e/c),s*c<t&&++s,l*c>e&&--l),l<s&&.5<=r&&r<2?Hi(t,e,2*r):[s,l,c]}function Ui(t,e,r){return Hi(t=+t,e=+e,r=+r)[2]}function Yi(t,e,r){r=+r;const i=(e=+e)<(t=+t),n=i?Ui(e,t,r):Ui(t,e,r);return(i?-1:1)*(n<0?1/-n:n)}function Gi(t,e){return null==t||null==e?NaN:t<e?-1:t>e?1:t>=e?0:NaN}function Xi(t,e){return null==t||null==e?NaN:e<t?-1:e>t?1:e>=t?0:NaN}function Vi(t){let e,r,i;function n(t,i,n=0,a=t.length){if(n<a){if(0!==e(i,i))return a;do{const e=n+a>>>1;r(t[e],i)<0?n=e+1:a=e}while(n<a)}return n}return 2!==t.length?(e=Gi,r=(e,r)=>Gi(t(e),r),i=(e,r)=>t(e)-r):(e=t===Gi||t===Xi?t:Zi,r=t,i=t),{left:n,center:function(t,e,r=0,a=t.length){const o=n(t,e,r,a-1);return o>r&&i(t[o-1],e)>-i(t[o],e)?o-1:o},right:function(t,i,n=0,a=t.length){if(n<a){if(0!==e(i,i))return a;do{const e=n+a>>>1;r(t[e],i)<=0?n=e+1:a=e}while(n<a)}return n}}}function Zi(){return 0}const Qi=Vi(Gi),Ji=Qi.right,tn=(Qi.left,Vi(function(t){return null===t?NaN:+t}).center,Ji);function en(t,e){var r,i=e?e.length:0,n=t?Math.min(i,t.length):0,a=new Array(n),o=new Array(i);for(r=0;r<n;++r)a[r]=on(t[r],e[r]);for(;r<i;++r)o[r]=e[r];return function(t){for(r=0;r<n;++r)o[r]=a[r](t);return o}}function rn(t,e){var r=new Date;return t=+t,e=+e,function(i){return r.setTime(t*(1-i)+e*i),r}}function nn(t,e){var r,i={},n={};for(r in null!==t&&"object"==typeof t||(t={}),null!==e&&"object"==typeof e||(e={}),e)r in t?i[r]=on(t[r],e[r]):n[r]=e[r];return function(t){for(r in i)n[r]=i[r](t);return n}}function an(t,e){e||(e=[]);var r,i=t?Math.min(e.length,t.length):0,n=e.slice();return function(a){for(r=0;r<i;++r)n[r]=t[r]*(1-a)+e[r]*a;return n}}function on(t,e){var r,i,n=typeof e;return null==e||"boolean"===n?er(e):("number"===n?le:"string"===n?(r=Ke(e))?(e=r,ar):cr:e instanceof Ke?ar:e instanceof Date?rn:(i=e,!ArrayBuffer.isView(i)||i instanceof DataView?Array.isArray(e)?en:"function"!=typeof e.valueOf&&"function"!=typeof e.toString||isNaN(e)?nn:le:an))(t,e)}function sn(t,e){return t=+t,e=+e,function(r){return Math.round(t*(1-r)+e*r)}}function ln(t){return+t}var cn=[0,1];function hn(t){return t}function un(t,e){return(e-=t=+t)?function(r){return(r-t)/e}:(r=isNaN(e)?NaN:.5,function(){return r});var r}function dn(t,e,r){var i=t[0],n=t[1],a=e[0],o=e[1];return n<i?(i=un(n,i),a=r(o,a)):(i=un(i,n),a=r(a,o)),function(t){return a(i(t))}}function pn(t,e,r){var i=Math.min(t.length,e.length)-1,n=new Array(i),a=new Array(i),o=-1;for(t[i]<t[0]&&(t=t.slice().reverse(),e=e.slice().reverse());++o<i;)n[o]=un(t[o],t[o+1]),a[o]=r(e[o],e[o+1]);return function(e){var r=tn(t,e,1,i)-1;return a[r](n[r](e))}}function fn(t,e){return e.domain(t.domain()).range(t.range()).interpolate(t.interpolate()).clamp(t.clamp()).unknown(t.unknown())}function gn(){var t,e,r,i,n,a,o=cn,s=cn,l=on,c=hn;function h(){var t,e,r,l=Math.min(o.length,s.length);return c!==hn&&(t=o[0],e=o[l-1],t>e&&(r=t,t=e,e=r),c=function(r){return Math.max(t,Math.min(e,r))}),i=l>2?pn:dn,n=a=null,u}function u(e){return null==e||isNaN(e=+e)?r:(n||(n=i(o.map(t),s,l)))(t(c(e)))}return u.invert=function(r){return c(e((a||(a=i(s,o.map(t),le)))(r)))},u.domain=function(t){return arguments.length?(o=Array.from(t,ln),h()):o.slice()},u.range=function(t){return arguments.length?(s=Array.from(t),h()):s.slice()},u.rangeRound=function(t){return s=Array.from(t),l=sn,h()},u.clamp=function(t){return arguments.length?(c=!!t||hn,h()):c!==hn},u.interpolate=function(t){return arguments.length?(l=t,h()):l},u.unknown=function(t){return arguments.length?(r=t,u):r},function(r,i){return t=r,e=i,h()}}function yn(){return gn()(hn,hn)}function mn(t,e,r,i){var n,a=Yi(t,e,r);switch((i=Pr(null==i?",f":i)).type){case"s":var o=Math.max(Math.abs(t),Math.abs(e));return null!=i.precision||isNaN(n=function(t,e){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(Ir(e)/3)))-Ir(Math.abs(t)))}(a,o))||(i.precision=n),Gr(i,o);case"":case"e":case"g":case"p":case"r":null!=i.precision||isNaN(n=function(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,Ir(e)-Ir(t))+1}(a,Math.max(Math.abs(t),Math.abs(e))))||(i.precision=n-("e"===i.type));break;case"f":case"%":null!=i.precision||isNaN(n=function(t){return Math.max(0,-Ir(Math.abs(t)))}(a))||(i.precision=n-2*("%"===i.type))}return Yr(i)}function xn(t){var e=t.domain;return t.ticks=function(t){var r=e();return function(t,e,r){if(!((r=+r)>0))return[];if((t=+t)===(e=+e))return[t];const i=e<t,[n,a,o]=i?Hi(e,t,r):Hi(t,e,r);if(!(a>=n))return[];const s=a-n+1,l=new Array(s);if(i)if(o<0)for(let c=0;c<s;++c)l[c]=(a-c)/-o;else for(let c=0;c<s;++c)l[c]=(a-c)*o;else if(o<0)for(let c=0;c<s;++c)l[c]=(n+c)/-o;else for(let c=0;c<s;++c)l[c]=(n+c)*o;return l}(r[0],r[r.length-1],null==t?10:t)},t.tickFormat=function(t,r){var i=e();return mn(i[0],i[i.length-1],null==t?10:t,r)},t.nice=function(r){null==r&&(r=10);var i,n,a=e(),o=0,s=a.length-1,l=a[o],c=a[s],h=10;for(c<l&&(n=l,l=c,c=n,n=o,o=s,s=n);h-- >0;){if((n=Ui(l,c,r))===i)return a[o]=l,a[s]=c,e(a);if(n>0)l=Math.floor(l/n)*n,c=Math.ceil(c/n)*n;else{if(!(n<0))break;l=Math.ceil(l*n)/n,c=Math.floor(c*n)/n}i=n}return t},t}function bn(){var t=yn();return t.copy=function(){return fn(t,bn())},Ei.apply(t,arguments),xn(t)}const kn=1e3,wn=6e4,Cn=36e5,_n=864e5,vn=6048e5,Sn=2592e6,Tn=31536e6,An=new Date,Mn=new Date;function Bn(t,e,r,i){function n(e){return t(e=0===arguments.length?new Date:new Date(+e)),e}return n.floor=e=>(t(e=new Date(+e)),e),n.ceil=r=>(t(r=new Date(r-1)),e(r,1),t(r),r),n.round=t=>{const e=n(t),r=n.ceil(t);return t-e<r-t?e:r},n.offset=(t,r)=>(e(t=new Date(+t),null==r?1:Math.floor(r)),t),n.range=(r,i,a)=>{const o=[];if(r=n.ceil(r),a=null==a?1:Math.floor(a),!(r<i&&a>0))return o;let s;do{o.push(s=new Date(+r)),e(r,a),t(r)}while(s<r&&r<i);return o},n.filter=r=>Bn(e=>{if(e>=e)for(;t(e),!r(e);)e.setTime(e-1)},(t,i)=>{if(t>=t)if(i<0)for(;++i<=0;)for(;e(t,-1),!r(t););else for(;--i>=0;)for(;e(t,1),!r(t););}),r&&(n.count=(e,i)=>(An.setTime(+e),Mn.setTime(+i),t(An),t(Mn),Math.floor(r(An,Mn))),n.every=t=>(t=Math.floor(t),isFinite(t)&&t>0?t>1?n.filter(i?e=>i(e)%t===0:e=>n.count(0,e)%t===0):n:null)),n}const Ln=Bn(()=>{},(t,e)=>{t.setTime(+t+e)},(t,e)=>e-t);Ln.every=t=>(t=Math.floor(t),isFinite(t)&&t>0?t>1?Bn(e=>{e.setTime(Math.floor(e/t)*t)},(e,r)=>{e.setTime(+e+r*t)},(e,r)=>(r-e)/t):Ln:null);Ln.range;const Fn=Bn(t=>{t.setTime(t-t.getMilliseconds())},(t,e)=>{t.setTime(+t+e*kn)},(t,e)=>(e-t)/kn,t=>t.getUTCSeconds()),$n=(Fn.range,Bn(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*kn)},(t,e)=>{t.setTime(+t+e*wn)},(t,e)=>(e-t)/wn,t=>t.getMinutes())),En=($n.range,Bn(t=>{t.setUTCSeconds(0,0)},(t,e)=>{t.setTime(+t+e*wn)},(t,e)=>(e-t)/wn,t=>t.getUTCMinutes())),Dn=(En.range,Bn(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*kn-t.getMinutes()*wn)},(t,e)=>{t.setTime(+t+e*Cn)},(t,e)=>(e-t)/Cn,t=>t.getHours())),On=(Dn.range,Bn(t=>{t.setUTCMinutes(0,0,0)},(t,e)=>{t.setTime(+t+e*Cn)},(t,e)=>(e-t)/Cn,t=>t.getUTCHours())),Rn=(On.range,Bn(t=>t.setHours(0,0,0,0),(t,e)=>t.setDate(t.getDate()+e),(t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*wn)/_n,t=>t.getDate()-1)),Kn=(Rn.range,Bn(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/_n,t=>t.getUTCDate()-1)),In=(Kn.range,Bn(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/_n,t=>Math.floor(t/_n)));In.range;function Nn(t){return Bn(e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)},(t,e)=>{t.setDate(t.getDate()+7*e)},(t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*wn)/vn)}const zn=Nn(0),Pn=Nn(1),qn=Nn(2),jn=Nn(3),Wn=Nn(4),Hn=Nn(5),Un=Nn(6);zn.range,Pn.range,qn.range,jn.range,Wn.range,Hn.range,Un.range;function Yn(t){return Bn(e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+7*e)},(t,e)=>(e-t)/vn)}const Gn=Yn(0),Xn=Yn(1),Vn=Yn(2),Zn=Yn(3),Qn=Yn(4),Jn=Yn(5),ta=Yn(6),ea=(Gn.range,Xn.range,Vn.range,Zn.range,Qn.range,Jn.range,ta.range,Bn(t=>{t.setDate(1),t.setHours(0,0,0,0)},(t,e)=>{t.setMonth(t.getMonth()+e)},(t,e)=>e.getMonth()-t.getMonth()+12*(e.getFullYear()-t.getFullYear()),t=>t.getMonth())),ra=(ea.range,Bn(t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCMonth(t.getUTCMonth()+e)},(t,e)=>e.getUTCMonth()-t.getUTCMonth()+12*(e.getUTCFullYear()-t.getUTCFullYear()),t=>t.getUTCMonth())),ia=(ra.range,Bn(t=>{t.setMonth(0,1),t.setHours(0,0,0,0)},(t,e)=>{t.setFullYear(t.getFullYear()+e)},(t,e)=>e.getFullYear()-t.getFullYear(),t=>t.getFullYear()));ia.every=t=>isFinite(t=Math.floor(t))&&t>0?Bn(e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)},(e,r)=>{e.setFullYear(e.getFullYear()+r*t)}):null;ia.range;const na=Bn(t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e)},(t,e)=>e.getUTCFullYear()-t.getUTCFullYear(),t=>t.getUTCFullYear());na.every=t=>isFinite(t=Math.floor(t))&&t>0?Bn(e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},(e,r)=>{e.setUTCFullYear(e.getUTCFullYear()+r*t)}):null;na.range;function aa(t,e,r,i,n,a){const o=[[Fn,1,kn],[Fn,5,5e3],[Fn,15,15e3],[Fn,30,3e4],[a,1,wn],[a,5,3e5],[a,15,9e5],[a,30,18e5],[n,1,Cn],[n,3,108e5],[n,6,216e5],[n,12,432e5],[i,1,_n],[i,2,1728e5],[r,1,vn],[e,1,Sn],[e,3,7776e6],[t,1,Tn]];function s(e,r,i){const n=Math.abs(r-e)/i,a=Vi(([,,t])=>t).right(o,n);if(a===o.length)return t.every(Yi(e/Tn,r/Tn,i));if(0===a)return Ln.every(Math.max(Yi(e,r,i),1));const[s,l]=o[n/o[a-1][2]<o[a][2]/n?a-1:a];return s.every(l)}return[function(t,e,r){const i=e<t;i&&([t,e]=[e,t]);const n=r&&"function"==typeof r.range?r:s(t,e,r),a=n?n.range(t,+e+1):[];return i?a.reverse():a},s]}const[oa,sa]=aa(na,ra,Gn,In,On,En),[la,ca]=aa(ia,ea,zn,Rn,Dn,$n);function ha(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function ua(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function da(t,e,r){return{y:t,m:e,d:r,H:0,M:0,S:0,L:0}}var pa,fa,ga={"-":"",_:" ",0:"0"},ya=/^\s*\d+/,ma=/^%/,xa=/[\\^$*+?|[\]().{}]/g;function ba(t,e,r){var i=t<0?"-":"",n=(i?-t:t)+"",a=n.length;return i+(a<r?new Array(r-a+1).join(e)+n:n)}function ka(t){return t.replace(xa,"\\$&")}function wa(t){return new RegExp("^(?:"+t.map(ka).join("|")+")","i")}function Ca(t){return new Map(t.map((t,e)=>[t.toLowerCase(),e]))}function _a(t,e,r){var i=ya.exec(e.slice(r,r+1));return i?(t.w=+i[0],r+i[0].length):-1}function va(t,e,r){var i=ya.exec(e.slice(r,r+1));return i?(t.u=+i[0],r+i[0].length):-1}function Sa(t,e,r){var i=ya.exec(e.slice(r,r+2));return i?(t.U=+i[0],r+i[0].length):-1}function Ta(t,e,r){var i=ya.exec(e.slice(r,r+2));return i?(t.V=+i[0],r+i[0].length):-1}function Aa(t,e,r){var i=ya.exec(e.slice(r,r+2));return i?(t.W=+i[0],r+i[0].length):-1}function Ma(t,e,r){var i=ya.exec(e.slice(r,r+4));return i?(t.y=+i[0],r+i[0].length):-1}function Ba(t,e,r){var i=ya.exec(e.slice(r,r+2));return i?(t.y=+i[0]+(+i[0]>68?1900:2e3),r+i[0].length):-1}function La(t,e,r){var i=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(r,r+6));return i?(t.Z=i[1]?0:-(i[2]+(i[3]||"00")),r+i[0].length):-1}function Fa(t,e,r){var i=ya.exec(e.slice(r,r+1));return i?(t.q=3*i[0]-3,r+i[0].length):-1}function $a(t,e,r){var i=ya.exec(e.slice(r,r+2));return i?(t.m=i[0]-1,r+i[0].length):-1}function Ea(t,e,r){var i=ya.exec(e.slice(r,r+2));return i?(t.d=+i[0],r+i[0].length):-1}function Da(t,e,r){var i=ya.exec(e.slice(r,r+3));return i?(t.m=0,t.d=+i[0],r+i[0].length):-1}function Oa(t,e,r){var i=ya.exec(e.slice(r,r+2));return i?(t.H=+i[0],r+i[0].length):-1}function Ra(t,e,r){var i=ya.exec(e.slice(r,r+2));return i?(t.M=+i[0],r+i[0].length):-1}function Ka(t,e,r){var i=ya.exec(e.slice(r,r+2));return i?(t.S=+i[0],r+i[0].length):-1}function Ia(t,e,r){var i=ya.exec(e.slice(r,r+3));return i?(t.L=+i[0],r+i[0].length):-1}function Na(t,e,r){var i=ya.exec(e.slice(r,r+6));return i?(t.L=Math.floor(i[0]/1e3),r+i[0].length):-1}function za(t,e,r){var i=ma.exec(e.slice(r,r+1));return i?r+i[0].length:-1}function Pa(t,e,r){var i=ya.exec(e.slice(r));return i?(t.Q=+i[0],r+i[0].length):-1}function qa(t,e,r){var i=ya.exec(e.slice(r));return i?(t.s=+i[0],r+i[0].length):-1}function ja(t,e){return ba(t.getDate(),e,2)}function Wa(t,e){return ba(t.getHours(),e,2)}function Ha(t,e){return ba(t.getHours()%12||12,e,2)}function Ua(t,e){return ba(1+Rn.count(ia(t),t),e,3)}function Ya(t,e){return ba(t.getMilliseconds(),e,3)}function Ga(t,e){return Ya(t,e)+"000"}function Xa(t,e){return ba(t.getMonth()+1,e,2)}function Va(t,e){return ba(t.getMinutes(),e,2)}function Za(t,e){return ba(t.getSeconds(),e,2)}function Qa(t){var e=t.getDay();return 0===e?7:e}function Ja(t,e){return ba(zn.count(ia(t)-1,t),e,2)}function to(t){var e=t.getDay();return e>=4||0===e?Wn(t):Wn.ceil(t)}function eo(t,e){return t=to(t),ba(Wn.count(ia(t),t)+(4===ia(t).getDay()),e,2)}function ro(t){return t.getDay()}function io(t,e){return ba(Pn.count(ia(t)-1,t),e,2)}function no(t,e){return ba(t.getFullYear()%100,e,2)}function ao(t,e){return ba((t=to(t)).getFullYear()%100,e,2)}function oo(t,e){return ba(t.getFullYear()%1e4,e,4)}function so(t,e){var r=t.getDay();return ba((t=r>=4||0===r?Wn(t):Wn.ceil(t)).getFullYear()%1e4,e,4)}function lo(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+ba(e/60|0,"0",2)+ba(e%60,"0",2)}function co(t,e){return ba(t.getUTCDate(),e,2)}function ho(t,e){return ba(t.getUTCHours(),e,2)}function uo(t,e){return ba(t.getUTCHours()%12||12,e,2)}function po(t,e){return ba(1+Kn.count(na(t),t),e,3)}function fo(t,e){return ba(t.getUTCMilliseconds(),e,3)}function go(t,e){return fo(t,e)+"000"}function yo(t,e){return ba(t.getUTCMonth()+1,e,2)}function mo(t,e){return ba(t.getUTCMinutes(),e,2)}function xo(t,e){return ba(t.getUTCSeconds(),e,2)}function bo(t){var e=t.getUTCDay();return 0===e?7:e}function ko(t,e){return ba(Gn.count(na(t)-1,t),e,2)}function wo(t){var e=t.getUTCDay();return e>=4||0===e?Qn(t):Qn.ceil(t)}function Co(t,e){return t=wo(t),ba(Qn.count(na(t),t)+(4===na(t).getUTCDay()),e,2)}function _o(t){return t.getUTCDay()}function vo(t,e){return ba(Xn.count(na(t)-1,t),e,2)}function So(t,e){return ba(t.getUTCFullYear()%100,e,2)}function To(t,e){return ba((t=wo(t)).getUTCFullYear()%100,e,2)}function Ao(t,e){return ba(t.getUTCFullYear()%1e4,e,4)}function Mo(t,e){var r=t.getUTCDay();return ba((t=r>=4||0===r?Qn(t):Qn.ceil(t)).getUTCFullYear()%1e4,e,4)}function Bo(){return"+0000"}function Lo(){return"%"}function Fo(t){return+t}function $o(t){return Math.floor(+t/1e3)}function Eo(t){return new Date(t)}function Do(t){return t instanceof Date?+t:+new Date(+t)}function Oo(t,e,r,i,n,a,o,s,l,c){var h=yn(),u=h.invert,d=h.domain,p=c(".%L"),f=c(":%S"),g=c("%I:%M"),y=c("%I %p"),m=c("%a %d"),x=c("%b %d"),b=c("%B"),k=c("%Y");function w(t){return(l(t)<t?p:s(t)<t?f:o(t)<t?g:a(t)<t?y:i(t)<t?n(t)<t?m:x:r(t)<t?b:k)(t)}return h.invert=function(t){return new Date(u(t))},h.domain=function(t){return arguments.length?d(Array.from(t,Do)):d().map(Eo)},h.ticks=function(e){var r=d();return t(r[0],r[r.length-1],null==e?10:e)},h.tickFormat=function(t,e){return null==e?w:c(e)},h.nice=function(t){var r=d();return t&&"function"==typeof t.range||(t=e(r[0],r[r.length-1],null==t?10:t)),t?d(function(t,e){var r,i=0,n=(t=t.slice()).length-1,a=t[i],o=t[n];return o<a&&(r=i,i=n,n=r,r=a,a=o,o=r),t[i]=e.floor(a),t[n]=e.ceil(o),t}(r,t)):h},h.copy=function(){return fn(h,Oo(t,e,r,i,n,a,o,s,l,c))},h}function Ro(){return Ei.apply(Oo(la,ca,ia,ea,zn,Rn,Dn,$n,Fn,fa).domain([new Date(2e3,0,1),new Date(2e3,0,2)]),arguments)}!function(t){pa=function(t){var e=t.dateTime,r=t.date,i=t.time,n=t.periods,a=t.days,o=t.shortDays,s=t.months,l=t.shortMonths,c=wa(n),h=Ca(n),u=wa(a),d=Ca(a),p=wa(o),f=Ca(o),g=wa(s),y=Ca(s),m=wa(l),x=Ca(l),b={a:function(t){return o[t.getDay()]},A:function(t){return a[t.getDay()]},b:function(t){return l[t.getMonth()]},B:function(t){return s[t.getMonth()]},c:null,d:ja,e:ja,f:Ga,g:ao,G:so,H:Wa,I:Ha,j:Ua,L:Ya,m:Xa,M:Va,p:function(t){return n[+(t.getHours()>=12)]},q:function(t){return 1+~~(t.getMonth()/3)},Q:Fo,s:$o,S:Za,u:Qa,U:Ja,V:eo,w:ro,W:io,x:null,X:null,y:no,Y:oo,Z:lo,"%":Lo},k={a:function(t){return o[t.getUTCDay()]},A:function(t){return a[t.getUTCDay()]},b:function(t){return l[t.getUTCMonth()]},B:function(t){return s[t.getUTCMonth()]},c:null,d:co,e:co,f:go,g:To,G:Mo,H:ho,I:uo,j:po,L:fo,m:yo,M:mo,p:function(t){return n[+(t.getUTCHours()>=12)]},q:function(t){return 1+~~(t.getUTCMonth()/3)},Q:Fo,s:$o,S:xo,u:bo,U:ko,V:Co,w:_o,W:vo,x:null,X:null,y:So,Y:Ao,Z:Bo,"%":Lo},w={a:function(t,e,r){var i=p.exec(e.slice(r));return i?(t.w=f.get(i[0].toLowerCase()),r+i[0].length):-1},A:function(t,e,r){var i=u.exec(e.slice(r));return i?(t.w=d.get(i[0].toLowerCase()),r+i[0].length):-1},b:function(t,e,r){var i=m.exec(e.slice(r));return i?(t.m=x.get(i[0].toLowerCase()),r+i[0].length):-1},B:function(t,e,r){var i=g.exec(e.slice(r));return i?(t.m=y.get(i[0].toLowerCase()),r+i[0].length):-1},c:function(t,r,i){return v(t,e,r,i)},d:Ea,e:Ea,f:Na,g:Ba,G:Ma,H:Oa,I:Oa,j:Da,L:Ia,m:$a,M:Ra,p:function(t,e,r){var i=c.exec(e.slice(r));return i?(t.p=h.get(i[0].toLowerCase()),r+i[0].length):-1},q:Fa,Q:Pa,s:qa,S:Ka,u:va,U:Sa,V:Ta,w:_a,W:Aa,x:function(t,e,i){return v(t,r,e,i)},X:function(t,e,r){return v(t,i,e,r)},y:Ba,Y:Ma,Z:La,"%":za};function C(t,e){return function(r){var i,n,a,o=[],s=-1,l=0,c=t.length;for(r instanceof Date||(r=new Date(+r));++s<c;)37===t.charCodeAt(s)&&(o.push(t.slice(l,s)),null!=(n=ga[i=t.charAt(++s)])?i=t.charAt(++s):n="e"===i?" ":"0",(a=e[i])&&(i=a(r,n)),o.push(i),l=s+1);return o.push(t.slice(l,s)),o.join("")}}function _(t,e){return function(r){var i,n,a=da(1900,void 0,1);if(v(a,t,r+="",0)!=r.length)return null;if("Q"in a)return new Date(a.Q);if("s"in a)return new Date(1e3*a.s+("L"in a?a.L:0));if(e&&!("Z"in a)&&(a.Z=0),"p"in a&&(a.H=a.H%12+12*a.p),void 0===a.m&&(a.m="q"in a?a.q:0),"V"in a){if(a.V<1||a.V>53)return null;"w"in a||(a.w=1),"Z"in a?(n=(i=ua(da(a.y,0,1))).getUTCDay(),i=n>4||0===n?Xn.ceil(i):Xn(i),i=Kn.offset(i,7*(a.V-1)),a.y=i.getUTCFullYear(),a.m=i.getUTCMonth(),a.d=i.getUTCDate()+(a.w+6)%7):(n=(i=ha(da(a.y,0,1))).getDay(),i=n>4||0===n?Pn.ceil(i):Pn(i),i=Rn.offset(i,7*(a.V-1)),a.y=i.getFullYear(),a.m=i.getMonth(),a.d=i.getDate()+(a.w+6)%7)}else("W"in a||"U"in a)&&("w"in a||(a.w="u"in a?a.u%7:"W"in a?1:0),n="Z"in a?ua(da(a.y,0,1)).getUTCDay():ha(da(a.y,0,1)).getDay(),a.m=0,a.d="W"in a?(a.w+6)%7+7*a.W-(n+5)%7:a.w+7*a.U-(n+6)%7);return"Z"in a?(a.H+=a.Z/100|0,a.M+=a.Z%100,ua(a)):ha(a)}}function v(t,e,r,i){for(var n,a,o=0,s=e.length,l=r.length;o<s;){if(i>=l)return-1;if(37===(n=e.charCodeAt(o++))){if(n=e.charAt(o++),!(a=w[n in ga?e.charAt(o++):n])||(i=a(t,r,i))<0)return-1}else if(n!=r.charCodeAt(i++))return-1}return i}return b.x=C(r,b),b.X=C(i,b),b.c=C(e,b),k.x=C(r,k),k.X=C(i,k),k.c=C(e,k),{format:function(t){var e=C(t+="",b);return e.toString=function(){return t},e},parse:function(t){var e=_(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=C(t+="",k);return e.toString=function(){return t},e},utcParse:function(t){var e=_(t+="",!0);return e.toString=function(){return t},e}}}(t),fa=pa.format,pa.parse,pa.utcFormat,pa.utcParse}({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});const Ko=function(t){for(var e=t.length/6|0,r=new Array(e),i=0;i<e;)r[i]="#"+t.slice(6*i,6*++i);return r}("4e79a7f28e2ce1575976b7b259a14fedc949af7aa1ff9da79c755fbab0ab");function Io(t){return"string"==typeof t?new Bt([[document.querySelector(t)]],[document.documentElement]):new Bt([[t]],Mt)}function No(t){return function(){return t}}const zo=Math.abs,Po=Math.atan2,qo=Math.cos,jo=Math.max,Wo=Math.min,Ho=Math.sin,Uo=Math.sqrt,Yo=1e-12,Go=Math.PI,Xo=Go/2,Vo=2*Go;function Zo(t){return t>=1?Xo:t<=-1?-Xo:Math.asin(t)}const Qo=Math.PI,Jo=2*Qo,ts=1e-6,es=Jo-ts;function rs(t){this._+=t[0];for(let e=1,r=t.length;e<r;++e)this._+=arguments[e]+t[e]}class is{constructor(t){this._x0=this._y0=this._x1=this._y1=null,this._="",this._append=null==t?rs:function(t){let e=Math.floor(t);if(!(e>=0))throw new Error(`invalid digits: ${t}`);if(e>15)return rs;const r=10**e;return function(t){this._+=t[0];for(let e=1,i=t.length;e<i;++e)this._+=Math.round(arguments[e]*r)/r+t[e]}}(t)}moveTo(t,e){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+e}`}closePath(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._append`Z`)}lineTo(t,e){this._append`L${this._x1=+t},${this._y1=+e}`}quadraticCurveTo(t,e,r,i){this._append`Q${+t},${+e},${this._x1=+r},${this._y1=+i}`}bezierCurveTo(t,e,r,i,n,a){this._append`C${+t},${+e},${+r},${+i},${this._x1=+n},${this._y1=+a}`}arcTo(t,e,r,i,n){if(t=+t,e=+e,r=+r,i=+i,(n=+n)<0)throw new Error(`negative radius: ${n}`);let a=this._x1,o=this._y1,s=r-t,l=i-e,c=a-t,h=o-e,u=c*c+h*h;if(null===this._x1)this._append`M${this._x1=t},${this._y1=e}`;else if(u>ts)if(Math.abs(h*s-l*c)>ts&&n){let d=r-a,p=i-o,f=s*s+l*l,g=d*d+p*p,y=Math.sqrt(f),m=Math.sqrt(u),x=n*Math.tan((Qo-Math.acos((f+u-g)/(2*y*m)))/2),b=x/m,k=x/y;Math.abs(b-1)>ts&&this._append`L${t+b*c},${e+b*h}`,this._append`A${n},${n},0,0,${+(h*d>c*p)},${this._x1=t+k*s},${this._y1=e+k*l}`}else this._append`L${this._x1=t},${this._y1=e}`;else;}arc(t,e,r,i,n,a){if(t=+t,e=+e,a=!!a,(r=+r)<0)throw new Error(`negative radius: ${r}`);let o=r*Math.cos(i),s=r*Math.sin(i),l=t+o,c=e+s,h=1^a,u=a?i-n:n-i;null===this._x1?this._append`M${l},${c}`:(Math.abs(this._x1-l)>ts||Math.abs(this._y1-c)>ts)&&this._append`L${l},${c}`,r&&(u<0&&(u=u%Jo+Jo),u>es?this._append`A${r},${r},0,1,${h},${t-o},${e-s}A${r},${r},0,1,${h},${this._x1=l},${this._y1=c}`:u>ts&&this._append`A${r},${r},0,${+(u>=Qo)},${h},${this._x1=t+r*Math.cos(n)},${this._y1=e+r*Math.sin(n)}`)}rect(t,e,r,i){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+e}h${r=+r}v${+i}h${-r}Z`}toString(){return this._}}function ns(t){let e=3;return t.digits=function(r){if(!arguments.length)return e;if(null==r)e=null;else{const t=Math.floor(r);if(!(t>=0))throw new RangeError(`invalid digits: ${r}`);e=t}return t},()=>new is(e)}function as(t){return t.innerRadius}function os(t){return t.outerRadius}function ss(t){return t.startAngle}function ls(t){return t.endAngle}function cs(t){return t&&t.padAngle}function hs(t,e,r,i,n,a,o){var s=t-r,l=e-i,c=(o?a:-a)/Uo(s*s+l*l),h=c*l,u=-c*s,d=t+h,p=e+u,f=r+h,g=i+u,y=(d+f)/2,m=(p+g)/2,x=f-d,b=g-p,k=x*x+b*b,w=n-a,C=d*g-f*p,_=(b<0?-1:1)*Uo(jo(0,w*w*k-C*C)),v=(C*b-x*_)/k,S=(-C*x-b*_)/k,T=(C*b+x*_)/k,A=(-C*x+b*_)/k,M=v-y,B=S-m,L=T-y,F=A-m;return M*M+B*B>L*L+F*F&&(v=T,S=A),{cx:v,cy:S,x01:-h,y01:-u,x11:v*(n/w-1),y11:S*(n/w-1)}}function us(){var t=as,e=os,r=No(0),i=null,n=ss,a=ls,o=cs,s=null,l=ns(c);function c(){var c,h,u,d=+t.apply(this,arguments),p=+e.apply(this,arguments),f=n.apply(this,arguments)-Xo,g=a.apply(this,arguments)-Xo,y=zo(g-f),m=g>f;if(s||(s=c=l()),p<d&&(h=p,p=d,d=h),p>Yo)if(y>Vo-Yo)s.moveTo(p*qo(f),p*Ho(f)),s.arc(0,0,p,f,g,!m),d>Yo&&(s.moveTo(d*qo(g),d*Ho(g)),s.arc(0,0,d,g,f,m));else{var x,b,k=f,w=g,C=f,_=g,v=y,S=y,T=o.apply(this,arguments)/2,A=T>Yo&&(i?+i.apply(this,arguments):Uo(d*d+p*p)),M=Wo(zo(p-d)/2,+r.apply(this,arguments)),B=M,L=M;if(A>Yo){var F=Zo(A/d*Ho(T)),$=Zo(A/p*Ho(T));(v-=2*F)>Yo?(C+=F*=m?1:-1,_-=F):(v=0,C=_=(f+g)/2),(S-=2*$)>Yo?(k+=$*=m?1:-1,w-=$):(S=0,k=w=(f+g)/2)}var E=p*qo(k),D=p*Ho(k),O=d*qo(_),R=d*Ho(_);if(M>Yo){var K,I=p*qo(w),N=p*Ho(w),z=d*qo(C),P=d*Ho(C);if(y<Go)if(K=function(t,e,r,i,n,a,o,s){var l=r-t,c=i-e,h=o-n,u=s-a,d=u*l-h*c;if(!(d*d<Yo))return[t+(d=(h*(e-a)-u*(t-n))/d)*l,e+d*c]}(E,D,z,P,I,N,O,R)){var q=E-K[0],j=D-K[1],W=I-K[0],H=N-K[1],U=1/Ho(((u=(q*W+j*H)/(Uo(q*q+j*j)*Uo(W*W+H*H)))>1?0:u<-1?Go:Math.acos(u))/2),Y=Uo(K[0]*K[0]+K[1]*K[1]);B=Wo(M,(d-Y)/(U-1)),L=Wo(M,(p-Y)/(U+1))}else B=L=0}S>Yo?L>Yo?(x=hs(z,P,E,D,p,L,m),b=hs(I,N,O,R,p,L,m),s.moveTo(x.cx+x.x01,x.cy+x.y01),L<M?s.arc(x.cx,x.cy,L,Po(x.y01,x.x01),Po(b.y01,b.x01),!m):(s.arc(x.cx,x.cy,L,Po(x.y01,x.x01),Po(x.y11,x.x11),!m),s.arc(0,0,p,Po(x.cy+x.y11,x.cx+x.x11),Po(b.cy+b.y11,b.cx+b.x11),!m),s.arc(b.cx,b.cy,L,Po(b.y11,b.x11),Po(b.y01,b.x01),!m))):(s.moveTo(E,D),s.arc(0,0,p,k,w,!m)):s.moveTo(E,D),d>Yo&&v>Yo?B>Yo?(x=hs(O,R,I,N,d,-B,m),b=hs(E,D,z,P,d,-B,m),s.lineTo(x.cx+x.x01,x.cy+x.y01),B<M?s.arc(x.cx,x.cy,B,Po(x.y01,x.x01),Po(b.y01,b.x01),!m):(s.arc(x.cx,x.cy,B,Po(x.y01,x.x01),Po(x.y11,x.x11),!m),s.arc(0,0,d,Po(x.cy+x.y11,x.cx+x.x11),Po(b.cy+b.y11,b.cx+b.x11),m),s.arc(b.cx,b.cy,B,Po(b.y11,b.x11),Po(b.y01,b.x01),!m))):s.arc(0,0,d,_,C,m):s.lineTo(O,R)}else s.moveTo(0,0);if(s.closePath(),c)return s=null,c+""||null}return c.centroid=function(){var r=(+t.apply(this,arguments)+ +e.apply(this,arguments))/2,i=(+n.apply(this,arguments)+ +a.apply(this,arguments))/2-Go/2;return[qo(i)*r,Ho(i)*r]},c.innerRadius=function(e){return arguments.length?(t="function"==typeof e?e:No(+e),c):t},c.outerRadius=function(t){return arguments.length?(e="function"==typeof t?t:No(+t),c):e},c.cornerRadius=function(t){return arguments.length?(r="function"==typeof t?t:No(+t),c):r},c.padRadius=function(t){return arguments.length?(i=null==t?null:"function"==typeof t?t:No(+t),c):i},c.startAngle=function(t){return arguments.length?(n="function"==typeof t?t:No(+t),c):n},c.endAngle=function(t){return arguments.length?(a="function"==typeof t?t:No(+t),c):a},c.padAngle=function(t){return arguments.length?(o="function"==typeof t?t:No(+t),c):o},c.context=function(t){return arguments.length?(s=null==t?null:t,c):s},c}is.prototype;Array.prototype.slice;function ds(t){return"object"==typeof t&&"length"in t?t:Array.from(t)}function ps(t){this._context=t}function fs(t){return new ps(t)}function gs(t){return t[0]}function ys(t){return t[1]}function ms(t,e){var r=No(!0),i=null,n=fs,a=null,o=ns(s);function s(s){var l,c,h,u=(s=ds(s)).length,d=!1;for(null==i&&(a=n(h=o())),l=0;l<=u;++l)!(l<u&&r(c=s[l],l,s))===d&&((d=!d)?a.lineStart():a.lineEnd()),d&&a.point(+t(c,l,s),+e(c,l,s));if(h)return a=null,h+""||null}return t="function"==typeof t?t:void 0===t?gs:No(t),e="function"==typeof e?e:void 0===e?ys:No(e),s.x=function(e){return arguments.length?(t="function"==typeof e?e:No(+e),s):t},s.y=function(t){return arguments.length?(e="function"==typeof t?t:No(+t),s):e},s.defined=function(t){return arguments.length?(r="function"==typeof t?t:No(!!t),s):r},s.curve=function(t){return arguments.length?(n=t,null!=i&&(a=n(i)),s):n},s.context=function(t){return arguments.length?(null==t?i=a=null:a=n(i=t),s):i},s}function xs(t,e){return e<t?-1:e>t?1:e>=t?0:NaN}function bs(t){return t}function ks(){var t=bs,e=xs,r=null,i=No(0),n=No(Vo),a=No(0);function o(o){var s,l,c,h,u,d=(o=ds(o)).length,p=0,f=new Array(d),g=new Array(d),y=+i.apply(this,arguments),m=Math.min(Vo,Math.max(-Vo,n.apply(this,arguments)-y)),x=Math.min(Math.abs(m)/d,a.apply(this,arguments)),b=x*(m<0?-1:1);for(s=0;s<d;++s)(u=g[f[s]=s]=+t(o[s],s,o))>0&&(p+=u);for(null!=e?f.sort(function(t,r){return e(g[t],g[r])}):null!=r&&f.sort(function(t,e){return r(o[t],o[e])}),s=0,c=p?(m-d*b)/p:0;s<d;++s,y=h)l=f[s],h=y+((u=g[l])>0?u*c:0)+b,g[l]={data:o[l],index:s,value:u,startAngle:y,endAngle:h,padAngle:x};return g}return o.value=function(e){return arguments.length?(t="function"==typeof e?e:No(+e),o):t},o.sortValues=function(t){return arguments.length?(e=t,r=null,o):e},o.sort=function(t){return arguments.length?(r=t,e=null,o):r},o.startAngle=function(t){return arguments.length?(i="function"==typeof t?t:No(+t),o):i},o.endAngle=function(t){return arguments.length?(n="function"==typeof t?t:No(+t),o):n},o.padAngle=function(t){return arguments.length?(a="function"==typeof t?t:No(+t),o):a},o}function ws(){}function Cs(t,e,r){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+r)/6)}function _s(t){this._context=t}function vs(t){return new _s(t)}function Ss(t){this._context=t}function Ts(t){return new Ss(t)}function As(t){this._context=t}function Ms(t){return new As(t)}ps.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._context.lineTo(t,e)}}},_s.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:Cs(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:Cs(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},Ss.prototype={areaStart:ws,areaEnd:ws,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:Cs(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},As.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var r=(this._x0+4*this._x1+t)/6,i=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(r,i):this._context.moveTo(r,i);break;case 3:this._point=4;default:Cs(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};class Bs{constructor(t,e){this._context=t,this._x=e}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line}point(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._x?this._context.bezierCurveTo(this._x0=(this._x0+t)/2,this._y0,this._x0,e,t,e):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+e)/2,t,this._y0,t,e)}this._x0=t,this._y0=e}}function Ls(t){return new Bs(t,!0)}function Fs(t){return new Bs(t,!1)}function $s(t,e){this._basis=new _s(t),this._beta=e}$s.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,e=this._y,r=t.length-1;if(r>0)for(var i,n=t[0],a=e[0],o=t[r]-n,s=e[r]-a,l=-1;++l<=r;)i=l/r,this._basis.point(this._beta*t[l]+(1-this._beta)*(n+i*o),this._beta*e[l]+(1-this._beta)*(a+i*s));this._x=this._y=null,this._basis.lineEnd()},point:function(t,e){this._x.push(+t),this._y.push(+e)}};const Es=function t(e){function r(t){return 1===e?new _s(t):new $s(t,e)}return r.beta=function(e){return t(+e)},r}(.85);function Ds(t,e,r){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-r),t._x2,t._y2)}function Os(t,e){this._context=t,this._k=(1-e)/6}Os.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:Ds(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:Ds(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Rs=function t(e){function r(t){return new Os(t,e)}return r.tension=function(e){return t(+e)},r}(0);function Ks(t,e){this._context=t,this._k=(1-e)/6}Ks.prototype={areaStart:ws,areaEnd:ws,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Ds(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Is=function t(e){function r(t){return new Ks(t,e)}return r.tension=function(e){return t(+e)},r}(0);function Ns(t,e){this._context=t,this._k=(1-e)/6}Ns.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Ds(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const zs=function t(e){function r(t){return new Ns(t,e)}return r.tension=function(e){return t(+e)},r}(0);function Ps(t,e,r){var i=t._x1,n=t._y1,a=t._x2,o=t._y2;if(t._l01_a>Yo){var s=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,l=3*t._l01_a*(t._l01_a+t._l12_a);i=(i*s-t._x0*t._l12_2a+t._x2*t._l01_2a)/l,n=(n*s-t._y0*t._l12_2a+t._y2*t._l01_2a)/l}if(t._l23_a>Yo){var c=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,h=3*t._l23_a*(t._l23_a+t._l12_a);a=(a*c+t._x1*t._l23_2a-e*t._l12_2a)/h,o=(o*c+t._y1*t._l23_2a-r*t._l12_2a)/h}t._context.bezierCurveTo(i,n,a,o,t._x2,t._y2)}function qs(t,e){this._context=t,this._alpha=e}qs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,i=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+i*i,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:Ps(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const js=function t(e){function r(t){return e?new qs(t,e):new Os(t,0)}return r.alpha=function(e){return t(+e)},r}(.5);function Ws(t,e){this._context=t,this._alpha=e}Ws.prototype={areaStart:ws,areaEnd:ws,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,i=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+i*i,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Ps(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Hs=function t(e){function r(t){return e?new Ws(t,e):new Ks(t,0)}return r.alpha=function(e){return t(+e)},r}(.5);function Us(t,e){this._context=t,this._alpha=e}Us.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,i=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+i*i,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Ps(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Ys=function t(e){function r(t){return e?new Us(t,e):new Ns(t,0)}return r.alpha=function(e){return t(+e)},r}(.5);function Gs(t){this._context=t}function Xs(t){return new Gs(t)}function Vs(t){return t<0?-1:1}function Zs(t,e,r){var i=t._x1-t._x0,n=e-t._x1,a=(t._y1-t._y0)/(i||n<0&&-0),o=(r-t._y1)/(n||i<0&&-0),s=(a*n+o*i)/(i+n);return(Vs(a)+Vs(o))*Math.min(Math.abs(a),Math.abs(o),.5*Math.abs(s))||0}function Qs(t,e){var r=t._x1-t._x0;return r?(3*(t._y1-t._y0)/r-e)/2:e}function Js(t,e,r){var i=t._x0,n=t._y0,a=t._x1,o=t._y1,s=(a-i)/3;t._context.bezierCurveTo(i+s,n+s*e,a-s,o-s*r,a,o)}function tl(t){this._context=t}function el(t){this._context=new rl(t)}function rl(t){this._context=t}function il(t){return new tl(t)}function nl(t){return new el(t)}function al(t){this._context=t}function ol(t){var e,r,i=t.length-1,n=new Array(i),a=new Array(i),o=new Array(i);for(n[0]=0,a[0]=2,o[0]=t[0]+2*t[1],e=1;e<i-1;++e)n[e]=1,a[e]=4,o[e]=4*t[e]+2*t[e+1];for(n[i-1]=2,a[i-1]=7,o[i-1]=8*t[i-1]+t[i],e=1;e<i;++e)r=n[e]/a[e-1],a[e]-=r,o[e]-=r*o[e-1];for(n[i-1]=o[i-1]/a[i-1],e=i-2;e>=0;--e)n[e]=(o[e]-n[e+1])/a[e];for(a[i-1]=(t[i]+n[i-1])/2,e=0;e<i-1;++e)a[e]=2*t[e+1]-n[e+1];return[n,a]}function sl(t){return new al(t)}function ll(t,e){this._context=t,this._t=e}function cl(t){return new ll(t,.5)}function hl(t){return new ll(t,0)}function ul(t){return new ll(t,1)}function dl(t,e,r){this.k=t,this.x=e,this.y=r}Gs.prototype={areaStart:ws,areaEnd:ws,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))}},tl.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:Js(this,this._t0,Qs(this,this._t0))}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){var r=NaN;if(e=+e,(t=+t)!==this._x1||e!==this._y1){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,Js(this,Qs(this,r=Zs(this,t,e)),r);break;default:Js(this,this._t0,r=Zs(this,t,e))}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e,this._t0=r}}},(el.prototype=Object.create(tl.prototype)).point=function(t,e){tl.prototype.point.call(this,e,t)},rl.prototype={moveTo:function(t,e){this._context.moveTo(e,t)},closePath:function(){this._context.closePath()},lineTo:function(t,e){this._context.lineTo(e,t)},bezierCurveTo:function(t,e,r,i,n,a){this._context.bezierCurveTo(e,t,i,r,a,n)}},al.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var t=this._x,e=this._y,r=t.length;if(r)if(this._line?this._context.lineTo(t[0],e[0]):this._context.moveTo(t[0],e[0]),2===r)this._context.lineTo(t[1],e[1]);else for(var i=ol(t),n=ol(e),a=0,o=1;o<r;++a,++o)this._context.bezierCurveTo(i[0][a],n[0][a],i[1][a],n[1][a],t[o],e[o]);(this._line||0!==this._line&&1===r)&&this._context.closePath(),this._line=1-this._line,this._x=this._y=null},point:function(t,e){this._x.push(+t),this._y.push(+e)}},ll.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=this._y=NaN,this._point=0},lineEnd:function(){0<this._t&&this._t<1&&2===this._point&&this._context.lineTo(this._x,this._y),(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line>=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var r=this._x*(1-this._t)+t*this._t;this._context.lineTo(r,this._y),this._context.lineTo(r,e)}}this._x=t,this._y=e}},dl.prototype={constructor:dl,scale:function(t){return 1===t?this:new dl(this.k*t,this.x,this.y)},translate:function(t,e){return 0===t&0===e?this:new dl(this.k,this.x+this.k*t,this.y+this.k*e)},apply:function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},applyX:function(t){return t*this.k+this.x},applyY:function(t){return t*this.k+this.y},invert:function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},invertX:function(t){return(t-this.x)/this.k},invertY:function(t){return(t-this.y)/this.k},rescaleX:function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},rescaleY:function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};new dl(1,0,0);dl.prototype},72136:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});const i="object"==typeof global&&global&&global.Object===Object&&global},72453:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});const i={min:{r:0,g:0,b:0,s:0,l:0,a:0},max:{r:255,g:255,b:255,h:360,s:100,l:100,a:1},clamp:{r:t=>t>=255?255:t<0?0:t,g:t=>t>=255?255:t<0?0:t,b:t=>t>=255?255:t<0?0:t,h:t=>t%360,s:t=>t>=100?100:t<0?0:t,l:t=>t>=100?100:t<0?0:t,a:t=>t>=1?1:t<0?0:t},toLinear:t=>{const e=t/255;return t>.03928?Math.pow((e+.055)/1.055,2.4):e/12.92},hue2rgb:(t,e,r)=>(r<0&&(r+=1),r>1&&(r-=1),r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t),hsl2rgb:({h:t,s:e,l:r},n)=>{if(!e)return 2.55*r;t/=360,e/=100;const a=(r/=100)<.5?r*(1+e):r+e-r*e,o=2*r-a;switch(n){case"r":return 255*i.hue2rgb(o,a,t+1/3);case"g":return 255*i.hue2rgb(o,a,t);case"b":return 255*i.hue2rgb(o,a,t-1/3)}},rgb2hsl:({r:t,g:e,b:r},i)=>{t/=255,e/=255,r/=255;const n=Math.max(t,e,r),a=Math.min(t,e,r),o=(n+a)/2;if("l"===i)return 100*o;if(n===a)return 0;const s=n-a;if("s"===i)return 100*(o>.5?s/(2-n-a):s/(n+a));switch(n){case t:return 60*((e-r)/s+(e<r?6:0));case e:return 60*((r-t)/s+2);case r:return 60*((t-e)/s+4);default:return-1}}},n={channel:i,lang:{clamp:(t,e,r)=>e>r?Math.min(e,Math.max(r,t)):Math.min(r,Math.max(e,t)),round:t=>Math.round(1e10*t)/1e10},unit:{dec2hex:t=>{const e=Math.round(t).toString(16);return e.length>1?e:`0${e}`}}}},73590:(t,e,r)=>{"use strict";r.d(e,{D:()=>o});var i=r(67633),n=r(40797),a=r(70451),o=(0,n.K2)(t=>{const{securityLevel:e}=(0,i.D7)();let r=(0,a.Ltv)("body");if("sandbox"===e){const e=(0,a.Ltv)(`#i${t}`),i=e.node()?.contentDocument??document;r=(0,a.Ltv)(i.body)}return r.select(`#${t}`)},"selectSvgElement")},73981:(t,e,r)=>{"use strict";r.d(e,{H:()=>rr,r:()=>er});var i=r(40797);function n(t){return null==t}function a(t){return"object"==typeof t&&null!==t}function o(t){return Array.isArray(t)?t:n(t)?[]:[t]}function s(t,e){var r,i,n,a;if(e)for(r=0,i=(a=Object.keys(e)).length;r<i;r+=1)t[n=a[r]]=e[n];return t}function l(t,e){var r,i="";for(r=0;r<e;r+=1)i+=t;return i}function c(t){return 0===t&&Number.NEGATIVE_INFINITY===1/t}(0,i.K2)(n,"isNothing"),(0,i.K2)(a,"isObject"),(0,i.K2)(o,"toArray"),(0,i.K2)(s,"extend"),(0,i.K2)(l,"repeat"),(0,i.K2)(c,"isNegativeZero");var h={isNothing:n,isObject:a,toArray:o,repeat:l,isNegativeZero:c,extend:s};function u(t,e){var r="",i=t.reason||"(unknown reason)";return t.mark?(t.mark.name&&(r+='in "'+t.mark.name+'" '),r+="("+(t.mark.line+1)+":"+(t.mark.column+1)+")",!e&&t.mark.snippet&&(r+="\n\n"+t.mark.snippet),i+" "+r):i}function d(t,e){Error.call(this),this.name="YAMLException",this.reason=t,this.mark=e,this.message=u(this,!1),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||""}(0,i.K2)(u,"formatError"),(0,i.K2)(d,"YAMLException$1"),d.prototype=Object.create(Error.prototype),d.prototype.constructor=d,d.prototype.toString=(0,i.K2)(function(t){return this.name+": "+u(this,t)},"toString");var p=d;function f(t,e,r,i,n){var a="",o="",s=Math.floor(n/2)-1;return i-e>s&&(e=i-s+(a=" ... ").length),r-i>s&&(r=i+s-(o=" ...").length),{str:a+t.slice(e,r).replace(/\t/g,"\u2192")+o,pos:i-e+a.length}}function g(t,e){return h.repeat(" ",e-t.length)+t}function y(t,e){if(e=Object.create(e||null),!t.buffer)return null;e.maxLength||(e.maxLength=79),"number"!=typeof e.indent&&(e.indent=1),"number"!=typeof e.linesBefore&&(e.linesBefore=3),"number"!=typeof e.linesAfter&&(e.linesAfter=2);for(var r,i=/\r?\n|\r|\0/g,n=[0],a=[],o=-1;r=i.exec(t.buffer);)a.push(r.index),n.push(r.index+r[0].length),t.position<=r.index&&o<0&&(o=n.length-2);o<0&&(o=n.length-1);var s,l,c="",u=Math.min(t.line+e.linesAfter,a.length).toString().length,d=e.maxLength-(e.indent+u+3);for(s=1;s<=e.linesBefore&&!(o-s<0);s++)l=f(t.buffer,n[o-s],a[o-s],t.position-(n[o]-n[o-s]),d),c=h.repeat(" ",e.indent)+g((t.line-s+1).toString(),u)+" | "+l.str+"\n"+c;for(l=f(t.buffer,n[o],a[o],t.position,d),c+=h.repeat(" ",e.indent)+g((t.line+1).toString(),u)+" | "+l.str+"\n",c+=h.repeat("-",e.indent+u+3+l.pos)+"^\n",s=1;s<=e.linesAfter&&!(o+s>=a.length);s++)l=f(t.buffer,n[o+s],a[o+s],t.position-(n[o]-n[o+s]),d),c+=h.repeat(" ",e.indent)+g((t.line+s+1).toString(),u)+" | "+l.str+"\n";return c.replace(/\n$/,"")}(0,i.K2)(f,"getLine"),(0,i.K2)(g,"padStart"),(0,i.K2)(y,"makeSnippet");var m=y,x=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],b=["scalar","sequence","mapping"];function k(t){var e={};return null!==t&&Object.keys(t).forEach(function(r){t[r].forEach(function(t){e[String(t)]=r})}),e}function w(t,e){if(e=e||{},Object.keys(e).forEach(function(e){if(-1===x.indexOf(e))throw new p('Unknown option "'+e+'" is met in definition of "'+t+'" YAML type.')}),this.options=e,this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.representName=e.representName||null,this.defaultStyle=e.defaultStyle||null,this.multi=e.multi||!1,this.styleAliases=k(e.styleAliases||null),-1===b.indexOf(this.kind))throw new p('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')}(0,i.K2)(k,"compileStyleAliases"),(0,i.K2)(w,"Type$1");var C=w;function _(t,e){var r=[];return t[e].forEach(function(t){var e=r.length;r.forEach(function(r,i){r.tag===t.tag&&r.kind===t.kind&&r.multi===t.multi&&(e=i)}),r[e]=t}),r}function v(){var t,e,r={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}};function n(t){t.multi?(r.multi[t.kind].push(t),r.multi.fallback.push(t)):r[t.kind][t.tag]=r.fallback[t.tag]=t}for((0,i.K2)(n,"collectType"),t=0,e=arguments.length;t<e;t+=1)arguments[t].forEach(n);return r}function S(t){return this.extend(t)}(0,i.K2)(_,"compileList"),(0,i.K2)(v,"compileMap"),(0,i.K2)(S,"Schema$1"),S.prototype.extend=(0,i.K2)(function(t){var e=[],r=[];if(t instanceof C)r.push(t);else if(Array.isArray(t))r=r.concat(t);else{if(!t||!Array.isArray(t.implicit)&&!Array.isArray(t.explicit))throw new p("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");t.implicit&&(e=e.concat(t.implicit)),t.explicit&&(r=r.concat(t.explicit))}e.forEach(function(t){if(!(t instanceof C))throw new p("Specified list of YAML types (or a single Type object) contains a non-Type object.");if(t.loadKind&&"scalar"!==t.loadKind)throw new p("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");if(t.multi)throw new p("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.")}),r.forEach(function(t){if(!(t instanceof C))throw new p("Specified list of YAML types (or a single Type object) contains a non-Type object.")});var i=Object.create(S.prototype);return i.implicit=(this.implicit||[]).concat(e),i.explicit=(this.explicit||[]).concat(r),i.compiledImplicit=_(i,"implicit"),i.compiledExplicit=_(i,"explicit"),i.compiledTypeMap=v(i.compiledImplicit,i.compiledExplicit),i},"extend");var T=new S({explicit:[new C("tag:yaml.org,2002:str",{kind:"scalar",construct:(0,i.K2)(function(t){return null!==t?t:""},"construct")}),new C("tag:yaml.org,2002:seq",{kind:"sequence",construct:(0,i.K2)(function(t){return null!==t?t:[]},"construct")}),new C("tag:yaml.org,2002:map",{kind:"mapping",construct:(0,i.K2)(function(t){return null!==t?t:{}},"construct")})]});function A(t){if(null===t)return!0;var e=t.length;return 1===e&&"~"===t||4===e&&("null"===t||"Null"===t||"NULL"===t)}function M(){return null}function B(t){return null===t}(0,i.K2)(A,"resolveYamlNull"),(0,i.K2)(M,"constructYamlNull"),(0,i.K2)(B,"isNull");var L=new C("tag:yaml.org,2002:null",{kind:"scalar",resolve:A,construct:M,predicate:B,represent:{canonical:(0,i.K2)(function(){return"~"},"canonical"),lowercase:(0,i.K2)(function(){return"null"},"lowercase"),uppercase:(0,i.K2)(function(){return"NULL"},"uppercase"),camelcase:(0,i.K2)(function(){return"Null"},"camelcase"),empty:(0,i.K2)(function(){return""},"empty")},defaultStyle:"lowercase"});function F(t){if(null===t)return!1;var e=t.length;return 4===e&&("true"===t||"True"===t||"TRUE"===t)||5===e&&("false"===t||"False"===t||"FALSE"===t)}function $(t){return"true"===t||"True"===t||"TRUE"===t}function E(t){return"[object Boolean]"===Object.prototype.toString.call(t)}(0,i.K2)(F,"resolveYamlBoolean"),(0,i.K2)($,"constructYamlBoolean"),(0,i.K2)(E,"isBoolean");var D=new C("tag:yaml.org,2002:bool",{kind:"scalar",resolve:F,construct:$,predicate:E,represent:{lowercase:(0,i.K2)(function(t){return t?"true":"false"},"lowercase"),uppercase:(0,i.K2)(function(t){return t?"TRUE":"FALSE"},"uppercase"),camelcase:(0,i.K2)(function(t){return t?"True":"False"},"camelcase")},defaultStyle:"lowercase"});function O(t){return 48<=t&&t<=57||65<=t&&t<=70||97<=t&&t<=102}function R(t){return 48<=t&&t<=55}function K(t){return 48<=t&&t<=57}function I(t){if(null===t)return!1;var e,r=t.length,i=0,n=!1;if(!r)return!1;if("-"!==(e=t[i])&&"+"!==e||(e=t[++i]),"0"===e){if(i+1===r)return!0;if("b"===(e=t[++i])){for(i++;i<r;i++)if("_"!==(e=t[i])){if("0"!==e&&"1"!==e)return!1;n=!0}return n&&"_"!==e}if("x"===e){for(i++;i<r;i++)if("_"!==(e=t[i])){if(!O(t.charCodeAt(i)))return!1;n=!0}return n&&"_"!==e}if("o"===e){for(i++;i<r;i++)if("_"!==(e=t[i])){if(!R(t.charCodeAt(i)))return!1;n=!0}return n&&"_"!==e}}if("_"===e)return!1;for(;i<r;i++)if("_"!==(e=t[i])){if(!K(t.charCodeAt(i)))return!1;n=!0}return!(!n||"_"===e)}function N(t){var e,r=t,i=1;if(-1!==r.indexOf("_")&&(r=r.replace(/_/g,"")),"-"!==(e=r[0])&&"+"!==e||("-"===e&&(i=-1),e=(r=r.slice(1))[0]),"0"===r)return 0;if("0"===e){if("b"===r[1])return i*parseInt(r.slice(2),2);if("x"===r[1])return i*parseInt(r.slice(2),16);if("o"===r[1])return i*parseInt(r.slice(2),8)}return i*parseInt(r,10)}function z(t){return"[object Number]"===Object.prototype.toString.call(t)&&t%1==0&&!h.isNegativeZero(t)}(0,i.K2)(O,"isHexCode"),(0,i.K2)(R,"isOctCode"),(0,i.K2)(K,"isDecCode"),(0,i.K2)(I,"resolveYamlInteger"),(0,i.K2)(N,"constructYamlInteger"),(0,i.K2)(z,"isInteger");var P=new C("tag:yaml.org,2002:int",{kind:"scalar",resolve:I,construct:N,predicate:z,represent:{binary:(0,i.K2)(function(t){return t>=0?"0b"+t.toString(2):"-0b"+t.toString(2).slice(1)},"binary"),octal:(0,i.K2)(function(t){return t>=0?"0o"+t.toString(8):"-0o"+t.toString(8).slice(1)},"octal"),decimal:(0,i.K2)(function(t){return t.toString(10)},"decimal"),hexadecimal:(0,i.K2)(function(t){return t>=0?"0x"+t.toString(16).toUpperCase():"-0x"+t.toString(16).toUpperCase().slice(1)},"hexadecimal")},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),q=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");function j(t){return null!==t&&!(!q.test(t)||"_"===t[t.length-1])}function W(t){var e,r;return r="-"===(e=t.replace(/_/g,"").toLowerCase())[0]?-1:1,"+-".indexOf(e[0])>=0&&(e=e.slice(1)),".inf"===e?1===r?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===e?NaN:r*parseFloat(e,10)}(0,i.K2)(j,"resolveYamlFloat"),(0,i.K2)(W,"constructYamlFloat");var H=/^[-+]?[0-9]+e/;function U(t,e){var r;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(h.isNegativeZero(t))return"-0.0";return r=t.toString(10),H.test(r)?r.replace("e",".e"):r}function Y(t){return"[object Number]"===Object.prototype.toString.call(t)&&(t%1!=0||h.isNegativeZero(t))}(0,i.K2)(U,"representYamlFloat"),(0,i.K2)(Y,"isFloat");var G=new C("tag:yaml.org,2002:float",{kind:"scalar",resolve:j,construct:W,predicate:Y,represent:U,defaultStyle:"lowercase"}),X=T.extend({implicit:[L,D,P,G]}),V=X,Z=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),Q=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");function J(t){return null!==t&&(null!==Z.exec(t)||null!==Q.exec(t))}function tt(t){var e,r,i,n,a,o,s,l,c=0,h=null;if(null===(e=Z.exec(t))&&(e=Q.exec(t)),null===e)throw new Error("Date resolve error");if(r=+e[1],i=+e[2]-1,n=+e[3],!e[4])return new Date(Date.UTC(r,i,n));if(a=+e[4],o=+e[5],s=+e[6],e[7]){for(c=e[7].slice(0,3);c.length<3;)c+="0";c=+c}return e[9]&&(h=6e4*(60*+e[10]+ +(e[11]||0)),"-"===e[9]&&(h=-h)),l=new Date(Date.UTC(r,i,n,a,o,s,c)),h&&l.setTime(l.getTime()-h),l}function et(t){return t.toISOString()}(0,i.K2)(J,"resolveYamlTimestamp"),(0,i.K2)(tt,"constructYamlTimestamp"),(0,i.K2)(et,"representYamlTimestamp");var rt=new C("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:J,construct:tt,instanceOf:Date,represent:et});function it(t){return"<<"===t||null===t}(0,i.K2)(it,"resolveYamlMerge");var nt=new C("tag:yaml.org,2002:merge",{kind:"scalar",resolve:it}),at="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";function ot(t){if(null===t)return!1;var e,r,i=0,n=t.length,a=at;for(r=0;r<n;r++)if(!((e=a.indexOf(t.charAt(r)))>64)){if(e<0)return!1;i+=6}return i%8==0}function st(t){var e,r,i=t.replace(/[\r\n=]/g,""),n=i.length,a=at,o=0,s=[];for(e=0;e<n;e++)e%4==0&&e&&(s.push(o>>16&255),s.push(o>>8&255),s.push(255&o)),o=o<<6|a.indexOf(i.charAt(e));return 0===(r=n%4*6)?(s.push(o>>16&255),s.push(o>>8&255),s.push(255&o)):18===r?(s.push(o>>10&255),s.push(o>>2&255)):12===r&&s.push(o>>4&255),new Uint8Array(s)}function lt(t){var e,r,i="",n=0,a=t.length,o=at;for(e=0;e<a;e++)e%3==0&&e&&(i+=o[n>>18&63],i+=o[n>>12&63],i+=o[n>>6&63],i+=o[63&n]),n=(n<<8)+t[e];return 0===(r=a%3)?(i+=o[n>>18&63],i+=o[n>>12&63],i+=o[n>>6&63],i+=o[63&n]):2===r?(i+=o[n>>10&63],i+=o[n>>4&63],i+=o[n<<2&63],i+=o[64]):1===r&&(i+=o[n>>2&63],i+=o[n<<4&63],i+=o[64],i+=o[64]),i}function ct(t){return"[object Uint8Array]"===Object.prototype.toString.call(t)}(0,i.K2)(ot,"resolveYamlBinary"),(0,i.K2)(st,"constructYamlBinary"),(0,i.K2)(lt,"representYamlBinary"),(0,i.K2)(ct,"isBinary");var ht=new C("tag:yaml.org,2002:binary",{kind:"scalar",resolve:ot,construct:st,predicate:ct,represent:lt}),ut=Object.prototype.hasOwnProperty,dt=Object.prototype.toString;function pt(t){if(null===t)return!0;var e,r,i,n,a,o=[],s=t;for(e=0,r=s.length;e<r;e+=1){if(i=s[e],a=!1,"[object Object]"!==dt.call(i))return!1;for(n in i)if(ut.call(i,n)){if(a)return!1;a=!0}if(!a)return!1;if(-1!==o.indexOf(n))return!1;o.push(n)}return!0}function ft(t){return null!==t?t:[]}(0,i.K2)(pt,"resolveYamlOmap"),(0,i.K2)(ft,"constructYamlOmap");var gt=new C("tag:yaml.org,2002:omap",{kind:"sequence",resolve:pt,construct:ft}),yt=Object.prototype.toString;function mt(t){if(null===t)return!0;var e,r,i,n,a,o=t;for(a=new Array(o.length),e=0,r=o.length;e<r;e+=1){if(i=o[e],"[object Object]"!==yt.call(i))return!1;if(1!==(n=Object.keys(i)).length)return!1;a[e]=[n[0],i[n[0]]]}return!0}function xt(t){if(null===t)return[];var e,r,i,n,a,o=t;for(a=new Array(o.length),e=0,r=o.length;e<r;e+=1)i=o[e],n=Object.keys(i),a[e]=[n[0],i[n[0]]];return a}(0,i.K2)(mt,"resolveYamlPairs"),(0,i.K2)(xt,"constructYamlPairs");var bt=new C("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:mt,construct:xt}),kt=Object.prototype.hasOwnProperty;function wt(t){if(null===t)return!0;var e,r=t;for(e in r)if(kt.call(r,e)&&null!==r[e])return!1;return!0}function Ct(t){return null!==t?t:{}}(0,i.K2)(wt,"resolveYamlSet"),(0,i.K2)(Ct,"constructYamlSet");var _t=new C("tag:yaml.org,2002:set",{kind:"mapping",resolve:wt,construct:Ct}),vt=V.extend({implicit:[rt,nt],explicit:[ht,gt,bt,_t]}),St=Object.prototype.hasOwnProperty,Tt=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,At=/[\x85\u2028\u2029]/,Mt=/[,\[\]\{\}]/,Bt=/^(?:!|!!|![a-z\-]+!)$/i,Lt=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function Ft(t){return Object.prototype.toString.call(t)}function $t(t){return 10===t||13===t}function Et(t){return 9===t||32===t}function Dt(t){return 9===t||32===t||10===t||13===t}function Ot(t){return 44===t||91===t||93===t||123===t||125===t}function Rt(t){var e;return 48<=t&&t<=57?t-48:97<=(e=32|t)&&e<=102?e-97+10:-1}function Kt(t){return 120===t?2:117===t?4:85===t?8:0}function It(t){return 48<=t&&t<=57?t-48:-1}function Nt(t){return 48===t?"\0":97===t?"\x07":98===t?"\b":116===t||9===t?"\t":110===t?"\n":118===t?"\v":102===t?"\f":114===t?"\r":101===t?"\x1b":32===t?" ":34===t?'"':47===t?"/":92===t?"\\":78===t?"\x85":95===t?"\xa0":76===t?"\u2028":80===t?"\u2029":""}function zt(t){return t<=65535?String.fromCharCode(t):String.fromCharCode(55296+(t-65536>>10),56320+(t-65536&1023))}(0,i.K2)(Ft,"_class"),(0,i.K2)($t,"is_EOL"),(0,i.K2)(Et,"is_WHITE_SPACE"),(0,i.K2)(Dt,"is_WS_OR_EOL"),(0,i.K2)(Ot,"is_FLOW_INDICATOR"),(0,i.K2)(Rt,"fromHexCode"),(0,i.K2)(Kt,"escapedHexLen"),(0,i.K2)(It,"fromDecimalCode"),(0,i.K2)(Nt,"simpleEscapeSequence"),(0,i.K2)(zt,"charFromCodepoint");var Pt,qt=new Array(256),jt=new Array(256);for(Pt=0;Pt<256;Pt++)qt[Pt]=Nt(Pt)?1:0,jt[Pt]=Nt(Pt);function Wt(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||vt,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function Ht(t,e){var r={name:t.filename,buffer:t.input.slice(0,-1),position:t.position,line:t.line,column:t.position-t.lineStart};return r.snippet=m(r),new p(e,r)}function Ut(t,e){throw Ht(t,e)}function Yt(t,e){t.onWarning&&t.onWarning.call(null,Ht(t,e))}(0,i.K2)(Wt,"State$1"),(0,i.K2)(Ht,"generateError"),(0,i.K2)(Ut,"throwError"),(0,i.K2)(Yt,"throwWarning");var Gt={YAML:(0,i.K2)(function(t,e,r){var i,n,a;null!==t.version&&Ut(t,"duplication of %YAML directive"),1!==r.length&&Ut(t,"YAML directive accepts exactly one argument"),null===(i=/^([0-9]+)\.([0-9]+)$/.exec(r[0]))&&Ut(t,"ill-formed argument of the YAML directive"),n=parseInt(i[1],10),a=parseInt(i[2],10),1!==n&&Ut(t,"unacceptable YAML version of the document"),t.version=r[0],t.checkLineBreaks=a<2,1!==a&&2!==a&&Yt(t,"unsupported YAML version of the document")},"handleYamlDirective"),TAG:(0,i.K2)(function(t,e,r){var i,n;2!==r.length&&Ut(t,"TAG directive accepts exactly two arguments"),i=r[0],n=r[1],Bt.test(i)||Ut(t,"ill-formed tag handle (first argument) of the TAG directive"),St.call(t.tagMap,i)&&Ut(t,'there is a previously declared suffix for "'+i+'" tag handle'),Lt.test(n)||Ut(t,"ill-formed tag prefix (second argument) of the TAG directive");try{n=decodeURIComponent(n)}catch(a){Ut(t,"tag prefix is malformed: "+n)}t.tagMap[i]=n},"handleTagDirective")};function Xt(t,e,r,i){var n,a,o,s;if(e<r){if(s=t.input.slice(e,r),i)for(n=0,a=s.length;n<a;n+=1)9===(o=s.charCodeAt(n))||32<=o&&o<=1114111||Ut(t,"expected valid JSON character");else Tt.test(s)&&Ut(t,"the stream contains non-printable characters");t.result+=s}}function Vt(t,e,r,i){var n,a,o,s;for(h.isObject(r)||Ut(t,"cannot merge mappings; the provided source object is unacceptable"),o=0,s=(n=Object.keys(r)).length;o<s;o+=1)a=n[o],St.call(e,a)||(e[a]=r[a],i[a]=!0)}function Zt(t,e,r,i,n,a,o,s,l){var c,h;if(Array.isArray(n))for(c=0,h=(n=Array.prototype.slice.call(n)).length;c<h;c+=1)Array.isArray(n[c])&&Ut(t,"nested arrays are not supported inside keys"),"object"==typeof n&&"[object Object]"===Ft(n[c])&&(n[c]="[object Object]");if("object"==typeof n&&"[object Object]"===Ft(n)&&(n="[object Object]"),n=String(n),null===e&&(e={}),"tag:yaml.org,2002:merge"===i)if(Array.isArray(a))for(c=0,h=a.length;c<h;c+=1)Vt(t,e,a[c],r);else Vt(t,e,a,r);else t.json||St.call(r,n)||!St.call(e,n)||(t.line=o||t.line,t.lineStart=s||t.lineStart,t.position=l||t.position,Ut(t,"duplicated mapping key")),"__proto__"===n?Object.defineProperty(e,n,{configurable:!0,enumerable:!0,writable:!0,value:a}):e[n]=a,delete r[n];return e}function Qt(t){var e;10===(e=t.input.charCodeAt(t.position))?t.position++:13===e?(t.position++,10===t.input.charCodeAt(t.position)&&t.position++):Ut(t,"a line break is expected"),t.line+=1,t.lineStart=t.position,t.firstTabInLine=-1}function Jt(t,e,r){for(var i=0,n=t.input.charCodeAt(t.position);0!==n;){for(;Et(n);)9===n&&-1===t.firstTabInLine&&(t.firstTabInLine=t.position),n=t.input.charCodeAt(++t.position);if(e&&35===n)do{n=t.input.charCodeAt(++t.position)}while(10!==n&&13!==n&&0!==n);if(!$t(n))break;for(Qt(t),n=t.input.charCodeAt(t.position),i++,t.lineIndent=0;32===n;)t.lineIndent++,n=t.input.charCodeAt(++t.position)}return-1!==r&&0!==i&&t.lineIndent<r&&Yt(t,"deficient indentation"),i}function te(t){var e,r=t.position;return!(45!==(e=t.input.charCodeAt(r))&&46!==e||e!==t.input.charCodeAt(r+1)||e!==t.input.charCodeAt(r+2)||(r+=3,0!==(e=t.input.charCodeAt(r))&&!Dt(e)))}function ee(t,e){1===e?t.result+=" ":e>1&&(t.result+=h.repeat("\n",e-1))}function re(t,e,r){var i,n,a,o,s,l,c,h,u=t.kind,d=t.result;if(Dt(h=t.input.charCodeAt(t.position))||Ot(h)||35===h||38===h||42===h||33===h||124===h||62===h||39===h||34===h||37===h||64===h||96===h)return!1;if((63===h||45===h)&&(Dt(i=t.input.charCodeAt(t.position+1))||r&&Ot(i)))return!1;for(t.kind="scalar",t.result="",n=a=t.position,o=!1;0!==h;){if(58===h){if(Dt(i=t.input.charCodeAt(t.position+1))||r&&Ot(i))break}else if(35===h){if(Dt(t.input.charCodeAt(t.position-1)))break}else{if(t.position===t.lineStart&&te(t)||r&&Ot(h))break;if($t(h)){if(s=t.line,l=t.lineStart,c=t.lineIndent,Jt(t,!1,-1),t.lineIndent>=e){o=!0,h=t.input.charCodeAt(t.position);continue}t.position=a,t.line=s,t.lineStart=l,t.lineIndent=c;break}}o&&(Xt(t,n,a,!1),ee(t,t.line-s),n=a=t.position,o=!1),Et(h)||(a=t.position+1),h=t.input.charCodeAt(++t.position)}return Xt(t,n,a,!1),!!t.result||(t.kind=u,t.result=d,!1)}function ie(t,e){var r,i,n;if(39!==(r=t.input.charCodeAt(t.position)))return!1;for(t.kind="scalar",t.result="",t.position++,i=n=t.position;0!==(r=t.input.charCodeAt(t.position));)if(39===r){if(Xt(t,i,t.position,!0),39!==(r=t.input.charCodeAt(++t.position)))return!0;i=t.position,t.position++,n=t.position}else $t(r)?(Xt(t,i,n,!0),ee(t,Jt(t,!1,e)),i=n=t.position):t.position===t.lineStart&&te(t)?Ut(t,"unexpected end of the document within a single quoted scalar"):(t.position++,n=t.position);Ut(t,"unexpected end of the stream within a single quoted scalar")}function ne(t,e){var r,i,n,a,o,s;if(34!==(s=t.input.charCodeAt(t.position)))return!1;for(t.kind="scalar",t.result="",t.position++,r=i=t.position;0!==(s=t.input.charCodeAt(t.position));){if(34===s)return Xt(t,r,t.position,!0),t.position++,!0;if(92===s){if(Xt(t,r,t.position,!0),$t(s=t.input.charCodeAt(++t.position)))Jt(t,!1,e);else if(s<256&&qt[s])t.result+=jt[s],t.position++;else if((o=Kt(s))>0){for(n=o,a=0;n>0;n--)(o=Rt(s=t.input.charCodeAt(++t.position)))>=0?a=(a<<4)+o:Ut(t,"expected hexadecimal character");t.result+=zt(a),t.position++}else Ut(t,"unknown escape sequence");r=i=t.position}else $t(s)?(Xt(t,r,i,!0),ee(t,Jt(t,!1,e)),r=i=t.position):t.position===t.lineStart&&te(t)?Ut(t,"unexpected end of the document within a double quoted scalar"):(t.position++,i=t.position)}Ut(t,"unexpected end of the stream within a double quoted scalar")}function ae(t,e){var r,i,n,a,o,s,l,c,h,u,d,p,f=!0,g=t.tag,y=t.anchor,m=Object.create(null);if(91===(p=t.input.charCodeAt(t.position)))o=93,c=!1,a=[];else{if(123!==p)return!1;o=125,c=!0,a={}}for(null!==t.anchor&&(t.anchorMap[t.anchor]=a),p=t.input.charCodeAt(++t.position);0!==p;){if(Jt(t,!0,e),(p=t.input.charCodeAt(t.position))===o)return t.position++,t.tag=g,t.anchor=y,t.kind=c?"mapping":"sequence",t.result=a,!0;f?44===p&&Ut(t,"expected the node content, but found ','"):Ut(t,"missed comma between flow collection entries"),d=null,s=l=!1,63===p&&Dt(t.input.charCodeAt(t.position+1))&&(s=l=!0,t.position++,Jt(t,!0,e)),r=t.line,i=t.lineStart,n=t.position,de(t,e,1,!1,!0),u=t.tag,h=t.result,Jt(t,!0,e),p=t.input.charCodeAt(t.position),!l&&t.line!==r||58!==p||(s=!0,p=t.input.charCodeAt(++t.position),Jt(t,!0,e),de(t,e,1,!1,!0),d=t.result),c?Zt(t,a,m,u,h,d,r,i,n):s?a.push(Zt(t,null,m,u,h,d,r,i,n)):a.push(h),Jt(t,!0,e),44===(p=t.input.charCodeAt(t.position))?(f=!0,p=t.input.charCodeAt(++t.position)):f=!1}Ut(t,"unexpected end of the stream within a flow collection")}function oe(t,e){var r,i,n,a,o=1,s=!1,l=!1,c=e,u=0,d=!1;if(124===(a=t.input.charCodeAt(t.position)))i=!1;else{if(62!==a)return!1;i=!0}for(t.kind="scalar",t.result="";0!==a;)if(43===(a=t.input.charCodeAt(++t.position))||45===a)1===o?o=43===a?3:2:Ut(t,"repeat of a chomping mode identifier");else{if(!((n=It(a))>=0))break;0===n?Ut(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):l?Ut(t,"repeat of an indentation width identifier"):(c=e+n-1,l=!0)}if(Et(a)){do{a=t.input.charCodeAt(++t.position)}while(Et(a));if(35===a)do{a=t.input.charCodeAt(++t.position)}while(!$t(a)&&0!==a)}for(;0!==a;){for(Qt(t),t.lineIndent=0,a=t.input.charCodeAt(t.position);(!l||t.lineIndent<c)&&32===a;)t.lineIndent++,a=t.input.charCodeAt(++t.position);if(!l&&t.lineIndent>c&&(c=t.lineIndent),$t(a))u++;else{if(t.lineIndent<c){3===o?t.result+=h.repeat("\n",s?1+u:u):1===o&&s&&(t.result+="\n");break}for(i?Et(a)?(d=!0,t.result+=h.repeat("\n",s?1+u:u)):d?(d=!1,t.result+=h.repeat("\n",u+1)):0===u?s&&(t.result+=" "):t.result+=h.repeat("\n",u):t.result+=h.repeat("\n",s?1+u:u),s=!0,l=!0,u=0,r=t.position;!$t(a)&&0!==a;)a=t.input.charCodeAt(++t.position);Xt(t,r,t.position,!1)}}return!0}function se(t,e){var r,i,n=t.tag,a=t.anchor,o=[],s=!1;if(-1!==t.firstTabInLine)return!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=o),i=t.input.charCodeAt(t.position);0!==i&&(-1!==t.firstTabInLine&&(t.position=t.firstTabInLine,Ut(t,"tab characters must not be used in indentation")),45===i)&&Dt(t.input.charCodeAt(t.position+1));)if(s=!0,t.position++,Jt(t,!0,-1)&&t.lineIndent<=e)o.push(null),i=t.input.charCodeAt(t.position);else if(r=t.line,de(t,e,3,!1,!0),o.push(t.result),Jt(t,!0,-1),i=t.input.charCodeAt(t.position),(t.line===r||t.lineIndent>e)&&0!==i)Ut(t,"bad indentation of a sequence entry");else if(t.lineIndent<e)break;return!!s&&(t.tag=n,t.anchor=a,t.kind="sequence",t.result=o,!0)}function le(t,e,r){var i,n,a,o,s,l,c,h=t.tag,u=t.anchor,d={},p=Object.create(null),f=null,g=null,y=null,m=!1,x=!1;if(-1!==t.firstTabInLine)return!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=d),c=t.input.charCodeAt(t.position);0!==c;){if(m||-1===t.firstTabInLine||(t.position=t.firstTabInLine,Ut(t,"tab characters must not be used in indentation")),i=t.input.charCodeAt(t.position+1),a=t.line,63!==c&&58!==c||!Dt(i)){if(o=t.line,s=t.lineStart,l=t.position,!de(t,r,2,!1,!0))break;if(t.line===a){for(c=t.input.charCodeAt(t.position);Et(c);)c=t.input.charCodeAt(++t.position);if(58===c)Dt(c=t.input.charCodeAt(++t.position))||Ut(t,"a whitespace character is expected after the key-value separator within a block mapping"),m&&(Zt(t,d,p,f,g,null,o,s,l),f=g=y=null),x=!0,m=!1,n=!1,f=t.tag,g=t.result;else{if(!x)return t.tag=h,t.anchor=u,!0;Ut(t,"can not read an implicit mapping pair; a colon is missed")}}else{if(!x)return t.tag=h,t.anchor=u,!0;Ut(t,"can not read a block mapping entry; a multiline key may not be an implicit key")}}else 63===c?(m&&(Zt(t,d,p,f,g,null,o,s,l),f=g=y=null),x=!0,m=!0,n=!0):m?(m=!1,n=!0):Ut(t,"incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line"),t.position+=1,c=i;if((t.line===a||t.lineIndent>e)&&(m&&(o=t.line,s=t.lineStart,l=t.position),de(t,e,4,!0,n)&&(m?g=t.result:y=t.result),m||(Zt(t,d,p,f,g,y,o,s,l),f=g=y=null),Jt(t,!0,-1),c=t.input.charCodeAt(t.position)),(t.line===a||t.lineIndent>e)&&0!==c)Ut(t,"bad indentation of a mapping entry");else if(t.lineIndent<e)break}return m&&Zt(t,d,p,f,g,null,o,s,l),x&&(t.tag=h,t.anchor=u,t.kind="mapping",t.result=d),x}function ce(t){var e,r,i,n,a=!1,o=!1;if(33!==(n=t.input.charCodeAt(t.position)))return!1;if(null!==t.tag&&Ut(t,"duplication of a tag property"),60===(n=t.input.charCodeAt(++t.position))?(a=!0,n=t.input.charCodeAt(++t.position)):33===n?(o=!0,r="!!",n=t.input.charCodeAt(++t.position)):r="!",e=t.position,a){do{n=t.input.charCodeAt(++t.position)}while(0!==n&&62!==n);t.position<t.length?(i=t.input.slice(e,t.position),n=t.input.charCodeAt(++t.position)):Ut(t,"unexpected end of the stream within a verbatim tag")}else{for(;0!==n&&!Dt(n);)33===n&&(o?Ut(t,"tag suffix cannot contain exclamation marks"):(r=t.input.slice(e-1,t.position+1),Bt.test(r)||Ut(t,"named tag handle cannot contain such characters"),o=!0,e=t.position+1)),n=t.input.charCodeAt(++t.position);i=t.input.slice(e,t.position),Mt.test(i)&&Ut(t,"tag suffix cannot contain flow indicator characters")}i&&!Lt.test(i)&&Ut(t,"tag name cannot contain such characters: "+i);try{i=decodeURIComponent(i)}catch(s){Ut(t,"tag name is malformed: "+i)}return a?t.tag=i:St.call(t.tagMap,r)?t.tag=t.tagMap[r]+i:"!"===r?t.tag="!"+i:"!!"===r?t.tag="tag:yaml.org,2002:"+i:Ut(t,'undeclared tag handle "'+r+'"'),!0}function he(t){var e,r;if(38!==(r=t.input.charCodeAt(t.position)))return!1;for(null!==t.anchor&&Ut(t,"duplication of an anchor property"),r=t.input.charCodeAt(++t.position),e=t.position;0!==r&&!Dt(r)&&!Ot(r);)r=t.input.charCodeAt(++t.position);return t.position===e&&Ut(t,"name of an anchor node must contain at least one character"),t.anchor=t.input.slice(e,t.position),!0}function ue(t){var e,r,i;if(42!==(i=t.input.charCodeAt(t.position)))return!1;for(i=t.input.charCodeAt(++t.position),e=t.position;0!==i&&!Dt(i)&&!Ot(i);)i=t.input.charCodeAt(++t.position);return t.position===e&&Ut(t,"name of an alias node must contain at least one character"),r=t.input.slice(e,t.position),St.call(t.anchorMap,r)||Ut(t,'unidentified alias "'+r+'"'),t.result=t.anchorMap[r],Jt(t,!0,-1),!0}function de(t,e,r,i,n){var a,o,s,l,c,h,u,d,p,f=1,g=!1,y=!1;if(null!==t.listener&&t.listener("open",t),t.tag=null,t.anchor=null,t.kind=null,t.result=null,a=o=s=4===r||3===r,i&&Jt(t,!0,-1)&&(g=!0,t.lineIndent>e?f=1:t.lineIndent===e?f=0:t.lineIndent<e&&(f=-1)),1===f)for(;ce(t)||he(t);)Jt(t,!0,-1)?(g=!0,s=a,t.lineIndent>e?f=1:t.lineIndent===e?f=0:t.lineIndent<e&&(f=-1)):s=!1;if(s&&(s=g||n),1!==f&&4!==r||(d=1===r||2===r?e:e+1,p=t.position-t.lineStart,1===f?s&&(se(t,p)||le(t,p,d))||ae(t,d)?y=!0:(o&&oe(t,d)||ie(t,d)||ne(t,d)?y=!0:ue(t)?(y=!0,null===t.tag&&null===t.anchor||Ut(t,"alias node should not have any properties")):re(t,d,1===r)&&(y=!0,null===t.tag&&(t.tag="?")),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):0===f&&(y=s&&se(t,p))),null===t.tag)null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);else if("?"===t.tag){for(null!==t.result&&"scalar"!==t.kind&&Ut(t,'unacceptable node kind for !<?> tag; it should be "scalar", not "'+t.kind+'"'),l=0,c=t.implicitTypes.length;l<c;l+=1)if((u=t.implicitTypes[l]).resolve(t.result)){t.result=u.construct(t.result),t.tag=u.tag,null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);break}}else if("!"!==t.tag){if(St.call(t.typeMap[t.kind||"fallback"],t.tag))u=t.typeMap[t.kind||"fallback"][t.tag];else for(u=null,l=0,c=(h=t.typeMap.multi[t.kind||"fallback"]).length;l<c;l+=1)if(t.tag.slice(0,h[l].tag.length)===h[l].tag){u=h[l];break}u||Ut(t,"unknown tag !<"+t.tag+">"),null!==t.result&&u.kind!==t.kind&&Ut(t,"unacceptable node kind for !<"+t.tag+'> tag; it should be "'+u.kind+'", not "'+t.kind+'"'),u.resolve(t.result,t.tag)?(t.result=u.construct(t.result,t.tag),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):Ut(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")}return null!==t.listener&&t.listener("close",t),null!==t.tag||null!==t.anchor||y}function pe(t){var e,r,i,n,a=t.position,o=!1;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap=Object.create(null),t.anchorMap=Object.create(null);0!==(n=t.input.charCodeAt(t.position))&&(Jt(t,!0,-1),n=t.input.charCodeAt(t.position),!(t.lineIndent>0||37!==n));){for(o=!0,n=t.input.charCodeAt(++t.position),e=t.position;0!==n&&!Dt(n);)n=t.input.charCodeAt(++t.position);for(i=[],(r=t.input.slice(e,t.position)).length<1&&Ut(t,"directive name must not be less than one character in length");0!==n;){for(;Et(n);)n=t.input.charCodeAt(++t.position);if(35===n){do{n=t.input.charCodeAt(++t.position)}while(0!==n&&!$t(n));break}if($t(n))break;for(e=t.position;0!==n&&!Dt(n);)n=t.input.charCodeAt(++t.position);i.push(t.input.slice(e,t.position))}0!==n&&Qt(t),St.call(Gt,r)?Gt[r](t,r,i):Yt(t,'unknown document directive "'+r+'"')}Jt(t,!0,-1),0===t.lineIndent&&45===t.input.charCodeAt(t.position)&&45===t.input.charCodeAt(t.position+1)&&45===t.input.charCodeAt(t.position+2)?(t.position+=3,Jt(t,!0,-1)):o&&Ut(t,"directives end mark is expected"),de(t,t.lineIndent-1,4,!1,!0),Jt(t,!0,-1),t.checkLineBreaks&&At.test(t.input.slice(a,t.position))&&Yt(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&te(t)?46===t.input.charCodeAt(t.position)&&(t.position+=3,Jt(t,!0,-1)):t.position<t.length-1&&Ut(t,"end of the stream or a document separator is expected")}function fe(t,e){e=e||{},0!==(t=String(t)).length&&(10!==t.charCodeAt(t.length-1)&&13!==t.charCodeAt(t.length-1)&&(t+="\n"),65279===t.charCodeAt(0)&&(t=t.slice(1)));var r=new Wt(t,e),i=t.indexOf("\0");for(-1!==i&&(r.position=i,Ut(r,"null byte is not allowed in input")),r.input+="\0";32===r.input.charCodeAt(r.position);)r.lineIndent+=1,r.position+=1;for(;r.position<r.length-1;)pe(r);return r.documents}function ge(t,e,r){null!==e&&"object"==typeof e&&void 0===r&&(r=e,e=null);var i=fe(t,r);if("function"!=typeof e)return i;for(var n=0,a=i.length;n<a;n+=1)e(i[n])}function ye(t,e){var r=fe(t,e);if(0!==r.length){if(1===r.length)return r[0];throw new p("expected a single document in the stream, but found more")}}(0,i.K2)(Xt,"captureSegment"),(0,i.K2)(Vt,"mergeMappings"),(0,i.K2)(Zt,"storeMappingPair"),(0,i.K2)(Qt,"readLineBreak"),(0,i.K2)(Jt,"skipSeparationSpace"),(0,i.K2)(te,"testDocumentSeparator"),(0,i.K2)(ee,"writeFoldedLines"),(0,i.K2)(re,"readPlainScalar"),(0,i.K2)(ie,"readSingleQuotedScalar"),(0,i.K2)(ne,"readDoubleQuotedScalar"),(0,i.K2)(ae,"readFlowCollection"),(0,i.K2)(oe,"readBlockScalar"),(0,i.K2)(se,"readBlockSequence"),(0,i.K2)(le,"readBlockMapping"),(0,i.K2)(ce,"readTagProperty"),(0,i.K2)(he,"readAnchorProperty"),(0,i.K2)(ue,"readAlias"),(0,i.K2)(de,"composeNode"),(0,i.K2)(pe,"readDocument"),(0,i.K2)(fe,"loadDocuments"),(0,i.K2)(ge,"loadAll$1"),(0,i.K2)(ye,"load$1");var me={loadAll:ge,load:ye},xe=Object.prototype.toString,be=Object.prototype.hasOwnProperty,ke=65279,we={0:"\\0",7:"\\a",8:"\\b",9:"\\t",10:"\\n",11:"\\v",12:"\\f",13:"\\r",27:"\\e",34:'\\"',92:"\\\\",133:"\\N",160:"\\_",8232:"\\L",8233:"\\P"},Ce=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"],_e=/^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/;function ve(t,e){var r,i,n,a,o,s,l;if(null===e)return{};for(r={},n=0,a=(i=Object.keys(e)).length;n<a;n+=1)o=i[n],s=String(e[o]),"!!"===o.slice(0,2)&&(o="tag:yaml.org,2002:"+o.slice(2)),(l=t.compiledTypeMap.fallback[o])&&be.call(l.styleAliases,s)&&(s=l.styleAliases[s]),r[o]=s;return r}function Se(t){var e,r,i;if(e=t.toString(16).toUpperCase(),t<=255)r="x",i=2;else if(t<=65535)r="u",i=4;else{if(!(t<=4294967295))throw new p("code point within a string may not be greater than 0xFFFFFFFF");r="U",i=8}return"\\"+r+h.repeat("0",i-e.length)+e}(0,i.K2)(ve,"compileStyleMap"),(0,i.K2)(Se,"encodeHex");function Te(t){this.schema=t.schema||vt,this.indent=Math.max(1,t.indent||2),this.noArrayIndent=t.noArrayIndent||!1,this.skipInvalid=t.skipInvalid||!1,this.flowLevel=h.isNothing(t.flowLevel)?-1:t.flowLevel,this.styleMap=ve(this.schema,t.styles||null),this.sortKeys=t.sortKeys||!1,this.lineWidth=t.lineWidth||80,this.noRefs=t.noRefs||!1,this.noCompatMode=t.noCompatMode||!1,this.condenseFlow=t.condenseFlow||!1,this.quotingType='"'===t.quotingType?2:1,this.forceQuotes=t.forceQuotes||!1,this.replacer="function"==typeof t.replacer?t.replacer:null,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function Ae(t,e){for(var r,i=h.repeat(" ",e),n=0,a=-1,o="",s=t.length;n<s;)-1===(a=t.indexOf("\n",n))?(r=t.slice(n),n=s):(r=t.slice(n,a+1),n=a+1),r.length&&"\n"!==r&&(o+=i),o+=r;return o}function Me(t,e){return"\n"+h.repeat(" ",t.indent*e)}function Be(t,e){var r,i;for(r=0,i=t.implicitTypes.length;r<i;r+=1)if(t.implicitTypes[r].resolve(e))return!0;return!1}function Le(t){return 32===t||9===t}function Fe(t){return 32<=t&&t<=126||161<=t&&t<=55295&&8232!==t&&8233!==t||57344<=t&&t<=65533&&t!==ke||65536<=t&&t<=1114111}function $e(t){return Fe(t)&&t!==ke&&13!==t&&10!==t}function Ee(t,e,r){var i=$e(t),n=i&&!Le(t);return(r?i:i&&44!==t&&91!==t&&93!==t&&123!==t&&125!==t)&&35!==t&&!(58===e&&!n)||$e(e)&&!Le(e)&&35===t||58===e&&n}function De(t){return Fe(t)&&t!==ke&&!Le(t)&&45!==t&&63!==t&&58!==t&&44!==t&&91!==t&&93!==t&&123!==t&&125!==t&&35!==t&&38!==t&&42!==t&&33!==t&&124!==t&&61!==t&&62!==t&&39!==t&&34!==t&&37!==t&&64!==t&&96!==t}function Oe(t){return!Le(t)&&58!==t}function Re(t,e){var r,i=t.charCodeAt(e);return i>=55296&&i<=56319&&e+1<t.length&&(r=t.charCodeAt(e+1))>=56320&&r<=57343?1024*(i-55296)+r-56320+65536:i}function Ke(t){return/^\n* /.test(t)}(0,i.K2)(Te,"State"),(0,i.K2)(Ae,"indentString"),(0,i.K2)(Me,"generateNextLine"),(0,i.K2)(Be,"testImplicitResolving"),(0,i.K2)(Le,"isWhitespace"),(0,i.K2)(Fe,"isPrintable"),(0,i.K2)($e,"isNsCharOrWhitespace"),(0,i.K2)(Ee,"isPlainSafe"),(0,i.K2)(De,"isPlainSafeFirst"),(0,i.K2)(Oe,"isPlainSafeLast"),(0,i.K2)(Re,"codePointAt"),(0,i.K2)(Ke,"needIndentIndicator");function Ie(t,e,r,i,n,a,o,s){var l,c=0,h=null,u=!1,d=!1,p=-1!==i,f=-1,g=De(Re(t,0))&&Oe(Re(t,t.length-1));if(e||o)for(l=0;l<t.length;c>=65536?l+=2:l++){if(!Fe(c=Re(t,l)))return 5;g=g&&Ee(c,h,s),h=c}else{for(l=0;l<t.length;c>=65536?l+=2:l++){if(10===(c=Re(t,l)))u=!0,p&&(d=d||l-f-1>i&&" "!==t[f+1],f=l);else if(!Fe(c))return 5;g=g&&Ee(c,h,s),h=c}d=d||p&&l-f-1>i&&" "!==t[f+1]}return u||d?r>9&&Ke(t)?5:o?2===a?5:2:d?4:3:!g||o||n(t)?2===a?5:2:1}function Ne(t,e,r,n,a){t.dump=function(){if(0===e.length)return 2===t.quotingType?'""':"''";if(!t.noCompatMode&&(-1!==Ce.indexOf(e)||_e.test(e)))return 2===t.quotingType?'"'+e+'"':"'"+e+"'";var o=t.indent*Math.max(1,r),s=-1===t.lineWidth?-1:Math.max(Math.min(t.lineWidth,40),t.lineWidth-o),l=n||t.flowLevel>-1&&r>=t.flowLevel;function c(e){return Be(t,e)}switch((0,i.K2)(c,"testAmbiguity"),Ie(e,l,t.indent,s,c,t.quotingType,t.forceQuotes&&!n,a)){case 1:return e;case 2:return"'"+e.replace(/'/g,"''")+"'";case 3:return"|"+ze(e,t.indent)+Pe(Ae(e,o));case 4:return">"+ze(e,t.indent)+Pe(Ae(qe(e,s),o));case 5:return'"'+We(e)+'"';default:throw new p("impossible error: invalid scalar style")}}()}function ze(t,e){var r=Ke(t)?String(e):"",i="\n"===t[t.length-1];return r+(i&&("\n"===t[t.length-2]||"\n"===t)?"+":i?"":"-")+"\n"}function Pe(t){return"\n"===t[t.length-1]?t.slice(0,-1):t}function qe(t,e){for(var r,i,n,a=/(\n+)([^\n]*)/g,o=(r=-1!==(r=t.indexOf("\n"))?r:t.length,a.lastIndex=r,je(t.slice(0,r),e)),s="\n"===t[0]||" "===t[0];n=a.exec(t);){var l=n[1],c=n[2];i=" "===c[0],o+=l+(s||i||""===c?"":"\n")+je(c,e),s=i}return o}function je(t,e){if(""===t||" "===t[0])return t;for(var r,i,n=/ [^ ]/g,a=0,o=0,s=0,l="";r=n.exec(t);)(s=r.index)-a>e&&(i=o>a?o:s,l+="\n"+t.slice(a,i),a=i+1),o=s;return l+="\n",t.length-a>e&&o>a?l+=t.slice(a,o)+"\n"+t.slice(o+1):l+=t.slice(a),l.slice(1)}function We(t){for(var e,r="",i=0,n=0;n<t.length;i>=65536?n+=2:n++)i=Re(t,n),!(e=we[i])&&Fe(i)?(r+=t[n],i>=65536&&(r+=t[n+1])):r+=e||Se(i);return r}function He(t,e,r){var i,n,a,o="",s=t.tag;for(i=0,n=r.length;i<n;i+=1)a=r[i],t.replacer&&(a=t.replacer.call(r,String(i),a)),(Ve(t,e,a,!1,!1)||void 0===a&&Ve(t,e,null,!1,!1))&&(""!==o&&(o+=","+(t.condenseFlow?"":" ")),o+=t.dump);t.tag=s,t.dump="["+o+"]"}function Ue(t,e,r,i){var n,a,o,s="",l=t.tag;for(n=0,a=r.length;n<a;n+=1)o=r[n],t.replacer&&(o=t.replacer.call(r,String(n),o)),(Ve(t,e+1,o,!0,!0,!1,!0)||void 0===o&&Ve(t,e+1,null,!0,!0,!1,!0))&&(i&&""===s||(s+=Me(t,e)),t.dump&&10===t.dump.charCodeAt(0)?s+="-":s+="- ",s+=t.dump);t.tag=l,t.dump=s||"[]"}function Ye(t,e,r){var i,n,a,o,s,l="",c=t.tag,h=Object.keys(r);for(i=0,n=h.length;i<n;i+=1)s="",""!==l&&(s+=", "),t.condenseFlow&&(s+='"'),o=r[a=h[i]],t.replacer&&(o=t.replacer.call(r,a,o)),Ve(t,e,a,!1,!1)&&(t.dump.length>1024&&(s+="? "),s+=t.dump+(t.condenseFlow?'"':"")+":"+(t.condenseFlow?"":" "),Ve(t,e,o,!1,!1)&&(l+=s+=t.dump));t.tag=c,t.dump="{"+l+"}"}function Ge(t,e,r,i){var n,a,o,s,l,c,h="",u=t.tag,d=Object.keys(r);if(!0===t.sortKeys)d.sort();else if("function"==typeof t.sortKeys)d.sort(t.sortKeys);else if(t.sortKeys)throw new p("sortKeys must be a boolean or a function");for(n=0,a=d.length;n<a;n+=1)c="",i&&""===h||(c+=Me(t,e)),s=r[o=d[n]],t.replacer&&(s=t.replacer.call(r,o,s)),Ve(t,e+1,o,!0,!0,!0)&&((l=null!==t.tag&&"?"!==t.tag||t.dump&&t.dump.length>1024)&&(t.dump&&10===t.dump.charCodeAt(0)?c+="?":c+="? "),c+=t.dump,l&&(c+=Me(t,e)),Ve(t,e+1,s,!0,l)&&(t.dump&&10===t.dump.charCodeAt(0)?c+=":":c+=": ",h+=c+=t.dump));t.tag=u,t.dump=h||"{}"}function Xe(t,e,r){var i,n,a,o,s,l;for(a=0,o=(n=r?t.explicitTypes:t.implicitTypes).length;a<o;a+=1)if(((s=n[a]).instanceOf||s.predicate)&&(!s.instanceOf||"object"==typeof e&&e instanceof s.instanceOf)&&(!s.predicate||s.predicate(e))){if(r?s.multi&&s.representName?t.tag=s.representName(e):t.tag=s.tag:t.tag="?",s.represent){if(l=t.styleMap[s.tag]||s.defaultStyle,"[object Function]"===xe.call(s.represent))i=s.represent(e,l);else{if(!be.call(s.represent,l))throw new p("!<"+s.tag+'> tag resolver accepts not "'+l+'" style');i=s.represent[l](e,l)}t.dump=i}return!0}return!1}function Ve(t,e,r,i,n,a,o){t.tag=null,t.dump=r,Xe(t,r,!1)||Xe(t,r,!0);var s,l=xe.call(t.dump),c=i;i&&(i=t.flowLevel<0||t.flowLevel>e);var h,u,d="[object Object]"===l||"[object Array]"===l;if(d&&(u=-1!==(h=t.duplicates.indexOf(r))),(null!==t.tag&&"?"!==t.tag||u||2!==t.indent&&e>0)&&(n=!1),u&&t.usedDuplicates[h])t.dump="*ref_"+h;else{if(d&&u&&!t.usedDuplicates[h]&&(t.usedDuplicates[h]=!0),"[object Object]"===l)i&&0!==Object.keys(t.dump).length?(Ge(t,e,t.dump,n),u&&(t.dump="&ref_"+h+t.dump)):(Ye(t,e,t.dump),u&&(t.dump="&ref_"+h+" "+t.dump));else if("[object Array]"===l)i&&0!==t.dump.length?(t.noArrayIndent&&!o&&e>0?Ue(t,e-1,t.dump,n):Ue(t,e,t.dump,n),u&&(t.dump="&ref_"+h+t.dump)):(He(t,e,t.dump),u&&(t.dump="&ref_"+h+" "+t.dump));else{if("[object String]"!==l){if("[object Undefined]"===l)return!1;if(t.skipInvalid)return!1;throw new p("unacceptable kind of an object to dump "+l)}"?"!==t.tag&&Ne(t,t.dump,e,a,c)}null!==t.tag&&"?"!==t.tag&&(s=encodeURI("!"===t.tag[0]?t.tag.slice(1):t.tag).replace(/!/g,"%21"),s="!"===t.tag[0]?"!"+s:"tag:yaml.org,2002:"===s.slice(0,18)?"!!"+s.slice(18):"!<"+s+">",t.dump=s+" "+t.dump)}return!0}function Ze(t,e){var r,i,n=[],a=[];for(Qe(t,n,a),r=0,i=a.length;r<i;r+=1)e.duplicates.push(n[a[r]]);e.usedDuplicates=new Array(i)}function Qe(t,e,r){var i,n,a;if(null!==t&&"object"==typeof t)if(-1!==(n=e.indexOf(t)))-1===r.indexOf(n)&&r.push(n);else if(e.push(t),Array.isArray(t))for(n=0,a=t.length;n<a;n+=1)Qe(t[n],e,r);else for(n=0,a=(i=Object.keys(t)).length;n<a;n+=1)Qe(t[i[n]],e,r)}function Je(t,e){var r=new Te(e=e||{});r.noRefs||Ze(t,r);var i=t;return r.replacer&&(i=r.replacer.call({"":i},"",i)),Ve(r,0,i,!0,!0)?r.dump+"\n":""}(0,i.K2)(Ie,"chooseScalarStyle"),(0,i.K2)(Ne,"writeScalar"),(0,i.K2)(ze,"blockHeader"),(0,i.K2)(Pe,"dropEndingNewline"),(0,i.K2)(qe,"foldString"),(0,i.K2)(je,"foldLine"),(0,i.K2)(We,"escapeString"),(0,i.K2)(He,"writeFlowSequence"),(0,i.K2)(Ue,"writeBlockSequence"),(0,i.K2)(Ye,"writeFlowMapping"),(0,i.K2)(Ge,"writeBlockMapping"),(0,i.K2)(Xe,"detectType"),(0,i.K2)(Ve,"writeNode"),(0,i.K2)(Ze,"getDuplicateReferences"),(0,i.K2)(Qe,"inspectNode"),(0,i.K2)(Je,"dump$1");function tr(t,e){return function(){throw new Error("Function yaml."+t+" is removed in js-yaml 4. Use yaml."+e+" instead, which is now safe by default.")}}(0,i.K2)(tr,"renamed");var er=X,rr=me.load;tr("safeLoad","load"),tr("safeLoadAll","loadAll"),tr("safeDump","dump")},74353:function(t){t.exports=function(){"use strict";var t=1e3,e=6e4,r=36e5,i="millisecond",n="second",a="minute",o="hour",s="day",l="week",c="month",h="quarter",u="year",d="date",p="Invalid Date",f=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,g=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,y={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var e=["th","st","nd","rd"],r=t%100;return"["+t+(e[(r-20)%10]||e[r]||e[0])+"]"}},m=function(t,e,r){var i=String(t);return!i||i.length>=e?t:""+Array(e+1-i.length).join(r)+t},x={s:m,z:function(t){var e=-t.utcOffset(),r=Math.abs(e),i=Math.floor(r/60),n=r%60;return(e<=0?"+":"-")+m(i,2,"0")+":"+m(n,2,"0")},m:function t(e,r){if(e.date()<r.date())return-t(r,e);var i=12*(r.year()-e.year())+(r.month()-e.month()),n=e.clone().add(i,c),a=r-n<0,o=e.clone().add(i+(a?-1:1),c);return+(-(i+(r-n)/(a?n-o:o-n))||0)},a:function(t){return t<0?Math.ceil(t)||0:Math.floor(t)},p:function(t){return{M:c,y:u,w:l,d:s,D:d,h:o,m:a,s:n,ms:i,Q:h}[t]||String(t||"").toLowerCase().replace(/s$/,"")},u:function(t){return void 0===t}},b="en",k={};k[b]=y;var w="$isDayjsObject",C=function(t){return t instanceof T||!(!t||!t[w])},_=function t(e,r,i){var n;if(!e)return b;if("string"==typeof e){var a=e.toLowerCase();k[a]&&(n=a),r&&(k[a]=r,n=a);var o=e.split("-");if(!n&&o.length>1)return t(o[0])}else{var s=e.name;k[s]=e,n=s}return!i&&n&&(b=n),n||!i&&b},v=function(t,e){if(C(t))return t.clone();var r="object"==typeof e?e:{};return r.date=t,r.args=arguments,new T(r)},S=x;S.l=_,S.i=C,S.w=function(t,e){return v(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var T=function(){function y(t){this.$L=_(t.locale,null,!0),this.parse(t),this.$x=this.$x||t.x||{},this[w]=!0}var m=y.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,r=t.utc;if(null===e)return new Date(NaN);if(S.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var i=e.match(f);if(i){var n=i[2]-1||0,a=(i[7]||"0").substring(0,3);return r?new Date(Date.UTC(i[1],n,i[3]||1,i[4]||0,i[5]||0,i[6]||0,a)):new Date(i[1],n,i[3]||1,i[4]||0,i[5]||0,i[6]||0,a)}}return new Date(e)}(t),this.init()},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},m.$utils=function(){return S},m.isValid=function(){return!(this.$d.toString()===p)},m.isSame=function(t,e){var r=v(t);return this.startOf(e)<=r&&r<=this.endOf(e)},m.isAfter=function(t,e){return v(t)<this.startOf(e)},m.isBefore=function(t,e){return this.endOf(e)<v(t)},m.$g=function(t,e,r){return S.u(t)?this[e]:this.set(r,t)},m.unix=function(){return Math.floor(this.valueOf()/1e3)},m.valueOf=function(){return this.$d.getTime()},m.startOf=function(t,e){var r=this,i=!!S.u(e)||e,h=S.p(t),p=function(t,e){var n=S.w(r.$u?Date.UTC(r.$y,e,t):new Date(r.$y,e,t),r);return i?n:n.endOf(s)},f=function(t,e){return S.w(r.toDate()[t].apply(r.toDate("s"),(i?[0,0,0,0]:[23,59,59,999]).slice(e)),r)},g=this.$W,y=this.$M,m=this.$D,x="set"+(this.$u?"UTC":"");switch(h){case u:return i?p(1,0):p(31,11);case c:return i?p(1,y):p(0,y+1);case l:var b=this.$locale().weekStart||0,k=(g<b?g+7:g)-b;return p(i?m-k:m+(6-k),y);case s:case d:return f(x+"Hours",0);case o:return f(x+"Minutes",1);case a:return f(x+"Seconds",2);case n:return f(x+"Milliseconds",3);default:return this.clone()}},m.endOf=function(t){return this.startOf(t,!1)},m.$set=function(t,e){var r,l=S.p(t),h="set"+(this.$u?"UTC":""),p=(r={},r[s]=h+"Date",r[d]=h+"Date",r[c]=h+"Month",r[u]=h+"FullYear",r[o]=h+"Hours",r[a]=h+"Minutes",r[n]=h+"Seconds",r[i]=h+"Milliseconds",r)[l],f=l===s?this.$D+(e-this.$W):e;if(l===c||l===u){var g=this.clone().set(d,1);g.$d[p](f),g.init(),this.$d=g.set(d,Math.min(this.$D,g.daysInMonth())).$d}else p&&this.$d[p](f);return this.init(),this},m.set=function(t,e){return this.clone().$set(t,e)},m.get=function(t){return this[S.p(t)]()},m.add=function(i,h){var d,p=this;i=Number(i);var f=S.p(h),g=function(t){var e=v(p);return S.w(e.date(e.date()+Math.round(t*i)),p)};if(f===c)return this.set(c,this.$M+i);if(f===u)return this.set(u,this.$y+i);if(f===s)return g(1);if(f===l)return g(7);var y=(d={},d[a]=e,d[o]=r,d[n]=t,d)[f]||1,m=this.$d.getTime()+i*y;return S.w(m,this)},m.subtract=function(t,e){return this.add(-1*t,e)},m.format=function(t){var e=this,r=this.$locale();if(!this.isValid())return r.invalidDate||p;var i=t||"YYYY-MM-DDTHH:mm:ssZ",n=S.z(this),a=this.$H,o=this.$m,s=this.$M,l=r.weekdays,c=r.months,h=r.meridiem,u=function(t,r,n,a){return t&&(t[r]||t(e,i))||n[r].slice(0,a)},d=function(t){return S.s(a%12||12,t,"0")},f=h||function(t,e,r){var i=t<12?"AM":"PM";return r?i.toLowerCase():i};return i.replace(g,function(t,i){return i||function(t){switch(t){case"YY":return String(e.$y).slice(-2);case"YYYY":return S.s(e.$y,4,"0");case"M":return s+1;case"MM":return S.s(s+1,2,"0");case"MMM":return u(r.monthsShort,s,c,3);case"MMMM":return u(c,s);case"D":return e.$D;case"DD":return S.s(e.$D,2,"0");case"d":return String(e.$W);case"dd":return u(r.weekdaysMin,e.$W,l,2);case"ddd":return u(r.weekdaysShort,e.$W,l,3);case"dddd":return l[e.$W];case"H":return String(a);case"HH":return S.s(a,2,"0");case"h":return d(1);case"hh":return d(2);case"a":return f(a,o,!0);case"A":return f(a,o,!1);case"m":return String(o);case"mm":return S.s(o,2,"0");case"s":return String(e.$s);case"ss":return S.s(e.$s,2,"0");case"SSS":return S.s(e.$ms,3,"0");case"Z":return n}return null}(t)||n.replace(":","")})},m.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},m.diff=function(i,d,p){var f,g=this,y=S.p(d),m=v(i),x=(m.utcOffset()-this.utcOffset())*e,b=this-m,k=function(){return S.m(g,m)};switch(y){case u:f=k()/12;break;case c:f=k();break;case h:f=k()/3;break;case l:f=(b-x)/6048e5;break;case s:f=(b-x)/864e5;break;case o:f=b/r;break;case a:f=b/e;break;case n:f=b/t;break;default:f=b}return p?f:S.a(f)},m.daysInMonth=function(){return this.endOf(c).$D},m.$locale=function(){return k[this.$L]},m.locale=function(t,e){if(!t)return this.$L;var r=this.clone(),i=_(t,e,!0);return i&&(r.$L=i),r},m.clone=function(){return S.w(this.$d,this)},m.toDate=function(){return new Date(this.valueOf())},m.toJSON=function(){return this.isValid()?this.toISOString():null},m.toISOString=function(){return this.$d.toISOString()},m.toString=function(){return this.$d.toUTCString()},y}(),A=T.prototype;return v.prototype=A,[["$ms",i],["$s",n],["$m",a],["$H",o],["$W",s],["$M",c],["$y",u],["$D",d]].forEach(function(t){A[t[1]]=function(e){return this.$g(e,t[0],t[1])}}),v.extend=function(t,e){return t.$i||(t(e,T,v),t.$i=!0),v},v.locale=_,v.isDayjs=C,v.unix=function(t){return v(1e3*t)},v.en=k[b],v.Ls=k,v.p={},v}()},74886:(t,e,r)=>{"use strict";r.d(e,{A:()=>g});var i=r(93539),n=r(63122);const a={re:/^#((?:[a-f0-9]{2}){2,4}|[a-f0-9]{3})$/i,parse:t=>{if(35!==t.charCodeAt(0))return;const e=t.match(a.re);if(!e)return;const r=e[1],n=parseInt(r,16),o=r.length,s=o%4==0,l=o>4,c=l?1:17,h=l?8:4,u=s?0:-1,d=l?255:15;return i.A.set({r:(n>>h*(u+3)&d)*c,g:(n>>h*(u+2)&d)*c,b:(n>>h*(u+1)&d)*c,a:s?(n&d)*c/255:1},t)},stringify:t=>{const{r:e,g:r,b:i,a:a}=t;return a<1?`#${n.Y[Math.round(e)]}${n.Y[Math.round(r)]}${n.Y[Math.round(i)]}${n.Y[Math.round(255*a)]}`:`#${n.Y[Math.round(e)]}${n.Y[Math.round(r)]}${n.Y[Math.round(i)]}`}},o=a;var s=r(72453);const l={re:/^hsla?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(?:deg|grad|rad|turn)?)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(%)?))?\s*?\)$/i,hueRe:/^(.+?)(deg|grad|rad|turn)$/i,_hue2deg:t=>{const e=t.match(l.hueRe);if(e){const[,t,r]=e;switch(r){case"grad":return s.A.channel.clamp.h(.9*parseFloat(t));case"rad":return s.A.channel.clamp.h(180*parseFloat(t)/Math.PI);case"turn":return s.A.channel.clamp.h(360*parseFloat(t))}}return s.A.channel.clamp.h(parseFloat(t))},parse:t=>{const e=t.charCodeAt(0);if(104!==e&&72!==e)return;const r=t.match(l.re);if(!r)return;const[,n,a,o,c,h]=r;return i.A.set({h:l._hue2deg(n),s:s.A.channel.clamp.s(parseFloat(a)),l:s.A.channel.clamp.l(parseFloat(o)),a:c?s.A.channel.clamp.a(h?parseFloat(c)/100:parseFloat(c)):1},t)},stringify:t=>{const{h:e,s:r,l:i,a:n}=t;return n<1?`hsla(${s.A.lang.round(e)}, ${s.A.lang.round(r)}%, ${s.A.lang.round(i)}%, ${n})`:`hsl(${s.A.lang.round(e)}, ${s.A.lang.round(r)}%, ${s.A.lang.round(i)}%)`}},c=l,h={colors:{aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyanaqua:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",transparent:"#00000000",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},parse:t=>{t=t.toLowerCase();const e=h.colors[t];if(e)return o.parse(e)},stringify:t=>{const e=o.stringify(t);for(const r in h.colors)if(h.colors[r]===e)return r}},u=h,d={re:/^rgba?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?)))?\s*?\)$/i,parse:t=>{const e=t.charCodeAt(0);if(114!==e&&82!==e)return;const r=t.match(d.re);if(!r)return;const[,n,a,o,l,c,h,u,p]=r;return i.A.set({r:s.A.channel.clamp.r(a?2.55*parseFloat(n):parseFloat(n)),g:s.A.channel.clamp.g(l?2.55*parseFloat(o):parseFloat(o)),b:s.A.channel.clamp.b(h?2.55*parseFloat(c):parseFloat(c)),a:u?s.A.channel.clamp.a(p?parseFloat(u)/100:parseFloat(u)):1},t)},stringify:t=>{const{r:e,g:r,b:i,a:n}=t;return n<1?`rgba(${s.A.lang.round(e)}, ${s.A.lang.round(r)}, ${s.A.lang.round(i)}, ${s.A.lang.round(n)})`:`rgb(${s.A.lang.round(e)}, ${s.A.lang.round(r)}, ${s.A.lang.round(i)})`}},p=d,f={format:{keyword:h,hex:o,rgb:d,rgba:d,hsl:l,hsla:l},parse:t=>{if("string"!=typeof t)return t;const e=o.parse(t)||p.parse(t)||c.parse(t)||u.parse(t);if(e)return e;throw new Error(`Unsupported color format: "${t}"`)},stringify:t=>!t.changed&&t.color?t.color:t.type.is(n.Z.HSL)||void 0===t.data.r?c.stringify(t):t.a<1||!Number.isInteger(t.r)||!Number.isInteger(t.g)||!Number.isInteger(t.b)?p.stringify(t):o.stringify(t)},g=f},75263:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});var i=r(95635);const n=(t,e)=>(0,i.A)(t,"l",-e)},76875:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});const i=function(t,e,r){switch(r.length){case 0:return t.call(e);case 1:return t.call(e,r[0]);case 2:return t.call(e,r[0],r[1]);case 3:return t.call(e,r[0],r[1],r[2])}return t.apply(e,r)};var n=Math.max;const a=function(t,e,r){return e=n(void 0===e?t.length-1:e,0),function(){for(var a=arguments,o=-1,s=n(a.length-e,0),l=Array(s);++o<s;)l[o]=a[e+o];o=-1;for(var c=Array(e+1);++o<e;)c[o]=a[o];return c[e]=r(l),i(t,this,c)}}},78041:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});var i=r(95635);const n=(t,e)=>(0,i.A)(t,"l",e)},80127:(t,e,r)=>{"use strict";r.d(e,{A:()=>d});const i=function(){this.__data__=[],this.size=0};var n=r(66984);const a=function(t,e){for(var r=t.length;r--;)if((0,n.A)(t[r][0],e))return r;return-1};var o=Array.prototype.splice;const s=function(t){var e=this.__data__,r=a(e,t);return!(r<0)&&(r==e.length-1?e.pop():o.call(e,r,1),--this.size,!0)};const l=function(t){var e=this.__data__,r=a(e,t);return r<0?void 0:e[r][1]};const c=function(t){return a(this.__data__,t)>-1};const h=function(t,e){var r=this.__data__,i=a(r,t);return i<0?(++this.size,r.push([t,e])):r[i][1]=e,this};function u(t){var e=-1,r=null==t?0:t.length;for(this.clear();++e<r;){var i=t[e];this.set(i[0],i[1])}}u.prototype.clear=i,u.prototype.delete=s,u.prototype.get=l,u.prototype.has=c,u.prototype.set=h;const d=u},80154:(t,e,r)=>{"use strict";r.d(e,{A:()=>l});var i=r(41917),n="object"==typeof exports&&exports&&!exports.nodeType&&exports,a=n&&"object"==typeof module&&module&&!module.nodeType&&module,o=a&&a.exports===n?i.A.Buffer:void 0,s=o?o.allocUnsafe:void 0;const l=function(t,e){if(e)return t.slice();var r=t.length,i=s?s(r):new t.constructor(r);return t.copy(i),i}},81121:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});var i=Function.prototype.toString;const n=function(t){if(null!=t){try{return i.call(t)}catch(e){}try{return t+""}catch(e){}}return""}},83607:(t,e,r)=>{"use strict";r.d(e,{A:()=>h});const i=function(t,e){for(var r=-1,i=Array(t);++r<t;)i[r]=e(r);return i};var n=r(52274),a=r(92049),o=r(99912),s=r(25353),l=r(33858),c=Object.prototype.hasOwnProperty;const h=function(t,e){var r=(0,a.A)(t),h=!r&&(0,n.A)(t),u=!r&&!h&&(0,o.A)(t),d=!r&&!h&&!u&&(0,l.A)(t),p=r||h||u||d,f=p?i(t.length,String):[],g=f.length;for(var y in t)!e&&!c.call(t,y)||p&&("length"==y||u&&("offset"==y||"parent"==y)||d&&("buffer"==y||"byteLength"==y||"byteOffset"==y)||(0,s.A)(y,g))||f.push(y);return f}},84171:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});var i=r(18744);const n=function(){try{var t=(0,i.A)(Object,"defineProperty");return t({},"",{}),t}catch(e){}}()},88496:(t,e,r)=>{"use strict";r.d(e,{A:()=>d});var i=r(241),n=Object.prototype,a=n.hasOwnProperty,o=n.toString,s=i.A?i.A.toStringTag:void 0;const l=function(t){var e=a.call(t,s),r=t[s];try{t[s]=void 0;var i=!0}catch(l){}var n=o.call(t);return i&&(e?t[s]=r:delete t[s]),n};var c=Object.prototype.toString;const h=function(t){return c.call(t)};var u=i.A?i.A.toStringTag:void 0;const d=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":u&&u in Object(t)?l(t):h(t)}},89610:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var i=r(88496),n=r(23149);const a=function(t){if(!(0,n.A)(t))return!1;var e=(0,i.A)(t);return"[object Function]"==e||"[object GeneratorFunction]"==e||"[object AsyncFunction]"==e||"[object Proxy]"==e}},90565:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});var i=r(43988);const n=function(t){var e=new t.constructor(t.byteLength);return new i.A(e).set(new i.A(t)),e}},92049:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});const i=Array.isArray},93539:(t,e,r)=>{"use strict";r.d(e,{A:()=>o});var i=r(72453),n=r(63122);const a=class{constructor(){this.type=n.Z.ALL}get(){return this.type}set(t){if(this.type&&this.type!==t)throw new Error("Cannot change both RGB and HSL channels at the same time");this.type=t}reset(){this.type=n.Z.ALL}is(t){return this.type===t}};const o=new class{constructor(t,e){this.color=e,this.changed=!1,this.data=t,this.type=new a}set(t,e){return this.color=e,this.changed=!1,this.data=t,this.type.type=n.Z.ALL,this}_ensureHSL(){const t=this.data,{h:e,s:r,l:n}=t;void 0===e&&(t.h=i.A.channel.rgb2hsl(t,"h")),void 0===r&&(t.s=i.A.channel.rgb2hsl(t,"s")),void 0===n&&(t.l=i.A.channel.rgb2hsl(t,"l"))}_ensureRGB(){const t=this.data,{r:e,g:r,b:n}=t;void 0===e&&(t.r=i.A.channel.hsl2rgb(t,"r")),void 0===r&&(t.g=i.A.channel.hsl2rgb(t,"g")),void 0===n&&(t.b=i.A.channel.hsl2rgb(t,"b"))}get r(){const t=this.data,e=t.r;return this.type.is(n.Z.HSL)||void 0===e?(this._ensureHSL(),i.A.channel.hsl2rgb(t,"r")):e}get g(){const t=this.data,e=t.g;return this.type.is(n.Z.HSL)||void 0===e?(this._ensureHSL(),i.A.channel.hsl2rgb(t,"g")):e}get b(){const t=this.data,e=t.b;return this.type.is(n.Z.HSL)||void 0===e?(this._ensureHSL(),i.A.channel.hsl2rgb(t,"b")):e}get h(){const t=this.data,e=t.h;return this.type.is(n.Z.RGB)||void 0===e?(this._ensureRGB(),i.A.channel.rgb2hsl(t,"h")):e}get s(){const t=this.data,e=t.s;return this.type.is(n.Z.RGB)||void 0===e?(this._ensureRGB(),i.A.channel.rgb2hsl(t,"s")):e}get l(){const t=this.data,e=t.l;return this.type.is(n.Z.RGB)||void 0===e?(this._ensureRGB(),i.A.channel.rgb2hsl(t,"l")):e}get a(){return this.data.a}set r(t){this.type.set(n.Z.RGB),this.changed=!0,this.data.r=t}set g(t){this.type.set(n.Z.RGB),this.changed=!0,this.data.g=t}set b(t){this.type.set(n.Z.RGB),this.changed=!0,this.data.b=t}set h(t){this.type.set(n.Z.HSL),this.changed=!0,this.data.h=t}set s(t){this.type.set(n.Z.HSL),this.changed=!0,this.data.s=t}set l(t){this.type.set(n.Z.HSL),this.changed=!0,this.data.l=t}set a(t){this.changed=!0,this.data.a=t}}({r:0,g:0,b:0,a:0},"transparent")},95635:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var i=r(72453),n=r(74886);const a=(t,e,r)=>{const a=n.A.parse(t),o=a[e],s=i.A.channel.clamp[e](o+r);return o!==s&&(a[e]=s),n.A.stringify(a)}},97271:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});var i=Object.prototype;const n=function(t){var e=t&&t.constructor;return t===("function"==typeof e&&e.prototype||i)}},99418:(t,e,r)=>{"use strict";r.d(e,{A:()=>st});const{entries:i,setPrototypeOf:n,isFrozen:a,getPrototypeOf:o,getOwnPropertyDescriptor:s}=Object;let{freeze:l,seal:c,create:h}=Object,{apply:u,construct:d}="undefined"!=typeof Reflect&&Reflect;l||(l=function(t){return t}),c||(c=function(t){return t}),u||(u=function(t,e){for(var r=arguments.length,i=new Array(r>2?r-2:0),n=2;n<r;n++)i[n-2]=arguments[n];return t.apply(e,i)}),d||(d=function(t){for(var e=arguments.length,r=new Array(e>1?e-1:0),i=1;i<e;i++)r[i-1]=arguments[i];return new t(...r)});const p=M(Array.prototype.forEach),f=M(Array.prototype.lastIndexOf),g=M(Array.prototype.pop),y=M(Array.prototype.push),m=M(Array.prototype.splice),x=M(String.prototype.toLowerCase),b=M(String.prototype.toString),k=M(String.prototype.match),w=M(String.prototype.replace),C=M(String.prototype.indexOf),_=M(String.prototype.trim),v=M(Object.prototype.hasOwnProperty),S=M(RegExp.prototype.test),T=(A=TypeError,function(){for(var t=arguments.length,e=new Array(t),r=0;r<t;r++)e[r]=arguments[r];return d(A,e)});var A;function M(t){return function(e){e instanceof RegExp&&(e.lastIndex=0);for(var r=arguments.length,i=new Array(r>1?r-1:0),n=1;n<r;n++)i[n-1]=arguments[n];return u(t,e,i)}}function B(t,e){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:x;n&&n(t,null);let i=e.length;for(;i--;){let n=e[i];if("string"==typeof n){const t=r(n);t!==n&&(a(e)||(e[i]=t),n=t)}t[n]=!0}return t}function L(t){for(let e=0;e<t.length;e++){v(t,e)||(t[e]=null)}return t}function F(t){const e=h(null);for(const[r,n]of i(t)){v(t,r)&&(Array.isArray(n)?e[r]=L(n):n&&"object"==typeof n&&n.constructor===Object?e[r]=F(n):e[r]=n)}return e}function $(t,e){for(;null!==t;){const r=s(t,e);if(r){if(r.get)return M(r.get);if("function"==typeof r.value)return M(r.value)}t=o(t)}return function(){return null}}const E=l(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","search","section","select","shadow","slot","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),D=l(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","enterkeyhint","exportparts","filter","font","g","glyph","glyphref","hkern","image","inputmode","line","lineargradient","marker","mask","metadata","mpath","part","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),O=l(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),R=l(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),K=l(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),I=l(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),N=l(["#text"]),z=l(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","exportparts","face","for","headers","height","hidden","high","href","hreflang","id","inert","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","part","pattern","placeholder","playsinline","popover","popovertarget","popovertargetaction","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","slot","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","wrap","xmlns","slot"]),P=l(["accent-height","accumulate","additive","alignment-baseline","amplitude","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","exponent","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","intercept","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","mask-type","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","slope","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","tablevalues","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),q=l(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),j=l(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),W=c(/\{\{[\w\W]*|[\w\W]*\}\}/gm),H=c(/<%[\w\W]*|[\w\W]*%>/gm),U=c(/\$\{[\w\W]*/gm),Y=c(/^data-[\-\w.\u00B7-\uFFFF]+$/),G=c(/^aria-[\-\w]+$/),X=c(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),V=c(/^(?:\w+script|data):/i),Z=c(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),Q=c(/^html$/i),J=c(/^[a-z][.\w]*(-[.\w]+)+$/i);var tt=Object.freeze({__proto__:null,ARIA_ATTR:G,ATTR_WHITESPACE:Z,CUSTOM_ELEMENT:J,DATA_ATTR:Y,DOCTYPE_NAME:Q,ERB_EXPR:H,IS_ALLOWED_URI:X,IS_SCRIPT_OR_DATA:V,MUSTACHE_EXPR:W,TMPLIT_EXPR:U});const et=1,rt=3,it=7,nt=8,at=9,ot=function(){return"undefined"==typeof window?null:window};var st=function t(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:ot();const r=e=>t(e);if(r.version="3.3.0",r.removed=[],!e||!e.document||e.document.nodeType!==at||!e.Element)return r.isSupported=!1,r;let{document:n}=e;const a=n,o=a.currentScript,{DocumentFragment:s,HTMLTemplateElement:c,Node:u,Element:d,NodeFilter:A,NamedNodeMap:M=e.NamedNodeMap||e.MozNamedAttrMap,HTMLFormElement:L,DOMParser:W,trustedTypes:H}=e,U=d.prototype,Y=$(U,"cloneNode"),G=$(U,"remove"),V=$(U,"nextSibling"),Z=$(U,"childNodes"),J=$(U,"parentNode");if("function"==typeof c){const t=n.createElement("template");t.content&&t.content.ownerDocument&&(n=t.content.ownerDocument)}let st,lt="";const{implementation:ct,createNodeIterator:ht,createDocumentFragment:ut,getElementsByTagName:dt}=n,{importNode:pt}=a;let ft={afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]};r.isSupported="function"==typeof i&&"function"==typeof J&&ct&&void 0!==ct.createHTMLDocument;const{MUSTACHE_EXPR:gt,ERB_EXPR:yt,TMPLIT_EXPR:mt,DATA_ATTR:xt,ARIA_ATTR:bt,IS_SCRIPT_OR_DATA:kt,ATTR_WHITESPACE:wt,CUSTOM_ELEMENT:Ct}=tt;let{IS_ALLOWED_URI:_t}=tt,vt=null;const St=B({},[...E,...D,...O,...K,...N]);let Tt=null;const At=B({},[...z,...P,...q,...j]);let Mt=Object.seal(h(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),Bt=null,Lt=null;const Ft=Object.seal(h(null,{tagCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeCheck:{writable:!0,configurable:!1,enumerable:!0,value:null}}));let $t=!0,Et=!0,Dt=!1,Ot=!0,Rt=!1,Kt=!0,It=!1,Nt=!1,zt=!1,Pt=!1,qt=!1,jt=!1,Wt=!0,Ht=!1,Ut=!0,Yt=!1,Gt={},Xt=null;const Vt=B({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let Zt=null;const Qt=B({},["audio","video","img","source","image","track"]);let Jt=null;const te=B({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),ee="http://www.w3.org/1998/Math/MathML",re="http://www.w3.org/2000/svg",ie="http://www.w3.org/1999/xhtml";let ne=ie,ae=!1,oe=null;const se=B({},[ee,re,ie],b);let le=B({},["mi","mo","mn","ms","mtext"]),ce=B({},["annotation-xml"]);const he=B({},["title","style","font","a","script"]);let ue=null;const de=["application/xhtml+xml","text/html"];let pe=null,fe=null;const ge=n.createElement("form"),ye=function(t){return t instanceof RegExp||t instanceof Function},me=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!fe||fe!==t){if(t&&"object"==typeof t||(t={}),t=F(t),ue=-1===de.indexOf(t.PARSER_MEDIA_TYPE)?"text/html":t.PARSER_MEDIA_TYPE,pe="application/xhtml+xml"===ue?b:x,vt=v(t,"ALLOWED_TAGS")?B({},t.ALLOWED_TAGS,pe):St,Tt=v(t,"ALLOWED_ATTR")?B({},t.ALLOWED_ATTR,pe):At,oe=v(t,"ALLOWED_NAMESPACES")?B({},t.ALLOWED_NAMESPACES,b):se,Jt=v(t,"ADD_URI_SAFE_ATTR")?B(F(te),t.ADD_URI_SAFE_ATTR,pe):te,Zt=v(t,"ADD_DATA_URI_TAGS")?B(F(Qt),t.ADD_DATA_URI_TAGS,pe):Qt,Xt=v(t,"FORBID_CONTENTS")?B({},t.FORBID_CONTENTS,pe):Vt,Bt=v(t,"FORBID_TAGS")?B({},t.FORBID_TAGS,pe):F({}),Lt=v(t,"FORBID_ATTR")?B({},t.FORBID_ATTR,pe):F({}),Gt=!!v(t,"USE_PROFILES")&&t.USE_PROFILES,$t=!1!==t.ALLOW_ARIA_ATTR,Et=!1!==t.ALLOW_DATA_ATTR,Dt=t.ALLOW_UNKNOWN_PROTOCOLS||!1,Ot=!1!==t.ALLOW_SELF_CLOSE_IN_ATTR,Rt=t.SAFE_FOR_TEMPLATES||!1,Kt=!1!==t.SAFE_FOR_XML,It=t.WHOLE_DOCUMENT||!1,Pt=t.RETURN_DOM||!1,qt=t.RETURN_DOM_FRAGMENT||!1,jt=t.RETURN_TRUSTED_TYPE||!1,zt=t.FORCE_BODY||!1,Wt=!1!==t.SANITIZE_DOM,Ht=t.SANITIZE_NAMED_PROPS||!1,Ut=!1!==t.KEEP_CONTENT,Yt=t.IN_PLACE||!1,_t=t.ALLOWED_URI_REGEXP||X,ne=t.NAMESPACE||ie,le=t.MATHML_TEXT_INTEGRATION_POINTS||le,ce=t.HTML_INTEGRATION_POINTS||ce,Mt=t.CUSTOM_ELEMENT_HANDLING||{},t.CUSTOM_ELEMENT_HANDLING&&ye(t.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(Mt.tagNameCheck=t.CUSTOM_ELEMENT_HANDLING.tagNameCheck),t.CUSTOM_ELEMENT_HANDLING&&ye(t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(Mt.attributeNameCheck=t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),t.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(Mt.allowCustomizedBuiltInElements=t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),Rt&&(Et=!1),qt&&(Pt=!0),Gt&&(vt=B({},N),Tt=[],!0===Gt.html&&(B(vt,E),B(Tt,z)),!0===Gt.svg&&(B(vt,D),B(Tt,P),B(Tt,j)),!0===Gt.svgFilters&&(B(vt,O),B(Tt,P),B(Tt,j)),!0===Gt.mathMl&&(B(vt,K),B(Tt,q),B(Tt,j))),t.ADD_TAGS&&("function"==typeof t.ADD_TAGS?Ft.tagCheck=t.ADD_TAGS:(vt===St&&(vt=F(vt)),B(vt,t.ADD_TAGS,pe))),t.ADD_ATTR&&("function"==typeof t.ADD_ATTR?Ft.attributeCheck=t.ADD_ATTR:(Tt===At&&(Tt=F(Tt)),B(Tt,t.ADD_ATTR,pe))),t.ADD_URI_SAFE_ATTR&&B(Jt,t.ADD_URI_SAFE_ATTR,pe),t.FORBID_CONTENTS&&(Xt===Vt&&(Xt=F(Xt)),B(Xt,t.FORBID_CONTENTS,pe)),Ut&&(vt["#text"]=!0),It&&B(vt,["html","head","body"]),vt.table&&(B(vt,["tbody"]),delete Bt.tbody),t.TRUSTED_TYPES_POLICY){if("function"!=typeof t.TRUSTED_TYPES_POLICY.createHTML)throw T('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof t.TRUSTED_TYPES_POLICY.createScriptURL)throw T('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');st=t.TRUSTED_TYPES_POLICY,lt=st.createHTML("")}else void 0===st&&(st=function(t,e){if("object"!=typeof t||"function"!=typeof t.createPolicy)return null;let r=null;const i="data-tt-policy-suffix";e&&e.hasAttribute(i)&&(r=e.getAttribute(i));const n="dompurify"+(r?"#"+r:"");try{return t.createPolicy(n,{createHTML:t=>t,createScriptURL:t=>t})}catch(a){return console.warn("TrustedTypes policy "+n+" could not be created."),null}}(H,o)),null!==st&&"string"==typeof lt&&(lt=st.createHTML(""));l&&l(t),fe=t}},xe=B({},[...D,...O,...R]),be=B({},[...K,...I]),ke=function(t){y(r.removed,{element:t});try{J(t).removeChild(t)}catch(e){G(t)}},we=function(t,e){try{y(r.removed,{attribute:e.getAttributeNode(t),from:e})}catch(i){y(r.removed,{attribute:null,from:e})}if(e.removeAttribute(t),"is"===t)if(Pt||qt)try{ke(e)}catch(i){}else try{e.setAttribute(t,"")}catch(i){}},Ce=function(t){let e=null,r=null;if(zt)t="<remove></remove>"+t;else{const e=k(t,/^[\r\n\t ]+/);r=e&&e[0]}"application/xhtml+xml"===ue&&ne===ie&&(t='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+t+"</body></html>");const i=st?st.createHTML(t):t;if(ne===ie)try{e=(new W).parseFromString(i,ue)}catch(o){}if(!e||!e.documentElement){e=ct.createDocument(ne,"template",null);try{e.documentElement.innerHTML=ae?lt:i}catch(o){}}const a=e.body||e.documentElement;return t&&r&&a.insertBefore(n.createTextNode(r),a.childNodes[0]||null),ne===ie?dt.call(e,It?"html":"body")[0]:It?e.documentElement:a},_e=function(t){return ht.call(t.ownerDocument||t,t,A.SHOW_ELEMENT|A.SHOW_COMMENT|A.SHOW_TEXT|A.SHOW_PROCESSING_INSTRUCTION|A.SHOW_CDATA_SECTION,null)},ve=function(t){return t instanceof L&&("string"!=typeof t.nodeName||"string"!=typeof t.textContent||"function"!=typeof t.removeChild||!(t.attributes instanceof M)||"function"!=typeof t.removeAttribute||"function"!=typeof t.setAttribute||"string"!=typeof t.namespaceURI||"function"!=typeof t.insertBefore||"function"!=typeof t.hasChildNodes)},Se=function(t){return"function"==typeof u&&t instanceof u};function Te(t,e,i){p(t,t=>{t.call(r,e,i,fe)})}const Ae=function(t){let e=null;if(Te(ft.beforeSanitizeElements,t,null),ve(t))return ke(t),!0;const i=pe(t.nodeName);if(Te(ft.uponSanitizeElement,t,{tagName:i,allowedTags:vt}),Kt&&t.hasChildNodes()&&!Se(t.firstElementChild)&&S(/<[/\w!]/g,t.innerHTML)&&S(/<[/\w!]/g,t.textContent))return ke(t),!0;if(t.nodeType===it)return ke(t),!0;if(Kt&&t.nodeType===nt&&S(/<[/\w]/g,t.data))return ke(t),!0;if(!(Ft.tagCheck instanceof Function&&Ft.tagCheck(i))&&(!vt[i]||Bt[i])){if(!Bt[i]&&Be(i)){if(Mt.tagNameCheck instanceof RegExp&&S(Mt.tagNameCheck,i))return!1;if(Mt.tagNameCheck instanceof Function&&Mt.tagNameCheck(i))return!1}if(Ut&&!Xt[i]){const e=J(t)||t.parentNode,r=Z(t)||t.childNodes;if(r&&e){for(let i=r.length-1;i>=0;--i){const n=Y(r[i],!0);n.__removalCount=(t.__removalCount||0)+1,e.insertBefore(n,V(t))}}}return ke(t),!0}return t instanceof d&&!function(t){let e=J(t);e&&e.tagName||(e={namespaceURI:ne,tagName:"template"});const r=x(t.tagName),i=x(e.tagName);return!!oe[t.namespaceURI]&&(t.namespaceURI===re?e.namespaceURI===ie?"svg"===r:e.namespaceURI===ee?"svg"===r&&("annotation-xml"===i||le[i]):Boolean(xe[r]):t.namespaceURI===ee?e.namespaceURI===ie?"math"===r:e.namespaceURI===re?"math"===r&&ce[i]:Boolean(be[r]):t.namespaceURI===ie?!(e.namespaceURI===re&&!ce[i])&&!(e.namespaceURI===ee&&!le[i])&&!be[r]&&(he[r]||!xe[r]):!("application/xhtml+xml"!==ue||!oe[t.namespaceURI]))}(t)?(ke(t),!0):"noscript"!==i&&"noembed"!==i&&"noframes"!==i||!S(/<\/no(script|embed|frames)/i,t.innerHTML)?(Rt&&t.nodeType===rt&&(e=t.textContent,p([gt,yt,mt],t=>{e=w(e,t," ")}),t.textContent!==e&&(y(r.removed,{element:t.cloneNode()}),t.textContent=e)),Te(ft.afterSanitizeElements,t,null),!1):(ke(t),!0)},Me=function(t,e,r){if(Wt&&("id"===e||"name"===e)&&(r in n||r in ge))return!1;if(Et&&!Lt[e]&&S(xt,e));else if($t&&S(bt,e));else if(Ft.attributeCheck instanceof Function&&Ft.attributeCheck(e,t));else if(!Tt[e]||Lt[e]){if(!(Be(t)&&(Mt.tagNameCheck instanceof RegExp&&S(Mt.tagNameCheck,t)||Mt.tagNameCheck instanceof Function&&Mt.tagNameCheck(t))&&(Mt.attributeNameCheck instanceof RegExp&&S(Mt.attributeNameCheck,e)||Mt.attributeNameCheck instanceof Function&&Mt.attributeNameCheck(e,t))||"is"===e&&Mt.allowCustomizedBuiltInElements&&(Mt.tagNameCheck instanceof RegExp&&S(Mt.tagNameCheck,r)||Mt.tagNameCheck instanceof Function&&Mt.tagNameCheck(r))))return!1}else if(Jt[e]);else if(S(_t,w(r,wt,"")));else if("src"!==e&&"xlink:href"!==e&&"href"!==e||"script"===t||0!==C(r,"data:")||!Zt[t]){if(Dt&&!S(kt,w(r,wt,"")));else if(r)return!1}else;return!0},Be=function(t){return"annotation-xml"!==t&&k(t,Ct)},Le=function(t){Te(ft.beforeSanitizeAttributes,t,null);const{attributes:e}=t;if(!e||ve(t))return;const i={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:Tt,forceKeepAttr:void 0};let n=e.length;for(;n--;){const o=e[n],{name:s,namespaceURI:l,value:c}=o,h=pe(s),u=c;let d="value"===s?u:_(u);if(i.attrName=h,i.attrValue=d,i.keepAttr=!0,i.forceKeepAttr=void 0,Te(ft.uponSanitizeAttribute,t,i),d=i.attrValue,!Ht||"id"!==h&&"name"!==h||(we(s,t),d="user-content-"+d),Kt&&S(/((--!?|])>)|<\/(style|title|textarea)/i,d)){we(s,t);continue}if("attributename"===h&&k(d,"href")){we(s,t);continue}if(i.forceKeepAttr)continue;if(!i.keepAttr){we(s,t);continue}if(!Ot&&S(/\/>/i,d)){we(s,t);continue}Rt&&p([gt,yt,mt],t=>{d=w(d,t," ")});const f=pe(t.nodeName);if(Me(f,h,d)){if(st&&"object"==typeof H&&"function"==typeof H.getAttributeType)if(l);else switch(H.getAttributeType(f,h)){case"TrustedHTML":d=st.createHTML(d);break;case"TrustedScriptURL":d=st.createScriptURL(d)}if(d!==u)try{l?t.setAttributeNS(l,s,d):t.setAttribute(s,d),ve(t)?ke(t):g(r.removed)}catch(a){we(s,t)}}else we(s,t)}Te(ft.afterSanitizeAttributes,t,null)},Fe=function t(e){let r=null;const i=_e(e);for(Te(ft.beforeSanitizeShadowDOM,e,null);r=i.nextNode();)Te(ft.uponSanitizeShadowNode,r,null),Ae(r),Le(r),r.content instanceof s&&t(r.content);Te(ft.afterSanitizeShadowDOM,e,null)};return r.sanitize=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=null,n=null,o=null,l=null;if(ae=!t,ae&&(t="\x3c!--\x3e"),"string"!=typeof t&&!Se(t)){if("function"!=typeof t.toString)throw T("toString is not a function");if("string"!=typeof(t=t.toString()))throw T("dirty is not a string, aborting")}if(!r.isSupported)return t;if(Nt||me(e),r.removed=[],"string"==typeof t&&(Yt=!1),Yt){if(t.nodeName){const e=pe(t.nodeName);if(!vt[e]||Bt[e])throw T("root node is forbidden and cannot be sanitized in-place")}}else if(t instanceof u)i=Ce("\x3c!----\x3e"),n=i.ownerDocument.importNode(t,!0),n.nodeType===et&&"BODY"===n.nodeName||"HTML"===n.nodeName?i=n:i.appendChild(n);else{if(!Pt&&!Rt&&!It&&-1===t.indexOf("<"))return st&&jt?st.createHTML(t):t;if(i=Ce(t),!i)return Pt?null:jt?lt:""}i&&zt&&ke(i.firstChild);const c=_e(Yt?t:i);for(;o=c.nextNode();)Ae(o),Le(o),o.content instanceof s&&Fe(o.content);if(Yt)return t;if(Pt){if(qt)for(l=ut.call(i.ownerDocument);i.firstChild;)l.appendChild(i.firstChild);else l=i;return(Tt.shadowroot||Tt.shadowrootmode)&&(l=pt.call(a,l,!0)),l}let h=It?i.outerHTML:i.innerHTML;return It&&vt["!doctype"]&&i.ownerDocument&&i.ownerDocument.doctype&&i.ownerDocument.doctype.name&&S(Q,i.ownerDocument.doctype.name)&&(h="<!DOCTYPE "+i.ownerDocument.doctype.name+">\n"+h),Rt&&p([gt,yt,mt],t=>{h=w(h,t," ")}),st&&jt?st.createHTML(h):h},r.setConfig=function(){me(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),Nt=!0},r.clearConfig=function(){fe=null,Nt=!1},r.isValidAttribute=function(t,e,r){fe||me({});const i=pe(t),n=pe(e);return Me(i,n,r)},r.addHook=function(t,e){"function"==typeof e&&y(ft[t],e)},r.removeHook=function(t,e){if(void 0!==e){const r=f(ft[t],e);return-1===r?void 0:m(ft[t],r,1)[0]}return g(ft[t])},r.removeHooks=function(t){ft[t]=[]},r.removeAllHooks=function(){ft={afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}},r}()},99912:(t,e,r)=>{"use strict";r.d(e,{A:()=>l});var i=r(41917);const n=function(){return!1};var a="object"==typeof exports&&exports&&!exports.nodeType&&exports,o=a&&"object"==typeof module&&module&&!module.nodeType&&module,s=o&&o.exports===a?i.A.Buffer:void 0;const l=(s?s.isBuffer:void 0)||n}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/2279.aea29fbb.js.LICENSE.txt b/pr-preview/pr-4027/assets/js/2279.aea29fbb.js.LICENSE.txt deleted file mode 100644 index d0090da2e..000000000 --- a/pr-preview/pr-4027/assets/js/2279.aea29fbb.js.LICENSE.txt +++ /dev/null @@ -1 +0,0 @@ -/*! @license DOMPurify 3.3.0 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.3.0/LICENSE */ diff --git a/pr-preview/pr-4027/assets/js/2291.abd3c57a.js b/pr-preview/pr-4027/assets/js/2291.abd3c57a.js deleted file mode 100644 index 9e656c699..000000000 --- a/pr-preview/pr-4027/assets/js/2291.abd3c57a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2291],{21152:(t,e,s)=>{s.d(e,{P:()=>r});var i=s(67633),n=s(40797),r=(0,n.K2)((t,e,s,r)=>{t.attr("class",s);const{width:o,height:l,x:c,y:h}=a(t,e);(0,i.a$)(t,l,o,r);const d=u(c,h,o,l,e);t.attr("viewBox",d),n.Rm.debug(`viewBox configured: ${d} with padding: ${e}`)},"setupViewPortForSVG"),a=(0,n.K2)((t,e)=>{const s=t.node()?.getBBox()||{width:0,height:0,x:0,y:0};return{width:s.width+2*e,height:s.height+2*e,x:s.x,y:s.y}},"calculateDimensionsWithPadding"),u=(0,n.K2)((t,e,s,i,n)=>`${t-n} ${e-n} ${s} ${i}`,"createViewBox")},22291:(t,e,s)=>{s.d(e,{diagram:()=>C});var i=s(52501),n=s(73981),r=s(89625),a=s(21152),u=s(10045),o=(s(5164),s(28698),s(5894)),l=(s(63245),s(32387),s(30092),s(13226)),c=s(67633),h=s(40797),d=s(70451),p=s(25582),g=s(75937),A=class{constructor(){this.vertexCounter=0,this.config=(0,c.D7)(),this.vertices=new Map,this.edges=[],this.classes=new Map,this.subGraphs=[],this.subGraphLookup=new Map,this.tooltips=new Map,this.subCount=0,this.firstGraphFlag=!0,this.secCount=-1,this.posCrossRef=[],this.funs=[],this.setAccTitle=c.SV,this.setAccDescription=c.EI,this.setDiagramTitle=c.ke,this.getAccTitle=c.iN,this.getAccDescription=c.m7,this.getDiagramTitle=c.ab,this.funs.push(this.setupToolTips.bind(this)),this.addVertex=this.addVertex.bind(this),this.firstGraph=this.firstGraph.bind(this),this.setDirection=this.setDirection.bind(this),this.addSubGraph=this.addSubGraph.bind(this),this.addLink=this.addLink.bind(this),this.setLink=this.setLink.bind(this),this.updateLink=this.updateLink.bind(this),this.addClass=this.addClass.bind(this),this.setClass=this.setClass.bind(this),this.destructLink=this.destructLink.bind(this),this.setClickEvent=this.setClickEvent.bind(this),this.setTooltip=this.setTooltip.bind(this),this.updateLinkInterpolate=this.updateLinkInterpolate.bind(this),this.setClickFun=this.setClickFun.bind(this),this.bindFunctions=this.bindFunctions.bind(this),this.lex={firstGraph:this.firstGraph.bind(this)},this.clear(),this.setGen("gen-2")}static{(0,h.K2)(this,"FlowDB")}sanitizeText(t){return c.Y2.sanitizeText(t,this.config)}lookUpDomId(t){for(const e of this.vertices.values())if(e.id===t)return e.domId;return t}addVertex(t,e,s,i,r,a,u={},l){if(!t||0===t.trim().length)return;let h;if(void 0!==l){let t;t=l.includes("\n")?l+"\n":"{\n"+l+"\n}",h=(0,n.H)(t,{schema:n.r})}const d=this.edges.find(e=>e.id===t);if(d){const t=h;return void 0!==t?.animate&&(d.animate=t.animate),void 0!==t?.animation&&(d.animation=t.animation),void(void 0!==t?.curve&&(d.interpolate=t.curve))}let p,g=this.vertices.get(t);if(void 0===g&&(g={id:t,labelType:"text",domId:"flowchart-"+t+"-"+this.vertexCounter,styles:[],classes:[]},this.vertices.set(t,g)),this.vertexCounter++,void 0!==e?(this.config=(0,c.D7)(),p=this.sanitizeText(e.text.trim()),g.labelType=e.type,p.startsWith('"')&&p.endsWith('"')&&(p=p.substring(1,p.length-1)),g.text=p):void 0===g.text&&(g.text=t),void 0!==s&&(g.type=s),null!=i&&i.forEach(t=>{g.styles.push(t)}),null!=r&&r.forEach(t=>{g.classes.push(t)}),void 0!==a&&(g.dir=a),void 0===g.props?g.props=u:void 0!==u&&Object.assign(g.props,u),void 0!==h){if(h.shape){if(h.shape!==h.shape.toLowerCase()||h.shape.includes("_"))throw new Error(`No such shape: ${h.shape}. Shape names should be lowercase.`);if(!(0,o.aP)(h.shape))throw new Error(`No such shape: ${h.shape}.`);g.type=h?.shape}h?.label&&(g.text=h?.label),h?.icon&&(g.icon=h?.icon,h.label?.trim()||g.text!==t||(g.text="")),h?.form&&(g.form=h?.form),h?.pos&&(g.pos=h?.pos),h?.img&&(g.img=h?.img,h.label?.trim()||g.text!==t||(g.text="")),h?.constraint&&(g.constraint=h.constraint),h.w&&(g.assetWidth=Number(h.w)),h.h&&(g.assetHeight=Number(h.h))}}addSingleLink(t,e,s,i){const n={start:t,end:e,type:void 0,text:"",labelType:"text",classes:[],isUserDefinedId:!1,interpolate:this.edges.defaultInterpolate};h.Rm.info("abc78 Got edge...",n);const r=s.text;if(void 0!==r&&(n.text=this.sanitizeText(r.text.trim()),n.text.startsWith('"')&&n.text.endsWith('"')&&(n.text=n.text.substring(1,n.text.length-1)),n.labelType=r.type),void 0!==s&&(n.type=s.type,n.stroke=s.stroke,n.length=s.length>10?10:s.length),i&&!this.edges.some(t=>t.id===i))n.id=i,n.isUserDefinedId=!0;else{const t=this.edges.filter(t=>t.start===n.start&&t.end===n.end);0===t.length?n.id=(0,l.rY)(n.start,n.end,{counter:0,prefix:"L"}):n.id=(0,l.rY)(n.start,n.end,{counter:t.length+1,prefix:"L"})}if(!(this.edges.length<(this.config.maxEdges??500)))throw new Error(`Edge limit exceeded. ${this.edges.length} edges found, but the limit is ${this.config.maxEdges}.\n\nInitialize mermaid with maxEdges set to a higher number to allow more edges.\nYou cannot set this config via configuration inside the diagram as it is a secure config.\nYou have to call mermaid.initialize.`);h.Rm.info("Pushing edge..."),this.edges.push(n)}isLinkData(t){return null!==t&&"object"==typeof t&&"id"in t&&"string"==typeof t.id}addLink(t,e,s){const i=this.isLinkData(s)?s.id.replace("@",""):void 0;h.Rm.info("addLink",t,e,i);for(const n of t)for(const r of e){const a=n===t[t.length-1],u=r===e[0];a&&u?this.addSingleLink(n,r,s,i):this.addSingleLink(n,r,s,void 0)}}updateLinkInterpolate(t,e){t.forEach(t=>{"default"===t?this.edges.defaultInterpolate=e:this.edges[t].interpolate=e})}updateLink(t,e){t.forEach(t=>{if("number"==typeof t&&t>=this.edges.length)throw new Error(`The index ${t} for linkStyle is out of bounds. Valid indices for linkStyle are between 0 and ${this.edges.length-1}. (Help: Ensure that the index is within the range of existing edges.)`);"default"===t?this.edges.defaultStyle=e:(this.edges[t].style=e,(this.edges[t]?.style?.length??0)>0&&!this.edges[t]?.style?.some(t=>t?.startsWith("fill"))&&this.edges[t]?.style?.push("fill:none"))})}addClass(t,e){const s=e.join().replace(/\\,/g,"\xa7\xa7\xa7").replace(/,/g,";").replace(/\xa7\xa7\xa7/g,",").split(";");t.split(",").forEach(t=>{let e=this.classes.get(t);void 0===e&&(e={id:t,styles:[],textStyles:[]},this.classes.set(t,e)),null!=s&&s.forEach(t=>{if(/color/.exec(t)){const s=t.replace("fill","bgFill");e.textStyles.push(s)}e.styles.push(t)})})}setDirection(t){this.direction=t.trim(),/.*</.exec(this.direction)&&(this.direction="RL"),/.*\^/.exec(this.direction)&&(this.direction="BT"),/.*>/.exec(this.direction)&&(this.direction="LR"),/.*v/.exec(this.direction)&&(this.direction="TB"),"TD"===this.direction&&(this.direction="TB")}setClass(t,e){for(const s of t.split(",")){const t=this.vertices.get(s);t&&t.classes.push(e);const i=this.edges.find(t=>t.id===s);i&&i.classes.push(e);const n=this.subGraphLookup.get(s);n&&n.classes.push(e)}}setTooltip(t,e){if(void 0!==e){e=this.sanitizeText(e);for(const s of t.split(","))this.tooltips.set("gen-1"===this.version?this.lookUpDomId(s):s,e)}}setClickFun(t,e,s){const i=this.lookUpDomId(t);if("loose"!==(0,c.D7)().securityLevel)return;if(void 0===e)return;let n=[];if("string"==typeof s){n=s.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t<n.length;t++){let e=n[t].trim();e.startsWith('"')&&e.endsWith('"')&&(e=e.substr(1,e.length-2)),n[t]=e}}0===n.length&&n.push(t);const r=this.vertices.get(t);r&&(r.haveCallback=!0,this.funs.push(()=>{const t=document.querySelector(`[id="${i}"]`);null!==t&&t.addEventListener("click",()=>{l._K.runFunc(e,...n)},!1)}))}setLink(t,e,s){t.split(",").forEach(t=>{const i=this.vertices.get(t);void 0!==i&&(i.link=l._K.formatUrl(e,this.config),i.linkTarget=s)}),this.setClass(t,"clickable")}getTooltip(t){return this.tooltips.get(t)}setClickEvent(t,e,s){t.split(",").forEach(t=>{this.setClickFun(t,e,s)}),this.setClass(t,"clickable")}bindFunctions(t){this.funs.forEach(e=>{e(t)})}getDirection(){return this.direction?.trim()}getVertices(){return this.vertices}getEdges(){return this.edges}getClasses(){return this.classes}setupToolTips(t){let e=(0,d.Ltv)(".mermaidTooltip");null===(e._groups||e)[0][0]&&(e=(0,d.Ltv)("body").append("div").attr("class","mermaidTooltip").style("opacity",0));(0,d.Ltv)(t).select("svg").selectAll("g.node").on("mouseover",t=>{const s=(0,d.Ltv)(t.currentTarget);if(null===s.attr("title"))return;const i=t.currentTarget?.getBoundingClientRect();e.transition().duration(200).style("opacity",".9"),e.text(s.attr("title")).style("left",window.scrollX+i.left+(i.right-i.left)/2+"px").style("top",window.scrollY+i.bottom+"px"),e.html(e.html().replace(/<br\/>/g,"<br/>")),s.classed("hover",!0)}).on("mouseout",t=>{e.transition().duration(500).style("opacity",0);(0,d.Ltv)(t.currentTarget).classed("hover",!1)})}clear(t="gen-2"){this.vertices=new Map,this.classes=new Map,this.edges=[],this.funs=[this.setupToolTips.bind(this)],this.subGraphs=[],this.subGraphLookup=new Map,this.subCount=0,this.tooltips=new Map,this.firstGraphFlag=!0,this.version=t,this.config=(0,c.D7)(),(0,c.IU)()}setGen(t){this.version=t||"gen-2"}defaultStyle(){return"fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"}addSubGraph(t,e,s){let i=t.text.trim(),n=s.text;t===s&&/\s/.exec(s.text)&&(i=void 0);const r=(0,h.K2)(t=>{const e={boolean:{},number:{},string:{}},s=[];let i;return{nodeList:t.filter(function(t){const n=typeof t;return t.stmt&&"dir"===t.stmt?(i=t.value,!1):""!==t.trim()&&(n in e?!e[n].hasOwnProperty(t)&&(e[n][t]=!0):!s.includes(t)&&s.push(t))}),dir:i}},"uniq")(e.flat()),a=r.nodeList;let u=r.dir;const o=(0,c.D7)().flowchart??{};if(u=u??(o.inheritDir?this.getDirection()??(0,c.D7)().direction??void 0:void 0),"gen-1"===this.version)for(let c=0;c<a.length;c++)a[c]=this.lookUpDomId(a[c]);i=i??"subGraph"+this.subCount,n=n||"",n=this.sanitizeText(n),this.subCount=this.subCount+1;const l={id:i,nodes:a,title:n.trim(),classes:[],dir:u,labelType:s.type};return h.Rm.info("Adding",l.id,l.nodes,l.dir),l.nodes=this.makeUniq(l,this.subGraphs).nodes,this.subGraphs.push(l),this.subGraphLookup.set(i,l),i}getPosForId(t){for(const[e,s]of this.subGraphs.entries())if(s.id===t)return e;return-1}indexNodes2(t,e){const s=this.subGraphs[e].nodes;if(this.secCount=this.secCount+1,this.secCount>2e3)return{result:!1,count:0};if(this.posCrossRef[this.secCount]=e,this.subGraphs[e].id===t)return{result:!0,count:0};let i=0,n=1;for(;i<s.length;){const e=this.getPosForId(s[i]);if(e>=0){const s=this.indexNodes2(t,e);if(s.result)return{result:!0,count:n+s.count};n+=s.count}i+=1}return{result:!1,count:n}}getDepthFirstPos(t){return this.posCrossRef[t]}indexNodes(){this.secCount=-1,this.subGraphs.length>0&&this.indexNodes2("none",this.subGraphs.length-1)}getSubGraphs(){return this.subGraphs}firstGraph(){return!!this.firstGraphFlag&&(this.firstGraphFlag=!1,!0)}destructStartLink(t){let e=t.trim(),s="arrow_open";switch(e[0]){case"<":s="arrow_point",e=e.slice(1);break;case"x":s="arrow_cross",e=e.slice(1);break;case"o":s="arrow_circle",e=e.slice(1)}let i="normal";return e.includes("=")&&(i="thick"),e.includes(".")&&(i="dotted"),{type:s,stroke:i}}countChar(t,e){const s=e.length;let i=0;for(let n=0;n<s;++n)e[n]===t&&++i;return i}destructEndLink(t){const e=t.trim();let s=e.slice(0,-1),i="arrow_open";switch(e.slice(-1)){case"x":i="arrow_cross",e.startsWith("x")&&(i="double_"+i,s=s.slice(1));break;case">":i="arrow_point",e.startsWith("<")&&(i="double_"+i,s=s.slice(1));break;case"o":i="arrow_circle",e.startsWith("o")&&(i="double_"+i,s=s.slice(1))}let n="normal",r=s.length-1;s.startsWith("=")&&(n="thick"),s.startsWith("~")&&(n="invisible");const a=this.countChar(".",s);return a&&(n="dotted",r=a),{type:i,stroke:n,length:r}}destructLink(t,e){const s=this.destructEndLink(t);let i;if(e){if(i=this.destructStartLink(e),i.stroke!==s.stroke)return{type:"INVALID",stroke:"INVALID"};if("arrow_open"===i.type)i.type=s.type;else{if(i.type!==s.type)return{type:"INVALID",stroke:"INVALID"};i.type="double_"+i.type}return"double_arrow"===i.type&&(i.type="double_arrow_point"),i.length=s.length,i}return s}exists(t,e){for(const s of t)if(s.nodes.includes(e))return!0;return!1}makeUniq(t,e){const s=[];return t.nodes.forEach((i,n)=>{this.exists(e,i)||s.push(t.nodes[n])}),{nodes:s}}getTypeFromVertex(t){if(t.img)return"imageSquare";if(t.icon)return"circle"===t.form?"iconCircle":"square"===t.form?"iconSquare":"rounded"===t.form?"iconRounded":"icon";switch(t.type){case"square":case void 0:return"squareRect";case"round":return"roundedRect";case"ellipse":return"ellipse";default:return t.type}}findNode(t,e){return t.find(t=>t.id===e)}destructEdgeType(t){let e="none",s="arrow_point";switch(t){case"arrow_point":case"arrow_circle":case"arrow_cross":s=t;break;case"double_arrow_point":case"double_arrow_circle":case"double_arrow_cross":e=t.replace("double_",""),s=e}return{arrowTypeStart:e,arrowTypeEnd:s}}addNodeFromVertex(t,e,s,i,n,r){const a=s.get(t.id),u=i.get(t.id)??!1,o=this.findNode(e,t.id);if(o)o.cssStyles=t.styles,o.cssCompiledStyles=this.getCompiledStyles(t.classes),o.cssClasses=t.classes.join(" ");else{const s={id:t.id,label:t.text,labelStyle:"",parentId:a,padding:n.flowchart?.padding||8,cssStyles:t.styles,cssCompiledStyles:this.getCompiledStyles(["default","node",...t.classes]),cssClasses:"default "+t.classes.join(" "),dir:t.dir,domId:t.domId,look:r,link:t.link,linkTarget:t.linkTarget,tooltip:this.getTooltip(t.id),icon:t.icon,pos:t.pos,img:t.img,assetWidth:t.assetWidth,assetHeight:t.assetHeight,constraint:t.constraint};u?e.push({...s,isGroup:!0,shape:"rect"}):e.push({...s,isGroup:!1,shape:this.getTypeFromVertex(t)})}}getCompiledStyles(t){let e=[];for(const s of t){const t=this.classes.get(s);t?.styles&&(e=[...e,...t.styles??[]].map(t=>t.trim())),t?.textStyles&&(e=[...e,...t.textStyles??[]].map(t=>t.trim()))}return e}getData(){const t=(0,c.D7)(),e=[],s=[],i=this.getSubGraphs(),n=new Map,r=new Map;for(let u=i.length-1;u>=0;u--){const t=i[u];t.nodes.length>0&&r.set(t.id,!0);for(const e of t.nodes)n.set(e,t.id)}for(let u=i.length-1;u>=0;u--){const s=i[u];e.push({id:s.id,label:s.title,labelStyle:"",parentId:n.get(s.id),padding:8,cssCompiledStyles:this.getCompiledStyles(s.classes),cssClasses:s.classes.join(" "),shape:"rect",dir:s.dir,isGroup:!0,look:t.look})}this.getVertices().forEach(s=>{this.addNodeFromVertex(s,e,n,r,t,t.look||"classic")});const a=this.getEdges();return a.forEach((e,i)=>{const{arrowTypeStart:n,arrowTypeEnd:r}=this.destructEdgeType(e.type),u=[...a.defaultStyle??[]];e.style&&u.push(...e.style);const o={id:(0,l.rY)(e.start,e.end,{counter:i,prefix:"L"},e.id),isUserDefinedId:e.isUserDefinedId,start:e.start,end:e.end,type:e.type??"normal",label:e.text,labelpos:"c",thickness:e.stroke,minlen:e.length,classes:"invisible"===e?.stroke?"":"edge-thickness-normal edge-pattern-solid flowchart-link",arrowTypeStart:"invisible"===e?.stroke||"arrow_open"===e?.type?"none":n,arrowTypeEnd:"invisible"===e?.stroke||"arrow_open"===e?.type?"none":r,arrowheadStyle:"fill: #333",cssCompiledStyles:this.getCompiledStyles(e.classes),labelStyle:u,style:u,pattern:e.stroke,look:t.look,animate:e.animate,animation:e.animation,curve:e.interpolate||this.edges.defaultInterpolate||t.flowchart?.curve};s.push(o)}),{nodes:e,edges:s,other:{},config:t}}defaultConfig(){return c.ME.flowchart}},b={getClasses:(0,h.K2)(function(t,e){return e.db.getClasses()},"getClasses"),draw:(0,h.K2)(async function(t,e,s,i){h.Rm.info("REF0:"),h.Rm.info("Drawing state diagram (v2)",e);const{securityLevel:n,flowchart:o,layout:p}=(0,c.D7)();let g;"sandbox"===n&&(g=(0,d.Ltv)("#i"+e));const A="sandbox"===n?g.nodes()[0].contentDocument:document;h.Rm.debug("Before getData: ");const b=i.db.getData();h.Rm.debug("Data: ",b);const y=(0,r.A)(e,n),k=i.db.getDirection();b.type=i.type,b.layoutAlgorithm=(0,u.q7)(p),"dagre"===b.layoutAlgorithm&&"elk"===p&&h.Rm.warn("flowchart-elk was moved to an external package in Mermaid v11. Please refer [release notes](https://github.com/mermaid-js/mermaid/releases/tag/v11.0.0) for more details. This diagram will be rendered using `dagre` layout as a fallback."),b.direction=k,b.nodeSpacing=o?.nodeSpacing||50,b.rankSpacing=o?.rankSpacing||50,b.markers=["point","circle","cross"],b.diagramId=e,h.Rm.debug("REF1:",b),await(0,u.XX)(b,y);const f=b.config.flowchart?.diagramPadding??8;l._K.insertTitle(y,"flowchartTitleText",o?.titleTopMargin||0,i.db.getDiagramTitle()),(0,a.P)(y,f,"flowchart",o?.useMaxWidth||!1);for(const r of b.nodes){const t=(0,d.Ltv)(`#${e} [id="${r.id}"]`);if(!t||!r.link)continue;const s=A.createElementNS("http://www.w3.org/2000/svg","a");s.setAttributeNS("http://www.w3.org/2000/svg","class",r.cssClasses),s.setAttributeNS("http://www.w3.org/2000/svg","rel","noopener"),"sandbox"===n?s.setAttributeNS("http://www.w3.org/2000/svg","target","_top"):r.linkTarget&&s.setAttributeNS("http://www.w3.org/2000/svg","target",r.linkTarget);const i=t.insert(function(){return s},":first-child"),a=t.select(".label-container");a&&i.append(function(){return a.node()});const u=t.select(".label");u&&i.append(function(){return u.node()})}},"draw")},y=function(){var t=(0,h.K2)(function(t,e,s,i){for(s=s||{},i=t.length;i--;s[t[i]]=e);return s},"o"),e=[1,4],s=[1,3],i=[1,5],n=[1,8,9,10,11,27,34,36,38,44,60,84,85,86,87,88,89,102,105,106,109,111,114,115,116,121,122,123,124],r=[2,2],a=[1,13],u=[1,14],o=[1,15],l=[1,16],c=[1,23],d=[1,25],p=[1,26],g=[1,27],A=[1,49],b=[1,48],y=[1,29],k=[1,30],f=[1,31],m=[1,32],E=[1,33],D=[1,44],C=[1,46],x=[1,42],T=[1,47],S=[1,43],F=[1,50],_=[1,45],v=[1,51],B=[1,52],w=[1,34],L=[1,35],$=[1,36],I=[1,37],R=[1,57],N=[1,8,9,10,11,27,32,34,36,38,44,60,84,85,86,87,88,89,102,105,106,109,111,114,115,116,121,122,123,124],P=[1,61],K=[1,60],G=[1,62],O=[8,9,11,75,77,78],V=[1,78],M=[1,91],U=[1,96],W=[1,95],Y=[1,92],j=[1,88],z=[1,94],X=[1,90],H=[1,97],q=[1,93],Q=[1,98],Z=[1,89],J=[8,9,10,11,40,75,77,78],tt=[8,9,10,11,40,46,75,77,78],et=[8,9,10,11,29,40,44,46,48,50,52,54,56,58,60,63,65,67,68,70,75,77,78,89,102,105,106,109,111,114,115,116],st=[8,9,11,44,60,75,77,78,89,102,105,106,109,111,114,115,116],it=[44,60,89,102,105,106,109,111,114,115,116],nt=[1,121],rt=[1,122],at=[1,124],ut=[1,123],ot=[44,60,62,74,89,102,105,106,109,111,114,115,116],lt=[1,133],ct=[1,147],ht=[1,148],dt=[1,149],pt=[1,150],gt=[1,135],At=[1,137],bt=[1,141],yt=[1,142],kt=[1,143],ft=[1,144],mt=[1,145],Et=[1,146],Dt=[1,151],Ct=[1,152],xt=[1,131],Tt=[1,132],St=[1,139],Ft=[1,134],_t=[1,138],vt=[1,136],Bt=[8,9,10,11,27,32,34,36,38,44,60,84,85,86,87,88,89,102,105,106,109,111,114,115,116,121,122,123,124],wt=[1,154],Lt=[1,156],$t=[8,9,11],It=[8,9,10,11,14,44,60,89,105,106,109,111,114,115,116],Rt=[1,176],Nt=[1,172],Pt=[1,173],Kt=[1,177],Gt=[1,174],Ot=[1,175],Vt=[77,116,119],Mt=[8,9,10,11,12,14,27,29,32,44,60,75,84,85,86,87,88,89,90,105,109,111,114,115,116],Ut=[10,106],Wt=[31,49,51,53,55,57,62,64,66,67,69,71,116,117,118],Yt=[1,247],jt=[1,245],zt=[1,249],Xt=[1,243],Ht=[1,244],qt=[1,246],Qt=[1,248],Zt=[1,250],Jt=[1,268],te=[8,9,11,106],ee=[8,9,10,11,60,84,105,106,109,110,111,112],se={trace:(0,h.K2)(function(){},"trace"),yy:{},symbols_:{error:2,start:3,graphConfig:4,document:5,line:6,statement:7,SEMI:8,NEWLINE:9,SPACE:10,EOF:11,GRAPH:12,NODIR:13,DIR:14,FirstStmtSeparator:15,ending:16,endToken:17,spaceList:18,spaceListNewline:19,vertexStatement:20,separator:21,styleStatement:22,linkStyleStatement:23,classDefStatement:24,classStatement:25,clickStatement:26,subgraph:27,textNoTags:28,SQS:29,text:30,SQE:31,end:32,direction:33,acc_title:34,acc_title_value:35,acc_descr:36,acc_descr_value:37,acc_descr_multiline_value:38,shapeData:39,SHAPE_DATA:40,link:41,node:42,styledVertex:43,AMP:44,vertex:45,STYLE_SEPARATOR:46,idString:47,DOUBLECIRCLESTART:48,DOUBLECIRCLEEND:49,PS:50,PE:51,"(-":52,"-)":53,STADIUMSTART:54,STADIUMEND:55,SUBROUTINESTART:56,SUBROUTINEEND:57,VERTEX_WITH_PROPS_START:58,"NODE_STRING[field]":59,COLON:60,"NODE_STRING[value]":61,PIPE:62,CYLINDERSTART:63,CYLINDEREND:64,DIAMOND_START:65,DIAMOND_STOP:66,TAGEND:67,TRAPSTART:68,TRAPEND:69,INVTRAPSTART:70,INVTRAPEND:71,linkStatement:72,arrowText:73,TESTSTR:74,START_LINK:75,edgeText:76,LINK:77,LINK_ID:78,edgeTextToken:79,STR:80,MD_STR:81,textToken:82,keywords:83,STYLE:84,LINKSTYLE:85,CLASSDEF:86,CLASS:87,CLICK:88,DOWN:89,UP:90,textNoTagsToken:91,stylesOpt:92,"idString[vertex]":93,"idString[class]":94,CALLBACKNAME:95,CALLBACKARGS:96,HREF:97,LINK_TARGET:98,"STR[link]":99,"STR[tooltip]":100,alphaNum:101,DEFAULT:102,numList:103,INTERPOLATE:104,NUM:105,COMMA:106,style:107,styleComponent:108,NODE_STRING:109,UNIT:110,BRKT:111,PCT:112,idStringToken:113,MINUS:114,MULT:115,UNICODE_TEXT:116,TEXT:117,TAGSTART:118,EDGE_TEXT:119,alphaNumToken:120,direction_tb:121,direction_bt:122,direction_rl:123,direction_lr:124,$accept:0,$end:1},terminals_:{2:"error",8:"SEMI",9:"NEWLINE",10:"SPACE",11:"EOF",12:"GRAPH",13:"NODIR",14:"DIR",27:"subgraph",29:"SQS",31:"SQE",32:"end",34:"acc_title",35:"acc_title_value",36:"acc_descr",37:"acc_descr_value",38:"acc_descr_multiline_value",40:"SHAPE_DATA",44:"AMP",46:"STYLE_SEPARATOR",48:"DOUBLECIRCLESTART",49:"DOUBLECIRCLEEND",50:"PS",51:"PE",52:"(-",53:"-)",54:"STADIUMSTART",55:"STADIUMEND",56:"SUBROUTINESTART",57:"SUBROUTINEEND",58:"VERTEX_WITH_PROPS_START",59:"NODE_STRING[field]",60:"COLON",61:"NODE_STRING[value]",62:"PIPE",63:"CYLINDERSTART",64:"CYLINDEREND",65:"DIAMOND_START",66:"DIAMOND_STOP",67:"TAGEND",68:"TRAPSTART",69:"TRAPEND",70:"INVTRAPSTART",71:"INVTRAPEND",74:"TESTSTR",75:"START_LINK",77:"LINK",78:"LINK_ID",80:"STR",81:"MD_STR",84:"STYLE",85:"LINKSTYLE",86:"CLASSDEF",87:"CLASS",88:"CLICK",89:"DOWN",90:"UP",93:"idString[vertex]",94:"idString[class]",95:"CALLBACKNAME",96:"CALLBACKARGS",97:"HREF",98:"LINK_TARGET",99:"STR[link]",100:"STR[tooltip]",102:"DEFAULT",104:"INTERPOLATE",105:"NUM",106:"COMMA",109:"NODE_STRING",110:"UNIT",111:"BRKT",112:"PCT",114:"MINUS",115:"MULT",116:"UNICODE_TEXT",117:"TEXT",118:"TAGSTART",119:"EDGE_TEXT",121:"direction_tb",122:"direction_bt",123:"direction_rl",124:"direction_lr"},productions_:[0,[3,2],[5,0],[5,2],[6,1],[6,1],[6,1],[6,1],[6,1],[4,2],[4,2],[4,2],[4,3],[16,2],[16,1],[17,1],[17,1],[17,1],[15,1],[15,1],[15,2],[19,2],[19,2],[19,1],[19,1],[18,2],[18,1],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,9],[7,6],[7,4],[7,1],[7,2],[7,2],[7,1],[21,1],[21,1],[21,1],[39,2],[39,1],[20,4],[20,3],[20,4],[20,2],[20,2],[20,1],[42,1],[42,6],[42,5],[43,1],[43,3],[45,4],[45,4],[45,6],[45,4],[45,4],[45,4],[45,8],[45,4],[45,4],[45,4],[45,6],[45,4],[45,4],[45,4],[45,4],[45,4],[45,1],[41,2],[41,3],[41,3],[41,1],[41,3],[41,4],[76,1],[76,2],[76,1],[76,1],[72,1],[72,2],[73,3],[30,1],[30,2],[30,1],[30,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[28,1],[28,2],[28,1],[28,1],[24,5],[25,5],[26,2],[26,4],[26,3],[26,5],[26,3],[26,5],[26,5],[26,7],[26,2],[26,4],[26,2],[26,4],[26,4],[26,6],[22,5],[23,5],[23,5],[23,9],[23,9],[23,7],[23,7],[103,1],[103,3],[92,1],[92,3],[107,1],[107,2],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[82,1],[82,1],[82,1],[82,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[79,1],[79,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[47,1],[47,2],[101,1],[101,2],[33,1],[33,1],[33,1],[33,1]],performAction:(0,h.K2)(function(t,e,s,i,n,r,a){var u=r.length-1;switch(n){case 2:case 28:case 29:case 30:case 31:case 32:this.$=[];break;case 3:(!Array.isArray(r[u])||r[u].length>0)&&r[u-1].push(r[u]),this.$=r[u-1];break;case 4:case 183:case 44:case 54:case 76:case 181:this.$=r[u];break;case 11:i.setDirection("TB"),this.$="TB";break;case 12:i.setDirection(r[u-1]),this.$=r[u-1];break;case 27:this.$=r[u-1].nodes;break;case 33:this.$=i.addSubGraph(r[u-6],r[u-1],r[u-4]);break;case 34:this.$=i.addSubGraph(r[u-3],r[u-1],r[u-3]);break;case 35:this.$=i.addSubGraph(void 0,r[u-1],void 0);break;case 37:this.$=r[u].trim(),i.setAccTitle(this.$);break;case 38:case 39:this.$=r[u].trim(),i.setAccDescription(this.$);break;case 43:case 133:this.$=r[u-1]+r[u];break;case 45:i.addVertex(r[u-1][r[u-1].length-1],void 0,void 0,void 0,void 0,void 0,void 0,r[u]),i.addLink(r[u-3].stmt,r[u-1],r[u-2]),this.$={stmt:r[u-1],nodes:r[u-1].concat(r[u-3].nodes)};break;case 46:i.addLink(r[u-2].stmt,r[u],r[u-1]),this.$={stmt:r[u],nodes:r[u].concat(r[u-2].nodes)};break;case 47:i.addLink(r[u-3].stmt,r[u-1],r[u-2]),this.$={stmt:r[u-1],nodes:r[u-1].concat(r[u-3].nodes)};break;case 48:this.$={stmt:r[u-1],nodes:r[u-1]};break;case 49:i.addVertex(r[u-1][r[u-1].length-1],void 0,void 0,void 0,void 0,void 0,void 0,r[u]),this.$={stmt:r[u-1],nodes:r[u-1],shapeData:r[u]};break;case 50:this.$={stmt:r[u],nodes:r[u]};break;case 51:case 128:case 130:this.$=[r[u]];break;case 52:i.addVertex(r[u-5][r[u-5].length-1],void 0,void 0,void 0,void 0,void 0,void 0,r[u-4]),this.$=r[u-5].concat(r[u]);break;case 53:this.$=r[u-4].concat(r[u]);break;case 55:this.$=r[u-2],i.setClass(r[u-2],r[u]);break;case 56:this.$=r[u-3],i.addVertex(r[u-3],r[u-1],"square");break;case 57:this.$=r[u-3],i.addVertex(r[u-3],r[u-1],"doublecircle");break;case 58:this.$=r[u-5],i.addVertex(r[u-5],r[u-2],"circle");break;case 59:this.$=r[u-3],i.addVertex(r[u-3],r[u-1],"ellipse");break;case 60:this.$=r[u-3],i.addVertex(r[u-3],r[u-1],"stadium");break;case 61:this.$=r[u-3],i.addVertex(r[u-3],r[u-1],"subroutine");break;case 62:this.$=r[u-7],i.addVertex(r[u-7],r[u-1],"rect",void 0,void 0,void 0,Object.fromEntries([[r[u-5],r[u-3]]]));break;case 63:this.$=r[u-3],i.addVertex(r[u-3],r[u-1],"cylinder");break;case 64:this.$=r[u-3],i.addVertex(r[u-3],r[u-1],"round");break;case 65:this.$=r[u-3],i.addVertex(r[u-3],r[u-1],"diamond");break;case 66:this.$=r[u-5],i.addVertex(r[u-5],r[u-2],"hexagon");break;case 67:this.$=r[u-3],i.addVertex(r[u-3],r[u-1],"odd");break;case 68:this.$=r[u-3],i.addVertex(r[u-3],r[u-1],"trapezoid");break;case 69:this.$=r[u-3],i.addVertex(r[u-3],r[u-1],"inv_trapezoid");break;case 70:this.$=r[u-3],i.addVertex(r[u-3],r[u-1],"lean_right");break;case 71:this.$=r[u-3],i.addVertex(r[u-3],r[u-1],"lean_left");break;case 72:this.$=r[u],i.addVertex(r[u]);break;case 73:r[u-1].text=r[u],this.$=r[u-1];break;case 74:case 75:r[u-2].text=r[u-1],this.$=r[u-2];break;case 77:var o=i.destructLink(r[u],r[u-2]);this.$={type:o.type,stroke:o.stroke,length:o.length,text:r[u-1]};break;case 78:o=i.destructLink(r[u],r[u-2]);this.$={type:o.type,stroke:o.stroke,length:o.length,text:r[u-1],id:r[u-3]};break;case 79:case 86:case 101:case 103:this.$={text:r[u],type:"text"};break;case 80:case 87:case 102:this.$={text:r[u-1].text+""+r[u],type:r[u-1].type};break;case 81:case 88:this.$={text:r[u],type:"string"};break;case 82:case 89:case 104:this.$={text:r[u],type:"markdown"};break;case 83:o=i.destructLink(r[u]);this.$={type:o.type,stroke:o.stroke,length:o.length};break;case 84:o=i.destructLink(r[u]);this.$={type:o.type,stroke:o.stroke,length:o.length,id:r[u-1]};break;case 85:this.$=r[u-1];break;case 105:this.$=r[u-4],i.addClass(r[u-2],r[u]);break;case 106:this.$=r[u-4],i.setClass(r[u-2],r[u]);break;case 107:case 115:this.$=r[u-1],i.setClickEvent(r[u-1],r[u]);break;case 108:case 116:this.$=r[u-3],i.setClickEvent(r[u-3],r[u-2]),i.setTooltip(r[u-3],r[u]);break;case 109:this.$=r[u-2],i.setClickEvent(r[u-2],r[u-1],r[u]);break;case 110:this.$=r[u-4],i.setClickEvent(r[u-4],r[u-3],r[u-2]),i.setTooltip(r[u-4],r[u]);break;case 111:this.$=r[u-2],i.setLink(r[u-2],r[u]);break;case 112:this.$=r[u-4],i.setLink(r[u-4],r[u-2]),i.setTooltip(r[u-4],r[u]);break;case 113:this.$=r[u-4],i.setLink(r[u-4],r[u-2],r[u]);break;case 114:this.$=r[u-6],i.setLink(r[u-6],r[u-4],r[u]),i.setTooltip(r[u-6],r[u-2]);break;case 117:this.$=r[u-1],i.setLink(r[u-1],r[u]);break;case 118:this.$=r[u-3],i.setLink(r[u-3],r[u-2]),i.setTooltip(r[u-3],r[u]);break;case 119:this.$=r[u-3],i.setLink(r[u-3],r[u-2],r[u]);break;case 120:this.$=r[u-5],i.setLink(r[u-5],r[u-4],r[u]),i.setTooltip(r[u-5],r[u-2]);break;case 121:this.$=r[u-4],i.addVertex(r[u-2],void 0,void 0,r[u]);break;case 122:this.$=r[u-4],i.updateLink([r[u-2]],r[u]);break;case 123:this.$=r[u-4],i.updateLink(r[u-2],r[u]);break;case 124:this.$=r[u-8],i.updateLinkInterpolate([r[u-6]],r[u-2]),i.updateLink([r[u-6]],r[u]);break;case 125:this.$=r[u-8],i.updateLinkInterpolate(r[u-6],r[u-2]),i.updateLink(r[u-6],r[u]);break;case 126:this.$=r[u-6],i.updateLinkInterpolate([r[u-4]],r[u]);break;case 127:this.$=r[u-6],i.updateLinkInterpolate(r[u-4],r[u]);break;case 129:case 131:r[u-2].push(r[u]),this.$=r[u-2];break;case 182:case 184:this.$=r[u-1]+""+r[u];break;case 185:this.$={stmt:"dir",value:"TB"};break;case 186:this.$={stmt:"dir",value:"BT"};break;case 187:this.$={stmt:"dir",value:"RL"};break;case 188:this.$={stmt:"dir",value:"LR"}}},"anonymous"),table:[{3:1,4:2,9:e,10:s,12:i},{1:[3]},t(n,r,{5:6}),{4:7,9:e,10:s,12:i},{4:8,9:e,10:s,12:i},{13:[1,9],14:[1,10]},{1:[2,1],6:11,7:12,8:a,9:u,10:o,11:l,20:17,22:18,23:19,24:20,25:21,26:22,27:c,33:24,34:d,36:p,38:g,42:28,43:38,44:A,45:39,47:40,60:b,84:y,85:k,86:f,87:m,88:E,89:D,102:C,105:x,106:T,109:S,111:F,113:41,114:_,115:v,116:B,121:w,122:L,123:$,124:I},t(n,[2,9]),t(n,[2,10]),t(n,[2,11]),{8:[1,54],9:[1,55],10:R,15:53,18:56},t(N,[2,3]),t(N,[2,4]),t(N,[2,5]),t(N,[2,6]),t(N,[2,7]),t(N,[2,8]),{8:P,9:K,11:G,21:58,41:59,72:63,75:[1,64],77:[1,66],78:[1,65]},{8:P,9:K,11:G,21:67},{8:P,9:K,11:G,21:68},{8:P,9:K,11:G,21:69},{8:P,9:K,11:G,21:70},{8:P,9:K,11:G,21:71},{8:P,9:K,10:[1,72],11:G,21:73},t(N,[2,36]),{35:[1,74]},{37:[1,75]},t(N,[2,39]),t(O,[2,50],{18:76,39:77,10:R,40:V}),{10:[1,79]},{10:[1,80]},{10:[1,81]},{10:[1,82]},{14:M,44:U,60:W,80:[1,86],89:Y,95:[1,83],97:[1,84],101:85,105:j,106:z,109:X,111:H,114:q,115:Q,116:Z,120:87},t(N,[2,185]),t(N,[2,186]),t(N,[2,187]),t(N,[2,188]),t(J,[2,51]),t(J,[2,54],{46:[1,99]}),t(tt,[2,72],{113:112,29:[1,100],44:A,48:[1,101],50:[1,102],52:[1,103],54:[1,104],56:[1,105],58:[1,106],60:b,63:[1,107],65:[1,108],67:[1,109],68:[1,110],70:[1,111],89:D,102:C,105:x,106:T,109:S,111:F,114:_,115:v,116:B}),t(et,[2,181]),t(et,[2,142]),t(et,[2,143]),t(et,[2,144]),t(et,[2,145]),t(et,[2,146]),t(et,[2,147]),t(et,[2,148]),t(et,[2,149]),t(et,[2,150]),t(et,[2,151]),t(et,[2,152]),t(n,[2,12]),t(n,[2,18]),t(n,[2,19]),{9:[1,113]},t(st,[2,26],{18:114,10:R}),t(N,[2,27]),{42:115,43:38,44:A,45:39,47:40,60:b,89:D,102:C,105:x,106:T,109:S,111:F,113:41,114:_,115:v,116:B},t(N,[2,40]),t(N,[2,41]),t(N,[2,42]),t(it,[2,76],{73:116,62:[1,118],74:[1,117]}),{76:119,79:120,80:nt,81:rt,116:at,119:ut},{75:[1,125],77:[1,126]},t(ot,[2,83]),t(N,[2,28]),t(N,[2,29]),t(N,[2,30]),t(N,[2,31]),t(N,[2,32]),{10:lt,12:ct,14:ht,27:dt,28:127,32:pt,44:gt,60:At,75:bt,80:[1,129],81:[1,130],83:140,84:yt,85:kt,86:ft,87:mt,88:Et,89:Dt,90:Ct,91:128,105:xt,109:Tt,111:St,114:Ft,115:_t,116:vt},t(Bt,r,{5:153}),t(N,[2,37]),t(N,[2,38]),t(O,[2,48],{44:wt}),t(O,[2,49],{18:155,10:R,40:Lt}),t(J,[2,44]),{44:A,47:157,60:b,89:D,102:C,105:x,106:T,109:S,111:F,113:41,114:_,115:v,116:B},{102:[1,158],103:159,105:[1,160]},{44:A,47:161,60:b,89:D,102:C,105:x,106:T,109:S,111:F,113:41,114:_,115:v,116:B},{44:A,47:162,60:b,89:D,102:C,105:x,106:T,109:S,111:F,113:41,114:_,115:v,116:B},t($t,[2,107],{10:[1,163],96:[1,164]}),{80:[1,165]},t($t,[2,115],{120:167,10:[1,166],14:M,44:U,60:W,89:Y,105:j,106:z,109:X,111:H,114:q,115:Q,116:Z}),t($t,[2,117],{10:[1,168]}),t(It,[2,183]),t(It,[2,170]),t(It,[2,171]),t(It,[2,172]),t(It,[2,173]),t(It,[2,174]),t(It,[2,175]),t(It,[2,176]),t(It,[2,177]),t(It,[2,178]),t(It,[2,179]),t(It,[2,180]),{44:A,47:169,60:b,89:D,102:C,105:x,106:T,109:S,111:F,113:41,114:_,115:v,116:B},{30:170,67:Rt,80:Nt,81:Pt,82:171,116:Kt,117:Gt,118:Ot},{30:178,67:Rt,80:Nt,81:Pt,82:171,116:Kt,117:Gt,118:Ot},{30:180,50:[1,179],67:Rt,80:Nt,81:Pt,82:171,116:Kt,117:Gt,118:Ot},{30:181,67:Rt,80:Nt,81:Pt,82:171,116:Kt,117:Gt,118:Ot},{30:182,67:Rt,80:Nt,81:Pt,82:171,116:Kt,117:Gt,118:Ot},{30:183,67:Rt,80:Nt,81:Pt,82:171,116:Kt,117:Gt,118:Ot},{109:[1,184]},{30:185,67:Rt,80:Nt,81:Pt,82:171,116:Kt,117:Gt,118:Ot},{30:186,65:[1,187],67:Rt,80:Nt,81:Pt,82:171,116:Kt,117:Gt,118:Ot},{30:188,67:Rt,80:Nt,81:Pt,82:171,116:Kt,117:Gt,118:Ot},{30:189,67:Rt,80:Nt,81:Pt,82:171,116:Kt,117:Gt,118:Ot},{30:190,67:Rt,80:Nt,81:Pt,82:171,116:Kt,117:Gt,118:Ot},t(et,[2,182]),t(n,[2,20]),t(st,[2,25]),t(O,[2,46],{39:191,18:192,10:R,40:V}),t(it,[2,73],{10:[1,193]}),{10:[1,194]},{30:195,67:Rt,80:Nt,81:Pt,82:171,116:Kt,117:Gt,118:Ot},{77:[1,196],79:197,116:at,119:ut},t(Vt,[2,79]),t(Vt,[2,81]),t(Vt,[2,82]),t(Vt,[2,168]),t(Vt,[2,169]),{76:198,79:120,80:nt,81:rt,116:at,119:ut},t(ot,[2,84]),{8:P,9:K,10:lt,11:G,12:ct,14:ht,21:200,27:dt,29:[1,199],32:pt,44:gt,60:At,75:bt,83:140,84:yt,85:kt,86:ft,87:mt,88:Et,89:Dt,90:Ct,91:201,105:xt,109:Tt,111:St,114:Ft,115:_t,116:vt},t(Mt,[2,101]),t(Mt,[2,103]),t(Mt,[2,104]),t(Mt,[2,157]),t(Mt,[2,158]),t(Mt,[2,159]),t(Mt,[2,160]),t(Mt,[2,161]),t(Mt,[2,162]),t(Mt,[2,163]),t(Mt,[2,164]),t(Mt,[2,165]),t(Mt,[2,166]),t(Mt,[2,167]),t(Mt,[2,90]),t(Mt,[2,91]),t(Mt,[2,92]),t(Mt,[2,93]),t(Mt,[2,94]),t(Mt,[2,95]),t(Mt,[2,96]),t(Mt,[2,97]),t(Mt,[2,98]),t(Mt,[2,99]),t(Mt,[2,100]),{6:11,7:12,8:a,9:u,10:o,11:l,20:17,22:18,23:19,24:20,25:21,26:22,27:c,32:[1,202],33:24,34:d,36:p,38:g,42:28,43:38,44:A,45:39,47:40,60:b,84:y,85:k,86:f,87:m,88:E,89:D,102:C,105:x,106:T,109:S,111:F,113:41,114:_,115:v,116:B,121:w,122:L,123:$,124:I},{10:R,18:203},{44:[1,204]},t(J,[2,43]),{10:[1,205],44:A,60:b,89:D,102:C,105:x,106:T,109:S,111:F,113:112,114:_,115:v,116:B},{10:[1,206]},{10:[1,207],106:[1,208]},t(Ut,[2,128]),{10:[1,209],44:A,60:b,89:D,102:C,105:x,106:T,109:S,111:F,113:112,114:_,115:v,116:B},{10:[1,210],44:A,60:b,89:D,102:C,105:x,106:T,109:S,111:F,113:112,114:_,115:v,116:B},{80:[1,211]},t($t,[2,109],{10:[1,212]}),t($t,[2,111],{10:[1,213]}),{80:[1,214]},t(It,[2,184]),{80:[1,215],98:[1,216]},t(J,[2,55],{113:112,44:A,60:b,89:D,102:C,105:x,106:T,109:S,111:F,114:_,115:v,116:B}),{31:[1,217],67:Rt,82:218,116:Kt,117:Gt,118:Ot},t(Wt,[2,86]),t(Wt,[2,88]),t(Wt,[2,89]),t(Wt,[2,153]),t(Wt,[2,154]),t(Wt,[2,155]),t(Wt,[2,156]),{49:[1,219],67:Rt,82:218,116:Kt,117:Gt,118:Ot},{30:220,67:Rt,80:Nt,81:Pt,82:171,116:Kt,117:Gt,118:Ot},{51:[1,221],67:Rt,82:218,116:Kt,117:Gt,118:Ot},{53:[1,222],67:Rt,82:218,116:Kt,117:Gt,118:Ot},{55:[1,223],67:Rt,82:218,116:Kt,117:Gt,118:Ot},{57:[1,224],67:Rt,82:218,116:Kt,117:Gt,118:Ot},{60:[1,225]},{64:[1,226],67:Rt,82:218,116:Kt,117:Gt,118:Ot},{66:[1,227],67:Rt,82:218,116:Kt,117:Gt,118:Ot},{30:228,67:Rt,80:Nt,81:Pt,82:171,116:Kt,117:Gt,118:Ot},{31:[1,229],67:Rt,82:218,116:Kt,117:Gt,118:Ot},{67:Rt,69:[1,230],71:[1,231],82:218,116:Kt,117:Gt,118:Ot},{67:Rt,69:[1,233],71:[1,232],82:218,116:Kt,117:Gt,118:Ot},t(O,[2,45],{18:155,10:R,40:Lt}),t(O,[2,47],{44:wt}),t(it,[2,75]),t(it,[2,74]),{62:[1,234],67:Rt,82:218,116:Kt,117:Gt,118:Ot},t(it,[2,77]),t(Vt,[2,80]),{77:[1,235],79:197,116:at,119:ut},{30:236,67:Rt,80:Nt,81:Pt,82:171,116:Kt,117:Gt,118:Ot},t(Bt,r,{5:237}),t(Mt,[2,102]),t(N,[2,35]),{43:238,44:A,45:39,47:40,60:b,89:D,102:C,105:x,106:T,109:S,111:F,113:41,114:_,115:v,116:B},{10:R,18:239},{10:Yt,60:jt,84:zt,92:240,105:Xt,107:241,108:242,109:Ht,110:qt,111:Qt,112:Zt},{10:Yt,60:jt,84:zt,92:251,104:[1,252],105:Xt,107:241,108:242,109:Ht,110:qt,111:Qt,112:Zt},{10:Yt,60:jt,84:zt,92:253,104:[1,254],105:Xt,107:241,108:242,109:Ht,110:qt,111:Qt,112:Zt},{105:[1,255]},{10:Yt,60:jt,84:zt,92:256,105:Xt,107:241,108:242,109:Ht,110:qt,111:Qt,112:Zt},{44:A,47:257,60:b,89:D,102:C,105:x,106:T,109:S,111:F,113:41,114:_,115:v,116:B},t($t,[2,108]),{80:[1,258]},{80:[1,259],98:[1,260]},t($t,[2,116]),t($t,[2,118],{10:[1,261]}),t($t,[2,119]),t(tt,[2,56]),t(Wt,[2,87]),t(tt,[2,57]),{51:[1,262],67:Rt,82:218,116:Kt,117:Gt,118:Ot},t(tt,[2,64]),t(tt,[2,59]),t(tt,[2,60]),t(tt,[2,61]),{109:[1,263]},t(tt,[2,63]),t(tt,[2,65]),{66:[1,264],67:Rt,82:218,116:Kt,117:Gt,118:Ot},t(tt,[2,67]),t(tt,[2,68]),t(tt,[2,70]),t(tt,[2,69]),t(tt,[2,71]),t([10,44,60,89,102,105,106,109,111,114,115,116],[2,85]),t(it,[2,78]),{31:[1,265],67:Rt,82:218,116:Kt,117:Gt,118:Ot},{6:11,7:12,8:a,9:u,10:o,11:l,20:17,22:18,23:19,24:20,25:21,26:22,27:c,32:[1,266],33:24,34:d,36:p,38:g,42:28,43:38,44:A,45:39,47:40,60:b,84:y,85:k,86:f,87:m,88:E,89:D,102:C,105:x,106:T,109:S,111:F,113:41,114:_,115:v,116:B,121:w,122:L,123:$,124:I},t(J,[2,53]),{43:267,44:A,45:39,47:40,60:b,89:D,102:C,105:x,106:T,109:S,111:F,113:41,114:_,115:v,116:B},t($t,[2,121],{106:Jt}),t(te,[2,130],{108:269,10:Yt,60:jt,84:zt,105:Xt,109:Ht,110:qt,111:Qt,112:Zt}),t(ee,[2,132]),t(ee,[2,134]),t(ee,[2,135]),t(ee,[2,136]),t(ee,[2,137]),t(ee,[2,138]),t(ee,[2,139]),t(ee,[2,140]),t(ee,[2,141]),t($t,[2,122],{106:Jt}),{10:[1,270]},t($t,[2,123],{106:Jt}),{10:[1,271]},t(Ut,[2,129]),t($t,[2,105],{106:Jt}),t($t,[2,106],{113:112,44:A,60:b,89:D,102:C,105:x,106:T,109:S,111:F,114:_,115:v,116:B}),t($t,[2,110]),t($t,[2,112],{10:[1,272]}),t($t,[2,113]),{98:[1,273]},{51:[1,274]},{62:[1,275]},{66:[1,276]},{8:P,9:K,11:G,21:277},t(N,[2,34]),t(J,[2,52]),{10:Yt,60:jt,84:zt,105:Xt,107:278,108:242,109:Ht,110:qt,111:Qt,112:Zt},t(ee,[2,133]),{14:M,44:U,60:W,89:Y,101:279,105:j,106:z,109:X,111:H,114:q,115:Q,116:Z,120:87},{14:M,44:U,60:W,89:Y,101:280,105:j,106:z,109:X,111:H,114:q,115:Q,116:Z,120:87},{98:[1,281]},t($t,[2,120]),t(tt,[2,58]),{30:282,67:Rt,80:Nt,81:Pt,82:171,116:Kt,117:Gt,118:Ot},t(tt,[2,66]),t(Bt,r,{5:283}),t(te,[2,131],{108:269,10:Yt,60:jt,84:zt,105:Xt,109:Ht,110:qt,111:Qt,112:Zt}),t($t,[2,126],{120:167,10:[1,284],14:M,44:U,60:W,89:Y,105:j,106:z,109:X,111:H,114:q,115:Q,116:Z}),t($t,[2,127],{120:167,10:[1,285],14:M,44:U,60:W,89:Y,105:j,106:z,109:X,111:H,114:q,115:Q,116:Z}),t($t,[2,114]),{31:[1,286],67:Rt,82:218,116:Kt,117:Gt,118:Ot},{6:11,7:12,8:a,9:u,10:o,11:l,20:17,22:18,23:19,24:20,25:21,26:22,27:c,32:[1,287],33:24,34:d,36:p,38:g,42:28,43:38,44:A,45:39,47:40,60:b,84:y,85:k,86:f,87:m,88:E,89:D,102:C,105:x,106:T,109:S,111:F,113:41,114:_,115:v,116:B,121:w,122:L,123:$,124:I},{10:Yt,60:jt,84:zt,92:288,105:Xt,107:241,108:242,109:Ht,110:qt,111:Qt,112:Zt},{10:Yt,60:jt,84:zt,92:289,105:Xt,107:241,108:242,109:Ht,110:qt,111:Qt,112:Zt},t(tt,[2,62]),t(N,[2,33]),t($t,[2,124],{106:Jt}),t($t,[2,125],{106:Jt})],defaultActions:{},parseError:(0,h.K2)(function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)},"parseError"),parse:(0,h.K2)(function(t){var e=this,s=[0],i=[],n=[null],r=[],a=this.table,u="",o=0,l=0,c=0,d=r.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var A in this.yy)Object.prototype.hasOwnProperty.call(this.yy,A)&&(g.yy[A]=this.yy[A]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var b=p.yylloc;r.push(b);var y=p.options&&p.options.ranges;function k(){var t;return"number"!=typeof(t=i.pop()||p.lex()||1)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,h.K2)(function(t){s.length=s.length-2*t,n.length=n.length-t,r.length=r.length-t},"popStack"),(0,h.K2)(k,"lex");for(var f,m,E,D,C,x,T,S,F,_={};;){if(E=s[s.length-1],this.defaultActions[E]?D=this.defaultActions[E]:(null==f&&(f=k()),D=a[E]&&a[E][f]),void 0===D||!D.length||!D[0]){var v="";for(x in F=[],a[E])this.terminals_[x]&&x>2&&F.push("'"+this.terminals_[x]+"'");v=p.showPosition?"Parse error on line "+(o+1)+":\n"+p.showPosition()+"\nExpecting "+F.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(v,{text:p.match,token:this.terminals_[f]||f,line:p.yylineno,loc:b,expected:F})}if(D[0]instanceof Array&&D.length>1)throw new Error("Parse Error: multiple actions possible at state: "+E+", token: "+f);switch(D[0]){case 1:s.push(f),n.push(p.yytext),r.push(p.yylloc),s.push(D[1]),f=null,m?(f=m,m=null):(l=p.yyleng,u=p.yytext,o=p.yylineno,b=p.yylloc,c>0&&c--);break;case 2:if(T=this.productions_[D[1]][1],_.$=n[n.length-T],_._$={first_line:r[r.length-(T||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(T||1)].first_column,last_column:r[r.length-1].last_column},y&&(_._$.range=[r[r.length-(T||1)].range[0],r[r.length-1].range[1]]),void 0!==(C=this.performAction.apply(_,[u,l,o,g.yy,D[1],n,r].concat(d))))return C;T&&(s=s.slice(0,-1*T*2),n=n.slice(0,-1*T),r=r.slice(0,-1*T)),s.push(this.productions_[D[1]][0]),n.push(_.$),r.push(_._$),S=a[s[s.length-2]][s[s.length-1]],s.push(S);break;case 3:return!0}}return!0},"parse")},ie=function(){return{EOF:1,parseError:(0,h.K2)(function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},"parseError"),setInput:(0,h.K2)(function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:(0,h.K2)(function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},"input"),unput:(0,h.K2)(function(t){var e=t.length,s=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),s.length-1&&(this.yylineno-=s.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:s?(s.length===i.length?this.yylloc.first_column:0)+i[i.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},"unput"),more:(0,h.K2)(function(){return this._more=!0,this},"more"),reject:(0,h.K2)(function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"reject"),less:(0,h.K2)(function(t){this.unput(this.match.slice(t))},"less"),pastInput:(0,h.K2)(function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:(0,h.K2)(function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:(0,h.K2)(function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},"showPosition"),test_match:(0,h.K2)(function(t,e){var s,i,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},"test_match"),next:(0,h.K2)(function(){if(this.done)return this.EOF;var t,e,s,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;r<n.length;r++)if((s=this._input.match(this.rules[n[r]]))&&(!e||s[0].length>e[0].length)){if(e=s,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,n[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,n[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:(0,h.K2)(function(){var t=this.next();return t||this.lex()},"lex"),begin:(0,h.K2)(function(t){this.conditionStack.push(t)},"begin"),popState:(0,h.K2)(function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:(0,h.K2)(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:(0,h.K2)(function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},"topState"),pushState:(0,h.K2)(function(t){this.begin(t)},"pushState"),stateStackSize:(0,h.K2)(function(){return this.conditionStack.length},"stateStackSize"),options:{},performAction:(0,h.K2)(function(t,e,s,i){switch(s){case 0:return this.begin("acc_title"),34;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),36;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:case 12:case 14:case 17:case 20:case 23:case 33:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return this.pushState("shapeData"),e.yytext="",40;case 8:return this.pushState("shapeDataStr"),40;case 9:return this.popState(),40;case 10:const s=/\n\s*/g;return e.yytext=e.yytext.replace(s,"<br/>"),40;case 11:return 40;case 13:this.begin("callbackname");break;case 15:this.popState(),this.begin("callbackargs");break;case 16:return 95;case 18:return 96;case 19:return"MD_STR";case 21:this.begin("md_string");break;case 22:return"STR";case 24:this.pushState("string");break;case 25:return 84;case 26:return 102;case 27:return 85;case 28:return 104;case 29:return 86;case 30:return 87;case 31:return 97;case 32:this.begin("click");break;case 34:return 88;case 35:case 36:case 37:return t.lex.firstGraph()&&this.begin("dir"),12;case 38:return 27;case 39:return 32;case 40:case 41:case 42:case 43:return 98;case 44:return this.popState(),13;case 45:case 46:case 47:case 48:case 49:case 50:case 51:case 52:case 53:case 54:return this.popState(),14;case 55:return 121;case 56:return 122;case 57:return 123;case 58:return 124;case 59:return 78;case 60:return 105;case 61:case 102:return 111;case 62:return 46;case 63:return 60;case 64:case 103:return 44;case 65:return 8;case 66:return 106;case 67:case 101:return 115;case 68:case 71:case 74:return this.popState(),77;case 69:return this.pushState("edgeText"),75;case 70:case 73:case 76:return 119;case 72:return this.pushState("thickEdgeText"),75;case 75:return this.pushState("dottedEdgeText"),75;case 77:return 77;case 78:return this.popState(),53;case 79:case 115:return"TEXT";case 80:return this.pushState("ellipseText"),52;case 81:return this.popState(),55;case 82:return this.pushState("text"),54;case 83:return this.popState(),57;case 84:return this.pushState("text"),56;case 85:return 58;case 86:return this.pushState("text"),67;case 87:return this.popState(),64;case 88:return this.pushState("text"),63;case 89:return this.popState(),49;case 90:return this.pushState("text"),48;case 91:return this.popState(),69;case 92:return this.popState(),71;case 93:return 117;case 94:return this.pushState("trapText"),68;case 95:return this.pushState("trapText"),70;case 96:return 118;case 97:return 67;case 98:return 90;case 99:return"SEP";case 100:return 89;case 104:return 109;case 105:return 114;case 106:return 116;case 107:return this.popState(),62;case 108:return this.pushState("text"),62;case 109:return this.popState(),51;case 110:return this.pushState("text"),50;case 111:return this.popState(),31;case 112:return this.pushState("text"),29;case 113:return this.popState(),66;case 114:return this.pushState("text"),65;case 116:return"QUOTE";case 117:return 9;case 118:return 10;case 119:return 11}},"anonymous"),rules:[/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:@\{)/,/^(?:["])/,/^(?:["])/,/^(?:[^\"]+)/,/^(?:[^}^"]+)/,/^(?:\})/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["][`])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:["])/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:href[\s])/,/^(?:click[\s]+)/,/^(?:[\s\n])/,/^(?:[^\s\n]*)/,/^(?:flowchart-elk\b)/,/^(?:graph\b)/,/^(?:flowchart\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:(\r?\n)*\s*\n)/,/^(?:\s*LR\b)/,/^(?:\s*RL\b)/,/^(?:\s*TB\b)/,/^(?:\s*BT\b)/,/^(?:\s*TD\b)/,/^(?:\s*BR\b)/,/^(?:\s*<)/,/^(?:\s*>)/,/^(?:\s*\^)/,/^(?:\s*v\b)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:[^\s\"]+@(?=[^\{\"]))/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::::)/,/^(?::)/,/^(?:&)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:[^-]|-(?!-)+)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:[^=]|=(?!))/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:[^\.]|\.(?!))/,/^(?:\s*~~[\~]+\s*)/,/^(?:[-/\)][\)])/,/^(?:[^\(\)\[\]\{\}]|!\)+)/,/^(?:\(-)/,/^(?:\]\))/,/^(?:\(\[)/,/^(?:\]\])/,/^(?:\[\[)/,/^(?:\[\|)/,/^(?:>)/,/^(?:\)\])/,/^(?:\[\()/,/^(?:\)\)\))/,/^(?:\(\(\()/,/^(?:[\\(?=\])][\]])/,/^(?:\/(?=\])\])/,/^(?:\/(?!\])|\\(?!\])|[^\\\[\]\(\)\{\}\/]+)/,/^(?:\[\/)/,/^(?:\[\\)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:\\\|)/,/^(?:v\b)/,/^(?:\*)/,/^(?:#)/,/^(?:&)/,/^(?:([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|-(?=[^\>\-\.])|(?!))+)/,/^(?:-)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\|)/,/^(?:\|)/,/^(?:\))/,/^(?:\()/,/^(?:\])/,/^(?:\[)/,/^(?:(\}))/,/^(?:\{)/,/^(?:[^\[\]\(\)\{\}\|\"]+)/,/^(?:")/,/^(?:(\r?\n)+)/,/^(?:\s)/,/^(?:$)/],conditions:{shapeDataEndBracket:{rules:[21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},shapeDataStr:{rules:[9,10,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},shapeData:{rules:[8,11,12,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},callbackargs:{rules:[17,18,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},callbackname:{rules:[14,15,16,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},href:{rules:[21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},click:{rules:[21,24,33,34,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},dottedEdgeText:{rules:[21,24,74,76,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},thickEdgeText:{rules:[21,24,71,73,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},edgeText:{rules:[21,24,68,70,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},trapText:{rules:[21,24,77,80,82,84,88,90,91,92,93,94,95,108,110,112,114],inclusive:!1},ellipseText:{rules:[21,24,77,78,79,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},text:{rules:[21,24,77,80,81,82,83,84,87,88,89,90,94,95,107,108,109,110,111,112,113,114,115],inclusive:!1},vertex:{rules:[21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},dir:{rules:[21,24,44,45,46,47,48,49,50,51,52,53,54,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},acc_descr_multiline:{rules:[5,6,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},acc_descr:{rules:[3,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},acc_title:{rules:[1,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},md_string:{rules:[19,20,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},string:{rules:[21,22,23,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},INITIAL:{rules:[0,2,4,7,13,21,24,25,26,27,28,29,30,31,32,35,36,37,38,39,40,41,42,43,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,71,72,74,75,77,80,82,84,85,86,88,90,94,95,96,97,98,99,100,101,102,103,104,105,106,108,110,112,114,116,117,118,119],inclusive:!0}}}}();function ne(){this.yy={}}return se.lexer=ie,(0,h.K2)(ne,"Parser"),ne.prototype=se,se.Parser=ne,new ne}();y.parser=y;var k=y,f=Object.assign({},k);f.parse=t=>{const e=t.replace(/}\s*\n/g,"}\n");return k.parse(e)};var m=f,E=(0,h.K2)((t,e)=>{const s=g.A,i=s(t,"r"),n=s(t,"g"),r=s(t,"b");return p.A(i,n,r,e)},"fade"),D=(0,h.K2)(t=>`.label {\n font-family: ${t.fontFamily};\n color: ${t.nodeTextColor||t.textColor};\n }\n .cluster-label text {\n fill: ${t.titleColor};\n }\n .cluster-label span {\n color: ${t.titleColor};\n }\n .cluster-label span p {\n background-color: transparent;\n }\n\n .label text,span {\n fill: ${t.nodeTextColor||t.textColor};\n color: ${t.nodeTextColor||t.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n .rough-node .label text , .node .label text, .image-shape .label, .icon-shape .label {\n text-anchor: middle;\n }\n // .flowchart-label .text-outer-tspan {\n // text-anchor: middle;\n // }\n // .flowchart-label .text-inner-tspan {\n // text-anchor: start;\n // }\n\n .node .katex path {\n fill: #000;\n stroke: #000;\n stroke-width: 1px;\n }\n\n .rough-node .label,.node .label, .image-shape .label, .icon-shape .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n\n .root .anchor path {\n fill: ${t.lineColor} !important;\n stroke-width: 0;\n stroke: ${t.lineColor};\n }\n\n .arrowheadPath {\n fill: ${t.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${t.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${t.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${t.edgeLabelBackground};\n p {\n background-color: ${t.edgeLabelBackground};\n }\n rect {\n opacity: 0.5;\n background-color: ${t.edgeLabelBackground};\n fill: ${t.edgeLabelBackground};\n }\n text-align: center;\n }\n\n /* For html labels only */\n .labelBkg {\n background-color: ${E(t.edgeLabelBackground,.5)};\n // background-color:\n }\n\n .cluster rect {\n fill: ${t.clusterBkg};\n stroke: ${t.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${t.titleColor};\n }\n\n .cluster span {\n color: ${t.titleColor};\n }\n /* .cluster div {\n color: ${t.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${t.fontFamily};\n font-size: 12px;\n background: ${t.tertiaryColor};\n border: 1px solid ${t.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n }\n\n rect.text {\n fill: none;\n stroke-width: 0;\n }\n\n .icon-shape, .image-shape {\n background-color: ${t.edgeLabelBackground};\n p {\n background-color: ${t.edgeLabelBackground};\n padding: 2px;\n }\n rect {\n opacity: 0.5;\n background-color: ${t.edgeLabelBackground};\n fill: ${t.edgeLabelBackground};\n }\n text-align: center;\n }\n ${(0,i.o)()}\n`,"getStyles"),C={parser:m,get db(){return new A},renderer:b,styles:D,init:(0,h.K2)(t=>{t.flowchart||(t.flowchart={}),t.layout&&(0,c.XV)({layout:t.layout}),t.flowchart.arrowMarkerAbsolute=t.arrowMarkerAbsolute,(0,c.XV)({flowchart:{arrowMarkerAbsolute:t.arrowMarkerAbsolute}})},"init")}},52501:(t,e,s)=>{s.d(e,{o:()=>i});var i=(0,s(40797).K2)(()=>"\n /* Font Awesome icon styling - consolidated */\n .label-icon {\n display: inline-block;\n height: 1em;\n overflow: visible;\n vertical-align: -0.125em;\n }\n \n .node .label-icon path {\n fill: currentColor;\n stroke: revert;\n stroke-width: revert;\n }\n","getIconStyles")},75937:(t,e,s)=>{s.d(e,{A:()=>r});var i=s(72453),n=s(74886);const r=(t,e)=>i.A.lang.round(n.A.parse(t)[e])},89625:(t,e,s)=>{s.d(e,{A:()=>r});var i=s(40797),n=s(70451),r=(0,i.K2)((t,e)=>{let s;"sandbox"===e&&(s=(0,n.Ltv)("#i"+t));return("sandbox"===e?(0,n.Ltv)(s.nodes()[0].contentDocument.body):(0,n.Ltv)("body")).select(`[id="${t}"]`)},"getDiagramElement")}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/2325.4b61ab01.js b/pr-preview/pr-4027/assets/js/2325.4b61ab01.js deleted file mode 100644 index a45a4d772..000000000 --- a/pr-preview/pr-4027/assets/js/2325.4b61ab01.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2325],{2325:(c,e,s)=>{s.d(e,{createPacketServices:()=>a.$});var a=s(73858);s(87960)}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/2334.ad641aac.js b/pr-preview/pr-4027/assets/js/2334.ad641aac.js deleted file mode 100644 index 334c76901..000000000 --- a/pr-preview/pr-4027/assets/js/2334.ad641aac.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2334],{697:(e,n,t)=>{t.d(n,{T:()=>r.T});var r=t(37981)},9703:(e,n,t)=>{t.d(n,{A:()=>u});var r=t(88496),o=t(92049),i=t(53098);const u=function(e){return"string"==typeof e||!(0,o.A)(e)&&(0,i.A)(e)&&"[object String]"==(0,r.A)(e)}},16145:(e,n,t)=>{t.d(n,{A:()=>c});var r=t(23958),o=t(38446),i=t(27422);const u=function(e){return function(n,t,u){var a=Object(n);if(!(0,o.A)(n)){var s=(0,r.A)(t,3);n=(0,i.A)(n),t=function(e){return s(a[e],e,a)}}var d=e(n,t,u);return d>-1?a[s?n[d]:d]:void 0}};var a=t(25707),s=t(18593),d=Math.max;const c=u(function(e,n,t){var o=null==e?0:e.length;if(!o)return-1;var i=null==t?0:(0,s.A)(t);return i<0&&(i=d(o+i,0)),(0,a.A)(e,(0,r.A)(n,3),i)})},18593:(e,n,t)=>{t.d(n,{A:()=>o});var r=t(74342);const o=function(e){var n=(0,r.A)(e),t=n%1;return n==n?t?n-t:n:0}},23068:(e,n,t)=>{t.d(n,{A:()=>d});var r=t(24326),o=t(66984),i=t(6832),u=t(55615),a=Object.prototype,s=a.hasOwnProperty;const d=(0,r.A)(function(e,n){e=Object(e);var t=-1,r=n.length,d=r>2?n[2]:void 0;for(d&&(0,i.A)(n[0],n[1],d)&&(r=1);++t<r;)for(var c=n[t],h=(0,u.A)(c),f=-1,l=h.length;++f<l;){var v=h[f],g=e[v];(void 0===g||(0,o.A)(g,a[v])&&!s.call(e,v))&&(e[v]=c[v])}return e})},26666:(e,n,t)=>{t.d(n,{A:()=>r});const r=function(e){var n=null==e?0:e.length;return n?e[n-1]:void 0}},34098:(e,n,t)=>{t.d(n,{A:()=>o});var r=t(13588);const o=function(e){return(null==e?0:e.length)?(0,r.A)(e,1):[]}},36224:(e,n,t)=>{t.d(n,{A:()=>r});const r=function(e,n){return e<n}},37981:(e,n,t)=>{t.d(n,{T:()=>w});var r=t(39142),o=t(89610),i=t(27422),u=t(94092),a=t(66401),s=t(8058),d=t(69592),c=t(13588),h=t(24326),f=t(99902),l=t(53533);const v=(0,h.A)(function(e){return(0,f.A)((0,c.A)(e,1,l.A,!0))});var g=t(38207),p=t(89463),A="\0";class w{constructor(e={}){this._isDirected=!Object.prototype.hasOwnProperty.call(e,"directed")||e.directed,this._isMultigraph=!!Object.prototype.hasOwnProperty.call(e,"multigraph")&&e.multigraph,this._isCompound=!!Object.prototype.hasOwnProperty.call(e,"compound")&&e.compound,this._label=void 0,this._defaultNodeLabelFn=r.A(void 0),this._defaultEdgeLabelFn=r.A(void 0),this._nodes={},this._isCompound&&(this._parent={},this._children={},this._children[A]={}),this._in={},this._preds={},this._out={},this._sucs={},this._edgeObjs={},this._edgeLabels={}}isDirected(){return this._isDirected}isMultigraph(){return this._isMultigraph}isCompound(){return this._isCompound}setGraph(e){return this._label=e,this}graph(){return this._label}setDefaultNodeLabel(e){return o.A(e)||(e=r.A(e)),this._defaultNodeLabelFn=e,this}nodeCount(){return this._nodeCount}nodes(){return i.A(this._nodes)}sources(){var e=this;return u.A(this.nodes(),function(n){return a.A(e._in[n])})}sinks(){var e=this;return u.A(this.nodes(),function(n){return a.A(e._out[n])})}setNodes(e,n){var t=arguments,r=this;return s.A(e,function(e){t.length>1?r.setNode(e,n):r.setNode(e)}),this}setNode(e,n){return Object.prototype.hasOwnProperty.call(this._nodes,e)?(arguments.length>1&&(this._nodes[e]=n),this):(this._nodes[e]=arguments.length>1?n:this._defaultNodeLabelFn(e),this._isCompound&&(this._parent[e]=A,this._children[e]={},this._children[A][e]=!0),this._in[e]={},this._preds[e]={},this._out[e]={},this._sucs[e]={},++this._nodeCount,this)}node(e){return this._nodes[e]}hasNode(e){return Object.prototype.hasOwnProperty.call(this._nodes,e)}removeNode(e){if(Object.prototype.hasOwnProperty.call(this._nodes,e)){var n=e=>this.removeEdge(this._edgeObjs[e]);delete this._nodes[e],this._isCompound&&(this._removeFromParentsChildList(e),delete this._parent[e],s.A(this.children(e),e=>{this.setParent(e)}),delete this._children[e]),s.A(i.A(this._in[e]),n),delete this._in[e],delete this._preds[e],s.A(i.A(this._out[e]),n),delete this._out[e],delete this._sucs[e],--this._nodeCount}return this}setParent(e,n){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(d.A(n))n=A;else{for(var t=n+="";!d.A(t);t=this.parent(t))if(t===e)throw new Error("Setting "+n+" as parent of "+e+" would create a cycle");this.setNode(n)}return this.setNode(e),this._removeFromParentsChildList(e),this._parent[e]=n,this._children[n][e]=!0,this}_removeFromParentsChildList(e){delete this._children[this._parent[e]][e]}parent(e){if(this._isCompound){var n=this._parent[e];if(n!==A)return n}}children(e){if(d.A(e)&&(e=A),this._isCompound){var n=this._children[e];if(n)return i.A(n)}else{if(e===A)return this.nodes();if(this.hasNode(e))return[]}}predecessors(e){var n=this._preds[e];if(n)return i.A(n)}successors(e){var n=this._sucs[e];if(n)return i.A(n)}neighbors(e){var n=this.predecessors(e);if(n)return v(n,this.successors(e))}isLeaf(e){return 0===(this.isDirected()?this.successors(e):this.neighbors(e)).length}filterNodes(e){var n=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});n.setGraph(this.graph());var t=this;s.A(this._nodes,function(t,r){e(r)&&n.setNode(r,t)}),s.A(this._edgeObjs,function(e){n.hasNode(e.v)&&n.hasNode(e.w)&&n.setEdge(e,t.edge(e))});var r={};function o(e){var i=t.parent(e);return void 0===i||n.hasNode(i)?(r[e]=i,i):i in r?r[i]:o(i)}return this._isCompound&&s.A(n.nodes(),function(e){n.setParent(e,o(e))}),n}setDefaultEdgeLabel(e){return o.A(e)||(e=r.A(e)),this._defaultEdgeLabelFn=e,this}edgeCount(){return this._edgeCount}edges(){return g.A(this._edgeObjs)}setPath(e,n){var t=this,r=arguments;return p.A(e,function(e,o){return r.length>1?t.setEdge(e,o,n):t.setEdge(e,o),o}),this}setEdge(){var e,n,t,r,o=!1,i=arguments[0];"object"==typeof i&&null!==i&&"v"in i?(e=i.v,n=i.w,t=i.name,2===arguments.length&&(r=arguments[1],o=!0)):(e=i,n=arguments[1],t=arguments[3],arguments.length>2&&(r=arguments[2],o=!0)),e=""+e,n=""+n,d.A(t)||(t=""+t);var u=y(this._isDirected,e,n,t);if(Object.prototype.hasOwnProperty.call(this._edgeLabels,u))return o&&(this._edgeLabels[u]=r),this;if(!d.A(t)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(e),this.setNode(n),this._edgeLabels[u]=o?r:this._defaultEdgeLabelFn(e,n,t);var a=function(e,n,t,r){var o=""+n,i=""+t;if(!e&&o>i){var u=o;o=i,i=u}var a={v:o,w:i};r&&(a.name=r);return a}(this._isDirected,e,n,t);return e=a.v,n=a.w,Object.freeze(a),this._edgeObjs[u]=a,b(this._preds[n],e),b(this._sucs[e],n),this._in[n][u]=a,this._out[e][u]=a,this._edgeCount++,this}edge(e,n,t){var r=1===arguments.length?_(this._isDirected,arguments[0]):y(this._isDirected,e,n,t);return this._edgeLabels[r]}hasEdge(e,n,t){var r=1===arguments.length?_(this._isDirected,arguments[0]):y(this._isDirected,e,n,t);return Object.prototype.hasOwnProperty.call(this._edgeLabels,r)}removeEdge(e,n,t){var r=1===arguments.length?_(this._isDirected,arguments[0]):y(this._isDirected,e,n,t),o=this._edgeObjs[r];return o&&(e=o.v,n=o.w,delete this._edgeLabels[r],delete this._edgeObjs[r],m(this._preds[n],e),m(this._sucs[e],n),delete this._in[n][r],delete this._out[e][r],this._edgeCount--),this}inEdges(e,n){var t=this._in[e];if(t){var r=g.A(t);return n?u.A(r,function(e){return e.v===n}):r}}outEdges(e,n){var t=this._out[e];if(t){var r=g.A(t);return n?u.A(r,function(e){return e.w===n}):r}}nodeEdges(e,n){var t=this.inEdges(e,n);if(t)return t.concat(this.outEdges(e,n))}}function b(e,n){e[n]?e[n]++:e[n]=1}function m(e,n){--e[n]||delete e[n]}function y(e,n,t,r){var o=""+n,i=""+t;if(!e&&o>i){var u=o;o=i,i=u}return o+"\x01"+i+"\x01"+(d.A(r)?"\0":r)}function _(e,n){return y(e,n.v,n.w,n.name)}w.prototype._nodeCount=0,w.prototype._edgeCount=0},48585:(e,n,t)=>{t.d(n,{A:()=>u});var r=Object.prototype.hasOwnProperty;const o=function(e,n){return null!=e&&r.call(e,n)};var i=t(85054);const u=function(e,n){return null!=e&&(0,i.A)(e,n,o)}},52568:(e,n,t)=>{t.d(n,{A:()=>i});var r=t(6240),o=t(38446);const i=function(e,n){var t=-1,i=(0,o.A)(e)?Array(e.length):[];return(0,r.A)(e,function(e,r,o){i[++t]=n(e,r,o)}),i}},62334:(e,n,t)=>{t.d(n,{Zp:()=>Rn});var r=t(8058),o=t(28894),i=0;const u=function(e){var n=++i;return(0,o.A)(e)+n};var a=t(39142),s=t(34098),d=t(74722),c=Math.ceil,h=Math.max;const f=function(e,n,t,r){for(var o=-1,i=h(c((n-e)/(t||1)),0),u=Array(i);i--;)u[r?i:++o]=e,e+=t;return u};var l=t(6832),v=t(74342);const g=function(e){return function(n,t,r){return r&&"number"!=typeof r&&(0,l.A)(n,t,r)&&(t=r=void 0),n=(0,v.A)(n),void 0===t?(t=n,n=0):t=(0,v.A)(t),r=void 0===r?n<t?1:-1:(0,v.A)(r),f(n,t,r,e)}}();var p=t(697);class A{constructor(){var e={};e._next=e._prev=e,this._sentinel=e}dequeue(){var e=this._sentinel,n=e._prev;if(n!==e)return w(n),n}enqueue(e){var n=this._sentinel;e._prev&&e._next&&w(e),e._next=n._next,n._next._prev=e,n._next=e,e._prev=n}toString(){for(var e=[],n=this._sentinel,t=n._prev;t!==n;)e.push(JSON.stringify(t,b)),t=t._prev;return"["+e.join(", ")+"]"}}function w(e){e._prev._next=e._next,e._next._prev=e._prev,delete e._next,delete e._prev}function b(e,n){if("_next"!==e&&"_prev"!==e)return n}var m=a.A(1);function y(e,n){if(e.nodeCount()<=1)return[];var t=function(e,n){var t=new p.T,o=0,i=0;r.A(e.nodes(),function(e){t.setNode(e,{v:e,in:0,out:0})}),r.A(e.edges(),function(e){var r=t.edge(e.v,e.w)||0,u=n(e),a=r+u;t.setEdge(e.v,e.w,a),i=Math.max(i,t.node(e.v).out+=u),o=Math.max(o,t.node(e.w).in+=u)});var u=g(i+o+3).map(function(){return new A}),a=o+1;return r.A(t.nodes(),function(e){E(u,a,t.node(e))}),{graph:t,buckets:u,zeroIdx:a}}(e,n||m),o=function(e,n,t){var r,o=[],i=n[n.length-1],u=n[0];for(;e.nodeCount();){for(;r=u.dequeue();)_(e,n,t,r);for(;r=i.dequeue();)_(e,n,t,r);if(e.nodeCount())for(var a=n.length-2;a>0;--a)if(r=n[a].dequeue()){o=o.concat(_(e,n,t,r,!0));break}}return o}(t.graph,t.buckets,t.zeroIdx);return s.A(d.A(o,function(n){return e.outEdges(n.v,n.w)}))}function _(e,n,t,o,i){var u=i?[]:void 0;return r.A(e.inEdges(o.v),function(r){var o=e.edge(r),a=e.node(r.v);i&&u.push({v:r.v,w:r.w}),a.out-=o,E(n,t,a)}),r.A(e.outEdges(o.v),function(r){var o=e.edge(r),i=r.w,u=e.node(i);u.in-=o,E(n,t,u)}),e.removeNode(o.v),u}function E(e,n,t){t.out?t.in?e[t.out-t.in+n].enqueue(t):e[e.length-1].enqueue(t):e[0].enqueue(t)}function x(e){var n="greedy"===e.graph().acyclicer?y(e,function(e){return function(n){return e.edge(n).weight}}(e)):function(e){var n=[],t={},o={};function i(u){Object.prototype.hasOwnProperty.call(o,u)||(o[u]=!0,t[u]=!0,r.A(e.outEdges(u),function(e){Object.prototype.hasOwnProperty.call(t,e.w)?n.push(e):i(e.w)}),delete t[u])}return r.A(e.nodes(),i),n}(e);r.A(n,function(n){var t=e.edge(n);e.removeEdge(n),t.forwardName=n.name,t.reversed=!0,e.setEdge(n.w,n.v,t,u("rev"))})}var O=t(42837),k=t(99354),N=t(39188);const P=function(e,n){return(0,k.A)(e,n,function(n,t){return(0,N.A)(e,t)})};var j=t(76875),C=t(67525);const I=function(e){return(0,C.A)((0,j.A)(e,void 0,s.A),e+"")}(function(e,n){return null==e?{}:P(e,n)});var L=t(23068),T=t(72559);const M=function(e,n){return e>n};var R=t(29008);const F=function(e){return e&&e.length?(0,T.A)(e,R.A,M):void 0};var D=t(26666),S=t(52528),G=t(79841),V=t(23958);const B=function(e,n){var t={};return n=(0,V.A)(n,3),(0,G.A)(e,function(e,r,o){(0,S.A)(t,r,n(e,r,o))}),t};var q=t(69592),Y=t(86452),z=t(48585),$=t(41917);const J=function(){return $.A.Date.now()};function Z(e,n,t,r){var o;do{o=u(r)}while(e.hasNode(o));return t.dummy=n,e.setNode(o,t),o}function H(e){var n=new p.T({multigraph:e.isMultigraph()}).setGraph(e.graph());return r.A(e.nodes(),function(t){e.children(t).length||n.setNode(t,e.node(t))}),r.A(e.edges(),function(t){n.setEdge(t,e.edge(t))}),n}function K(e,n){var t,r,o=e.x,i=e.y,u=n.x-o,a=n.y-i,s=e.width/2,d=e.height/2;if(!u&&!a)throw new Error("Not possible to find intersection inside of the rectangle");return Math.abs(a)*s>Math.abs(u)*d?(a<0&&(d=-d),t=d*u/a,r=d):(u<0&&(s=-s),t=s,r=s*a/u),{x:o+t,y:i+r}}function Q(e){var n=d.A(g(W(e)+1),function(){return[]});return r.A(e.nodes(),function(t){var r=e.node(t),o=r.rank;q.A(o)||(n[o][r.order]=t)}),n}function U(e,n,t,r){var o={width:0,height:0};return arguments.length>=4&&(o.rank=t,o.order=r),Z(e,"border",o,n)}function W(e){return F(d.A(e.nodes(),function(n){var t=e.node(n).rank;if(!q.A(t))return t}))}function X(e,n){var t=J();try{return n()}finally{console.log(e+" time: "+(J()-t)+"ms")}}function ee(e,n){return n()}function ne(e,n,t,r,o,i){var u={width:0,height:0,rank:i,borderType:n},a=o[n][i-1],s=Z(e,"border",u,t);o[n][i]=s,e.setParent(s,r),a&&e.setEdge(a,s,{weight:1})}function te(e){var n=e.graph().rankdir.toLowerCase();"bt"!==n&&"rl"!==n||function(e){r.A(e.nodes(),function(n){ie(e.node(n))}),r.A(e.edges(),function(n){var t=e.edge(n);r.A(t.points,ie),Object.prototype.hasOwnProperty.call(t,"y")&&ie(t)})}(e),"lr"!==n&&"rl"!==n||(!function(e){r.A(e.nodes(),function(n){ue(e.node(n))}),r.A(e.edges(),function(n){var t=e.edge(n);r.A(t.points,ue),Object.prototype.hasOwnProperty.call(t,"x")&&ue(t)})}(e),re(e))}function re(e){r.A(e.nodes(),function(n){oe(e.node(n))}),r.A(e.edges(),function(n){oe(e.edge(n))})}function oe(e){var n=e.width;e.width=e.height,e.height=n}function ie(e){e.y=-e.y}function ue(e){var n=e.x;e.x=e.y,e.y=n}function ae(e){e.graph().dummyChains=[],r.A(e.edges(),function(n){!function(e,n){var t=n.v,r=e.node(t).rank,o=n.w,i=e.node(o).rank,u=n.name,a=e.edge(n),s=a.labelRank;if(i===r+1)return;e.removeEdge(n);var d,c,h=void 0;for(c=0,++r;r<i;++c,++r)a.points=[],d=Z(e,"edge",h={width:0,height:0,edgeLabel:a,edgeObj:n,rank:r},"_d"),r===s&&(h.width=a.width,h.height=a.height,h.dummy="edge-label",h.labelpos=a.labelpos),e.setEdge(t,d,{weight:a.weight},u),0===c&&e.graph().dummyChains.push(d),t=d;e.setEdge(t,o,{weight:a.weight},u)}(e,n)})}var se=t(36224);const de=function(e,n){return e&&e.length?(0,T.A)(e,(0,V.A)(n,2),se.A):void 0};function ce(e){var n={};r.A(e.sources(),function t(r){var o=e.node(r);if(Object.prototype.hasOwnProperty.call(n,r))return o.rank;n[r]=!0;var i=Y.A(d.A(e.outEdges(r),function(n){return t(n.w)-e.edge(n).minlen}));return i!==Number.POSITIVE_INFINITY&&null!=i||(i=0),o.rank=i})}function he(e,n){return e.node(n.w).rank-e.node(n.v).rank-e.edge(n).minlen}function fe(e){var n,t,r=new p.T({directed:!1}),o=e.nodes()[0],i=e.nodeCount();for(r.setNode(o,{});le(r,e)<i;)n=ve(r,e),t=r.hasNode(n.v)?he(e,n):-he(e,n),ge(r,e,t);return r}function le(e,n){return r.A(e.nodes(),function t(o){r.A(n.nodeEdges(o),function(r){var i=r.v,u=o===i?r.w:i;e.hasNode(u)||he(n,r)||(e.setNode(u,{}),e.setEdge(o,u,{}),t(u))})}),e.nodeCount()}function ve(e,n){return de(n.edges(),function(t){if(e.hasNode(t.v)!==e.hasNode(t.w))return he(n,t)})}function ge(e,n,t){r.A(e.nodes(),function(e){n.node(e).rank+=t})}var pe=t(16145),Ae=t(94092);a.A(1);a.A(1);t(69471),t(9779),t(38446),t(9703);(0,t(70805).A)("length");RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]");var we="\\ud800-\\udfff",be="["+we+"]",me="[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]",ye="\\ud83c[\\udffb-\\udfff]",_e="[^"+we+"]",Ee="(?:\\ud83c[\\udde6-\\uddff]){2}",xe="[\\ud800-\\udbff][\\udc00-\\udfff]",Oe="(?:"+me+"|"+ye+")"+"?",ke="[\\ufe0e\\ufe0f]?",Ne=ke+Oe+("(?:\\u200d(?:"+[_e,Ee,xe].join("|")+")"+ke+Oe+")*"),Pe="(?:"+[_e+me+"?",me,Ee,xe,be].join("|")+")";RegExp(ye+"(?="+ye+")|"+Pe+Ne,"g");function je(){}je.prototype=new Error;var Ce=t(92049);function Ie(e,n,t){Ce.A(n)||(n=[n]);var o=(e.isDirected()?e.successors:e.neighbors).bind(e),i=[],u={};return r.A(n,function(n){if(!e.hasNode(n))throw new Error("Graph does not have node: "+n);Le(e,n,"post"===t,u,o,i)}),i}function Le(e,n,t,o,i,u){Object.prototype.hasOwnProperty.call(o,n)||(o[n]=!0,t||u.push(n),r.A(i(n),function(n){Le(e,n,t,o,i,u)}),t&&u.push(n))}t(37981);function Te(e){e=function(e){var n=(new p.T).setGraph(e.graph());return r.A(e.nodes(),function(t){n.setNode(t,e.node(t))}),r.A(e.edges(),function(t){var r=n.edge(t.v,t.w)||{weight:0,minlen:1},o=e.edge(t);n.setEdge(t.v,t.w,{weight:r.weight+o.weight,minlen:Math.max(r.minlen,o.minlen)})}),n}(e),ce(e);var n,t=fe(e);for(Fe(t),Me(t,e);n=Se(t);)Ve(t,e,n,Ge(t,e,n))}function Me(e,n){var t=function(e,n){return Ie(e,n,"post")}(e,e.nodes());t=t.slice(0,t.length-1),r.A(t,function(t){!function(e,n,t){var r=e.node(t),o=r.parent;e.edge(t,o).cutvalue=Re(e,n,t)}(e,n,t)})}function Re(e,n,t){var o=e.node(t).parent,i=!0,u=n.edge(t,o),a=0;return u||(i=!1,u=n.edge(o,t)),a=u.weight,r.A(n.nodeEdges(t),function(r){var u,s,d=r.v===t,c=d?r.w:r.v;if(c!==o){var h=d===i,f=n.edge(r).weight;if(a+=h?f:-f,u=t,s=c,e.hasEdge(u,s)){var l=e.edge(t,c).cutvalue;a+=h?-l:l}}}),a}function Fe(e,n){arguments.length<2&&(n=e.nodes()[0]),De(e,{},1,n)}function De(e,n,t,o,i){var u=t,a=e.node(o);return n[o]=!0,r.A(e.neighbors(o),function(r){Object.prototype.hasOwnProperty.call(n,r)||(t=De(e,n,t,r,o))}),a.low=u,a.lim=t++,i?a.parent=i:delete a.parent,t}function Se(e){return pe.A(e.edges(),function(n){return e.edge(n).cutvalue<0})}function Ge(e,n,t){var r=t.v,o=t.w;n.hasEdge(r,o)||(r=t.w,o=t.v);var i=e.node(r),u=e.node(o),a=i,s=!1;i.lim>u.lim&&(a=u,s=!0);var d=Ae.A(n.edges(),function(n){return s===Be(e,e.node(n.v),a)&&s!==Be(e,e.node(n.w),a)});return de(d,function(e){return he(n,e)})}function Ve(e,n,t,o){var i=t.v,u=t.w;e.removeEdge(i,u),e.setEdge(o.v,o.w,{}),Fe(e),Me(e,n),function(e,n){var t=pe.A(e.nodes(),function(e){return!n.node(e).parent}),o=function(e,n){return Ie(e,n,"pre")}(e,t);o=o.slice(1),r.A(o,function(t){var r=e.node(t).parent,o=n.edge(t,r),i=!1;o||(o=n.edge(r,t),i=!0),n.node(t).rank=n.node(r).rank+(i?o.minlen:-o.minlen)})}(e,n)}function Be(e,n,t){return t.low<=n.lim&&n.lim<=t.lim}function qe(e){switch(e.graph().ranker){case"network-simplex":default:ze(e);break;case"tight-tree":!function(e){ce(e),fe(e)}(e);break;case"longest-path":Ye(e)}}Te.initLowLimValues=Fe,Te.initCutValues=Me,Te.calcCutValue=Re,Te.leaveEdge=Se,Te.enterEdge=Ge,Te.exchangeEdges=Ve;var Ye=ce;function ze(e){Te(e)}var $e=t(38207),Je=t(89463);function Ze(e){var n=Z(e,"root",{},"_root"),t=function(e){var n={};function t(o,i){var u=e.children(o);u&&u.length&&r.A(u,function(e){t(e,i+1)}),n[o]=i}return r.A(e.children(),function(e){t(e,1)}),n}(e),o=F($e.A(t))-1,i=2*o+1;e.graph().nestingRoot=n,r.A(e.edges(),function(n){e.edge(n).minlen*=i});var u=function(e){return Je.A(e.edges(),function(n,t){return n+e.edge(t).weight},0)}(e)+1;r.A(e.children(),function(r){He(e,n,i,u,o,t,r)}),e.graph().nodeRankFactor=i}function He(e,n,t,o,i,u,a){var s=e.children(a);if(s.length){var d=U(e,"_bt"),c=U(e,"_bb"),h=e.node(a);e.setParent(d,a),h.borderTop=d,e.setParent(c,a),h.borderBottom=c,r.A(s,function(r){He(e,n,t,o,i,u,r);var s=e.node(r),h=s.borderTop?s.borderTop:r,f=s.borderBottom?s.borderBottom:r,l=s.borderTop?o:2*o,v=h!==f?1:i-u[a]+1;e.setEdge(d,h,{weight:l,minlen:v,nestingEdge:!0}),e.setEdge(f,c,{weight:l,minlen:v,nestingEdge:!0})}),e.parent(a)||e.setEdge(n,d,{weight:0,minlen:i+u[a]})}else a!==n&&e.setEdge(n,a,{weight:0,minlen:t})}var Ke=t(68675);const Qe=function(e){return(0,Ke.A)(e,5)};function Ue(e,n,t){var o=function(e){var n;for(;e.hasNode(n=u("_root")););return n}(e),i=new p.T({compound:!0}).setGraph({root:o}).setDefaultNodeLabel(function(n){return e.node(n)});return r.A(e.nodes(),function(u){var a=e.node(u),s=e.parent(u);(a.rank===n||a.minRank<=n&&n<=a.maxRank)&&(i.setNode(u),i.setParent(u,s||o),r.A(e[t](u),function(n){var t=n.v===u?n.w:n.v,r=i.edge(t,u),o=q.A(r)?0:r.weight;i.setEdge(t,u,{weight:e.edge(n).weight+o})}),Object.prototype.hasOwnProperty.call(a,"minRank")&&i.setNode(u,{borderLeft:a.borderLeft[n],borderRight:a.borderRight[n]}))}),i}var We=t(52851);const Xe=function(e,n,t){for(var r=-1,o=e.length,i=n.length,u={};++r<o;){var a=r<i?n[r]:void 0;t(u,e[r],a)}return u};const en=function(e,n){return Xe(e||[],n||[],We.A)};var nn=t(13588),tn=t(45572),rn=t(66318),on=t(52568);const un=function(e,n){var t=e.length;for(e.sort(n);t--;)e[t]=e[t].value;return e};var an=t(52789),sn=t(61882);const dn=function(e,n){if(e!==n){var t=void 0!==e,r=null===e,o=e==e,i=(0,sn.A)(e),u=void 0!==n,a=null===n,s=n==n,d=(0,sn.A)(n);if(!a&&!d&&!i&&e>n||i&&u&&s&&!a&&!d||r&&u&&s||!t&&s||!o)return 1;if(!r&&!i&&!d&&e<n||d&&t&&o&&!r&&!i||a&&t&&o||!u&&o||!s)return-1}return 0};const cn=function(e,n,t){for(var r=-1,o=e.criteria,i=n.criteria,u=o.length,a=t.length;++r<u;){var s=dn(o[r],i[r]);if(s)return r>=a?s:s*("desc"==t[r]?-1:1)}return e.index-n.index};const hn=function(e,n,t){n=n.length?(0,tn.A)(n,function(e){return(0,Ce.A)(e)?function(n){return(0,rn.A)(n,1===e.length?e[0]:e)}:e}):[R.A];var r=-1;n=(0,tn.A)(n,(0,an.A)(V.A));var o=(0,on.A)(e,function(e,t,o){return{criteria:(0,tn.A)(n,function(n){return n(e)}),index:++r,value:e}});return un(o,function(e,n){return cn(e,n,t)})};const fn=(0,t(24326).A)(function(e,n){if(null==e)return[];var t=n.length;return t>1&&(0,l.A)(e,n[0],n[1])?n=[]:t>2&&(0,l.A)(n[0],n[1],n[2])&&(n=[n[0]]),hn(e,(0,nn.A)(n,1),[])});function ln(e,n){for(var t=0,r=1;r<n.length;++r)t+=vn(e,n[r-1],n[r]);return t}function vn(e,n,t){for(var o=en(t,d.A(t,function(e,n){return n})),i=s.A(d.A(n,function(n){return fn(d.A(e.outEdges(n),function(n){return{pos:o[n.w],weight:e.edge(n).weight}}),"pos")})),u=1;u<t.length;)u<<=1;var a=2*u-1;u-=1;var c=d.A(new Array(a),function(){return 0}),h=0;return r.A(i.forEach(function(e){var n=e.pos+u;c[n]+=e.weight;for(var t=0;n>0;)n%2&&(t+=c[n+1]),c[n=n-1>>1]+=e.weight;h+=e.weight*t})),h}function gn(e,n){var t={};return r.A(e,function(e,n){var r=t[e.v]={indegree:0,in:[],out:[],vs:[e.v],i:n};q.A(e.barycenter)||(r.barycenter=e.barycenter,r.weight=e.weight)}),r.A(n.edges(),function(e){var n=t[e.v],r=t[e.w];q.A(n)||q.A(r)||(r.indegree++,n.out.push(t[e.w]))}),function(e){var n=[];function t(e){return function(n){n.merged||(q.A(n.barycenter)||q.A(e.barycenter)||n.barycenter>=e.barycenter)&&function(e,n){var t=0,r=0;e.weight&&(t+=e.barycenter*e.weight,r+=e.weight);n.weight&&(t+=n.barycenter*n.weight,r+=n.weight);e.vs=n.vs.concat(e.vs),e.barycenter=t/r,e.weight=r,e.i=Math.min(n.i,e.i),n.merged=!0}(e,n)}}function o(n){return function(t){t.in.push(n),0===--t.indegree&&e.push(t)}}for(;e.length;){var i=e.pop();n.push(i),r.A(i.in.reverse(),t(i)),r.A(i.out,o(i))}return d.A(Ae.A(n,function(e){return!e.merged}),function(e){return I(e,["vs","i","barycenter","weight"])})}(Ae.A(t,function(e){return!e.indegree}))}function pn(e,n){var t,o=function(e,n){var t={lhs:[],rhs:[]};return r.A(e,function(e){n(e)?t.lhs.push(e):t.rhs.push(e)}),t}(e,function(e){return Object.prototype.hasOwnProperty.call(e,"barycenter")}),i=o.lhs,u=fn(o.rhs,function(e){return-e.i}),a=[],d=0,c=0,h=0;i.sort((t=!!n,function(e,n){return e.barycenter<n.barycenter?-1:e.barycenter>n.barycenter?1:t?n.i-e.i:e.i-n.i})),h=An(a,u,h),r.A(i,function(e){h+=e.vs.length,a.push(e.vs),d+=e.barycenter*e.weight,c+=e.weight,h=An(a,u,h)});var f={vs:s.A(a)};return c&&(f.barycenter=d/c,f.weight=c),f}function An(e,n,t){for(var r;n.length&&(r=D.A(n)).i<=t;)n.pop(),e.push(r.vs),t++;return t}function wn(e,n,t,o){var i=e.children(n),u=e.node(n),a=u?u.borderLeft:void 0,c=u?u.borderRight:void 0,h={};a&&(i=Ae.A(i,function(e){return e!==a&&e!==c}));var f=function(e,n){return d.A(n,function(n){var t=e.inEdges(n);if(t.length){var r=Je.A(t,function(n,t){var r=e.edge(t),o=e.node(t.v);return{sum:n.sum+r.weight*o.order,weight:n.weight+r.weight}},{sum:0,weight:0});return{v:n,barycenter:r.sum/r.weight,weight:r.weight}}return{v:n}})}(e,i);r.A(f,function(n){if(e.children(n.v).length){var r=wn(e,n.v,t,o);h[n.v]=r,Object.prototype.hasOwnProperty.call(r,"barycenter")&&(i=n,u=r,q.A(i.barycenter)?(i.barycenter=u.barycenter,i.weight=u.weight):(i.barycenter=(i.barycenter*i.weight+u.barycenter*u.weight)/(i.weight+u.weight),i.weight+=u.weight))}var i,u});var l=gn(f,t);!function(e,n){r.A(e,function(e){e.vs=s.A(e.vs.map(function(e){return n[e]?n[e].vs:e}))})}(l,h);var v=pn(l,o);if(a&&(v.vs=s.A([a,v.vs,c]),e.predecessors(a).length)){var g=e.node(e.predecessors(a)[0]),p=e.node(e.predecessors(c)[0]);Object.prototype.hasOwnProperty.call(v,"barycenter")||(v.barycenter=0,v.weight=0),v.barycenter=(v.barycenter*v.weight+g.order+p.order)/(v.weight+2),v.weight+=2}return v}function bn(e){var n=W(e),t=mn(e,g(1,n+1),"inEdges"),o=mn(e,g(n-1,-1,-1),"outEdges"),i=function(e){var n={},t=Ae.A(e.nodes(),function(n){return!e.children(n).length}),o=F(d.A(t,function(n){return e.node(n).rank})),i=d.A(g(o+1),function(){return[]}),u=fn(t,function(n){return e.node(n).rank});return r.A(u,function t(o){if(!z.A(n,o)){n[o]=!0;var u=e.node(o);i[u.rank].push(o),r.A(e.successors(o),t)}}),i}(e);_n(e,i);for(var u,a=Number.POSITIVE_INFINITY,s=0,c=0;c<4;++s,++c){yn(s%2?t:o,s%4>=2);var h=ln(e,i=Q(e));h<a&&(c=0,u=Qe(i),a=h)}_n(e,u)}function mn(e,n,t){return d.A(n,function(n){return Ue(e,n,t)})}function yn(e,n){var t=new p.T;r.A(e,function(e){var o=e.graph().root,i=wn(e,o,t,n);r.A(i.vs,function(n,t){e.node(n).order=t}),function(e,n,t){var o,i={};r.A(t,function(t){for(var r,u,a=e.parent(t);a;){if((r=e.parent(a))?(u=i[r],i[r]=a):(u=o,o=a),u&&u!==a)return void n.setEdge(u,a);a=r}})}(e,t,i.vs)})}function _n(e,n){r.A(n,function(n){r.A(n,function(n,t){e.node(n).order=t})})}function En(e){var n=function(e){var n={},t=0;function o(i){var u=t;r.A(e.children(i),o),n[i]={low:u,lim:t++}}return r.A(e.children(),o),n}(e);r.A(e.graph().dummyChains,function(t){for(var r=e.node(t),o=r.edgeObj,i=function(e,n,t,r){var o,i,u=[],a=[],s=Math.min(n[t].low,n[r].low),d=Math.max(n[t].lim,n[r].lim);o=t;do{o=e.parent(o),u.push(o)}while(o&&(n[o].low>s||d>n[o].lim));i=o,o=r;for(;(o=e.parent(o))!==i;)a.push(o);return{path:u.concat(a.reverse()),lca:i}}(e,n,o.v,o.w),u=i.path,a=i.lca,s=0,d=u[s],c=!0;t!==o.w;){if(r=e.node(t),c){for(;(d=u[s])!==a&&e.node(d).maxRank<r.rank;)s++;d===a&&(c=!1)}if(!c){for(;s<u.length-1&&e.node(d=u[s+1]).minRank<=r.rank;)s++;d=u[s]}e.setParent(t,d),t=e.successors(t)[0]}})}var xn=t(99922);const On=function(e,n){return e&&(0,G.A)(e,(0,xn.A)(n))};var kn=t(4574),Nn=t(55615);const Pn=function(e,n){return null==e?e:(0,kn.A)(e,(0,xn.A)(n),Nn.A)};function jn(e,n){var t={};return Je.A(n,function(n,o){var i=0,u=0,a=n.length,s=D.A(o);return r.A(o,function(n,d){var c=function(e,n){if(e.node(n).dummy)return pe.A(e.predecessors(n),function(n){return e.node(n).dummy})}(e,n),h=c?e.node(c).order:a;(c||n===s)&&(r.A(o.slice(u,d+1),function(n){r.A(e.predecessors(n),function(r){var o=e.node(r),u=o.order;!(u<i||h<u)||o.dummy&&e.node(n).dummy||Cn(t,r,n)})}),u=d+1,i=h)}),o}),t}function Cn(e,n,t){if(n>t){var r=n;n=t,t=r}var o=e[n];o||(e[n]=o={}),o[t]=!0}function In(e,n,t){if(n>t){var r=n;n=t,t=r}return!!e[n]&&Object.prototype.hasOwnProperty.call(e[n],t)}function Ln(e,n,t,o,i){var u={},a=function(e,n,t,o){var i=new p.T,u=e.graph(),a=function(e,n,t){return function(r,o,i){var u,a=r.node(o),s=r.node(i),d=0;if(d+=a.width/2,Object.prototype.hasOwnProperty.call(a,"labelpos"))switch(a.labelpos.toLowerCase()){case"l":u=-a.width/2;break;case"r":u=a.width/2}if(u&&(d+=t?u:-u),u=0,d+=(a.dummy?n:e)/2,d+=(s.dummy?n:e)/2,d+=s.width/2,Object.prototype.hasOwnProperty.call(s,"labelpos"))switch(s.labelpos.toLowerCase()){case"l":u=s.width/2;break;case"r":u=-s.width/2}return u&&(d+=t?u:-u),u=0,d}}(u.nodesep,u.edgesep,o);return r.A(n,function(n){var o;r.A(n,function(n){var r=t[n];if(i.setNode(r),o){var u=t[o],s=i.edge(u,r);i.setEdge(u,r,Math.max(a(e,n,o),s||0))}o=n})}),i}(e,n,t,i),s=i?"borderLeft":"borderRight";function d(e,n){for(var t=a.nodes(),r=t.pop(),o={};r;)o[r]?e(r):(o[r]=!0,t.push(r),t=t.concat(n(r))),r=t.pop()}return d(function(e){u[e]=a.inEdges(e).reduce(function(e,n){return Math.max(e,u[n.v]+a.edge(n))},0)},a.predecessors.bind(a)),d(function(n){var t=a.outEdges(n).reduce(function(e,n){return Math.min(e,u[n.w]-a.edge(n))},Number.POSITIVE_INFINITY),r=e.node(n);t!==Number.POSITIVE_INFINITY&&r.borderType!==s&&(u[n]=Math.max(u[n],t))},a.successors.bind(a)),r.A(o,function(e){u[e]=u[t[e]]}),u}function Tn(e){var n,t=Q(e),o=O.A(jn(e,t),function(e,n){var t={};function o(n,o,i,u,a){var s;r.A(g(o,i),function(o){s=n[o],e.node(s).dummy&&r.A(e.predecessors(s),function(n){var r=e.node(n);r.dummy&&(r.order<u||r.order>a)&&Cn(t,n,s)})})}return Je.A(n,function(n,t){var i,u=-1,a=0;return r.A(t,function(r,s){if("border"===e.node(r).dummy){var d=e.predecessors(r);d.length&&(i=e.node(d[0]).order,o(t,a,s,u,i),a=s,u=i)}o(t,a,t.length,i,n.length)}),t}),t}(e,t)),i={};r.A(["u","d"],function(u){n="u"===u?t:$e.A(t).reverse(),r.A(["l","r"],function(t){"r"===t&&(n=d.A(n,function(e){return $e.A(e).reverse()}));var a=("u"===u?e.predecessors:e.successors).bind(e),s=function(e,n,t,o){var i={},u={},a={};return r.A(n,function(e){r.A(e,function(e,n){i[e]=e,u[e]=e,a[e]=n})}),r.A(n,function(e){var n=-1;r.A(e,function(e){var r=o(e);if(r.length){r=fn(r,function(e){return a[e]});for(var s=(r.length-1)/2,d=Math.floor(s),c=Math.ceil(s);d<=c;++d){var h=r[d];u[e]===e&&n<a[h]&&!In(t,e,h)&&(u[h]=e,u[e]=i[e]=i[h],n=a[h])}}})}),{root:i,align:u}}(0,n,o,a),c=Ln(e,n,s.root,s.align,"r"===t);"r"===t&&(c=B(c,function(e){return-e})),i[u+t]=c})});var u=function(e,n){return de($e.A(n),function(n){var t=Number.NEGATIVE_INFINITY,r=Number.POSITIVE_INFINITY;return Pn(n,function(n,o){var i=function(e,n){return e.node(n).width}(e,o)/2;t=Math.max(n+i,t),r=Math.min(n-i,r)}),t-r})}(e,i);return function(e,n){var t=$e.A(n),o=Y.A(t),i=F(t);r.A(["u","d"],function(t){r.A(["l","r"],function(r){var u,a=t+r,s=e[a];if(s!==n){var d=$e.A(s);(u="l"===r?o-Y.A(d):i-F(d))&&(e[a]=B(s,function(e){return e+u}))}})})}(i,u),function(e,n){return B(e.ul,function(t,r){if(n)return e[n.toLowerCase()][r];var o=fn(d.A(e,r));return(o[1]+o[2])/2})}(i,e.graph().align)}function Mn(e){(function(e){var n=Q(e),t=e.graph().ranksep,o=0;r.A(n,function(n){var i=F(d.A(n,function(n){return e.node(n).height}));r.A(n,function(n){e.node(n).y=o+i/2}),o+=i+t})})(e=H(e)),On(Tn(e),function(n,t){e.node(t).x=n})}function Rn(e,n){var t=n&&n.debugTiming?X:ee;t("layout",()=>{var n=t(" buildLayoutGraph",()=>function(e){var n=new p.T({multigraph:!0,compound:!0}),t=$n(e.graph());return n.setGraph(O.A({},Dn,zn(t,Fn),I(t,Sn))),r.A(e.nodes(),function(t){var r=$n(e.node(t));n.setNode(t,L.A(zn(r,Gn),Vn)),n.setParent(t,e.parent(t))}),r.A(e.edges(),function(t){var r=$n(e.edge(t));n.setEdge(t,O.A({},qn,zn(r,Bn),I(r,Yn)))}),n}(e));t(" runLayout",()=>function(e,n){n(" makeSpaceForEdgeLabels",()=>function(e){var n=e.graph();n.ranksep/=2,r.A(e.edges(),function(t){var r=e.edge(t);r.minlen*=2,"c"!==r.labelpos.toLowerCase()&&("TB"===n.rankdir||"BT"===n.rankdir?r.width+=r.labeloffset:r.height+=r.labeloffset)})}(e)),n(" removeSelfEdges",()=>function(e){r.A(e.edges(),function(n){if(n.v===n.w){var t=e.node(n.v);t.selfEdges||(t.selfEdges=[]),t.selfEdges.push({e:n,label:e.edge(n)}),e.removeEdge(n)}})}(e)),n(" acyclic",()=>x(e)),n(" nestingGraph.run",()=>Ze(e)),n(" rank",()=>qe(H(e))),n(" injectEdgeLabelProxies",()=>function(e){r.A(e.edges(),function(n){var t=e.edge(n);if(t.width&&t.height){var r=e.node(n.v),o={rank:(e.node(n.w).rank-r.rank)/2+r.rank,e:n};Z(e,"edge-proxy",o,"_ep")}})}(e)),n(" removeEmptyRanks",()=>function(e){var n=Y.A(d.A(e.nodes(),function(n){return e.node(n).rank})),t=[];r.A(e.nodes(),function(r){var o=e.node(r).rank-n;t[o]||(t[o]=[]),t[o].push(r)});var o=0,i=e.graph().nodeRankFactor;r.A(t,function(n,t){q.A(n)&&t%i!==0?--o:o&&r.A(n,function(n){e.node(n).rank+=o})})}(e)),n(" nestingGraph.cleanup",()=>function(e){var n=e.graph();e.removeNode(n.nestingRoot),delete n.nestingRoot,r.A(e.edges(),function(n){e.edge(n).nestingEdge&&e.removeEdge(n)})}(e)),n(" normalizeRanks",()=>function(e){var n=Y.A(d.A(e.nodes(),function(n){return e.node(n).rank}));r.A(e.nodes(),function(t){var r=e.node(t);z.A(r,"rank")&&(r.rank-=n)})}(e)),n(" assignRankMinMax",()=>function(e){var n=0;r.A(e.nodes(),function(t){var r=e.node(t);r.borderTop&&(r.minRank=e.node(r.borderTop).rank,r.maxRank=e.node(r.borderBottom).rank,n=F(n,r.maxRank))}),e.graph().maxRank=n}(e)),n(" removeEdgeLabelProxies",()=>function(e){r.A(e.nodes(),function(n){var t=e.node(n);"edge-proxy"===t.dummy&&(e.edge(t.e).labelRank=t.rank,e.removeNode(n))})}(e)),n(" normalize.run",()=>ae(e)),n(" parentDummyChains",()=>En(e)),n(" addBorderSegments",()=>function(e){r.A(e.children(),function n(t){var o=e.children(t),i=e.node(t);if(o.length&&r.A(o,n),Object.prototype.hasOwnProperty.call(i,"minRank")){i.borderLeft=[],i.borderRight=[];for(var u=i.minRank,a=i.maxRank+1;u<a;++u)ne(e,"borderLeft","_bl",t,i,u),ne(e,"borderRight","_br",t,i,u)}})}(e)),n(" order",()=>bn(e)),n(" insertSelfEdges",()=>function(e){var n=Q(e);r.A(n,function(n){var t=0;r.A(n,function(n,o){var i=e.node(n);i.order=o+t,r.A(i.selfEdges,function(n){Z(e,"selfedge",{width:n.label.width,height:n.label.height,rank:i.rank,order:o+ ++t,e:n.e,label:n.label},"_se")}),delete i.selfEdges})})}(e)),n(" adjustCoordinateSystem",()=>function(e){var n=e.graph().rankdir.toLowerCase();"lr"!==n&&"rl"!==n||re(e)}(e)),n(" position",()=>Mn(e)),n(" positionSelfEdges",()=>function(e){r.A(e.nodes(),function(n){var t=e.node(n);if("selfedge"===t.dummy){var r=e.node(t.e.v),o=r.x+r.width/2,i=r.y,u=t.x-o,a=r.height/2;e.setEdge(t.e,t.label),e.removeNode(n),t.label.points=[{x:o+2*u/3,y:i-a},{x:o+5*u/6,y:i-a},{x:o+u,y:i},{x:o+5*u/6,y:i+a},{x:o+2*u/3,y:i+a}],t.label.x=t.x,t.label.y=t.y}})}(e)),n(" removeBorderNodes",()=>function(e){r.A(e.nodes(),function(n){if(e.children(n).length){var t=e.node(n),r=e.node(t.borderTop),o=e.node(t.borderBottom),i=e.node(D.A(t.borderLeft)),u=e.node(D.A(t.borderRight));t.width=Math.abs(u.x-i.x),t.height=Math.abs(o.y-r.y),t.x=i.x+t.width/2,t.y=r.y+t.height/2}}),r.A(e.nodes(),function(n){"border"===e.node(n).dummy&&e.removeNode(n)})}(e)),n(" normalize.undo",()=>function(e){r.A(e.graph().dummyChains,function(n){var t,r=e.node(n),o=r.edgeLabel;for(e.setEdge(r.edgeObj,o);r.dummy;)t=e.successors(n)[0],e.removeNode(n),o.points.push({x:r.x,y:r.y}),"edge-label"===r.dummy&&(o.x=r.x,o.y=r.y,o.width=r.width,o.height=r.height),n=t,r=e.node(n)})}(e)),n(" fixupEdgeLabelCoords",()=>function(e){r.A(e.edges(),function(n){var t=e.edge(n);if(Object.prototype.hasOwnProperty.call(t,"x"))switch("l"!==t.labelpos&&"r"!==t.labelpos||(t.width-=t.labeloffset),t.labelpos){case"l":t.x-=t.width/2+t.labeloffset;break;case"r":t.x+=t.width/2+t.labeloffset}})}(e)),n(" undoCoordinateSystem",()=>te(e)),n(" translateGraph",()=>function(e){var n=Number.POSITIVE_INFINITY,t=0,o=Number.POSITIVE_INFINITY,i=0,u=e.graph(),a=u.marginx||0,s=u.marginy||0;function d(e){var r=e.x,u=e.y,a=e.width,s=e.height;n=Math.min(n,r-a/2),t=Math.max(t,r+a/2),o=Math.min(o,u-s/2),i=Math.max(i,u+s/2)}r.A(e.nodes(),function(n){d(e.node(n))}),r.A(e.edges(),function(n){var t=e.edge(n);Object.prototype.hasOwnProperty.call(t,"x")&&d(t)}),n-=a,o-=s,r.A(e.nodes(),function(t){var r=e.node(t);r.x-=n,r.y-=o}),r.A(e.edges(),function(t){var i=e.edge(t);r.A(i.points,function(e){e.x-=n,e.y-=o}),Object.prototype.hasOwnProperty.call(i,"x")&&(i.x-=n),Object.prototype.hasOwnProperty.call(i,"y")&&(i.y-=o)}),u.width=t-n+a,u.height=i-o+s}(e)),n(" assignNodeIntersects",()=>function(e){r.A(e.edges(),function(n){var t,r,o=e.edge(n),i=e.node(n.v),u=e.node(n.w);o.points?(t=o.points[0],r=o.points[o.points.length-1]):(o.points=[],t=u,r=i),o.points.unshift(K(i,t)),o.points.push(K(u,r))})}(e)),n(" reversePoints",()=>function(e){r.A(e.edges(),function(n){var t=e.edge(n);t.reversed&&t.points.reverse()})}(e)),n(" acyclic.undo",()=>function(e){r.A(e.edges(),function(n){var t=e.edge(n);if(t.reversed){e.removeEdge(n);var r=t.forwardName;delete t.reversed,delete t.forwardName,e.setEdge(n.w,n.v,t,r)}})}(e))}(n,t)),t(" updateInputGraph",()=>function(e,n){r.A(e.nodes(),function(t){var r=e.node(t),o=n.node(t);r&&(r.x=o.x,r.y=o.y,n.children(t).length&&(r.width=o.width,r.height=o.height))}),r.A(e.edges(),function(t){var r=e.edge(t),o=n.edge(t);r.points=o.points,Object.prototype.hasOwnProperty.call(o,"x")&&(r.x=o.x,r.y=o.y)}),e.graph().width=n.graph().width,e.graph().height=n.graph().height}(e,n))})}var Fn=["nodesep","edgesep","ranksep","marginx","marginy"],Dn={ranksep:50,edgesep:20,nodesep:50,rankdir:"tb"},Sn=["acyclicer","ranker","rankdir","align"],Gn=["width","height"],Vn={width:0,height:0},Bn=["minlen","weight","width","height","labeloffset"],qn={minlen:1,weight:1,width:0,height:0,labeloffset:10,labelpos:"r"},Yn=["labelpos"];function zn(e,n){return B(I(e,n),Number)}function $n(e){var n={};return r.A(e,function(e,t){n[t.toLowerCase()]=e}),n}},72559:(e,n,t)=>{t.d(n,{A:()=>o});var r=t(61882);const o=function(e,n,t){for(var o=-1,i=e.length;++o<i;){var u=e[o],a=n(u);if(null!=a&&(void 0===s?a==a&&!(0,r.A)(a):t(a,s)))var s=a,d=u}return d}},74342:(e,n,t)=>{t.d(n,{A:()=>g});var r=/\s/;const o=function(e){for(var n=e.length;n--&&r.test(e.charAt(n)););return n};var i=/^\s+/;const u=function(e){return e?e.slice(0,o(e)+1).replace(i,""):e};var a=t(23149),s=t(61882),d=/^[-+]0x[0-9a-f]+$/i,c=/^0b[01]+$/i,h=/^0o[0-7]+$/i,f=parseInt;const l=function(e){if("number"==typeof e)return e;if((0,s.A)(e))return NaN;if((0,a.A)(e)){var n="function"==typeof e.valueOf?e.valueOf():e;e=(0,a.A)(n)?n+"":n}if("string"!=typeof e)return 0===e?e:+e;e=u(e);var t=c.test(e);return t||h.test(e)?f(e.slice(2),t?2:8):d.test(e)?NaN:+e};var v=1/0;const g=function(e){return e?(e=l(e))===v||e===-1/0?17976931348623157e292*(e<0?-1:1):e==e?e:0:0===e?e:0}},74722:(e,n,t)=>{t.d(n,{A:()=>a});var r=t(45572),o=t(23958),i=t(52568),u=t(92049);const a=function(e,n){return((0,u.A)(e)?r.A:i.A)(e,(0,o.A)(n,3))}},86452:(e,n,t)=>{t.d(n,{A:()=>u});var r=t(72559),o=t(36224),i=t(29008);const u=function(e){return e&&e.length?(0,r.A)(e,i.A,o.A):void 0}},99354:(e,n,t)=>{t.d(n,{A:()=>c});var r=t(66318),o=t(52851),i=t(7819),u=t(25353),a=t(23149),s=t(30901);const d=function(e,n,t,r){if(!(0,a.A)(e))return e;for(var d=-1,c=(n=(0,i.A)(n,e)).length,h=c-1,f=e;null!=f&&++d<c;){var l=(0,s.A)(n[d]),v=t;if("__proto__"===l||"constructor"===l||"prototype"===l)return e;if(d!=h){var g=f[l];void 0===(v=r?r(g,l,f):void 0)&&(v=(0,a.A)(g)?g:(0,u.A)(n[d+1])?[]:{})}(0,o.A)(f,l,v),f=f[l]}return e};const c=function(e,n,t){for(var o=-1,u=n.length,a={};++o<u;){var s=n[o],c=(0,r.A)(e,s);t(c,s)&&d(a,(0,i.A)(s,e),c)}return a}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/242e7908.2e5b368b.js b/pr-preview/pr-4027/assets/js/242e7908.2e5b368b.js deleted file mode 100644 index be443e79e..000000000 --- a/pr-preview/pr-4027/assets/js/242e7908.2e5b368b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6510],{26696:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Getting started","slug":"/category/getting-started","permalink":"/constellation/pr-preview/pr-4027/next/category/getting-started","sidebar":"docs","navigation":{"previous":{"title":"License","permalink":"/constellation/pr-preview/pr-4027/next/overview/license"},"next":{"title":"Installation","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/install"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/25e50762.f7764672.js b/pr-preview/pr-4027/assets/js/25e50762.f7764672.js deleted file mode 100644 index 1cbd0afff..000000000 --- a/pr-preview/pr-4027/assets/js/25e50762.f7764672.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7625],{28453:(e,s,t)=>{t.d(s,{R:()=>o,x:()=>l});var n=t(96540);const r={},i=n.createContext(r);function o(e){const s=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(i.Provider,{value:s},e.children)}},37789:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"workflows/storage","title":"Use persistent storage","description":"Persistent storage in Kubernetes requires cloud-specific configuration.","source":"@site/docs/workflows/storage.md","sourceDirName":"workflows","slug":"/workflows/storage","permalink":"/constellation/pr-preview/pr-4027/next/workflows/storage","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/workflows/storage.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Verify your cluster","permalink":"/constellation/pr-preview/pr-4027/next/workflows/verify-cluster"},"next":{"title":"Use the Terraform provider","permalink":"/constellation/pr-preview/pr-4027/next/workflows/terraform-provider"}}');var r=t(74848),i=t(28453);const o={},l="Use persistent storage",a={},c=[{value:"Confidential storage",id:"confidential-storage",level:2},{value:"CSI drivers",id:"csi-drivers",level:2},{value:"Installation",id:"installation",level:2},{value:"Change the default storage class",id:"change-the-default-storage-class",level:3}];function d(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components},{TabItem:t,Tabs:n}=s;return t||p("TabItem",!0),n||p("Tabs",!0),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"use-persistent-storage",children:"Use persistent storage"})}),"\n",(0,r.jsxs)(s.p,{children:["Persistent storage in Kubernetes requires cloud-specific configuration.\nFor abstraction of container storage, Kubernetes offers ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/volumes/",children:"volumes"}),",\nallowing users to mount storage solutions directly into containers.\nThe ",(0,r.jsx)(s.a,{href:"https://kubernetes-csi.github.io/docs/",children:"Container Storage Interface (CSI)"})," is the standard interface for exposing arbitrary block and file storage systems into containers in Kubernetes.\nCloud service providers (CSPs) offer their own CSI-based solutions for cloud storage."]}),"\n",(0,r.jsx)(s.h2,{id:"confidential-storage",children:"Confidential storage"}),"\n",(0,r.jsxs)(s.p,{children:["Most cloud storage solutions support encryption, such as ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/kubernetes-engine/docs/how-to/using-cmek",children:"GCE Persistent Disks (PD)"}),".\nConstellation supports the available CSI-based storage options for Kubernetes engines in AWS, Azure, GCP, and STACKIT.\nHowever, their encryption takes place in the storage backend and is managed by the CSP.\nThus, using the default CSI drivers for these storage types means trusting the CSP with your persistent data."]}),"\n",(0,r.jsxs)(s.p,{children:["To address this, Constellation provides CSI drivers for AWS EBS, Azure Disk, GCE PD, and OpenStack Cinder, offering ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys#storage-encryption",children:"encryption on the node level"}),". They enable transparent encryption for persistent volumes without needing to trust the cloud backend. Plaintext data never leaves the confidential VM context, offering you confidential storage."]}),"\n",(0,r.jsxs)(s.p,{children:["For more details see ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage",children:"encrypted persistent storage"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"csi-drivers",children:"CSI drivers"}),"\n",(0,r.jsx)(s.p,{children:"Constellation supports the following drivers, which offer node-level encryption and optional integrity protection."}),"\n",(0,r.jsxs)(n,{groupId:"csp",children:[(0,r.jsx)(t,{value:"aws",label:"AWS",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Constellation CSI driver for AWS Elastic Block Store"}),"\nMount ",(0,r.jsx)(s.a,{href:"https://aws.amazon.com/ebs/",children:"Elastic Block Store"})," storage volumes into your Constellation cluster.\nFollow the instructions on how to ",(0,r.jsx)(s.a,{href:"#installation",children:"install the Constellation CSI driver"})," or check out the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation-aws-ebs-csi-driver",children:"repository"})," for more information."]})}),(0,r.jsx)(t,{value:"azure",label:"Azure",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Constellation CSI driver for Azure Disk"}),":\nMount Azure ",(0,r.jsx)(s.a,{href:"https://azure.microsoft.com/en-us/services/storage/disks/#overview",children:"Disk Storage"})," into your Constellation cluster.\nSee the instructions on how to ",(0,r.jsx)(s.a,{href:"#installation",children:"install the Constellation CSI driver"})," or check out the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation-azuredisk-csi-driver",children:"repository"})," for more information.\nSince Azure Disks are mounted as ",(0,r.jsx)(s.code,{children:"ReadWriteOnce"}),", they're only available to a single pod."]})}),(0,r.jsx)(t,{value:"gcp",label:"GCP",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Constellation CSI driver for GCP Persistent Disk"}),":\nMount ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/persistent-disk",children:"Persistent Disk"})," block storage into your Constellation cluster.\nFollow the instructions on how to ",(0,r.jsx)(s.a,{href:"#installation",children:"install the Constellation CSI driver"})," or check out the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation-gcp-compute-persistent-disk-csi-driver",children:"repository"})," for more information."]})}),(0,r.jsx)(t,{value:"stackit",label:"STACKIT",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Constellation CSI driver for STACKIT / OpenStack Cinder"}),"\nMount ",(0,r.jsx)(s.a,{href:"https://docs.openstack.org/cinder/latest/",children:"Cinder"})," block storage volumes into your Constellation cluster.\nFollow the instructions on how to ",(0,r.jsx)(s.a,{href:"#installation",children:"install the Constellation CSI driver"})," or check out the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation-cloud-provider-openstack",children:"repository"})," for more information."]})})]}),"\n",(0,r.jsxs)(s.p,{children:["Note that in case the options above aren't a suitable solution for you, Constellation is compatible with all other CSI-based storage options. For example, you can use ",(0,r.jsx)(s.a,{href:"https://docs.aws.amazon.com/en_en/eks/latest/userguide/efs-csi.html",children:"AWS EFS"}),", ",(0,r.jsx)(s.a,{href:"https://docs.microsoft.com/en-us/azure/storage/files/storage-files-introduction",children:"Azure Files"}),", or ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/filestore",children:"GCP Filestore"})," with Constellation out of the box. Constellation is just not providing transparent encryption on the node level for these storage types yet."]}),"\n",(0,r.jsx)(s.h2,{id:"installation",children:"Installation"}),"\n",(0,r.jsxs)(s.p,{children:["The Constellation CLI automatically installs Constellation's CSI driver for the selected CSP in your cluster.\nIf you don't need a CSI driver or wish to deploy your own, you can disable the automatic installation by setting ",(0,r.jsx)(s.code,{children:"deployCSIDriver"})," to ",(0,r.jsx)(s.code,{children:"false"})," in your Constellation config file."]}),"\n",(0,r.jsxs)(n,{groupId:"csp",children:[(0,r.jsxs)(t,{value:"aws",label:"AWS",children:[(0,r.jsx)(s.p,{children:"AWS comes with two storage classes by default."}),(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsxs)(s.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volume-types.html",children:["SSDs of ",(0,r.jsx)(s.code,{children:"gp3"})," type"]})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsxs)(s.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volume-types.html",children:["SSDs of ",(0,r.jsx)(s.code,{children:"gp3"})," type"]})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n",(0,r.jsx)(s.li,{children:"Integrity protection of data written to disk"}),"\n"]}),"\n"]}),"\n"]}),(0,r.jsxs)(s.p,{children:["For more information on encryption algorithms and key sizes, refer to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage#cryptographic-algorithms",children:"cryptographic algorithms"}),"."]}),(0,r.jsxs)(s.admonition,{type:"info",children:[(0,r.jsxs)(s.p,{children:["The default storage class is set to ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," for performance reasons.\nIf you want integrity-protected storage, set the ",(0,r.jsx)(s.code,{children:"storageClassName"})," parameter of your persistent volume claim to ",(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"."]}),(0,r.jsxs)(s.p,{children:["Alternatively, you can create your own storage class with integrity protection enabled by adding ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: ext4-integrity"})," to the class ",(0,r.jsx)(s.code,{children:"parameters"}),".\nOr use another filesystem by specifying another file system type with the suffix ",(0,r.jsx)(s.code,{children:"-integrity"}),", e.g., ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: xfs-integrity"}),"."]}),(0,r.jsx)(s.p,{children:"Note that volume expansion isn't supported for integrity-protected disks."})]})]}),(0,r.jsxs)(t,{value:"azure",label:"Azure",children:[(0,r.jsx)(s.p,{children:"Azure comes with two storage classes by default."}),(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsx)(s.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/disks-types#standard-ssds",children:"Standard SSDs"})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsx)(s.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/disks-types#premium-ssds",children:"Premium SSDs"})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n",(0,r.jsx)(s.li,{children:"Integrity protection of data written to disk"}),"\n"]}),"\n"]}),"\n"]}),(0,r.jsxs)(s.p,{children:["For more information on encryption algorithms and key sizes, refer to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage#cryptographic-algorithms",children:"cryptographic algorithms"}),"."]}),(0,r.jsxs)(s.admonition,{type:"info",children:[(0,r.jsxs)(s.p,{children:["The default storage class is set to ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," for performance reasons.\nIf you want integrity-protected storage, set the ",(0,r.jsx)(s.code,{children:"storageClassName"})," parameter of your persistent volume claim to ",(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"."]}),(0,r.jsxs)(s.p,{children:["Alternatively, you can create your own storage class with integrity protection enabled by adding ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: ext4-integrity"})," to the class ",(0,r.jsx)(s.code,{children:"parameters"}),".\nOr use another filesystem by specifying another file system type with the suffix ",(0,r.jsx)(s.code,{children:"-integrity"}),", e.g., ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: xfs-integrity"}),"."]}),(0,r.jsx)(s.p,{children:"Note that volume expansion isn't supported for integrity-protected disks."})]})]}),(0,r.jsxs)(t,{value:"gcp",label:"GCP",children:[(0,r.jsx)(s.p,{children:"GCP comes with two storage classes by default."}),(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/compute/docs/disks#pdspecs",children:"standard persistent disks"})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/compute/docs/disks#pdspecs",children:"performance (SSD) persistent disks"})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n",(0,r.jsx)(s.li,{children:"Integrity protection of data written to disk"}),"\n"]}),"\n"]}),"\n"]}),(0,r.jsxs)(s.p,{children:["For more information on encryption algorithms and key sizes, refer to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage#cryptographic-algorithms",children:"cryptographic algorithms"}),"."]}),(0,r.jsxs)(s.admonition,{type:"info",children:[(0,r.jsxs)(s.p,{children:["The default storage class is set to ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," for performance reasons.\nIf you want integrity-protected storage, set the ",(0,r.jsx)(s.code,{children:"storageClassName"})," parameter of your persistent volume claim to ",(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"."]}),(0,r.jsxs)(s.p,{children:["Alternatively, you can create your own storage class with integrity protection enabled by adding ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: ext4-integrity"})," to the class ",(0,r.jsx)(s.code,{children:"parameters"}),".\nOr use another filesystem by specifying another file system type with the suffix ",(0,r.jsx)(s.code,{children:"-integrity"}),", e.g., ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: xfs-integrity"}),"."]}),(0,r.jsx)(s.p,{children:"Note that volume expansion isn't supported for integrity-protected disks."})]})]}),(0,r.jsxs)(t,{value:"stackit",label:"STACKIT",children:[(0,r.jsx)(s.p,{children:"STACKIT comes with two storage classes by default."}),(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsxs)(s.a,{href:"https://docs.stackit.cloud/stackit/en/service-plans-blockstorage-75137974.html",children:["disks of ",(0,r.jsx)(s.code,{children:"storage_premium_perf1"})," type"]})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsxs)(s.a,{href:"https://docs.stackit.cloud/stackit/en/service-plans-blockstorage-75137974.html",children:["disks of ",(0,r.jsx)(s.code,{children:"storage_premium_perf1"})," type"]})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n",(0,r.jsx)(s.li,{children:"Integrity protection of data written to disk"}),"\n"]}),"\n"]}),"\n"]}),(0,r.jsxs)(s.p,{children:["For more information on encryption algorithms and key sizes, refer to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage#cryptographic-algorithms",children:"cryptographic algorithms"}),"."]}),(0,r.jsxs)(s.admonition,{type:"info",children:[(0,r.jsxs)(s.p,{children:["The default storage class is set to ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," for performance reasons.\nIf you want integrity-protected storage, set the ",(0,r.jsx)(s.code,{children:"storageClassName"})," parameter of your persistent volume claim to ",(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"."]}),(0,r.jsxs)(s.p,{children:["Alternatively, you can create your own storage class with integrity protection enabled by adding ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: ext4-integrity"})," to the class ",(0,r.jsx)(s.code,{children:"parameters"}),".\nOr use another filesystem by specifying another file system type with the suffix ",(0,r.jsx)(s.code,{children:"-integrity"}),", e.g., ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: xfs-integrity"}),"."]}),(0,r.jsx)(s.p,{children:"Note that volume expansion isn't supported for integrity-protected disks."})]})]})]}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["Create a ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/",children:"persistent volume"})]}),"\n",(0,r.jsxs)(s.p,{children:["A ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims",children:"persistent volume claim"})," is a request for storage with certain properties.\nIt can refer to a storage class.\nThe following creates a persistent volume claim, requesting 20 GB of storage via the ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," storage class:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"cat <<EOF | kubectl apply -f -\nkind: PersistentVolumeClaim\napiVersion: v1\nmetadata:\n name: pvc-example\n namespace: default\nspec:\n accessModes:\n - ReadWriteOnce\n storageClassName: encrypted-rwo\n resources:\n requests:\n storage: 20Gi\nEOF\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Create a Pod with persistent storage"}),"\n",(0,r.jsx)(s.p,{children:"You can assign a persistent volume claim to an application in need of persistent storage.\nThe mounted volume will persist restarts.\nThe following creates a pod that uses the previously created persistent volume claim:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"cat <<EOF | kubectl apply -f -\napiVersion: v1\nkind: Pod\nmetadata:\n name: web-server\n namespace: default\nspec:\n containers:\n - name: web-server\n image: nginx\n volumeMounts:\n - mountPath: /var/lib/www/html\n name: mypvc\n volumes:\n - name: mypvc\n persistentVolumeClaim:\n claimName: pvc-example\n readOnly: false\nEOF\n"})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"change-the-default-storage-class",children:"Change the default storage class"}),"\n",(0,r.jsxs)(s.p,{children:["The default storage class is responsible for all persistent volume claims that don't explicitly request ",(0,r.jsx)(s.code,{children:"storageClassName"}),".\nConstellation creates a storage class with encryption enabled and sets this as the default class.\nIn case you wish to change it, follow the steps below:"]}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"List the storage classes in your cluster:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"kubectl get storageclass\n"})}),"\n",(0,r.jsx)(s.p,{children:"The output is similar to this:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-shell-session",children:"NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE\nencrypted-rwo (default) {your-csp}.csi.confidential.cloud Delete Immediate true 1d\nintegrity-encrypted-rwo {your-csp}.csi.confidential.cloud Delete Immediate false 1d\n"})}),"\n",(0,r.jsxs)(s.p,{children:["The default storage class is marked by ",(0,r.jsx)(s.code,{children:"(default)"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Mark old default storage class as non default"}),"\n",(0,r.jsx)(s.p,{children:"If you previously used another storage class as the default, you will have to remove that annotation:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:'kubectl patch storageclass encrypted-rwo -p \'{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}\'\n'})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Mark new class as the default"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:'kubectl patch storageclass integrity-encrypted-rwo -p \'{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}\'\n'})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Verify that your chosen storage class is default:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"kubectl get storageclass\n"})}),"\n",(0,r.jsx)(s.p,{children:"The output is similar to this:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-shell-session",children:"NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE\nencrypted-rwo {your-csp}.csi.confidential.cloud Delete Immediate true 1d\nintegrity-encrypted-rwo (default) {your-csp}.csi.confidential.cloud Delete Immediate false 1d\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}function p(e,s){throw new Error("Expected "+(s?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/260d3cdf.4f1fe1d9.js b/pr-preview/pr-4027/assets/js/260d3cdf.4f1fe1d9.js deleted file mode 100644 index 969b73deb..000000000 --- a/pr-preview/pr-4027/assets/js/260d3cdf.4f1fe1d9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9619],{16301:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"architecture/microservices","title":"Microservices","description":"Constellation takes care of bootstrapping and initializing a Confidential Kubernetes cluster.","source":"@site/versioned_docs/version-2.24/architecture/microservices.md","sourceDirName":"architecture","slug":"/architecture/microservices","permalink":"/constellation/pr-preview/pr-4027/architecture/microservices","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/architecture/microservices.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Versions and support","permalink":"/constellation/pr-preview/pr-4027/architecture/versions"},"next":{"title":"Attestation","permalink":"/constellation/pr-preview/pr-4027/architecture/attestation"}}');var i=n(74848),s=n(28453);const o={},a="Microservices",c={},l=[{value:"Bootstrapper",id:"bootstrapper",level:2},{value:"JoinService",id:"joinservice",level:2},{value:"VerificationService",id:"verificationservice",level:2},{value:"KeyService",id:"keyservice",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",mermaid:"mermaid",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"microservices",children:"Microservices"})}),"\n",(0,i.jsx)(t.p,{children:"Constellation takes care of bootstrapping and initializing a Confidential Kubernetes cluster.\nDuring the lifetime of the cluster, it handles day 2 operations such as key management, remote attestation, and updates.\nThese features are provided by several microservices:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#bootstrapper",children:"Bootstrapper"})," initializes a Constellation node and bootstraps the cluster"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#joinservice",children:"JoinService"})," joins new nodes to an existing cluster"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#verificationservice",children:"VerificationService"})," provides remote attestation functionality"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#keyservice",children:"KeyService"})," manages Constellation-internal keys"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"The relations between microservices are shown in the following diagram:"}),"\n",(0,i.jsx)(t.mermaid,{value:"flowchart LR\n subgraph admin [Admin's machine]\n A[Constellation CLI]\n end\n subgraph img [Constellation OS image]\n B[Constellation OS]\n C[Bootstrapper]\n end\n subgraph Kubernetes\n D[JoinService]\n E[KeyService]\n F[VerificationService]\n end\n A -- deploys --\x3e\n B -- starts --\x3e C\n C -- deploys --\x3e D\n C -- deploys --\x3e E\n C -- deploys --\x3e F"}),"\n",(0,i.jsx)(t.h2,{id:"bootstrapper",children:"Bootstrapper"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"Bootstrapper"})," is the first microservice launched after booting a Constellation node image.\nIt sets up that machine as a Kubernetes node and integrates that node into the Kubernetes cluster.\nTo this end, the ",(0,i.jsx)(t.em,{children:"Bootstrapper"})," first downloads and verifies the ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/overview/components/",children:"Kubernetes components"})," at the configured versions.\nThe ",(0,i.jsx)(t.em,{children:"Bootstrapper"})," tries to find an existing cluster and if successful, communicates with the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#joinservice",children:"JoinService"})," to join the node.\nOtherwise, it waits for an initialization request to create a new Kubernetes cluster."]}),"\n",(0,i.jsx)(t.h2,{id:"joinservice",children:"JoinService"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"JoinService"})," runs as ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/",children:"DaemonSet"})," on each control-plane node.\nNew nodes (at cluster start, or later through autoscaling) send a request to the service over ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/attestation#attested-tls-atls",children:"attested TLS (aTLS)"}),".\nThe ",(0,i.jsx)(t.em,{children:"JoinService"})," verifies the new node's certificate and attestation statement.\nIf attestation is successful, the new node is supplied with an encryption key from the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#keyservice",children:(0,i.jsx)(t.em,{children:"KeyService"})})," for its state disk, and a Kubernetes bootstrap token."]}),"\n",(0,i.jsx)(t.mermaid,{value:"sequenceDiagram\n participant New node\n participant JoinService\n New node->>JoinService: aTLS handshake (server side verification)\n JoinService--\x3e>New node: #\n New node->>+JoinService: IssueJoinTicket(DiskUUID, NodeName, IsControlPlane)\n JoinService->>+KeyService: GetDataKey(DiskUUID)\n KeyService--\x3e>-JoinService: DiskEncryptionKey\n JoinService--\x3e>-New node: DiskEncryptionKey, KubernetesJoinToken, ..."}),"\n",(0,i.jsx)(t.h2,{id:"verificationservice",children:"VerificationService"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"VerificationService"})," runs as DaemonSet on each node.\nIt provides user-facing functionality for remote attestation during the cluster's lifetime via an endpoint for ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/attestation#cluster-attestation",children:"verifying the cluster"}),".\nRead more about the hardware-based ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/attestation",children:"attestation feature"})," of Constellation and how to ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/verify-cluster",children:"verify"})," a cluster on the client side."]}),"\n",(0,i.jsx)(t.h2,{id:"keyservice",children:"KeyService"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"KeyService"})," runs as DaemonSet on each control-plane node.\nIt implements the key management for the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys#storage-encryption",children:"storage encryption keys"})," in Constellation. These keys are used for the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/images#state-disk",children:"state disk"})," of each node and the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/encrypted-storage",children:"transparently encrypted storage"})," for Kubernetes.\nDepending on wether the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys#constellation-managed-key-management",children:"constellation-managed"})," or ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys#user-managed-key-management",children:"user-managed"})," mode is used, the ",(0,i.jsx)(t.em,{children:"KeyService"})," holds the key encryption key (KEK) directly or calls an external key management service (KMS) for key derivation respectively."]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var r=n(96540);const i={},s=r.createContext(i);function o(e){const t=r.useContext(s);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/269ef64a.cc437b10.js b/pr-preview/pr-4027/assets/js/269ef64a.cc437b10.js deleted file mode 100644 index 18d23a41c..000000000 --- a/pr-preview/pr-4027/assets/js/269ef64a.cc437b10.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6664],{28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>l});var n=r(96540);const o={},s=n.createContext(o);function i(e){const t=n.useContext(s);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(s.Provider,{value:t},e.children)}},35080:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>l,default:()=>d,frontMatter:()=>i,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"workflows/create","title":"Create your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","source":"@site/docs/workflows/create.md","sourceDirName":"workflows","slug":"/workflows/create","permalink":"/constellation/pr-preview/pr-4027/next/workflows/create","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/workflows/create.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Configure your cluster","permalink":"/constellation/pr-preview/pr-4027/next/workflows/config"},"next":{"title":"Scale your cluster","permalink":"/constellation/pr-preview/pr-4027/next/workflows/scale"}}');var o=r(74848),s=r(28453);const i={},l="Create your cluster",a={},c=[{value:"Troubleshooting",id:"troubleshooting",level:3}];function u(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h3:"h3",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.R)(),...e.components},{AsciinemaWidget:r,TabItem:n,Tabs:i}=t;return r||h("AsciinemaWidget",!0),n||h("TabItem",!0),i||h("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"create-your-cluster",children:"Create your cluster"})}),"\n",(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsx)(t.p,{children:"This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details."})}),"\n",(0,o.jsx)(r,{src:"/constellation/assets/create-cluster.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,o.jsx)(t.hr,{}),"\n",(0,o.jsx)(t.p,{children:"Creating your cluster happens through multiple phases.\nThe most significant ones are:"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsx)(t.li,{children:"Creating the necessary resources in your cloud environment"}),"\n",(0,o.jsx)(t.li,{children:"Bootstrapping the Constellation cluster and setting up a connection"}),"\n",(0,o.jsx)(t.li,{children:"Installing the necessary Kubernetes components"}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.code,{children:"constellation apply"})," handles all this in a single command.\nYou can use the ",(0,o.jsx)(t.code,{children:"--skip-phases"})," flag to skip specific phases of the process.\nFor example, if you created the infrastructure manually, you can skip the cloud resource creation phase."]}),"\n",(0,o.jsxs)(t.p,{children:["See the ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/orchestration",children:"architecture"})," section for details on the inner workings of this process."]}),"\n",(0,o.jsx)(t.admonition,{type:"tip",children:(0,o.jsxs)(t.p,{children:["If you don't have a cloud subscription, you can also set up a ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/first-steps-local",children:"local Constellation cluster using virtualization"})," for testing."]})}),"\n",(0,o.jsxs)(t.p,{children:["Before you create the cluster, make sure to have a ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/config",children:"valid configuration file"}),"."]}),"\n",(0,o.jsxs)(i,{groupId:"usage",children:[(0,o.jsxs)(n,{value:"cli",label:"CLI",children:[(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation apply\n"})}),(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.code,{children:"apply"})," stores the state of your cluster's cloud resources in a ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/orchestration#cluster-creation-process",children:(0,o.jsx)(t.code,{children:"constellation-terraform"})})," directory in your workspace."]})]}),(0,o.jsxs)(n,{value:"self-managed",label:"Self-managed",children:[(0,o.jsx)(t.p,{children:"Self-managed infrastructure allows for more flexibility in the setup, by separating the infrastructure setup from the Constellation cluster management.\nThis provides flexibility in DevOps and can meet potential regulatory requirements.\nIt's recommended to use Terraform for infrastructure management, but you can use any tool of your choice."}),(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsxs)(t.p,{children:["When using Terraform, you can use the ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/terraform-provider",children:"Constellation Terraform provider"})," to manage the entire Constellation cluster lifecycle."]})}),(0,o.jsxs)(t.p,{children:["You can refer to the Terraform files for the selected CSP from the ",(0,o.jsx)(t.a,{href:"https://github.com/edgelesssys/constellation/tree/main/terraform/infrastructure",children:"Constellation GitHub repository"})," for a minimum Constellation cluster configuration. From this base, you can now add, edit, or substitute resources per your own requirements with the infrastructure\nmanagement tooling of your choice. You need to keep the essential functionality of the base configuration in order for your cluster to function correctly."]}),(0,o.jsxs)(t.admonition,{type:"info",children:[(0,o.jsxs)(t.p,{children:["On Azure, a manual update to the MAA provider's policy is necessary.\nYou can apply the update with the following command after creating the infrastructure, with ",(0,o.jsx)(t.code,{children:"<URL>"})," being the URL of the MAA provider (i.e., ",(0,o.jsx)(t.code,{children:"$(terraform output attestation_url | jq -r)"}),", when using the minimal Terraform configuration)."]}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation maa-patch <URL>\n"})})]}),(0,o.jsxs)(t.p,{children:["Make sure all necessary resources are created, e.g., through checking your CSP's portal and retrieve the necessary values, aligned with the outputs (specified in ",(0,o.jsx)(t.code,{children:"outputs.tf"}),") of the base configuration."]}),(0,o.jsxs)(t.p,{children:["Fill these outputs into the corresponding fields of the ",(0,o.jsx)(t.code,{children:"Infrastructure"})," block inside the ",(0,o.jsx)(t.code,{children:"constellation-state.yaml"})," file. For example, fill the IP or DNS name your cluster can be reached at into the ",(0,o.jsx)(t.code,{children:".Infrastructure.ClusterEndpoint"})," field."]}),(0,o.jsx)(t.p,{children:"With the required cloud resources set up, continue with initializing your cluster."}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation apply --skip-phases=infrastructure\n"})})]})]}),"\n",(0,o.jsxs)(t.p,{children:["Finally, configure ",(0,o.jsx)(t.code,{children:"kubectl"})," for your cluster:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:'export KUBECONFIG="$PWD/constellation-admin.conf"\n'})}),"\n",(0,o.jsx)(t.p,{children:"\ud83c\udfc1 That's it. You've successfully created a Constellation cluster."}),"\n",(0,o.jsx)(t.h3,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,o.jsxs)(t.p,{children:["In case ",(0,o.jsx)(t.code,{children:"apply"})," fails, the CLI collects logs from the bootstrapping instance and stores them inside ",(0,o.jsx)(t.code,{children:"constellation-cluster.log"}),"."]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}function h(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/2821.b92d32c5.js b/pr-preview/pr-4027/assets/js/2821.b92d32c5.js deleted file mode 100644 index aaec1564e..000000000 --- a/pr-preview/pr-4027/assets/js/2821.b92d32c5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2821],{21152:(e,t,a)=>{a.d(t,{P:()=>r});var l=a(67633),s=a(40797),r=(0,s.K2)((e,t,a,r)=>{e.attr("class",a);const{width:o,height:c,x:d,y:p}=n(e,t);(0,l.a$)(e,c,o,r);const h=i(d,p,o,c,t);e.attr("viewBox",h),s.Rm.debug(`viewBox configured: ${h} with padding: ${t}`)},"setupViewPortForSVG"),n=(0,s.K2)((e,t)=>{const a=e.node()?.getBBox()||{width:0,height:0,x:0,y:0};return{width:a.width+2*t,height:a.height+2*t,x:a.x,y:a.y}},"calculateDimensionsWithPadding"),i=(0,s.K2)((e,t,a,l,s)=>`${e-s} ${t-s} ${a} ${l}`,"createViewBox")},25871:(e,t,a)=>{function l(e,t){e.accDescr&&t.setAccDescription?.(e.accDescr),e.accTitle&&t.setAccTitle?.(e.accTitle),e.title&&t.setDiagramTitle?.(e.title)}a.d(t,{S:()=>l}),(0,a(40797).K2)(l,"populateCommonDb")},82821:(e,t,a)=>{a.d(t,{diagram:()=>v});var l=a(73590),s=a(21152),r=a(32387),n=a(25871),i=a(13226),o=a(67633),c=a(40797),d=a(78731),p=a(70451),h=class{constructor(){this.nodes=[],this.levels=new Map,this.outerNodes=[],this.classes=new Map,this.setAccTitle=o.SV,this.getAccTitle=o.iN,this.setDiagramTitle=o.ke,this.getDiagramTitle=o.ab,this.getAccDescription=o.m7,this.setAccDescription=o.EI}static{(0,c.K2)(this,"TreeMapDB")}getNodes(){return this.nodes}getConfig(){const e=o.UI,t=(0,o.zj)();return(0,i.$t)({...e.treemap,...t.treemap??{}})}addNode(e,t){this.nodes.push(e),this.levels.set(e,t),0===t&&(this.outerNodes.push(e),this.root??=e)}getRoot(){return{name:"",children:this.outerNodes}}addClass(e,t){const a=this.classes.get(e)??{id:e,styles:[],textStyles:[]},l=t.replace(/\\,/g,"\xa7\xa7\xa7").replace(/,/g,";").replace(/\xa7\xa7\xa7/g,",").split(";");l&&l.forEach(e=>{(0,r.KX)(e)&&(a?.textStyles?a.textStyles.push(e):a.textStyles=[e]),a?.styles?a.styles.push(e):a.styles=[e]}),this.classes.set(e,a)}getClasses(){return this.classes}getStylesForClass(e){return this.classes.get(e)?.styles??[]}clear(){(0,o.IU)(),this.nodes=[],this.levels=new Map,this.outerNodes=[],this.classes=new Map,this.root=void 0}};function m(e){if(!e.length)return[];const t=[],a=[];return e.forEach(e=>{const l={name:e.name,children:"Leaf"===e.type?void 0:[]};for(l.classSelector=e?.classSelector,e?.cssCompiledStyles&&(l.cssCompiledStyles=[e.cssCompiledStyles]),"Leaf"===e.type&&void 0!==e.value&&(l.value=e.value);a.length>0&&a[a.length-1].level>=e.level;)a.pop();if(0===a.length)t.push(l);else{const e=a[a.length-1].node;e.children?e.children.push(l):e.children=[l]}"Leaf"!==e.type&&a.push({node:l,level:e.level})}),t}(0,c.K2)(m,"buildHierarchy");var y=(0,c.K2)((e,t)=>{(0,n.S)(e,t);const a=[];for(const r of e.TreemapRows??[])"ClassDefStatement"===r.$type&&t.addClass(r.className??"",r.styleText??"");for(const r of e.TreemapRows??[]){const e=r.item;if(!e)continue;const l=r.indent?parseInt(r.indent):0,s=u(e),n=e.classSelector?t.getStylesForClass(e.classSelector):[],i=n.length>0?n.join(";"):void 0,o={level:l,name:s,type:e.$type,value:e.value,classSelector:e.classSelector,cssCompiledStyles:i};a.push(o)}const l=m(a),s=(0,c.K2)((e,a)=>{for(const l of e)t.addNode(l,a),l.children&&l.children.length>0&&s(l.children,a+1)},"addNodesRecursively");s(l,0)},"populate"),u=(0,c.K2)(e=>e.name?String(e.name):"","getItemName"),f={parser:{yy:void 0},parse:(0,c.K2)(async e=>{try{const t=d.qg,a=await t("treemap",e);c.Rm.debug("Treemap AST:",a);const l=f.parser?.yy;if(!(l instanceof h))throw new Error("parser.parser?.yy was not a TreemapDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.");y(a,l)}catch(t){throw c.Rm.error("Error parsing treemap:",t),t}},"parse")},g=10,S={draw:(0,c.K2)((e,t,a,n)=>{const i=n.db,d=i.getConfig(),h=d.padding??10,m=i.getDiagramTitle(),y=i.getRoot(),{themeVariables:u}=(0,o.zj)();if(!y)return;const f=m?30:0,S=(0,l.D)(t),x=d.nodeWidth?d.nodeWidth*g:960,b=d.nodeHeight?d.nodeHeight*g:500,v=x,$=b+f;let C;S.attr("viewBox",`0 0 ${v} ${$}`),(0,o.a$)(S,$,v,d.useMaxWidth);try{const e=d.valueFormat||",";if("$0,0"===e)C=(0,c.K2)(e=>"$"+(0,p.GPZ)(",")(e),"valueFormat");else if(e.startsWith("$")&&e.includes(",")){const t=/\.\d+/.exec(e),a=t?t[0]:"";C=(0,c.K2)(e=>"$"+(0,p.GPZ)(","+a)(e),"valueFormat")}else if(e.startsWith("$")){const t=e.substring(1);C=(0,c.K2)(e=>"$"+(0,p.GPZ)(t||"")(e),"valueFormat")}else C=(0,p.GPZ)(e)}catch(G){c.Rm.error("Error creating format function:",G),C=(0,p.GPZ)(",")}const w=(0,p.UMr)().range(["transparent",u.cScale0,u.cScale1,u.cScale2,u.cScale3,u.cScale4,u.cScale5,u.cScale6,u.cScale7,u.cScale8,u.cScale9,u.cScale10,u.cScale11]),L=(0,p.UMr)().range(["transparent",u.cScalePeer0,u.cScalePeer1,u.cScalePeer2,u.cScalePeer3,u.cScalePeer4,u.cScalePeer5,u.cScalePeer6,u.cScalePeer7,u.cScalePeer8,u.cScalePeer9,u.cScalePeer10,u.cScalePeer11]),k=(0,p.UMr)().range([u.cScaleLabel0,u.cScaleLabel1,u.cScaleLabel2,u.cScaleLabel3,u.cScaleLabel4,u.cScaleLabel5,u.cScaleLabel6,u.cScaleLabel7,u.cScaleLabel8,u.cScaleLabel9,u.cScaleLabel10,u.cScaleLabel11]);m&&S.append("text").attr("x",v/2).attr("y",f/2).attr("class","treemapTitle").attr("text-anchor","middle").attr("dominant-baseline","middle").text(m);const T=S.append("g").attr("transform",`translate(0, ${f})`).attr("class","treemapContainer"),M=(0,p.Sk5)(y).sum(e=>e.value??0).sort((e,t)=>(t.value??0)-(e.value??0)),P=(0,p.hkb)().size([x,b]).paddingTop(e=>e.children&&e.children.length>0?35:0).paddingInner(h).paddingLeft(e=>e.children&&e.children.length>0?g:0).paddingRight(e=>e.children&&e.children.length>0?g:0).paddingBottom(e=>e.children&&e.children.length>0?g:0).round(!0)(M),z=P.descendants().filter(e=>e.children&&e.children.length>0),F=T.selectAll(".treemapSection").data(z).enter().append("g").attr("class","treemapSection").attr("transform",e=>`translate(${e.x0},${e.y0})`);F.append("rect").attr("width",e=>e.x1-e.x0).attr("height",25).attr("class","treemapSectionHeader").attr("fill","none").attr("fill-opacity",.6).attr("stroke-width",.6).attr("style",e=>0===e.depth?"display: none;":""),F.append("clipPath").attr("id",(e,a)=>`clip-section-${t}-${a}`).append("rect").attr("width",e=>Math.max(0,e.x1-e.x0-12)).attr("height",25),F.append("rect").attr("width",e=>e.x1-e.x0).attr("height",e=>e.y1-e.y0).attr("class",(e,t)=>`treemapSection section${t}`).attr("fill",e=>w(e.data.name)).attr("fill-opacity",.6).attr("stroke",e=>L(e.data.name)).attr("stroke-width",2).attr("stroke-opacity",.4).attr("style",e=>{if(0===e.depth)return"display: none;";const t=(0,r.GX)({cssCompiledStyles:e.data.cssCompiledStyles});return t.nodeStyles+";"+t.borderStyles.join(";")}),F.append("text").attr("class","treemapSectionLabel").attr("x",6).attr("y",12.5).attr("dominant-baseline","middle").text(e=>0===e.depth?"":e.data.name).attr("font-weight","bold").attr("style",e=>{if(0===e.depth)return"display: none;";return"dominant-baseline: middle; font-size: 12px; fill:"+k(e.data.name)+"; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"+(0,r.GX)({cssCompiledStyles:e.data.cssCompiledStyles}).labelStyles.replace("color:","fill:")}).each(function(e){if(0===e.depth)return;const t=(0,p.Ltv)(this),a=e.data.name;t.text(a);const l=e.x1-e.x0;let s;if(!1!==d.showValues&&e.value){s=l-10-30-10-6}else{s=l-6-6}const r=Math.max(15,s),n=t.node();if(n.getComputedTextLength()>r){const e="...";let l=a;for(;l.length>0;){if(l=a.substring(0,l.length-1),0===l.length){t.text(e),n.getComputedTextLength()>r&&t.text("");break}if(t.text(l+e),n.getComputedTextLength()<=r)break}}}),!1!==d.showValues&&F.append("text").attr("class","treemapSectionValue").attr("x",e=>e.x1-e.x0-10).attr("y",12.5).attr("text-anchor","end").attr("dominant-baseline","middle").text(e=>e.value?C(e.value):"").attr("font-style","italic").attr("style",e=>{if(0===e.depth)return"display: none;";return"text-anchor: end; dominant-baseline: middle; font-size: 10px; fill:"+k(e.data.name)+"; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"+(0,r.GX)({cssCompiledStyles:e.data.cssCompiledStyles}).labelStyles.replace("color:","fill:")});const K=P.leaves(),D=T.selectAll(".treemapLeafGroup").data(K).enter().append("g").attr("class",(e,t)=>`treemapNode treemapLeafGroup leaf${t}${e.data.classSelector?` ${e.data.classSelector}`:""}x`).attr("transform",e=>`translate(${e.x0},${e.y0})`);D.append("rect").attr("width",e=>e.x1-e.x0).attr("height",e=>e.y1-e.y0).attr("class","treemapLeaf").attr("fill",e=>e.parent?w(e.parent.data.name):w(e.data.name)).attr("style",e=>(0,r.GX)({cssCompiledStyles:e.data.cssCompiledStyles}).nodeStyles).attr("fill-opacity",.3).attr("stroke",e=>e.parent?w(e.parent.data.name):w(e.data.name)).attr("stroke-width",3),D.append("clipPath").attr("id",(e,a)=>`clip-${t}-${a}`).append("rect").attr("width",e=>Math.max(0,e.x1-e.x0-4)).attr("height",e=>Math.max(0,e.y1-e.y0-4));if(D.append("text").attr("class","treemapLabel").attr("x",e=>(e.x1-e.x0)/2).attr("y",e=>(e.y1-e.y0)/2).attr("style",e=>"text-anchor: middle; dominant-baseline: middle; font-size: 38px;fill:"+k(e.data.name)+";"+(0,r.GX)({cssCompiledStyles:e.data.cssCompiledStyles}).labelStyles.replace("color:","fill:")).attr("clip-path",(e,a)=>`url(#clip-${t}-${a})`).text(e=>e.data.name).each(function(e){const t=(0,p.Ltv)(this),a=e.x1-e.x0,l=e.y1-e.y0,s=t.node(),r=a-8,n=l-8;if(r<10||n<10)return void t.style("display","none");let i=parseInt(t.style("font-size"),10);for(;s.getComputedTextLength()>r&&i>8;)i--,t.style("font-size",`${i}px`);let o=Math.max(6,Math.min(28,Math.round(.6*i))),c=i+2+o;for(;c>n&&i>8&&(i--,o=Math.max(6,Math.min(28,Math.round(.6*i))),!(o<6&&8===i));)t.style("font-size",`${i}px`),c=i+2+o;t.style("font-size",`${i}px`),(s.getComputedTextLength()>r||i<8||n<i)&&t.style("display","none")}),!1!==d.showValues){D.append("text").attr("class","treemapValue").attr("x",e=>(e.x1-e.x0)/2).attr("y",function(e){return(e.y1-e.y0)/2}).attr("style",e=>"text-anchor: middle; dominant-baseline: hanging; font-size: 28px;fill:"+k(e.data.name)+";"+(0,r.GX)({cssCompiledStyles:e.data.cssCompiledStyles}).labelStyles.replace("color:","fill:")).attr("clip-path",(e,a)=>`url(#clip-${t}-${a})`).text(e=>e.value?C(e.value):"").each(function(e){const t=(0,p.Ltv)(this),a=this.parentNode;if(!a)return void t.style("display","none");const l=(0,p.Ltv)(a).select(".treemapLabel");if(l.empty()||"none"===l.style("display"))return void t.style("display","none");const s=parseFloat(l.style("font-size")),r=Math.max(6,Math.min(28,Math.round(.6*s)));t.style("font-size",`${r}px`);const n=(e.y1-e.y0)/2+s/2+2;t.attr("y",n);const i=e.x1-e.x0,o=e.y1-e.y0-4,c=i-8;t.node().getComputedTextLength()>c||n+r>o||r<6?t.style("display","none"):t.style("display",null)})}const N=d.diagramPadding??8;(0,s.P)(S,N,"flowchart",d?.useMaxWidth||!1)},"draw"),getClasses:(0,c.K2)(function(e,t){return t.db.getClasses()},"getClasses")},x={sectionStrokeColor:"black",sectionStrokeWidth:"1",sectionFillColor:"#efefef",leafStrokeColor:"black",leafStrokeWidth:"1",leafFillColor:"#efefef",labelColor:"black",labelFontSize:"12px",valueFontSize:"10px",valueColor:"black",titleColor:"black",titleFontSize:"14px"},b=(0,c.K2)(({treemap:e}={})=>{const t=(0,i.$t)(x,e);return`\n .treemapNode.section {\n stroke: ${t.sectionStrokeColor};\n stroke-width: ${t.sectionStrokeWidth};\n fill: ${t.sectionFillColor};\n }\n .treemapNode.leaf {\n stroke: ${t.leafStrokeColor};\n stroke-width: ${t.leafStrokeWidth};\n fill: ${t.leafFillColor};\n }\n .treemapLabel {\n fill: ${t.labelColor};\n font-size: ${t.labelFontSize};\n }\n .treemapValue {\n fill: ${t.valueColor};\n font-size: ${t.valueFontSize};\n }\n .treemapTitle {\n fill: ${t.titleColor};\n font-size: ${t.titleFontSize};\n }\n `},"getStyles"),v={parser:f,get db(){return new h},renderer:S,styles:b}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/28513d82.46a0c6a0.js b/pr-preview/pr-4027/assets/js/28513d82.46a0c6a0.js deleted file mode 100644 index b2742831c..000000000 --- a/pr-preview/pr-4027/assets/js/28513d82.46a0c6a0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9612],{28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>r});var a=s(96540);const n={},l=a.createContext(n);function o(e){const t=a.useContext(l);return a.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),a.createElement(l.Provider,{value:t},e.children)}},62453:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>c});const a=JSON.parse('{"id":"getting-started/marketplaces","title":"Using Constellation via Cloud Marketplaces","description":"Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please contact us.","source":"@site/versioned_docs/version-2.23/getting-started/marketplaces.md","sourceDirName":"getting-started","slug":"/getting-started/marketplaces","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/marketplaces","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/getting-started/marketplaces.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"First steps (local)","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps-local"},"next":{"title":"Examples","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples"}}');var n=s(74848),l=s(28453);const o={},r="Using Constellation via Cloud Marketplaces",i={},c=[];function p(e){const t={a:"a",code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,l.R)(),...e.components},{TabItem:s,Tabs:a}=t;return s||h("TabItem",!0),a||h("Tabs",!0),(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"using-constellation-via-cloud-marketplaces",children:"Using Constellation via Cloud Marketplaces"})}),"\n",(0,n.jsxs)(t.p,{children:["Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please ",(0,n.jsx)(t.a,{href:"https://www.edgeless.systems/enterprise-support/",children:"contact us"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"This document explains how to run Constellation with the dynamically billed cloud marketplace images."}),"\n",(0,n.jsxs)(a,{groupId:"csp",children:[(0,n.jsxs)(s,{value:"aws",label:"AWS",children:[(0,n.jsxs)(t.p,{children:["To use Constellation's marketplace images, ensure that you are subscribed to the ",(0,n.jsx)(t.a,{href:"https://aws.amazon.com/marketplace/pp/prodview-2mbn65nv57oys",children:"marketplace offering"})," through the web portal."]}),(0,n.jsxs)(t.p,{children:["Then, enable the use of marketplace images in your Constellation ",(0,n.jsx)(t.code,{children:"constellation-conf.yaml"})," ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/config",children:"config file"}),":"]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:'yq eval -i ".provider.aws.useMarketplaceImage = true" constellation-conf.yaml\n'})})]}),(0,n.jsxs)(s,{value:"azure",label:"Azure",children:[(0,n.jsxs)(t.p,{children:["Constellation has a private marketplace plan. Please ",(0,n.jsx)(t.a,{href:"https://www.edgeless.systems/enterprise-support/",children:"contact us"})," to gain access."]}),(0,n.jsxs)(t.p,{children:["To use a marketplace image, you need to accept the marketplace image's terms once for your subscription with the ",(0,n.jsx)(t.a,{href:"https://learn.microsoft.com/en-us/cli/azure/vm/image/terms?view=azure-cli-latest",children:"Azure CLI"}),":"]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"az vm image terms accept --publisher edgelesssystems --offer constellation --plan constellation\n"})}),(0,n.jsxs)(t.p,{children:["Then, enable the use of marketplace images in your Constellation ",(0,n.jsx)(t.code,{children:"constellation-conf.yaml"})," ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/config",children:"config file"}),":"]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:'yq eval -i ".provider.azure.useMarketplaceImage = true" constellation-conf.yaml\n'})})]}),(0,n.jsxs)(s,{value:"gcp",label:"GCP",children:[(0,n.jsxs)(t.p,{children:["To use a marketplace image, ensure that the account is entitled to use marketplace images by Edgeless Systems by accepting the terms through the ",(0,n.jsx)(t.a,{href:"https://console.cloud.google.com/marketplace/vm/config/edgeless-systems-public/constellation",children:"web portal"}),"."]}),(0,n.jsxs)(t.p,{children:["Then, enable the use of marketplace images in your Constellation ",(0,n.jsx)(t.code,{children:"constellation-conf.yaml"})," ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/config",children:"config file"}),":"]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:'yq eval -i ".provider.gcp.useMarketplaceImage = true" constellation-conf.yaml\n'})})]}),(0,n.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,n.jsx)(t.p,{children:"On STACKIT, the selected Constellation image is always a marketplace image. You can find more information on the STACKIT portal."})})]}),"\n",(0,n.jsxs)(t.p,{children:["Ensure that the cluster uses an official release image version (i.e., ",(0,n.jsx)(t.code,{children:".image=vX.Y.Z"})," in the ",(0,n.jsx)(t.code,{children:"constellation-conf.yaml"})," file)."]}),"\n",(0,n.jsxs)(t.p,{children:["From there, you can proceed with the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/create",children:"cluster creation"})," as usual."]})]})}function d(e={}){const{wrapper:t}={...(0,l.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}function h(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/28a0f3ab.4e0d0da1.js b/pr-preview/pr-4027/assets/js/28a0f3ab.4e0d0da1.js deleted file mode 100644 index 267057c2d..000000000 --- a/pr-preview/pr-4027/assets/js/28a0f3ab.4e0d0da1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4954],{3051:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_net_p2p_azure-fbad5555553d559281f605939f5e26c8.png"},9281:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_fio_azure_bw-9294313529fb8cc2c0230b3b581faddb.png"},28453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>a});var r=s(96540);const i={},o=r.createContext(i);function t(e){const n=r.useContext(o);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),r.createElement(o.Provider,{value:n},e.children)}},42202:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_net_p2svc_gcp-4ae5b9b8d4317ad9d3005c4243d78367.png"},55722:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_fio_gcp_iops-ba4f26c2dd679d3d5e4ad7c7b0c8370e.png"},68435:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_fio_azure_iops-a85caab4031a29df58a3e7175a62b792.png"},82624:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_fio_gcp_bw-f8739bb79b0e47f896217bcacba14cdf.png"},85612:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_net_p2p_gcp-8ce759468868272c67b53f5db2a3cf88.png"},90809:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"overview/performance/io","title":"I/O performance benchmarks","description":"To assess the overall performance of Constellation, this benchmark evaluates Constellation v2.6.0 in terms of storage I/O using fio and network performance using the Kubernetes Network Benchmark.","source":"@site/versioned_docs/version-2.23/overview/performance/io.md","sourceDirName":"overview/performance","slug":"/overview/performance/io","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/performance/io","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/overview/performance/io.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Compute benchmarks","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/performance/compute"},"next":{"title":"Application benchmarks","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/performance/application"}}');var i=s(74848),o=s(28453);const t={},a="I/O performance benchmarks",l={},c=[{value:"Configurations",id:"configurations",level:2},{value:"Constellation",id:"constellation",level:3},{value:"AKS",id:"aks",level:3},{value:"GKE",id:"gke",level:3},{value:"Results",id:"results",level:2},{value:"Network",id:"network",level:3},{value:"Pod-to-Pod",id:"pod-to-pod",level:4},{value:"Pod-to-Service",id:"pod-to-service",level:4},{value:"Storage I/O",id:"storage-io",level:3},{value:"Conclusion",id:"conclusion",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",mermaid:"mermaid",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"io-performance-benchmarks",children:"I/O performance benchmarks"})}),"\n",(0,i.jsxs)(n.p,{children:["To assess the overall performance of Constellation, this benchmark evaluates Constellation v2.6.0 in terms of storage I/O using ",(0,i.jsx)(n.a,{href:"https://fio.readthedocs.io/en/latest/fio_doc.html",children:(0,i.jsx)(n.code,{children:"fio"})})," and network performance using the ",(0,i.jsx)(n.a,{href:"https://github.com/InfraBuilder/k8s-bench-suite#knb--kubernetes-network-be",children:"Kubernetes Network Benchmark"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"This benchmark tested Constellation on Azure and GCP and compared the results against the managed Kubernetes offerings AKS and GKE."}),"\n",(0,i.jsx)(n.h2,{id:"configurations",children:"Configurations"}),"\n",(0,i.jsx)(n.h3,{id:"constellation",children:"Constellation"}),"\n",(0,i.jsx)(n.p,{children:"The benchmark was conducted with Constellation v2.6.0, Kubernetes v1.25.7, and Cilium v1.12.\nIt ran on the following infrastructure configurations."}),"\n",(0,i.jsx)(n.p,{children:"Constellation on Azure:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Nodes: 3 (1 Control-plane, 2 Worker)"}),"\n",(0,i.jsxs)(n.li,{children:["Machines: ",(0,i.jsx)(n.code,{children:"DC4as_v5"}),": 3rd Generation AMD EPYC 7763v (Milan) processor with 4 Cores, 16 GiB memory"]}),"\n",(0,i.jsxs)(n.li,{children:["CVM: ",(0,i.jsx)(n.code,{children:"true"})]}),"\n",(0,i.jsxs)(n.li,{children:["Region: ",(0,i.jsx)(n.code,{children:"West US"})]}),"\n",(0,i.jsxs)(n.li,{children:["Zone: ",(0,i.jsx)(n.code,{children:"2"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Constellation on GCP:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Nodes: 3 (1 Control-plane, 2 Worker)"}),"\n",(0,i.jsxs)(n.li,{children:["Machines: ",(0,i.jsx)(n.code,{children:"n2d-standard-4"}),": 2nd Generation AMD EPYC (Rome) processor with 4 Cores, 16 GiB of memory"]}),"\n",(0,i.jsxs)(n.li,{children:["CVM: ",(0,i.jsx)(n.code,{children:"true"})]}),"\n",(0,i.jsxs)(n.li,{children:["Zone: ",(0,i.jsx)(n.code,{children:"europe-west3-b"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"aks",children:"AKS"}),"\n",(0,i.jsxs)(n.p,{children:["On AKS, the benchmark used Kubernetes ",(0,i.jsx)(n.code,{children:"v1.24.9"})," and nodes with version ",(0,i.jsx)(n.code,{children:"AKSUbuntu-1804gen2containerd-2023.02.15"}),".\nAKS ran with the ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/concepts-network#kubenet-basic-networking",children:(0,i.jsx)(n.code,{children:"kubenet"})})," CNI and the ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/azure-disk-csi",children:"default CSI driver"})," for Azure Disk."]}),"\n",(0,i.jsx)(n.p,{children:"The following infrastructure configurations was used:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Nodes: 2 (2 Worker)"}),"\n",(0,i.jsxs)(n.li,{children:["Machines: ",(0,i.jsx)(n.code,{children:"D4as_v5"}),": 3rd Generation AMD EPYC 7763v (Milan) processor with 4 Cores, 16 GiB memory"]}),"\n",(0,i.jsxs)(n.li,{children:["CVM: ",(0,i.jsx)(n.code,{children:"false"})]}),"\n",(0,i.jsxs)(n.li,{children:["Region: ",(0,i.jsx)(n.code,{children:"West US"})]}),"\n",(0,i.jsxs)(n.li,{children:["Zone: ",(0,i.jsx)(n.code,{children:"2"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"gke",children:"GKE"}),"\n",(0,i.jsxs)(n.p,{children:["On GKE, the benchmark used Kubernetes ",(0,i.jsx)(n.code,{children:"v1.24.9"})," and nodes with version ",(0,i.jsx)(n.code,{children:"1.24.9-gke.3200"}),".\nGKE ran with the ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/kubernetes-engine/docs/concepts/network-overview",children:(0,i.jsx)(n.code,{children:"kubenet"})})," CNI and the ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/gce-pd-csi-driver",children:"default CSI driver"})," for Compute Engine persistent disk."]}),"\n",(0,i.jsx)(n.p,{children:"The following infrastructure configurations was used:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Nodes: 2 (2 Worker)"}),"\n",(0,i.jsxs)(n.li,{children:["Machines: ",(0,i.jsx)(n.code,{children:"n2d-standard-4"})," 2nd Generation AMD EPYC (Rome) processor with 4 Cores, 16 GiB of memory"]}),"\n",(0,i.jsxs)(n.li,{children:["CVM: ",(0,i.jsx)(n.code,{children:"false"})]}),"\n",(0,i.jsxs)(n.li,{children:["Zone: ",(0,i.jsx)(n.code,{children:"europe-west3-b"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"results",children:"Results"}),"\n",(0,i.jsx)(n.h3,{id:"network",children:"Network"}),"\n",(0,i.jsxs)(n.p,{children:["This section gives a thorough analysis of the network performance of Constellation, specifically focusing on measuring TCP and UDP bandwidth.\nThe benchmark measured the bandwidth of pod-to-pod and pod-to-service connections between two different nodes using ",(0,i.jsx)(n.a,{href:"https://iperf.fr/",children:(0,i.jsx)(n.code,{children:"iperf"})}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["GKE and Constellation on GCP had a maximum network bandwidth of ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/general-purpose-machines#n2d_machines",children:"10 Gbps"}),".\nAKS with ",(0,i.jsx)(n.code,{children:"Standard_D4as_v5"})," machines a maximum network bandwidth of ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/dasv5-dadsv5-series#dasv5-series",children:"12.5 Gbps"}),".\nThe Confidential VM equivalent ",(0,i.jsx)(n.code,{children:"Standard_DC4as_v5"})," currently has a network bandwidth of ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/dcasv5-dcadsv5-series#dcasv5-series-products",children:"1.25 Gbps"}),".\nTherefore, to make the test comparable, both AKS and Constellation on Azure were running with ",(0,i.jsx)(n.code,{children:"Standard_DC4as_v5"})," machines and 1.25 Gbps bandwidth."]}),"\n",(0,i.jsx)(n.p,{children:"Constellation on Azure and AKS used an MTU of 1500.\nConstellation on GCP used an MTU of 8896. GKE used an MTU of 1450."}),"\n",(0,i.jsx)(n.p,{children:"The difference in network bandwidth can largely be attributed to two factors."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Constellation's ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/networking",children:"network encryption"})," via Cilium and WireGuard, which protects data in-transit."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"https://lore.kernel.org/all/20200204193500.GA15564@ashkalra_ubuntu_server/T/",children:"AMD SEV using SWIOTLB bounce buffers"})," for all DMA including network I/O."]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"pod-to-pod",children:"Pod-to-Pod"}),"\n",(0,i.jsx)(n.p,{children:"In this scenario, the client Pod connects directly to the server pod via its IP address."}),"\n",(0,i.jsx)(n.mermaid,{value:"flowchart LR\n subgraph Node A\n Client[Client]\n end\n subgraph Node B\n Server[Server]\n end\n Client ==>|traffic| Server"}),"\n",(0,i.jsx)(n.p,{children:'The results for "Pod-to-Pod" on Azure are as follows:'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Network Pod2Pod Azure benchmark graph",src:s(3051).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:'The results for "Pod-to-Pod" on GCP are as follows:'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Network Pod2Pod GCP benchmark graph",src:s(85612).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.h4,{id:"pod-to-service",children:"Pod-to-Service"}),"\n",(0,i.jsx)(n.p,{children:"In this scenario, the client Pod connects to the server Pod via a ClusterIP service. This is more relevant to real-world use cases."}),"\n",(0,i.jsx)(n.mermaid,{value:"flowchart LR\n subgraph Node A\n Client[Client] ==>|traffic| Service[Service]\n end\n subgraph Node B\n Server[Server]\n end\n Service ==>|traffic| Server"}),"\n",(0,i.jsx)(n.p,{children:'The results for "Pod-to-Pod" on Azure are as follows:'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Network Pod2SVC Azure benchmark graph",src:s(91065).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:'The results for "Pod-to-Pod" on GCP are as follows:'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Network Pod2SVC GCP benchmark graph",src:s(42202).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"In our recent comparison of Constellation on GCP with GKE, Constellation has 58% less TCP bandwidth. However, UDP bandwidth was slightly better with Constellation, thanks to its higher MTU."}),"\n",(0,i.jsx)(n.p,{children:"Similarly, when comparing Constellation on Azure with AKS using CVMs, Constellation achieved approximately 10% less TCP and 40% less UDP bandwidth."}),"\n",(0,i.jsx)(n.h3,{id:"storage-io",children:"Storage I/O"}),"\n",(0,i.jsxs)(n.p,{children:["Azure and GCP offer persistent storage for their Kubernetes services AKS and GKE via the Container Storage Interface (CSI). CSI storage in Kubernetes is available via ",(0,i.jsx)(n.code,{children:"PersistentVolumes"})," (PV) and consumed via ",(0,i.jsx)(n.code,{children:"PersistentVolumeClaims"})," (PVC).\nUpon requesting persistent storage through a PVC, GKE and AKS will provision a PV as defined by a default ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/storage/storage-classes/",children:"storage class"}),".\nConstellation provides persistent storage on Azure and GCP ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage",children:"that's encrypted on the CSI layer"}),".\nSimilarly, upon a PVC request, Constellation will provision a PV via a default storage class."]}),"\n",(0,i.jsxs)(n.p,{children:["For Constellation on Azure and AKS, the benchmark ran with Azure Disk storage ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/disks-types#standard-ssds",children:"Standard SSD"})," of 400 GiB size.\nThe ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/dasv5-dadsv5-series#dasv5-series",children:"DC4as machine type"})," with four cores provides the following maximum performance:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"6400 (20000 burst) IOPS"}),"\n",(0,i.jsx)(n.li,{children:"144 MB/s (600 MB/s burst) throughput"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["However, the performance is bound by the capabilities of the ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/disks-types#standard-ssds",children:"512 GiB Standard SSD size"})," (the size class of 400 GiB volumes):"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"500 (600 burst) IOPS"}),"\n",(0,i.jsx)(n.li,{children:"60 MB/s (150 MB/s burst) throughput"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["For Constellation on GCP and GKE, the benchmark ran with Compute Engine Persistent Disk Storage ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/disks",children:"pd-balanced"})," of 400 GiB size.\nThe N2D machine type with four cores and pd-balanced provides the following ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/disks/performance#n2d_vms",children:"maximum performance"}),":"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"3,000 read IOPS"}),"\n",(0,i.jsx)(n.li,{children:"15,000 write IOPS"}),"\n",(0,i.jsx)(n.li,{children:"240 MB/s read throughput"}),"\n",(0,i.jsx)(n.li,{children:"240 MB/s write throughput"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["However, the performance is bound by the capabilities of a ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/disks/performance#zonal-persistent-disks",children:(0,i.jsx)(n.code,{children:"Zonal balanced PD"})})," with 400 GiB size:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"2400 read IOPS"}),"\n",(0,i.jsx)(n.li,{children:"2400 write IOPS"}),"\n",(0,i.jsx)(n.li,{children:"112 MB/s read throughput"}),"\n",(0,i.jsx)(n.li,{children:"112 MB/s write throughput"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"https://fio.readthedocs.io/en/latest/fio_doc.html",children:(0,i.jsx)(n.code,{children:"fio"})})," benchmark consists of several tests.\nThe benchmark used ",(0,i.jsx)(n.a,{href:"https://github.com/kastenhq/kubestr",children:(0,i.jsx)(n.code,{children:"Kubestr"})})," to run ",(0,i.jsx)(n.code,{children:"fio"})," in Kubernetes.\nThe default test performs randomized access patterns that accurately depict worst-case I/O scenarios for most applications."]}),"\n",(0,i.jsxs)(n.p,{children:["The following ",(0,i.jsx)(n.code,{children:"fio"})," settings were used:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"No Cloud caching"}),"\n",(0,i.jsx)(n.li,{children:"No OS caching"}),"\n",(0,i.jsx)(n.li,{children:"Single CPU"}),"\n",(0,i.jsx)(n.li,{children:"60 seconds runtime"}),"\n",(0,i.jsx)(n.li,{children:"10 seconds ramp-up time"}),"\n",(0,i.jsx)(n.li,{children:"10 GiB file"}),"\n",(0,i.jsx)(n.li,{children:"IOPS: 4 KB blocks and 128 iodepth"}),"\n",(0,i.jsx)(n.li,{children:"Bandwidth: 1024 KB blocks and 128 iodepth"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["For more details, see the ",(0,i.jsxs)(n.a,{href:"https://github.com/edgelesssys/constellation/blob/main/.github/actions/e2e_benchmark/fio.ini",children:[(0,i.jsx)(n.code,{children:"fio"})," test configuration"]}),"."]}),"\n",(0,i.jsx)(n.p,{children:"The results for IOPS on Azure are as follows:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"I/O IOPS Azure benchmark graph",src:s(68435).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"The results for IOPS on GCP are as follows:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"I/O IOPS GCP benchmark graph",src:s(55722).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"The results for bandwidth on Azure are as follows:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"I/O bandwidth Azure benchmark graph",src:s(9281).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"The results for bandwidth on GCP are as follows:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"I/O bandwidth GCP benchmark graph",src:s(82624).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"On GCP, the results exceed the maximum performance guarantees of the chosen disk type. There are two possible explanations for this. The first is that there may be cloud caching in place that isn't configurable. Alternatively, the underlying provisioned disk size may be larger than what was requested, resulting in higher performance boundaries."}),"\n",(0,i.jsx)(n.p,{children:"When comparing Constellation on GCP with GKE, Constellation has similar bandwidth but about 10% less IOPS performance. On Azure, Constellation has similar IOPS performance compared to AKS, where both likely hit the maximum storage performance. However, Constellation has approximately 15% less read and write bandwidth."}),"\n",(0,i.jsx)(n.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,i.jsxs)(n.p,{children:["Despite the added ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/overview/security-benefits",children:"security benefits"})," that Constellation provides, it only incurs a slight performance overhead when compared to managed Kubernetes offerings such as AKS and GKE. In most compute benchmarks, Constellation is on par with it's alternatives.\nWhile it may be slightly slower in certain I/O scenarios due to network and storage encryption, there is ongoing work to reduce this overhead to single digits."]}),"\n",(0,i.jsxs)(n.p,{children:["For instance, storage encryption only adds between 10% to 15% overhead in terms of bandwidth and IOPS.\nMeanwhile, the biggest performance impact that Constellation currently faces is network encryption, which can incur up to 58% overhead on a 10 Gbps network.\nHowever, the Cilium team has conducted ",(0,i.jsx)(n.a,{href:"https://docs.cilium.io/en/latest/operations/performance/benchmark/#encryption-wireguard-ipsec",children:"benchmarks with Cilium using WireGuard encryption"})," on a 100 Gbps network that yielded over 15 Gbps.\nWe're confident that Constellation will provide a similar level of performance with an upcoming release."]}),"\n",(0,i.jsx)(n.p,{children:"Overall, Constellation strikes a great balance between security and performance, and we're continuously working to improve its performance capabilities while maintaining its high level of security."})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},91065:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_net_p2svc_azure-823916c53e426752564179c0f7147266.png"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/291.ab24d400.js b/pr-preview/pr-4027/assets/js/291.ab24d400.js deleted file mode 100644 index 73ec7c296..000000000 --- a/pr-preview/pr-4027/assets/js/291.ab24d400.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[291],{50291:(t,e,n)=>{n.d(e,{diagram:()=>Y});var i=n(67633),s=n(40797),r=n(70451),a=n(3219),o=n(78041),c=n(75263),l=function(){var t=(0,s.K2)(function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},"o"),e=[6,8,10,11,12,14,16,17,20,21],n=[1,9],i=[1,10],r=[1,11],a=[1,12],o=[1,13],c=[1,16],l=[1,17],h={trace:(0,s.K2)(function(){},"trace"),yy:{},symbols_:{error:2,start:3,timeline:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,period_statement:18,event_statement:19,period:20,event:21,$accept:0,$end:1},terminals_:{2:"error",4:"timeline",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",20:"period",21:"event"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[18,1],[19,1]],performAction:(0,s.K2)(function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 2:case 6:case 7:this.$=[];break;case 3:r[o-1].push(r[o]),this.$=r[o-1];break;case 4:case 5:this.$=r[o];break;case 8:i.getCommonDb().setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 9:this.$=r[o].trim(),i.getCommonDb().setAccTitle(this.$);break;case 10:case 11:this.$=r[o].trim(),i.getCommonDb().setAccDescription(this.$);break;case 12:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 15:i.addTask(r[o],0,""),this.$=r[o];break;case 16:i.addEvent(r[o].substr(2)),this.$=r[o]}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:n,12:i,14:r,16:a,17:o,18:14,19:15,20:c,21:l},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:18,11:n,12:i,14:r,16:a,17:o,18:14,19:15,20:c,21:l},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,19]},{15:[1,20]},t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),t(e,[2,15]),t(e,[2,16]),t(e,[2,4]),t(e,[2,9]),t(e,[2,10])],defaultActions:{},parseError:(0,s.K2)(function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},"parseError"),parse:(0,s.K2)(function(t){var e=this,n=[0],i=[],r=[null],a=[],o=this.table,c="",l=0,h=0,d=0,u=a.slice.call(arguments,1),p=Object.create(this.lexer),y={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(y.yy[g]=this.yy[g]);p.setInput(t,y.yy),y.yy.lexer=p,y.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var f=p.yylloc;a.push(f);var m=p.options&&p.options.ranges;function x(){var t;return"number"!=typeof(t=i.pop()||p.lex()||1)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,s.K2)(function(t){n.length=n.length-2*t,r.length=r.length-t,a.length=a.length-t},"popStack"),(0,s.K2)(x,"lex");for(var b,k,_,w,v,K,S,$,E,T={};;){if(_=n[n.length-1],this.defaultActions[_]?w=this.defaultActions[_]:(null==b&&(b=x()),w=o[_]&&o[_][b]),void 0===w||!w.length||!w[0]){var I="";for(K in E=[],o[_])this.terminals_[K]&&K>2&&E.push("'"+this.terminals_[K]+"'");I=p.showPosition?"Parse error on line "+(l+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(I,{text:p.match,token:this.terminals_[b]||b,line:p.yylineno,loc:f,expected:E})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+_+", token: "+b);switch(w[0]){case 1:n.push(b),r.push(p.yytext),a.push(p.yylloc),n.push(w[1]),b=null,k?(b=k,k=null):(h=p.yyleng,c=p.yytext,l=p.yylineno,f=p.yylloc,d>0&&d--);break;case 2:if(S=this.productions_[w[1]][1],T.$=r[r.length-S],T._$={first_line:a[a.length-(S||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(S||1)].first_column,last_column:a[a.length-1].last_column},m&&(T._$.range=[a[a.length-(S||1)].range[0],a[a.length-1].range[1]]),void 0!==(v=this.performAction.apply(T,[c,h,l,y.yy,w[1],r,a].concat(u))))return v;S&&(n=n.slice(0,-1*S*2),r=r.slice(0,-1*S),a=a.slice(0,-1*S)),n.push(this.productions_[w[1]][0]),r.push(T.$),a.push(T._$),$=o[n[n.length-2]][n[n.length-1]],n.push($);break;case 3:return!0}}return!0},"parse")},d=function(){return{EOF:1,parseError:(0,s.K2)(function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},"parseError"),setInput:(0,s.K2)(function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:(0,s.K2)(function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},"input"),unput:(0,s.K2)(function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},"unput"),more:(0,s.K2)(function(){return this._more=!0,this},"more"),reject:(0,s.K2)(function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"reject"),less:(0,s.K2)(function(t){this.unput(this.match.slice(t))},"less"),pastInput:(0,s.K2)(function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:(0,s.K2)(function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:(0,s.K2)(function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},"showPosition"),test_match:(0,s.K2)(function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},"test_match"),next:(0,s.K2)(function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((n=this._input.match(this.rules[s[r]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:(0,s.K2)(function(){var t=this.next();return t||this.lex()},"lex"),begin:(0,s.K2)(function(t){this.conditionStack.push(t)},"begin"),popState:(0,s.K2)(function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:(0,s.K2)(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:(0,s.K2)(function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},"topState"),pushState:(0,s.K2)(function(t){this.begin(t)},"pushState"),stateStackSize:(0,s.K2)(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,s.K2)(function(t,e,n,i){switch(n){case 0:case 1:case 3:case 4:break;case 2:return 10;case 5:return 4;case 6:return 11;case 7:return this.begin("acc_title"),12;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),14;case 10:return this.popState(),"acc_descr_value";case 11:this.begin("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 17;case 15:return 21;case 16:return 20;case 17:return 6;case 18:return"INVALID"}},"anonymous"),rules:[/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:timeline\b)/i,/^(?:title\s[^\n]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^:\n]+)/i,/^(?::\s(?:[^:\n]|:(?!\s))+)/i,/^(?:[^#:\n]+)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,9,11,14,15,16,17,18],inclusive:!0}}}}();function u(){this.yy={}}return h.lexer=d,(0,s.K2)(u,"Parser"),u.prototype=h,h.Parser=u,new u}();l.parser=l;var h=l,d={};(0,s.VA)(d,{addEvent:()=>v,addSection:()=>b,addTask:()=>w,addTaskOrg:()=>K,clear:()=>x,default:()=>$,getCommonDb:()=>m,getSections:()=>k,getTasks:()=>_});var u="",p=0,y=[],g=[],f=[],m=(0,s.K2)(()=>i.Wt,"getCommonDb"),x=(0,s.K2)(function(){y.length=0,g.length=0,u="",f.length=0,(0,i.IU)()},"clear"),b=(0,s.K2)(function(t){u=t,y.push(t)},"addSection"),k=(0,s.K2)(function(){return y},"getSections"),_=(0,s.K2)(function(){let t=S();let e=0;for(;!t&&e<100;)t=S(),e++;return g.push(...f),g},"getTasks"),w=(0,s.K2)(function(t,e,n){const i={id:p++,section:u,type:u,task:t,score:e||0,events:n?[n]:[]};f.push(i)},"addTask"),v=(0,s.K2)(function(t){f.find(t=>t.id===p-1).events.push(t)},"addEvent"),K=(0,s.K2)(function(t){const e={section:u,type:u,description:t,task:t,classes:[]};g.push(e)},"addTaskOrg"),S=(0,s.K2)(function(){const t=(0,s.K2)(function(t){return f[t].processed},"compileTask");let e=!0;for(const[n,i]of f.entries())t(n),e=e&&i.processed;return e},"compileTasks"),$={clear:x,getCommonDb:m,addSection:b,getSections:k,getTasks:_,addTask:w,addTaskOrg:K,addEvent:v},E=(0,s.K2)(function(t,e){const n=t.append("rect");return n.attr("x",e.x),n.attr("y",e.y),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("width",e.width),n.attr("height",e.height),n.attr("rx",e.rx),n.attr("ry",e.ry),void 0!==e.class&&n.attr("class",e.class),n},"drawRect"),T=(0,s.K2)(function(t,e){const n=15,i=t.append("circle").attr("cx",e.cx).attr("cy",e.cy).attr("class","face").attr("r",n).attr("stroke-width",2).attr("overflow","visible"),a=t.append("g");function o(t){const i=(0,r.JLW)().startAngle(Math.PI/2).endAngle(Math.PI/2*3).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+2)+")")}function c(t){const i=(0,r.JLW)().startAngle(3*Math.PI/2).endAngle(Math.PI/2*5).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+7)+")")}function l(t){t.append("line").attr("class","mouth").attr("stroke",2).attr("x1",e.cx-5).attr("y1",e.cy+7).attr("x2",e.cx+5).attr("y2",e.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}return a.append("circle").attr("cx",e.cx-5).attr("cy",e.cy-5).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),a.append("circle").attr("cx",e.cx+5).attr("cy",e.cy-5).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),(0,s.K2)(o,"smile"),(0,s.K2)(c,"sad"),(0,s.K2)(l,"ambivalent"),e.score>3?o(a):e.score<3?c(a):l(a),i},"drawFace"),I=(0,s.K2)(function(t,e){const n=t.append("circle");return n.attr("cx",e.cx),n.attr("cy",e.cy),n.attr("class","actor-"+e.pos),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("r",e.r),void 0!==n.class&&n.attr("class",n.class),void 0!==e.title&&n.append("title").text(e.title),n},"drawCircle"),R=(0,s.K2)(function(t,e){const n=e.text.replace(/<br\s*\/?>/gi," "),i=t.append("text");i.attr("x",e.x),i.attr("y",e.y),i.attr("class","legend"),i.style("text-anchor",e.anchor),void 0!==e.class&&i.attr("class",e.class);const s=i.append("tspan");return s.attr("x",e.x+2*e.textMargin),s.text(n),i},"drawText"),A=(0,s.K2)(function(t,e){function n(t,e,n,i,s){return t+","+e+" "+(t+n)+","+e+" "+(t+n)+","+(e+i-s)+" "+(t+n-1.2*s)+","+(e+i)+" "+t+","+(e+i)}(0,s.K2)(n,"genPoints");const i=t.append("polygon");i.attr("points",n(e.x,e.y,50,20,7)),i.attr("class","labelBox"),e.y=e.y+e.labelMargin,e.x=e.x+.5*e.labelMargin,R(t,e)},"drawLabel"),L=(0,s.K2)(function(t,e,n){const i=t.append("g"),s=H();s.x=e.x,s.y=e.y,s.fill=e.fill,s.width=n.width,s.height=n.height,s.class="journey-section section-type-"+e.num,s.rx=3,s.ry=3,E(i,s),O(n)(e.text,i,s.x,s.y,s.width,s.height,{class:"journey-section section-type-"+e.num},n,e.colour)},"drawSection"),M=-1,C=(0,s.K2)(function(t,e,n){const i=e.x+n.width/2,s=t.append("g");M++;s.append("line").attr("id","task"+M).attr("x1",i).attr("y1",e.y).attr("x2",i).attr("y2",450).attr("class","task-line").attr("stroke-width","1px").attr("stroke-dasharray","4 2").attr("stroke","#666"),T(s,{cx:i,cy:300+30*(5-e.score),score:e.score});const r=H();r.x=e.x,r.y=e.y,r.fill=e.fill,r.width=n.width,r.height=n.height,r.class="task task-type-"+e.num,r.rx=3,r.ry=3,E(s,r),O(n)(e.task,s,r.x,r.y,r.width,r.height,{class:"task"},n,e.colour)},"drawTask"),N=(0,s.K2)(function(t,e){E(t,{x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,class:"rect"}).lower()},"drawBackgroundRect"),P=(0,s.K2)(function(){return{x:0,y:0,fill:void 0,"text-anchor":"start",width:100,height:100,textMargin:0,rx:0,ry:0}},"getTextObj"),H=(0,s.K2)(function(){return{x:0,y:0,width:100,anchor:"start",height:100,rx:0,ry:0}},"getNoteRect"),O=function(){function t(t,e,n,s,r,a,o,c){i(e.append("text").attr("x",n+r/2).attr("y",s+a/2+5).style("font-color",c).style("text-anchor","middle").text(t),o)}function e(t,e,n,s,r,a,o,c,l){const{taskFontSize:h,taskFontFamily:d}=c,u=t.split(/<br\s*\/?>/gi);for(let p=0;p<u.length;p++){const t=p*h-h*(u.length-1)/2,c=e.append("text").attr("x",n+r/2).attr("y",s).attr("fill",l).style("text-anchor","middle").style("font-size",h).style("font-family",d);c.append("tspan").attr("x",n+r/2).attr("dy",t).text(u[p]),c.attr("y",s+a/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),i(c,o)}}function n(t,n,s,r,a,o,c,l){const h=n.append("switch"),d=h.append("foreignObject").attr("x",s).attr("y",r).attr("width",a).attr("height",o).attr("position","fixed").append("xhtml:div").style("display","table").style("height","100%").style("width","100%");d.append("div").attr("class","label").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,s,r,a,o,c,l),i(d,c)}function i(t,e){for(const n in e)n in e&&t.attr(n,e[n])}return(0,s.K2)(t,"byText"),(0,s.K2)(e,"byTspan"),(0,s.K2)(n,"byFo"),(0,s.K2)(i,"_setTextAttrs"),function(i){return"fo"===i.textPlacement?n:"old"===i.textPlacement?t:e}}(),j=(0,s.K2)(function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")},"initGraphics");function D(t,e){t.each(function(){var t,n=(0,r.Ltv)(this),i=n.text().split(/(\s+|<br>)/).reverse(),s=[],a=n.attr("y"),o=parseFloat(n.attr("dy")),c=n.text(null).append("tspan").attr("x",0).attr("y",a).attr("dy",o+"em");for(let r=0;r<i.length;r++)t=i[i.length-1-r],s.push(t),c.text(s.join(" ").trim()),(c.node().getComputedTextLength()>e||"<br>"===t)&&(s.pop(),c.text(s.join(" ").trim()),s="<br>"===t?[""]:[t],c=n.append("tspan").attr("x",0).attr("y",a).attr("dy","1.1em").text(t))})}(0,s.K2)(D,"wrap");var z=(0,s.K2)(function(t,e,n,i){const s=n%12-1,r=t.append("g");e.section=s,r.attr("class",(e.class?e.class+" ":"")+"timeline-node section-"+s);const a=r.append("g"),o=r.append("g"),c=o.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(D,e.width).node().getBBox(),l=i.fontSize?.replace?i.fontSize.replace("px",""):i.fontSize;return e.height=c.height+1.1*l*.5+e.padding,e.height=Math.max(e.height,e.maxHeight),e.width=e.width+2*e.padding,o.attr("transform","translate("+e.width/2+", "+e.padding/2+")"),B(a,e,s,i),e},"drawNode"),W=(0,s.K2)(function(t,e,n){const i=t.append("g"),s=i.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(D,e.width).node().getBBox(),r=n.fontSize?.replace?n.fontSize.replace("px",""):n.fontSize;return i.remove(),s.height+1.1*r*.5+e.padding},"getVirtualNodeHeight"),B=(0,s.K2)(function(t,e,n){t.append("path").attr("id","node-"+e.id).attr("class","node-bkg node-"+e.type).attr("d",`M0 ${e.height-5} v${10-e.height} q0,-5 5,-5 h${e.width-10} q5,0 5,5 v${e.height-5} H0 Z`),t.append("line").attr("class","node-line-"+n).attr("x1",0).attr("y1",e.height).attr("x2",e.width).attr("y2",e.height)},"defaultBkg"),F={drawRect:E,drawCircle:I,drawSection:L,drawText:R,drawLabel:A,drawTask:C,drawBackgroundRect:N,getTextObj:P,getNoteRect:H,initGraphics:j,drawNode:z,getVirtualNodeHeight:W},V=(0,s.K2)(function(t,e,n,a){const o=(0,i.D7)(),c=o.timeline?.leftMargin??50;s.Rm.debug("timeline",a.db);const l=o.securityLevel;let h;"sandbox"===l&&(h=(0,r.Ltv)("#i"+e));const d=("sandbox"===l?(0,r.Ltv)(h.nodes()[0].contentDocument.body):(0,r.Ltv)("body")).select("#"+e);d.append("g");const u=a.db.getTasks(),p=a.db.getCommonDb().getDiagramTitle();s.Rm.debug("task",u),F.initGraphics(d);const y=a.db.getSections();s.Rm.debug("sections",y);let g=0,f=0,m=0,x=0,b=50+c,k=50;x=50;let _=0,w=!0;y.forEach(function(t){const e={number:_,descr:t,section:_,width:150,padding:20,maxHeight:g},n=F.getVirtualNodeHeight(d,e,o);s.Rm.debug("sectionHeight before draw",n),g=Math.max(g,n+20)});let v=0,K=0;s.Rm.debug("tasks.length",u.length);for(const[i,r]of u.entries()){const t={number:i,descr:r,section:r.section,width:150,padding:20,maxHeight:f},e=F.getVirtualNodeHeight(d,t,o);s.Rm.debug("taskHeight before draw",e),f=Math.max(f,e+20),v=Math.max(v,r.events.length);let n=0;for(const i of r.events){const t={descr:i,section:r.section,number:r.section,width:150,padding:20,maxHeight:50};n+=F.getVirtualNodeHeight(d,t,o)}r.events.length>0&&(n+=10*(r.events.length-1)),K=Math.max(K,n)}s.Rm.debug("maxSectionHeight before draw",g),s.Rm.debug("maxTaskHeight before draw",f),y&&y.length>0?y.forEach(t=>{const e=u.filter(e=>e.section===t),n={number:_,descr:t,section:_,width:200*Math.max(e.length,1)-50,padding:20,maxHeight:g};s.Rm.debug("sectionNode",n);const i=d.append("g"),r=F.drawNode(i,n,_,o);s.Rm.debug("sectionNode output",r),i.attr("transform",`translate(${b}, 50)`),k+=g+50,e.length>0&&G(d,e,_,b,k,f,o,v,K,g,!1),b+=200*Math.max(e.length,1),k=50,_++}):(w=!1,G(d,u,_,b,k,f,o,v,K,g,!0));const S=d.node().getBBox();s.Rm.debug("bounds",S),p&&d.append("text").text(p).attr("x",S.width/2-c).attr("font-size","4ex").attr("font-weight","bold").attr("y",20),m=w?g+f+150:f+100;d.append("g").attr("class","lineWrapper").append("line").attr("x1",c).attr("y1",m).attr("x2",S.width+3*c).attr("y2",m).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)"),(0,i.ot)(void 0,d,o.timeline?.padding??50,o.timeline?.useMaxWidth??!1)},"draw"),G=(0,s.K2)(function(t,e,n,i,r,a,o,c,l,h,d){for(const u of e){const e={descr:u.task,section:n,number:n,width:150,padding:20,maxHeight:a};s.Rm.debug("taskNode",e);const c=t.append("g").attr("class","taskWrapper"),h=F.drawNode(c,e,n,o).height;if(s.Rm.debug("taskHeight after draw",h),c.attr("transform",`translate(${i}, ${r})`),a=Math.max(a,h),u.events){const e=t.append("g").attr("class","lineWrapper");let s=a;r+=100,s+=U(t,u.events,n,i,r,o),r-=100,e.append("line").attr("x1",i+95).attr("y1",r+a).attr("x2",i+95).attr("y2",r+a+100+l+100).attr("stroke-width",2).attr("stroke","black").attr("marker-end","url(#arrowhead)").attr("stroke-dasharray","5,5")}i+=200,d&&!o.timeline?.disableMulticolor&&n++}r-=10},"drawTasks"),U=(0,s.K2)(function(t,e,n,i,r,a){let o=0;const c=r;r+=100;for(const l of e){const e={descr:l,section:n,number:n,width:150,padding:20,maxHeight:50};s.Rm.debug("eventNode",e);const c=t.append("g").attr("class","eventWrapper"),h=F.drawNode(c,e,n,a).height;o+=h,c.attr("transform",`translate(${i}, ${r})`),r=r+10+h}return r=c,o},"drawEvents"),q={setConf:(0,s.K2)(()=>{},"setConf"),draw:V},J=(0,s.K2)(t=>{let e="";for(let n=0;n<t.THEME_COLOR_LIMIT;n++)t["lineColor"+n]=t["lineColor"+n]||t["cScaleInv"+n],(0,a.A)(t["lineColor"+n])?t["lineColor"+n]=(0,o.A)(t["lineColor"+n],20):t["lineColor"+n]=(0,c.A)(t["lineColor"+n],20);for(let n=0;n<t.THEME_COLOR_LIMIT;n++){const i=""+(17-3*n);e+=`\n .section-${n-1} rect, .section-${n-1} path, .section-${n-1} circle, .section-${n-1} path {\n fill: ${t["cScale"+n]};\n }\n .section-${n-1} text {\n fill: ${t["cScaleLabel"+n]};\n }\n .node-icon-${n-1} {\n font-size: 40px;\n color: ${t["cScaleLabel"+n]};\n }\n .section-edge-${n-1}{\n stroke: ${t["cScale"+n]};\n }\n .edge-depth-${n-1}{\n stroke-width: ${i};\n }\n .section-${n-1} line {\n stroke: ${t["cScaleInv"+n]} ;\n stroke-width: 3;\n }\n\n .lineWrapper line{\n stroke: ${t["cScaleLabel"+n]} ;\n }\n\n .disabled, .disabled circle, .disabled text {\n fill: lightgray;\n }\n .disabled text {\n fill: #efefef;\n }\n `}return e},"genSections"),Y={db:d,renderer:q,parser:h,styles:(0,s.K2)(t=>`\n .edge {\n stroke-width: 3;\n }\n ${J(t)}\n .section-root rect, .section-root path, .section-root circle {\n fill: ${t.git0};\n }\n .section-root text {\n fill: ${t.gitBranchLabel0};\n }\n .icon-container {\n height:100%;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .edge {\n fill: none;\n }\n .eventWrapper {\n filter: brightness(120%);\n }\n`,"getStyles")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/294c0512.1a966ee8.js b/pr-preview/pr-4027/assets/js/294c0512.1a966ee8.js deleted file mode 100644 index 1d8398baa..000000000 --- a/pr-preview/pr-4027/assets/js/294c0512.1a966ee8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3339],{28453:(e,t,i)=>{i.d(t,{R:()=>r,x:()=>a});var n=i(96540);const s={},o=n.createContext(s);function r(e){const t=n.useContext(o);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(o.Provider,{value:t},e.children)}},44780:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"architecture/images","title":"Constellation images","description":"Constellation uses a minimal version of Fedora as the operating system running inside confidential VMs. This Linux distribution is optimized for containers and designed to be stateless.","source":"@site/versioned_docs/version-2.24/architecture/images.md","sourceDirName":"architecture","slug":"/architecture/images","permalink":"/constellation/pr-preview/pr-4027/architecture/images","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/architecture/images.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Attestation","permalink":"/constellation/pr-preview/pr-4027/architecture/attestation"},"next":{"title":"Keys and cryptographic primitives","permalink":"/constellation/pr-preview/pr-4027/architecture/keys"}}');var s=i(74848),o=i(28453);const r={},a="Constellation images",d={},l=[{value:"Measured boot",id:"measured-boot",level:2},{value:"Firmware",id:"firmware",level:3},{value:"Bootloader",id:"bootloader",level:3},{value:"initramfs",id:"initramfs",level:3},{value:"State disk",id:"state-disk",level:2},{value:"Kubernetes components",id:"kubernetes-components",level:2}];function c(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",mermaid:"mermaid",p:"p",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"constellation-images",children:"Constellation images"})}),"\n",(0,s.jsx)(t.p,{children:"Constellation uses a minimal version of Fedora as the operating system running inside confidential VMs. This Linux distribution is optimized for containers and designed to be stateless.\nThe Constellation images provide measured boot and an immutable filesystem."}),"\n",(0,s.jsx)(t.h2,{id:"measured-boot",children:"Measured boot"}),"\n",(0,s.jsx)(t.mermaid,{value:"flowchart LR\n Firmware --\x3e Bootloader\n Bootloader --\x3e uki\n subgraph uki[Unified Kernel Image]\n Kernel[Kernel]\n initramfs[Initramfs]\n cmdline[Kernel Command Line]\n end\n uki --\x3e rootfs[Root Filesystem]"}),"\n",(0,s.jsx)(t.p,{children:"Measured boot uses a Trusted Platform Module (TPM) to measure every part of the boot process. This allows for verification of the integrity of a running system at any point in time. To ensure correct measurements of every stage, each stage is responsible to measure the next stage before transitioning."}),"\n",(0,s.jsx)(t.h3,{id:"firmware",children:"Firmware"}),"\n",(0,s.jsx)(t.p,{children:"With confidential VMs, the firmware is the root of trust and is measured automatically at boot. After initialization, the firmware will load and measure the bootloader before executing it."}),"\n",(0,s.jsx)(t.h3,{id:"bootloader",children:"Bootloader"}),"\n",(0,s.jsx)(t.p,{children:"The bootloader is the first modifiable part of the boot chain. The bootloader is tasked with loading the kernel, initramfs and setting the kernel command line. The Constellation bootloader measures these components before starting the kernel."}),"\n",(0,s.jsx)(t.h3,{id:"initramfs",children:"initramfs"}),"\n",(0,s.jsxs)(t.p,{children:["The initramfs is a small filesystem loaded to prepare the actual root filesystem. The Constellation initramfs maps the block device containing the root filesystem with ",(0,s.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"}),". The initramfs then mounts the root filesystem from the mapped block device."]}),"\n",(0,s.jsx)(t.p,{children:"dm-verity provides integrity checking using a cryptographic hash tree. When a block is read, its integrity is checked by verifying the tree against a trusted root hash. The initramfs reads this root hash from the previously measured kernel command line. Thus, if any block of the root filesystem's device is modified on disk, trying to read the modified block will result in a kernel panic at runtime."}),"\n",(0,s.jsxs)(t.p,{children:["After mounting the root filesystem, the initramfs will switch over and start the ",(0,s.jsx)(t.code,{children:"init"})," process of the integrity-protected root filesystem."]}),"\n",(0,s.jsx)(t.h2,{id:"state-disk",children:"State disk"}),"\n",(0,s.jsxs)(t.p,{children:["In addition to the read-only root filesystem, each Constellation node has a disk for storing state data.\nThis disk is mounted readable and writable by the initramfs and contains data that should persist across reboots.\nSuch data can contain sensitive information and, therefore, must be stored securely.\nTo that end, the state disk is protected by authenticated encryption.\nSee the section on ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys#storage-encryption",children:"keys and encryption"})," for more information on the cryptographic primitives in use."]}),"\n",(0,s.jsx)(t.h2,{id:"kubernetes-components",children:"Kubernetes components"}),"\n",(0,s.jsxs)(t.p,{children:["During initialization, the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#bootstrapper",children:(0,s.jsx)(t.em,{children:"Bootstrapper"})})," downloads and verifies the ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/overview/components/",children:"Kubernetes components"})," as configured by the user.\nThey're stored on the state partition and can be updated once new releases need to be installed."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/2a05e475.bd72699c.js b/pr-preview/pr-4027/assets/js/2a05e475.bd72699c.js deleted file mode 100644 index 4968d7978..000000000 --- a/pr-preview/pr-4027/assets/js/2a05e475.bd72699c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3610],{28453:(e,s,n)=>{n.d(s,{R:()=>r,x:()=>a});var o=n(96540);const t={},i=o.createContext(t);function r(e){const s=o.useContext(i);return o.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),o.createElement(i.Provider,{value:s},e.children)}},75806:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"workflows/sbom","title":"Consume software bill of materials (SBOMs)","description":"---","source":"@site/versioned_docs/version-2.22/workflows/sbom.md","sourceDirName":"workflows","slug":"/workflows/sbom","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/sbom","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/workflows/sbom.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Use the Terraform provider","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/terraform-provider"},"next":{"title":"Reproduce release artifacts","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/reproducible-builds"}}');var t=n(74848),i=n(28453);const r={},a="Consume software bill of materials (SBOMs)",l={},c=[{value:"Verify and download SBOMs",id:"verify-and-download-sboms",level:2},{value:"Constellation CLI",id:"constellation-cli",level:3},{value:"Container Images",id:"container-images",level:3},{value:"Vulnerability scanning",id:"vulnerability-scanning",level:2},{value:"Grype",id:"grype",level:3},{value:"Dependency Track",id:"dependency-track",level:3}];function d(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",...(0,i.R)(),...e.components},{AsciinemaWidget:n}=s;return n||function(e,s){throw new Error("Expected "+(s?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("AsciinemaWidget",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"consume-software-bill-of-materials-sboms",children:"Consume software bill of materials (SBOMs)"})}),"\n",(0,t.jsx)(n,{src:"/constellation/assets/check-sbom.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,t.jsx)(s.hr,{}),"\n",(0,t.jsxs)(s.p,{children:["Constellation builds produce a ",(0,t.jsx)(s.a,{href:"https://www.ntia.gov/SBOM",children:"software bill of materials (SBOM)"})," for each generated ",(0,t.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices",children:"artifact"}),".\nYou can use SBOMs to make informed decisions about dependencies and vulnerabilities in a given application. Enterprises rely on SBOMs to maintain an inventory of used applications, which allows them to take data-driven approaches to managing risks related to vulnerabilities."]}),"\n",(0,t.jsxs)(s.p,{children:["SBOMs for Constellation are generated using ",(0,t.jsx)(s.a,{href:"https://github.com/anchore/syft",children:"Syft"}),", signed using ",(0,t.jsx)(s.a,{href:"https://github.com/sigstore/cosign",children:"Cosign"}),", and stored with the produced artifact."]}),"\n",(0,t.jsxs)(s.admonition,{type:"note",children:[(0,t.jsx)(s.p,{children:"The public key for Edgeless Systems' long-term code-signing key is:"}),(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT\nJmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==\n-----END PUBLIC KEY-----\n"})}),(0,t.jsxs)(s.p,{children:["The public key is also available for download at ",(0,t.jsx)(s.a,{href:"https://edgeless.systems/es.pub",children:"https://edgeless.systems/es.pub"})," and in the Twitter profile ",(0,t.jsx)(s.a,{href:"https://twitter.com/EdgelessSystems",children:"@EdgelessSystems"}),"."]}),(0,t.jsxs)(s.p,{children:["Make sure the key is available in a file named ",(0,t.jsx)(s.code,{children:"cosign.pub"})," to execute the following examples."]})]}),"\n",(0,t.jsx)(s.h2,{id:"verify-and-download-sboms",children:"Verify and download SBOMs"}),"\n",(0,t.jsx)(s.p,{children:"The following sections detail how to work with each type of artifact to verify and extract the SBOM."}),"\n",(0,t.jsx)(s.h3,{id:"constellation-cli",children:"Constellation CLI"}),"\n",(0,t.jsxs)(s.p,{children:["The SBOM for Constellation CLI is made available on the ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub release page"}),". The SBOM (",(0,t.jsx)(s.code,{children:"constellation.spdx.sbom"}),") and corresponding signature (",(0,t.jsx)(s.code,{children:"constellation.spdx.sbom.sig"}),") are valid for each Constellation CLI for a given version, regardless of architecture and operating system."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom\ncurl -LO https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom.sig\ncosign verify-blob --key cosign.pub --signature constellation.spdx.sbom.sig constellation.spdx.sbom\n"})}),"\n",(0,t.jsx)(s.h3,{id:"container-images",children:"Container Images"}),"\n",(0,t.jsxs)(s.p,{children:["SBOMs for container images are ",(0,t.jsx)(s.a,{href:"https://docs.sigstore.dev/cosign/signing/other_types/#sboms-software-bill-of-materials",children:"attached to the image using Cosign"})," and uploaded to the same registry."]}),"\n",(0,t.jsx)(s.p,{children:"As a consumer, use cosign to download and verify the SBOM:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"# Verify and download the attestation statement\ncosign verify-attestation ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --type 'https://cyclonedx.org/bom' --key cosign.pub --output-file verification-service.att.json\n# Extract SBOM from attestation statement\njq -r .payload verification-service.att.json | base64 -d > verification-service.cyclonedx.sbom\n"})}),"\n",(0,t.jsx)(s.p,{children:"A successful verification should result in similar output:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-shell-session",children:"$ cosign verify-attestation ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --type 'https://cyclonedx.org/bom' --key cosign.pub --output-file verification-service.sbom\n\nVerification for ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --\nThe following checks were performed on each of these signatures:\n - The cosign claims were validated\n - The signatures were verified against the specified public key\n$ jq -r .payload verification-service.sbom | base64 -d > verification-service.cyclonedx.sbom\n"})}),"\n",(0,t.jsx)(s.admonition,{type:"note",children:(0,t.jsxs)(s.p,{children:["This example considers only the ",(0,t.jsx)(s.code,{children:"verification-service"}),". The same approach works for all containers in the ",(0,t.jsx)(s.a,{href:"https://github.com/orgs/edgelesssys/packages?repo_name=constellation",children:"Constellation container registry"}),"."]})}),"\n",(0,t.jsx)(s.h2,{id:"vulnerability-scanning",children:"Vulnerability scanning"}),"\n",(0,t.jsxs)(s.p,{children:["You can use a plethora of tools to consume SBOMs. This section provides suggestions for tools that are popular and known to produce reliable results, but any tool that consumes ",(0,t.jsx)(s.a,{href:"https://spdx.dev/",children:"SPDX"})," or ",(0,t.jsx)(s.a,{href:"https://cyclonedx.org/",children:"CycloneDX"})," files should work."]}),"\n",(0,t.jsxs)(s.p,{children:["Syft is able to ",(0,t.jsx)(s.a,{href:"https://github.com/anchore/syft#format-conversion-experimental",children:"convert between the two formats"})," in case you require a specific type."]}),"\n",(0,t.jsx)(s.h3,{id:"grype",children:"Grype"}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"https://github.com/anchore/grype",children:"Grype"})," is a CLI tool that lends itself well for integration into CI/CD systems or local developer machines. It's also able to consume the signed attestation statement directly and does the verification in one go."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"grype att:verification-service.sbom --key cosign.pub --add-cpes-if-none -q\n"})}),"\n",(0,t.jsx)(s.h3,{id:"dependency-track",children:"Dependency Track"}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"https://dependencytrack.org/",children:"Dependency Track"})," is one of the oldest and most mature solutions when it comes to managing software inventory and vulnerabilities. Once imported, it continuously scans SBOMs for new vulnerabilities. It supports the CycloneDX format and provides direct guidance on how to comply with ",(0,t.jsx)(s.a,{href:"https://docs.dependencytrack.org/usage/executive-order-14028/",children:"U.S. Executive Order 14028"}),"."]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/2a2a0c40.118b00b5.js b/pr-preview/pr-4027/assets/js/2a2a0c40.118b00b5.js deleted file mode 100644 index c321ea99b..000000000 --- a/pr-preview/pr-4027/assets/js/2a2a0c40.118b00b5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7292],{28453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>c});var i=s(96540);const l={},r=i.createContext(l);function t(e){const n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:t(e.components),i.createElement(r.Provider,{value:n},e.children)}},48672:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>t,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"getting-started/install","title":"Installation and setup","description":"Constellation runs entirely in your cloud environment and can be controlled via a dedicated command-line interface (CLI) or a Terraform provider.","source":"@site/docs/getting-started/install.md","sourceDirName":"getting-started","slug":"/getting-started/install","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/install","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/getting-started/install.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Getting started","permalink":"/constellation/pr-preview/pr-4027/next/category/getting-started"},"next":{"title":"First steps (cloud)","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/first-steps"}}');var l=s(74848),r=s(28453);const t={},c="Installation and setup",o={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install the Constellation CLI",id:"install-the-constellation-cli",level:2},{value:"Set up cloud credentials",id:"set-up-cloud-credentials",level:2},{value:"Required permissions",id:"required-permissions",level:3},{value:"Authentication",id:"authentication",level:3},{value:"Next steps",id:"next-steps",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components},{TabItem:s,Tabs:i}=n;return s||u("TabItem",!0),i||u("Tabs",!0),(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"installation-and-setup",children:"Installation and setup"})}),"\n",(0,l.jsxs)(n.p,{children:["Constellation runs entirely in your cloud environment and can be controlled via a dedicated ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/reference/cli",children:"command-line interface (CLI)"})," or a ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/terraform-provider",children:"Terraform provider"}),"."]}),"\n",(0,l.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,l.jsx)(n.p,{children:"Make sure the following requirements are met:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Your machine is running Linux, macOS, or Windows"}),"\n",(0,l.jsx)(n.li,{children:"You have admin rights on your machine"}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/tools/",children:"kubectl"})," is installed"]}),"\n",(0,l.jsx)(n.li,{children:"Your CSP is Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), or STACKIT"}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"install-the-constellation-cli",children:"Install the Constellation CLI"}),"\n",(0,l.jsx)(n.admonition,{type:"tip",children:(0,l.jsxs)(n.p,{children:["If you prefer to use Terraform, you can alternatively use the ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/terraform-provider",children:"Terraform provider"})," to manage the cluster's lifecycle."]})}),"\n",(0,l.jsxs)(n.p,{children:["The CLI executable is available at ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub"}),".\nInstall it with the following commands:"]}),"\n",(0,l.jsxs)(i,{children:[(0,l.jsxs)(s,{value:"linux-amd64",label:"Linux (amd64)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-amd64\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Install the CLI to your PATH:"}),"\n"]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo install constellation-linux-amd64 /usr/local/bin/constellation\n"})})]}),(0,l.jsxs)(s,{value:"linux-arm64",label:"Linux (arm64)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-arm64\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Install the CLI to your PATH:"}),"\n"]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo install constellation-linux-arm64 /usr/local/bin/constellation\n"})})]}),(0,l.jsxs)(s,{value:"darwin-arm64",label:"macOS (Apple Silicon)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-darwin-arm64\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Install the CLI to your PATH:"}),"\n"]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo install constellation-darwin-arm64 /usr/local/bin/constellation\n"})})]}),(0,l.jsxs)(s,{value:"darwin-amd64",label:"macOS (Intel)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-darwin-amd64\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Install the CLI to your PATH:"}),"\n"]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo install constellation-darwin-amd64 /usr/local/bin/constellation\n"})})]}),(0,l.jsxs)(s,{value:"windows-amd64",label:"Windows (amd64)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"Invoke-WebRequest -OutFile ./constellation.exe -Uri 'https://github.com/edgelesssys/constellation/releases/latest/download/constellation-windows-amd64.exe'\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Install the CLI under ",(0,l.jsx)(n.code,{children:"C:\\Program Files\\Constellation\\bin\\constellation.exe"})]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Add the CLI to your PATH:"}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["Open ",(0,l.jsx)(n.code,{children:"Advanced system settings"})," by searching for the App in the Windows search"]}),"\n",(0,l.jsxs)(n.li,{children:["Go to the ",(0,l.jsx)(n.code,{children:"Advanced"})," tab"]}),"\n",(0,l.jsxs)(n.li,{children:["Click ",(0,l.jsx)(n.code,{children:"Environment Variables\u2026"})]}),"\n",(0,l.jsxs)(n.li,{children:["Click variable called ",(0,l.jsx)(n.code,{children:"Path"})," and click ",(0,l.jsx)(n.code,{children:"Edit\u2026"})]}),"\n",(0,l.jsxs)(n.li,{children:["Click ",(0,l.jsx)(n.code,{children:"New"})]}),"\n",(0,l.jsxs)(n.li,{children:["Enter the path to the folder containing the binary you want on your PATH: ",(0,l.jsx)(n.code,{children:"C:\\Program Files\\Constellation\\bin"})]}),"\n"]}),"\n"]}),"\n"]})]})]}),"\n",(0,l.jsx)(n.admonition,{type:"tip",children:(0,l.jsxs)(n.p,{children:["The CLI supports autocompletion for various shells. To set it up, run ",(0,l.jsx)(n.code,{children:"constellation completion"})," and follow the given steps."]})}),"\n",(0,l.jsx)(n.h2,{id:"set-up-cloud-credentials",children:"Set up cloud credentials"}),"\n",(0,l.jsx)(n.p,{children:"Constellation makes authenticated calls to the CSP API. Therefore, you need to set up Constellation with the credentials for your CSP."}),"\n",(0,l.jsx)(n.admonition,{type:"tip",children:(0,l.jsxs)(n.p,{children:["If you don't have a cloud subscription, you can also set up a ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/first-steps-local",children:"local Constellation cluster using virtualization"})," for testing."]})}),"\n",(0,l.jsx)(n.h3,{id:"required-permissions",children:"Required permissions"}),"\n",(0,l.jsxs)(i,{groupId:"csp",children:[(0,l.jsxs)(s,{value:"aws",label:"AWS",children:[(0,l.jsx)(n.p,{children:"To set up a Constellation cluster, you need to perform two tasks that require permissions: create the infrastructure and create roles for cluster nodes. Both of these actions can be performed by different users, e.g., an administrator to create roles and a DevOps engineer to create the infrastructure."}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/config#creating-an-iam-configuration",children:"create the IAM configuration"})," for Constellation, you need the following permissions:"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-json",children:'{\n "Version": "2012-10-17",\n "Statement": [\n {\n "Effect": "Allow",\n "Action": [\n "ec2:DescribeAccountAttributes",\n "iam:AddRoleToInstanceProfile",\n "iam:AttachRolePolicy",\n "iam:CreateInstanceProfile",\n "iam:CreatePolicy",\n "iam:CreateRole",\n "iam:DeleteInstanceProfile",\n "iam:DeletePolicy",\n "iam:DeletePolicyVersion",\n "iam:DeleteRole",\n "iam:DetachRolePolicy",\n "iam:GetInstanceProfile",\n "iam:GetPolicy",\n "iam:GetPolicyVersion",\n "iam:GetRole",\n "iam:ListAttachedRolePolicies",\n "iam:ListInstanceProfilesForRole",\n "iam:ListPolicyVersions",\n "iam:ListRolePolicies",\n "iam:PassRole",\n "iam:RemoveRoleFromInstanceProfile",\n "sts:GetCallerIdentity"\n ],\n "Resource": "*"\n }\n ]\n}\n'})}),(0,l.jsxs)(n.p,{children:["The built-in ",(0,l.jsx)(n.code,{children:"AdministratorAccess"})," policy is a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/create",children:"create a Constellation cluster"}),", see the permissions of ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/blob/main/terraform/infrastructure/iam/aws/main.tf",children:"main.tf"}),"."]}),(0,l.jsxs)(n.p,{children:["The built-in ",(0,l.jsx)(n.code,{children:"PowerUserAccess"})," policy is a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["Follow Amazon's guide on ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html",children:"understanding"})," and ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html",children:"managing policies"}),"."]})]}),(0,l.jsxs)(s,{value:"azure",label:"Azure",children:[(0,l.jsxs)(n.p,{children:["The following ",(0,l.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/resource-providers-and-types#register-resource-provider",children:"resource providers need to be registered"})," in your subscription:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Attestation"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Compute"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Insights"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.ManagedIdentity"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network"})}),"\n"]}),(0,l.jsx)(n.p,{children:"By default, Constellation tries to register these automatically if they haven't been registered before."}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/config#creating-an-iam-configuration",children:"create the IAM configuration"})," for Constellation, you need the following permissions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"*/register/action"})," [1]"]}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Authorization/roleAssignments/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Authorization/roleDefinitions/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.ManagedIdentity/userAssignedIdentities/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Resources/subscriptions/resourcegroups/*"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["The built-in ",(0,l.jsx)(n.code,{children:"Owner"})," role is a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/create",children:"create a Constellation cluster"}),", you need the following permissions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Attestation/attestationProviders/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Compute/virtualMachineScaleSets/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Insights/components/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.ManagedIdentity/userAssignedIdentities/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/loadBalancers/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/loadBalancers/backendAddressPools/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/networkSecurityGroups/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/publicIPAddresses/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/virtualNetworks/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/virtualNetworks/subnets/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/natGateways/*"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["The built-in ",(0,l.jsx)(n.code,{children:"Contributor"})," role is a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["Follow Microsoft's guide on ",(0,l.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/role-based-access-control/role-definitions",children:"understanding"})," and ",(0,l.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments",children:"assigning roles"}),"."]}),(0,l.jsxs)(n.p,{children:["1: You can omit ",(0,l.jsx)(n.code,{children:"*/register/Action"})," if the resource providers mentioned above are already registered and the ",(0,l.jsx)(n.code,{children:"ARM_SKIP_PROVIDER_REGISTRATION"})," environment variable is set to ",(0,l.jsx)(n.code,{children:"true"})," when creating the IAM configuration."]})]}),(0,l.jsxs)(s,{value:"gcp",label:"GCP",children:[(0,l.jsxs)(n.p,{children:["Create a new project for Constellation or use an existing one.\nEnable the ",(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/apis/library/compute.googleapis.com",children:"Compute Engine API"})," on it."]}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/config#creating-an-iam-configuration",children:"create the IAM configuration"})," for Constellation, you need the following permissions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.roles.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.roles.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.roles.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccountKeys.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccountKeys.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccountKeys.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccounts.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccounts.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccounts.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"resourcemanager.projects.getIamPolicy"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"resourcemanager.projects.setIamPolicy"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["Together, the built-in roles ",(0,l.jsx)(n.code,{children:"roles/editor"})," and ",(0,l.jsx)(n.code,{children:"roles/resourcemanager.projectIamAdmin"})," form a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/create",children:"create a Constellation cluster"}),", you need the following permissions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.addresses.createInternal"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.addresses.deleteInternal"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.addresses.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.addresses.useInternal"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.backendServices.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.backendServices.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.backendServices.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.backendServices.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.disks.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.firewalls.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.firewalls.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.firewalls.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.firewalls.update"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.forwardingRules.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.forwardingRules.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.forwardingRules.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.forwardingRules.setLabels"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.forwardingRules.list"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalAddresses.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalAddresses.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalAddresses.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalAddresses.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalForwardingRules.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalForwardingRules.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalForwardingRules.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalForwardingRules.setLabels"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalOperations.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.healthChecks.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.healthChecks.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.healthChecks.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.healthChecks.useReadOnly"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroupManagers.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroupManagers.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroupManagers.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroupManagers.update"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.update"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instances.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instances.setLabels"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instances.setMetadata"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instances.setTags"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceTemplates.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceTemplates.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceTemplates.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceTemplates.useReadOnly"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.networks.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.networks.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.networks.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.networks.updatePolicy"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.routers.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.routers.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.routers.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.routers.update"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.subnetworks.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.subnetworks.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.subnetworks.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.subnetworks.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.targetTcpProxies.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.targetTcpProxies.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.targetTcpProxies.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.targetTcpProxies.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccounts.actAs"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["Together, the built-in roles ",(0,l.jsx)(n.code,{children:"roles/editor"}),", ",(0,l.jsx)(n.code,{children:"roles/compute.instanceAdmin"})," and ",(0,l.jsx)(n.code,{children:"roles/resourcemanager.projectIamAdmin"})," form a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["Follow Google's guide on ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/iam/docs/understanding-roles",children:"understanding"})," and ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/iam/docs/granting-changing-revoking-access",children:"assigning roles"}),"."]})]}),(0,l.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,l.jsxs)(n.p,{children:["Constellation on STACKIT requires a User Access Token (UAT) for the OpenStack API and a STACKIT service account.\nThe UAT already has all required permissions by default.\nThe STACKIT service account needs the ",(0,l.jsx)(n.code,{children:"editor"})," role to create STACKIT LoadBalancers.\nLook at the ",(0,l.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/getting-started-in-service-accounts-134415831.html",children:"STACKIT documentation"})," on how to create the service account and assign the role."]})})]}),"\n",(0,l.jsx)(n.h3,{id:"authentication",children:"Authentication"}),"\n",(0,l.jsxs)(n.p,{children:["You need to authenticate with your CSP. The following lists the required steps for ",(0,l.jsx)(n.em,{children:"testing"})," and ",(0,l.jsx)(n.em,{children:"production"})," environments."]}),"\n",(0,l.jsx)(n.admonition,{type:"note",children:(0,l.jsxs)(n.p,{children:["The steps for a ",(0,l.jsx)(n.em,{children:"testing"})," environment are simpler. However, they may expose secrets to the CSP. If in doubt, follow the ",(0,l.jsx)(n.em,{children:"production"})," steps."]})}),"\n",(0,l.jsxs)(i,{groupId:"csp",children:[(0,l.jsxs)(s,{value:"aws",label:"AWS",children:[(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Testing"})}),(0,l.jsxs)(n.p,{children:["You can use the ",(0,l.jsx)(n.a,{href:"https://console.aws.amazon.com/cloudshell/home",children:"AWS CloudShell"}),". Make sure you are ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/cloudshell/latest/userguide/sec-auth-with-identities.html",children:"authorized to use it"}),"."]}),(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Production"})}),(0,l.jsxs)(n.p,{children:["Use the latest version of the ",(0,l.jsx)(n.a,{href:"https://aws.amazon.com/cli/",children:"AWS CLI"})," on a trusted machine:"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"aws configure\n"})}),(0,l.jsxs)(n.p,{children:["Options and first steps are described in the ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/cli/index.html",children:"AWS CLI documentation"}),"."]})]}),(0,l.jsxs)(s,{value:"azure",label:"Azure",children:[(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Testing"})}),(0,l.jsxs)(n.p,{children:["Simply open the ",(0,l.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/cloud-shell/overview",children:"Azure Cloud Shell"}),"."]}),(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Production"})}),(0,l.jsxs)(n.p,{children:["Use the latest version of the ",(0,l.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/",children:"Azure CLI"})," on a trusted machine:"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"az login\n"})}),(0,l.jsxs)(n.p,{children:["Other options are described in Azure's ",(0,l.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli",children:"authentication guide"}),"."]})]}),(0,l.jsxs)(s,{value:"gcp",label:"GCP",children:[(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Testing"})}),(0,l.jsxs)(n.p,{children:["You can use the ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/shell",children:"Google Cloud Shell"}),". Make sure your ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/shell/docs/auth",children:"session is authorized"}),". For example, execute ",(0,l.jsx)(n.code,{children:"gsutil"})," and accept the authorization prompt."]}),(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Production"})}),(0,l.jsx)(n.p,{children:"Use one of the following options on a trusted machine:"}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Use the ",(0,l.jsxs)(n.a,{href:"https://cloud.google.com/sdk/gcloud",children:[(0,l.jsx)(n.code,{children:"gcloud"})," CLI"]})]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"gcloud auth application-default login\n"})}),"\n",(0,l.jsx)(n.p,{children:"This will ask you to log-in to your Google account and create your credentials.\nThe Constellation CLI will automatically load these credentials when needed."}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Set up a service account and pass the credentials manually"}),"\n",(0,l.jsxs)(n.p,{children:["Follow ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/docs/authentication/production#manually",children:"Google's guide"})," for setting up your credentials."]}),"\n"]}),"\n"]})]}),(0,l.jsxs)(s,{value:"stackit",label:"STACKIT",children:[(0,l.jsx)(n.p,{children:"You need to authenticate with the infrastructure API (OpenStack) and create a service account (STACKIT API)."}),(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/step-1-generating-of-user-access-token-11763726.html",children:"Follow the STACKIT documentation"})," for obtaining a User Access Token (UAT) to use the infrastructure API"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Create a configuration file with the credentials from the User Access Token under:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Linux: ",(0,l.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})]}),"\n",(0,l.jsxs)(n.li,{children:["macOS: ",(0,l.jsx)(n.code,{children:"/Users/<user>/Library/Application Support/openstack/clouds.yaml"})," or ",(0,l.jsx)(n.code,{children:"/etc/openstack/clouds.yaml"})]}),"\n",(0,l.jsxs)(n.li,{children:["Windows: ",(0,l.jsx)(n.code,{children:"%AppData%\\openstack\\clouds.yaml"})]}),"\n"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",children:"clouds:\n stackit:\n auth:\n auth_url: https://keystone.api.iaas.eu01.stackit.cloud/v3\n username: REPLACE_WITH_UAT_USERNAME\n password: REPLACE_WITH_UAT_PASSWORD\n project_id: REPLACE_WITH_OPENSTACK_PROJECT_ID\n project_name: REPLACE_WITH_STACKIT_PROJECT_NAME\n user_domain_name: portal_mvp\n project_domain_name: portal_mvp\n region_name: RegionOne\n identity_api_version: 3\n"})}),"\n"]}),"\n"]}),(0,l.jsx)(n.admonition,{type:"caution",children:(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:"project_id"})," refers to the ID of your OpenStack project. The STACKIT portal also shows the STACKIT ID that's associated with your project in some places. Make sure you insert the OpenStack project ID in the ",(0,l.jsx)(n.code,{children:"clouds.yaml"})," file."]})}),(0,l.jsxs)(n.ol,{start:"3",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/getting-started-in-service-accounts-134415831.html",children:"Follow the STACKIT documentation"})," for creating a service account and an access token"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Assign the ",(0,l.jsx)(n.code,{children:"editor"})," role to the service account by ",(0,l.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/getting-started-in-service-accounts-134415831.html",children:"following the documentation"})]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Create a configuration file under ",(0,l.jsx)(n.code,{children:"~/.stackit/credentials.json"})," (",(0,l.jsx)(n.code,{children:"%USERPROFILE%\\.stackit\\credentials.json"})," on Windows)"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-json",children:'{"STACKIT_SERVICE_ACCOUNT_TOKEN":"REPLACE_WITH_TOKEN"}\n'})}),"\n"]}),"\n"]})]})]}),"\n",(0,l.jsx)(n.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,l.jsxs)(n.p,{children:["You are now ready to ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/first-steps",children:"deploy your first confidential Kubernetes cluster and application"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(a,{...e})}):a(e)}function u(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/2a9ad702.a6e81067.js b/pr-preview/pr-4027/assets/js/2a9ad702.a6e81067.js deleted file mode 100644 index 8fd57c545..000000000 --- a/pr-preview/pr-4027/assets/js/2a9ad702.a6e81067.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6879],{28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}},71985:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"overview/clouds","title":"Feature status of clouds","description":"What works on which cloud? Currently, Confidential VMs (CVMs) are available in varying quality on the different clouds and software stacks.","source":"@site/versioned_docs/version-2.24/overview/clouds.md","sourceDirName":"overview","slug":"/overview/clouds","permalink":"/constellation/pr-preview/pr-4027/overview/clouds","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/overview/clouds.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Product features","permalink":"/constellation/pr-preview/pr-4027/overview/product"},"next":{"title":"Performance analysis of Constellation","permalink":"/constellation/pr-preview/pr-4027/overview/performance/"}}');var r=n(74848),i=n(28453);const o={},a="Feature status of clouds",l={},d=[{value:"Amazon Web Services (AWS)",id:"amazon-web-services-aws",level:2},{value:"Microsoft Azure",id:"microsoft-azure",level:2},{value:"Google Cloud Platform (GCP)",id:"google-cloud-platform-gcp",level:2},{value:"STACKIT",id:"stackit",level:2},{value:"OpenStack",id:"openstack",level:2},{value:"Conclusion",id:"conclusion",level:2}];function c(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"feature-status-of-clouds",children:"Feature status of clouds"})}),"\n",(0,r.jsx)(t.p,{children:"What works on which cloud? Currently, Confidential VMs (CVMs) are available in varying quality on the different clouds and software stacks."}),"\n",(0,r.jsx)(t.p,{children:"For Constellation, the ideal environment provides the following:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"Ability to run arbitrary software and images inside CVMs"}),"\n",(0,r.jsx)(t.li,{children:"CVMs based on AMD SEV-SNP (available in EPYC CPUs since the Milan generation) or Intel TDX (available in Xeon CPUs since the Sapphire Rapids generation)"}),"\n",(0,r.jsx)(t.li,{children:"Ability for CVM guests to obtain raw hardware attestation statements"}),"\n",(0,r.jsx)(t.li,{children:"Reviewable, open-source firmware inside CVMs"}),"\n",(0,r.jsx)(t.li,{children:"Capability of the firmware to attest the integrity of the code it passes control to, e.g., with an embedded virtual TPM (vTPM)"}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"(1) is a functional must-have. (2)--(5) are required for remote attestation that fully keeps the infrastructure/cloud out. Constellation can work without them or with approximations, but won't protect against certain privileged attackers anymore."}),"\n",(0,r.jsx)(t.p,{children:"The following table summarizes the state of features for different infrastructures."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"Feature"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"AWS"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"Azure"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"GCP"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"STACKIT"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"OpenStack (Yoga)"})})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"1. Custom images"})}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"2. SEV-SNP or TDX"})}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Depends on kernel/HV"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"3. Raw guest attestation"})}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Depends on kernel/HV"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"4. Reviewable firmware"})}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"No*"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Depends on kernel/HV"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"5. Confidential measured boot"})}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Depends on kernel/HV"})]})]})]}),"\n",(0,r.jsx)(t.h2,{id:"amazon-web-services-aws",children:"Amazon Web Services (AWS)"}),"\n",(0,r.jsxs)(t.p,{children:["Amazon EC2 ",(0,r.jsx)(t.a,{href:"https://aws.amazon.com/de/about-aws/whats-new/2023/04/amazon-ec2-amd-sev-snp/",children:"supports AMD SEV-SNP"}),".\nRegarding (3), AWS provides direct access to attestation statements.\nHowever, regarding (5), attestation is partially based on the ",(0,r.jsx)(t.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nitrotpm.html",children:"NitroTPM"})," for ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/attestation#measured-boot",children:"measured boot"}),", which is a vTPM managed by the Nitro hypervisor.\nHence, the hypervisor is currently part of Constellation's TCB.\nRegarding (4), the ",(0,r.jsx)(t.a,{href:"https://github.com/aws/uefi",children:"firmware is open source"})," and can be reproducibly built."]}),"\n",(0,r.jsx)(t.h2,{id:"microsoft-azure",children:"Microsoft Azure"}),"\n",(0,r.jsxs)(t.p,{children:["With its ",(0,r.jsx)(t.a,{href:"https://docs.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview",children:"CVM offering"}),", Azure provides the best foundations for Constellation.\nRegarding (3), Azure provides direct access to attestation statements.\nThe firmware runs in an isolated domain inside the CVM and exposes a vTPM (5), but it's closed source (4).\nOn SEV-SNP, Azure uses VM Privilege Level (VMPL) isolation for the separation of firmware and the rest of the VM; on TDX, they use TD partitioning.\nThis firmware is signed by Azure.\nThe signature is reflected in the attestation statements of CVMs.\nThus, the Azure closed-source firmware becomes part of Constellation's trusted computing base (TCB)."]}),"\n",(0,r.jsxs)(t.p,{children:["* Recently, ",(0,r.jsx)(t.a,{href:"https://techcommunity.microsoft.com/blog/windowsosplatform/openhcl-the-new-open-source-paravisor/4273172",children:"Azure announced the open source paravisor OpenHCL"}),". It's the foundation for fully open source and verifiable CVM firmware. Once Azure provides their CVM firmware with reproducible builds based on OpenHCL, (4) switches from ",(0,r.jsx)(t.em,{children:"No"})," to ",(0,r.jsx)(t.em,{children:"Yes"}),". Constellation will support OpenHCL based firmware on Azure in the future."]}),"\n",(0,r.jsx)(t.h2,{id:"google-cloud-platform-gcp",children:"Google Cloud Platform (GCP)"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"https://cloud.google.com/confidential-computing/confidential-vm/docs/confidential-vm-overview#technologies",children:"CVMs Generally Available in GCP"})," are based on AMD SEV-ES or SEV-SNP.\nRegarding (3), with their SEV-SNP offering Google provides direct access to attestation statements.\nHowever, regarding (5), attestation is partially based on the ",(0,r.jsx)(t.a,{href:"https://cloud.google.com/compute/shielded-vm/docs/shielded-vm#vtpm",children:"Shielded VM vTPM"})," for ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/attestation#measured-boot",children:"measured boot"}),", which is a vTPM managed by Google's hypervisor.\nHence, the hypervisor is currently part of Constellation's TCB.\nRegarding (4), the CVMs still include closed-source firmware."]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://cloud.google.com/blog/products/identity-security/confidential-vms-on-intel-cpus-your-datas-new-intelligent-defense",children:"TDX on Google"})," is in public preview.\nWith it, Constellation would have a similar TCB and attestation flow as with the current SEV-SNP offering."]}),"\n",(0,r.jsx)(t.h2,{id:"stackit",children:"STACKIT"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://www.stackit.de/en/product/stackit-compute-engine/",children:"STACKIT Compute Engine"})," supports AMD SEV-ES. A vTPM is used for measured boot, which is a vTPM managed by STACKIT's hypervisor. Hence, the hypervisor is currently part of Constellation's TCB."]}),"\n",(0,r.jsx)(t.h2,{id:"openstack",children:"OpenStack"}),"\n",(0,r.jsxs)(t.p,{children:["OpenStack is an open-source cloud and infrastructure management software. It's used by many smaller CSPs and datacenters. In the latest ",(0,r.jsx)(t.em,{children:"Yoga"})," version, OpenStack has basic support for CVMs. However, much depends on the employed kernel and hypervisor. Features (2)--(4) are likely to be a ",(0,r.jsx)(t.em,{children:"Yes"})," with Linux kernel version 6.2. Thus, going forward, OpenStack on corresponding AMD or Intel hardware will be a viable underpinning for Constellation."]}),"\n",(0,r.jsx)(t.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,r.jsx)(t.p,{children:"The different clouds and software like the Linux kernel and OpenStack are in the process of building out their support for state-of-the-art CVMs. Azure has already most features in place. For Constellation, the status quo means that the TCB has different shapes on different infrastructures. With broad SEV-SNP support coming to the Linux kernel, we soon expect a normalization of features across infrastructures."})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/2b3dcc9b.bd88b6ce.js b/pr-preview/pr-4027/assets/js/2b3dcc9b.bd88b6ce.js deleted file mode 100644 index 7d1093821..000000000 --- a/pr-preview/pr-4027/assets/js/2b3dcc9b.bd88b6ce.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1793],{7248:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"architecture/images","title":"Constellation images","description":"Constellation uses a minimal version of Fedora as the operating system running inside confidential VMs. This Linux distribution is optimized for containers and designed to be stateless.","source":"@site/versioned_docs/version-2.23/architecture/images.md","sourceDirName":"architecture","slug":"/architecture/images","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/images","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/architecture/images.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Attestation","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/attestation"},"next":{"title":"Keys and cryptographic primitives","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/keys"}}');var s=i(74848),o=i(28453);const r={},a="Constellation images",d={},l=[{value:"Measured boot",id:"measured-boot",level:2},{value:"Firmware",id:"firmware",level:3},{value:"Bootloader",id:"bootloader",level:3},{value:"initramfs",id:"initramfs",level:3},{value:"State disk",id:"state-disk",level:2},{value:"Kubernetes components",id:"kubernetes-components",level:2}];function c(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",mermaid:"mermaid",p:"p",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"constellation-images",children:"Constellation images"})}),"\n",(0,s.jsx)(t.p,{children:"Constellation uses a minimal version of Fedora as the operating system running inside confidential VMs. This Linux distribution is optimized for containers and designed to be stateless.\nThe Constellation images provide measured boot and an immutable filesystem."}),"\n",(0,s.jsx)(t.h2,{id:"measured-boot",children:"Measured boot"}),"\n",(0,s.jsx)(t.mermaid,{value:"flowchart LR\n Firmware --\x3e Bootloader\n Bootloader --\x3e uki\n subgraph uki[Unified Kernel Image]\n Kernel[Kernel]\n initramfs[Initramfs]\n cmdline[Kernel Command Line]\n end\n uki --\x3e rootfs[Root Filesystem]"}),"\n",(0,s.jsx)(t.p,{children:"Measured boot uses a Trusted Platform Module (TPM) to measure every part of the boot process. This allows for verification of the integrity of a running system at any point in time. To ensure correct measurements of every stage, each stage is responsible to measure the next stage before transitioning."}),"\n",(0,s.jsx)(t.h3,{id:"firmware",children:"Firmware"}),"\n",(0,s.jsx)(t.p,{children:"With confidential VMs, the firmware is the root of trust and is measured automatically at boot. After initialization, the firmware will load and measure the bootloader before executing it."}),"\n",(0,s.jsx)(t.h3,{id:"bootloader",children:"Bootloader"}),"\n",(0,s.jsx)(t.p,{children:"The bootloader is the first modifiable part of the boot chain. The bootloader is tasked with loading the kernel, initramfs and setting the kernel command line. The Constellation bootloader measures these components before starting the kernel."}),"\n",(0,s.jsx)(t.h3,{id:"initramfs",children:"initramfs"}),"\n",(0,s.jsxs)(t.p,{children:["The initramfs is a small filesystem loaded to prepare the actual root filesystem. The Constellation initramfs maps the block device containing the root filesystem with ",(0,s.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"}),". The initramfs then mounts the root filesystem from the mapped block device."]}),"\n",(0,s.jsx)(t.p,{children:"dm-verity provides integrity checking using a cryptographic hash tree. When a block is read, its integrity is checked by verifying the tree against a trusted root hash. The initramfs reads this root hash from the previously measured kernel command line. Thus, if any block of the root filesystem's device is modified on disk, trying to read the modified block will result in a kernel panic at runtime."}),"\n",(0,s.jsxs)(t.p,{children:["After mounting the root filesystem, the initramfs will switch over and start the ",(0,s.jsx)(t.code,{children:"init"})," process of the integrity-protected root filesystem."]}),"\n",(0,s.jsx)(t.h2,{id:"state-disk",children:"State disk"}),"\n",(0,s.jsxs)(t.p,{children:["In addition to the read-only root filesystem, each Constellation node has a disk for storing state data.\nThis disk is mounted readable and writable by the initramfs and contains data that should persist across reboots.\nSuch data can contain sensitive information and, therefore, must be stored securely.\nTo that end, the state disk is protected by authenticated encryption.\nSee the section on ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys#storage-encryption",children:"keys and encryption"})," for more information on the cryptographic primitives in use."]}),"\n",(0,s.jsx)(t.h2,{id:"kubernetes-components",children:"Kubernetes components"}),"\n",(0,s.jsxs)(t.p,{children:["During initialization, the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#bootstrapper",children:(0,s.jsx)(t.em,{children:"Bootstrapper"})})," downloads and verifies the ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/overview/components/",children:"Kubernetes components"})," as configured by the user.\nThey're stored on the state partition and can be updated once new releases need to be installed."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>r,x:()=>a});var n=i(96540);const s={},o=n.createContext(s);function r(e){const t=n.useContext(o);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/2dc3352a.943010bc.js b/pr-preview/pr-4027/assets/js/2dc3352a.943010bc.js deleted file mode 100644 index 4472331a7..000000000 --- a/pr-preview/pr-4027/assets/js/2dc3352a.943010bc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4616],{28453:(e,s,r)=>{r.d(s,{R:()=>i,x:()=>l});var n=r(96540);const t={},o=n.createContext(t);function i(e){const s=n.useContext(o);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),n.createElement(o.Provider,{value:s},e.children)}},93432:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>c,contentTitle:()=>l,default:()=>p,frontMatter:()=>i,metadata:()=>n,toc:()=>a});const n=JSON.parse('{"id":"architecture/versions","title":"Versions and support policy","description":"All components of Constellation use a three-digit version number of the form v...","source":"@site/versioned_docs/version-2.22/architecture/versions.md","sourceDirName":"architecture","slug":"/architecture/versions","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/versions","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/architecture/versions.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Cluster orchestration","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration"},"next":{"title":"Microservices","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/microservices"}}');var t=r(74848),o=r(28453);const i={},l="Versions and support policy",c={},a=[{value:"Kubernetes support policy",id:"kubernetes-support-policy",level:2}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"versions-and-support-policy",children:"Versions and support policy"})}),"\n",(0,t.jsxs)(s.p,{children:["All components of Constellation use a three-digit version number of the form ",(0,t.jsx)(s.code,{children:"v<MAJOR>.<MINOR>.<PATCH>"}),".\nThe components are released in lock step, usually on the first Tuesday of every month. This release primarily introduces new features, but may also include security or performance improvements. The ",(0,t.jsx)(s.code,{children:"MINOR"})," version will be incremented as part of this release."]}),"\n",(0,t.jsxs)(s.p,{children:["Additional ",(0,t.jsx)(s.code,{children:"PATCH"})," releases may be created on demand, to fix security issues or bugs before the next ",(0,t.jsx)(s.code,{children:"MINOR"})," release window."]}),"\n",(0,t.jsxs)(s.p,{children:["New releases are published on ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"kubernetes-support-policy",children:"Kubernetes support policy"}),"\n",(0,t.jsxs)(s.p,{children:["Constellation is aligned to the ",(0,t.jsx)(s.a,{href:"https://kubernetes.io/releases/version-skew-policy/#supported-versions",children:"version support policy of Kubernetes"}),", and therefore usually supports the most recent three minor versions.\nWhen a new minor version of Kubernetes is released, support is added to the next Constellation release, and that version then supports four Kubernetes versions.\nSubsequent Constellation releases drop support for the oldest (and deprecated) Kubernetes version."]}),"\n",(0,t.jsx)(s.p,{children:"The following Kubernetes versions are currently supported:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"v1.29.15"}),"\n",(0,t.jsx)(s.li,{children:"v1.30.11"}),"\n",(0,t.jsx)(s.li,{children:"v1.31.7"}),"\n"]})]})}function p(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3003.ac806f1f.js b/pr-preview/pr-4027/assets/js/3003.ac806f1f.js deleted file mode 100644 index e9403c08e..000000000 --- a/pr-preview/pr-4027/assets/js/3003.ac806f1f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3003],{21152:(e,t,s)=>{s.d(t,{P:()=>r});var i=s(67633),n=s(40797),r=(0,n.K2)((e,t,s,r)=>{e.attr("class",s);const{width:c,height:o,x:h,y:u}=a(e,t);(0,i.a$)(e,o,c,r);const y=l(h,u,c,o,t);e.attr("viewBox",y),n.Rm.debug(`viewBox configured: ${y} with padding: ${t}`)},"setupViewPortForSVG"),a=(0,n.K2)((e,t)=>{const s=e.node()?.getBBox()||{width:0,height:0,x:0,y:0};return{width:s.width+2*t,height:s.height+2*t,x:s.x,y:s.y}},"calculateDimensionsWithPadding"),l=(0,n.K2)((e,t,s,i,n)=>`${e-n} ${t-n} ${s} ${i}`,"createViewBox")},29032:(e,t,s)=>{s.d(t,{diagram:()=>E});var i=s(89625),n=s(21152),r=s(10045),a=(s(5164),s(28698),s(5894),s(63245),s(32387),s(30092),s(13226)),l=s(67633),c=s(40797),o=function(){var e=(0,c.K2)(function(e,t,s,i){for(s=s||{},i=e.length;i--;s[e[i]]=t);return s},"o"),t=[1,3],s=[1,4],i=[1,5],n=[1,6],r=[5,6,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,77,89,90],a=[1,22],l=[2,7],o=[1,26],h=[1,27],u=[1,28],y=[1,29],m=[1,33],d=[1,34],E=[1,35],p=[1,36],R=[1,37],f=[1,38],_=[1,24],g=[1,31],S=[1,32],I=[1,30],b=[1,39],T=[1,40],k=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,77,89,90],N=[1,61],q=[89,90],A=[5,8,9,11,13,21,22,23,24,27,29,41,42,43,44,45,46,54,61,63,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],C=[27,29],v=[1,70],w=[1,71],x=[1,72],L=[1,73],D=[1,74],O=[1,75],$=[1,76],M=[1,83],F=[1,80],K=[1,84],P=[1,85],V=[1,86],U=[1,87],Y=[1,88],B=[1,89],Q=[1,90],H=[1,91],W=[1,92],j=[5,8,9,11,13,21,22,23,24,27,41,42,43,44,45,46,54,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],G=[63,64],z=[1,101],X=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,76,77,89,90],J=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],Z=[1,110],ee=[1,106],te=[1,107],se=[1,108],ie=[1,109],ne=[1,111],re=[1,116],ae=[1,117],le=[1,114],ce=[1,115],oe={trace:(0,c.K2)(function(){},"trace"),yy:{},symbols_:{error:2,start:3,directive:4,NEWLINE:5,RD:6,diagram:7,EOF:8,acc_title:9,acc_title_value:10,acc_descr:11,acc_descr_value:12,acc_descr_multiline_value:13,requirementDef:14,elementDef:15,relationshipDef:16,direction:17,styleStatement:18,classDefStatement:19,classStatement:20,direction_tb:21,direction_bt:22,direction_rl:23,direction_lr:24,requirementType:25,requirementName:26,STRUCT_START:27,requirementBody:28,STYLE_SEPARATOR:29,idList:30,ID:31,COLONSEP:32,id:33,TEXT:34,text:35,RISK:36,riskLevel:37,VERIFYMTHD:38,verifyType:39,STRUCT_STOP:40,REQUIREMENT:41,FUNCTIONAL_REQUIREMENT:42,INTERFACE_REQUIREMENT:43,PERFORMANCE_REQUIREMENT:44,PHYSICAL_REQUIREMENT:45,DESIGN_CONSTRAINT:46,LOW_RISK:47,MED_RISK:48,HIGH_RISK:49,VERIFY_ANALYSIS:50,VERIFY_DEMONSTRATION:51,VERIFY_INSPECTION:52,VERIFY_TEST:53,ELEMENT:54,elementName:55,elementBody:56,TYPE:57,type:58,DOCREF:59,ref:60,END_ARROW_L:61,relationship:62,LINE:63,END_ARROW_R:64,CONTAINS:65,COPIES:66,DERIVES:67,SATISFIES:68,VERIFIES:69,REFINES:70,TRACES:71,CLASSDEF:72,stylesOpt:73,CLASS:74,ALPHA:75,COMMA:76,STYLE:77,style:78,styleComponent:79,NUM:80,COLON:81,UNIT:82,SPACE:83,BRKT:84,PCT:85,MINUS:86,LABEL:87,SEMICOLON:88,unqString:89,qString:90,$accept:0,$end:1},terminals_:{2:"error",5:"NEWLINE",6:"RD",8:"EOF",9:"acc_title",10:"acc_title_value",11:"acc_descr",12:"acc_descr_value",13:"acc_descr_multiline_value",21:"direction_tb",22:"direction_bt",23:"direction_rl",24:"direction_lr",27:"STRUCT_START",29:"STYLE_SEPARATOR",31:"ID",32:"COLONSEP",34:"TEXT",36:"RISK",38:"VERIFYMTHD",40:"STRUCT_STOP",41:"REQUIREMENT",42:"FUNCTIONAL_REQUIREMENT",43:"INTERFACE_REQUIREMENT",44:"PERFORMANCE_REQUIREMENT",45:"PHYSICAL_REQUIREMENT",46:"DESIGN_CONSTRAINT",47:"LOW_RISK",48:"MED_RISK",49:"HIGH_RISK",50:"VERIFY_ANALYSIS",51:"VERIFY_DEMONSTRATION",52:"VERIFY_INSPECTION",53:"VERIFY_TEST",54:"ELEMENT",57:"TYPE",59:"DOCREF",61:"END_ARROW_L",63:"LINE",64:"END_ARROW_R",65:"CONTAINS",66:"COPIES",67:"DERIVES",68:"SATISFIES",69:"VERIFIES",70:"REFINES",71:"TRACES",72:"CLASSDEF",74:"CLASS",75:"ALPHA",76:"COMMA",77:"STYLE",80:"NUM",81:"COLON",82:"UNIT",83:"SPACE",84:"BRKT",85:"PCT",86:"MINUS",87:"LABEL",88:"SEMICOLON",89:"unqString",90:"qString"},productions_:[0,[3,3],[3,2],[3,4],[4,2],[4,2],[4,1],[7,0],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[17,1],[17,1],[17,1],[17,1],[14,5],[14,7],[28,5],[28,5],[28,5],[28,5],[28,2],[28,1],[25,1],[25,1],[25,1],[25,1],[25,1],[25,1],[37,1],[37,1],[37,1],[39,1],[39,1],[39,1],[39,1],[15,5],[15,7],[56,5],[56,5],[56,2],[56,1],[16,5],[16,5],[62,1],[62,1],[62,1],[62,1],[62,1],[62,1],[62,1],[19,3],[20,3],[20,3],[30,1],[30,3],[30,1],[30,3],[18,3],[73,1],[73,3],[78,1],[78,2],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[26,1],[26,1],[33,1],[33,1],[35,1],[35,1],[55,1],[55,1],[58,1],[58,1],[60,1],[60,1]],performAction:(0,c.K2)(function(e,t,s,i,n,r,a){var l=r.length-1;switch(n){case 4:this.$=r[l].trim(),i.setAccTitle(this.$);break;case 5:case 6:this.$=r[l].trim(),i.setAccDescription(this.$);break;case 7:this.$=[];break;case 17:i.setDirection("TB");break;case 18:i.setDirection("BT");break;case 19:i.setDirection("RL");break;case 20:i.setDirection("LR");break;case 21:i.addRequirement(r[l-3],r[l-4]);break;case 22:i.addRequirement(r[l-5],r[l-6]),i.setClass([r[l-5]],r[l-3]);break;case 23:i.setNewReqId(r[l-2]);break;case 24:i.setNewReqText(r[l-2]);break;case 25:i.setNewReqRisk(r[l-2]);break;case 26:i.setNewReqVerifyMethod(r[l-2]);break;case 29:this.$=i.RequirementType.REQUIREMENT;break;case 30:this.$=i.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 31:this.$=i.RequirementType.INTERFACE_REQUIREMENT;break;case 32:this.$=i.RequirementType.PERFORMANCE_REQUIREMENT;break;case 33:this.$=i.RequirementType.PHYSICAL_REQUIREMENT;break;case 34:this.$=i.RequirementType.DESIGN_CONSTRAINT;break;case 35:this.$=i.RiskLevel.LOW_RISK;break;case 36:this.$=i.RiskLevel.MED_RISK;break;case 37:this.$=i.RiskLevel.HIGH_RISK;break;case 38:this.$=i.VerifyType.VERIFY_ANALYSIS;break;case 39:this.$=i.VerifyType.VERIFY_DEMONSTRATION;break;case 40:this.$=i.VerifyType.VERIFY_INSPECTION;break;case 41:this.$=i.VerifyType.VERIFY_TEST;break;case 42:i.addElement(r[l-3]);break;case 43:i.addElement(r[l-5]),i.setClass([r[l-5]],r[l-3]);break;case 44:i.setNewElementType(r[l-2]);break;case 45:i.setNewElementDocRef(r[l-2]);break;case 48:i.addRelationship(r[l-2],r[l],r[l-4]);break;case 49:i.addRelationship(r[l-2],r[l-4],r[l]);break;case 50:this.$=i.Relationships.CONTAINS;break;case 51:this.$=i.Relationships.COPIES;break;case 52:this.$=i.Relationships.DERIVES;break;case 53:this.$=i.Relationships.SATISFIES;break;case 54:this.$=i.Relationships.VERIFIES;break;case 55:this.$=i.Relationships.REFINES;break;case 56:this.$=i.Relationships.TRACES;break;case 57:this.$=r[l-2],i.defineClass(r[l-1],r[l]);break;case 58:i.setClass(r[l-1],r[l]);break;case 59:i.setClass([r[l-2]],r[l]);break;case 60:case 62:case 65:this.$=[r[l]];break;case 61:case 63:this.$=r[l-2].concat([r[l]]);break;case 64:this.$=r[l-2],i.setCssStyle(r[l-1],r[l]);break;case 66:r[l-2].push(r[l]),this.$=r[l-2];break;case 68:this.$=r[l-1]+r[l]}},"anonymous"),table:[{3:1,4:2,6:t,9:s,11:i,13:n},{1:[3]},{3:8,4:2,5:[1,7],6:t,9:s,11:i,13:n},{5:[1,9]},{10:[1,10]},{12:[1,11]},e(r,[2,6]),{3:12,4:2,6:t,9:s,11:i,13:n},{1:[2,2]},{4:17,5:a,7:13,8:l,9:s,11:i,13:n,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:o,22:h,23:u,24:y,25:23,33:25,41:m,42:d,43:E,44:p,45:R,46:f,54:_,72:g,74:S,77:I,89:b,90:T},e(r,[2,4]),e(r,[2,5]),{1:[2,1]},{8:[1,41]},{4:17,5:a,7:42,8:l,9:s,11:i,13:n,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:o,22:h,23:u,24:y,25:23,33:25,41:m,42:d,43:E,44:p,45:R,46:f,54:_,72:g,74:S,77:I,89:b,90:T},{4:17,5:a,7:43,8:l,9:s,11:i,13:n,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:o,22:h,23:u,24:y,25:23,33:25,41:m,42:d,43:E,44:p,45:R,46:f,54:_,72:g,74:S,77:I,89:b,90:T},{4:17,5:a,7:44,8:l,9:s,11:i,13:n,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:o,22:h,23:u,24:y,25:23,33:25,41:m,42:d,43:E,44:p,45:R,46:f,54:_,72:g,74:S,77:I,89:b,90:T},{4:17,5:a,7:45,8:l,9:s,11:i,13:n,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:o,22:h,23:u,24:y,25:23,33:25,41:m,42:d,43:E,44:p,45:R,46:f,54:_,72:g,74:S,77:I,89:b,90:T},{4:17,5:a,7:46,8:l,9:s,11:i,13:n,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:o,22:h,23:u,24:y,25:23,33:25,41:m,42:d,43:E,44:p,45:R,46:f,54:_,72:g,74:S,77:I,89:b,90:T},{4:17,5:a,7:47,8:l,9:s,11:i,13:n,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:o,22:h,23:u,24:y,25:23,33:25,41:m,42:d,43:E,44:p,45:R,46:f,54:_,72:g,74:S,77:I,89:b,90:T},{4:17,5:a,7:48,8:l,9:s,11:i,13:n,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:o,22:h,23:u,24:y,25:23,33:25,41:m,42:d,43:E,44:p,45:R,46:f,54:_,72:g,74:S,77:I,89:b,90:T},{4:17,5:a,7:49,8:l,9:s,11:i,13:n,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:o,22:h,23:u,24:y,25:23,33:25,41:m,42:d,43:E,44:p,45:R,46:f,54:_,72:g,74:S,77:I,89:b,90:T},{4:17,5:a,7:50,8:l,9:s,11:i,13:n,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:o,22:h,23:u,24:y,25:23,33:25,41:m,42:d,43:E,44:p,45:R,46:f,54:_,72:g,74:S,77:I,89:b,90:T},{26:51,89:[1,52],90:[1,53]},{55:54,89:[1,55],90:[1,56]},{29:[1,59],61:[1,57],63:[1,58]},e(k,[2,17]),e(k,[2,18]),e(k,[2,19]),e(k,[2,20]),{30:60,33:62,75:N,89:b,90:T},{30:63,33:62,75:N,89:b,90:T},{30:64,33:62,75:N,89:b,90:T},e(q,[2,29]),e(q,[2,30]),e(q,[2,31]),e(q,[2,32]),e(q,[2,33]),e(q,[2,34]),e(A,[2,81]),e(A,[2,82]),{1:[2,3]},{8:[2,8]},{8:[2,9]},{8:[2,10]},{8:[2,11]},{8:[2,12]},{8:[2,13]},{8:[2,14]},{8:[2,15]},{8:[2,16]},{27:[1,65],29:[1,66]},e(C,[2,79]),e(C,[2,80]),{27:[1,67],29:[1,68]},e(C,[2,85]),e(C,[2,86]),{62:69,65:v,66:w,67:x,68:L,69:D,70:O,71:$},{62:77,65:v,66:w,67:x,68:L,69:D,70:O,71:$},{30:78,33:62,75:N,89:b,90:T},{73:79,75:M,76:F,78:81,79:82,80:K,81:P,82:V,83:U,84:Y,85:B,86:Q,87:H,88:W},e(j,[2,60]),e(j,[2,62]),{73:93,75:M,76:F,78:81,79:82,80:K,81:P,82:V,83:U,84:Y,85:B,86:Q,87:H,88:W},{30:94,33:62,75:N,76:F,89:b,90:T},{5:[1,95]},{30:96,33:62,75:N,89:b,90:T},{5:[1,97]},{30:98,33:62,75:N,89:b,90:T},{63:[1,99]},e(G,[2,50]),e(G,[2,51]),e(G,[2,52]),e(G,[2,53]),e(G,[2,54]),e(G,[2,55]),e(G,[2,56]),{64:[1,100]},e(k,[2,59],{76:F}),e(k,[2,64],{76:z}),{33:103,75:[1,102],89:b,90:T},e(X,[2,65],{79:104,75:M,80:K,81:P,82:V,83:U,84:Y,85:B,86:Q,87:H,88:W}),e(J,[2,67]),e(J,[2,69]),e(J,[2,70]),e(J,[2,71]),e(J,[2,72]),e(J,[2,73]),e(J,[2,74]),e(J,[2,75]),e(J,[2,76]),e(J,[2,77]),e(J,[2,78]),e(k,[2,57],{76:z}),e(k,[2,58],{76:F}),{5:Z,28:105,31:ee,34:te,36:se,38:ie,40:ne},{27:[1,112],76:F},{5:re,40:ae,56:113,57:le,59:ce},{27:[1,118],76:F},{33:119,89:b,90:T},{33:120,89:b,90:T},{75:M,78:121,79:82,80:K,81:P,82:V,83:U,84:Y,85:B,86:Q,87:H,88:W},e(j,[2,61]),e(j,[2,63]),e(J,[2,68]),e(k,[2,21]),{32:[1,122]},{32:[1,123]},{32:[1,124]},{32:[1,125]},{5:Z,28:126,31:ee,34:te,36:se,38:ie,40:ne},e(k,[2,28]),{5:[1,127]},e(k,[2,42]),{32:[1,128]},{32:[1,129]},{5:re,40:ae,56:130,57:le,59:ce},e(k,[2,47]),{5:[1,131]},e(k,[2,48]),e(k,[2,49]),e(X,[2,66],{79:104,75:M,80:K,81:P,82:V,83:U,84:Y,85:B,86:Q,87:H,88:W}),{33:132,89:b,90:T},{35:133,89:[1,134],90:[1,135]},{37:136,47:[1,137],48:[1,138],49:[1,139]},{39:140,50:[1,141],51:[1,142],52:[1,143],53:[1,144]},e(k,[2,27]),{5:Z,28:145,31:ee,34:te,36:se,38:ie,40:ne},{58:146,89:[1,147],90:[1,148]},{60:149,89:[1,150],90:[1,151]},e(k,[2,46]),{5:re,40:ae,56:152,57:le,59:ce},{5:[1,153]},{5:[1,154]},{5:[2,83]},{5:[2,84]},{5:[1,155]},{5:[2,35]},{5:[2,36]},{5:[2,37]},{5:[1,156]},{5:[2,38]},{5:[2,39]},{5:[2,40]},{5:[2,41]},e(k,[2,22]),{5:[1,157]},{5:[2,87]},{5:[2,88]},{5:[1,158]},{5:[2,89]},{5:[2,90]},e(k,[2,43]),{5:Z,28:159,31:ee,34:te,36:se,38:ie,40:ne},{5:Z,28:160,31:ee,34:te,36:se,38:ie,40:ne},{5:Z,28:161,31:ee,34:te,36:se,38:ie,40:ne},{5:Z,28:162,31:ee,34:te,36:se,38:ie,40:ne},{5:re,40:ae,56:163,57:le,59:ce},{5:re,40:ae,56:164,57:le,59:ce},e(k,[2,23]),e(k,[2,24]),e(k,[2,25]),e(k,[2,26]),e(k,[2,44]),e(k,[2,45])],defaultActions:{8:[2,2],12:[2,1],41:[2,3],42:[2,8],43:[2,9],44:[2,10],45:[2,11],46:[2,12],47:[2,13],48:[2,14],49:[2,15],50:[2,16],134:[2,83],135:[2,84],137:[2,35],138:[2,36],139:[2,37],141:[2,38],142:[2,39],143:[2,40],144:[2,41],147:[2,87],148:[2,88],150:[2,89],151:[2,90]},parseError:(0,c.K2)(function(e,t){if(!t.recoverable){var s=new Error(e);throw s.hash=t,s}this.trace(e)},"parseError"),parse:(0,c.K2)(function(e){var t=this,s=[0],i=[],n=[null],r=[],a=this.table,l="",o=0,h=0,u=0,y=r.slice.call(arguments,1),m=Object.create(this.lexer),d={yy:{}};for(var E in this.yy)Object.prototype.hasOwnProperty.call(this.yy,E)&&(d.yy[E]=this.yy[E]);m.setInput(e,d.yy),d.yy.lexer=m,d.yy.parser=this,void 0===m.yylloc&&(m.yylloc={});var p=m.yylloc;r.push(p);var R=m.options&&m.options.ranges;function f(){var e;return"number"!=typeof(e=i.pop()||m.lex()||1)&&(e instanceof Array&&(e=(i=e).pop()),e=t.symbols_[e]||e),e}"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,c.K2)(function(e){s.length=s.length-2*e,n.length=n.length-e,r.length=r.length-e},"popStack"),(0,c.K2)(f,"lex");for(var _,g,S,I,b,T,k,N,q,A={};;){if(S=s[s.length-1],this.defaultActions[S]?I=this.defaultActions[S]:(null==_&&(_=f()),I=a[S]&&a[S][_]),void 0===I||!I.length||!I[0]){var C="";for(T in q=[],a[S])this.terminals_[T]&&T>2&&q.push("'"+this.terminals_[T]+"'");C=m.showPosition?"Parse error on line "+(o+1)+":\n"+m.showPosition()+"\nExpecting "+q.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==_?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(C,{text:m.match,token:this.terminals_[_]||_,line:m.yylineno,loc:p,expected:q})}if(I[0]instanceof Array&&I.length>1)throw new Error("Parse Error: multiple actions possible at state: "+S+", token: "+_);switch(I[0]){case 1:s.push(_),n.push(m.yytext),r.push(m.yylloc),s.push(I[1]),_=null,g?(_=g,g=null):(h=m.yyleng,l=m.yytext,o=m.yylineno,p=m.yylloc,u>0&&u--);break;case 2:if(k=this.productions_[I[1]][1],A.$=n[n.length-k],A._$={first_line:r[r.length-(k||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(k||1)].first_column,last_column:r[r.length-1].last_column},R&&(A._$.range=[r[r.length-(k||1)].range[0],r[r.length-1].range[1]]),void 0!==(b=this.performAction.apply(A,[l,h,o,d.yy,I[1],n,r].concat(y))))return b;k&&(s=s.slice(0,-1*k*2),n=n.slice(0,-1*k),r=r.slice(0,-1*k)),s.push(this.productions_[I[1]][0]),n.push(A.$),r.push(A._$),N=a[s[s.length-2]][s[s.length-1]],s.push(N);break;case 3:return!0}}return!0},"parse")},he=function(){return{EOF:1,parseError:(0,c.K2)(function(e,t){if(!this.yy.parser)throw new Error(e);this.yy.parser.parseError(e,t)},"parseError"),setInput:(0,c.K2)(function(e,t){return this.yy=t||this.yy||{},this._input=e,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:(0,c.K2)(function(){var e=this._input[0];return this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e,e.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},"input"),unput:(0,c.K2)(function(e){var t=e.length,s=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t),this.offset-=t;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),s.length-1&&(this.yylineno-=s.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:s?(s.length===i.length?this.yylloc.first_column:0)+i[i.length-s.length].length-s[0].length:this.yylloc.first_column-t},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-t]),this.yyleng=this.yytext.length,this},"unput"),more:(0,c.K2)(function(){return this._more=!0,this},"more"),reject:(0,c.K2)(function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"reject"),less:(0,c.K2)(function(e){this.unput(this.match.slice(e))},"less"),pastInput:(0,c.K2)(function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:(0,c.K2)(function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:(0,c.K2)(function(){var e=this.pastInput(),t=new Array(e.length+1).join("-");return e+this.upcomingInput()+"\n"+t+"^"},"showPosition"),test_match:(0,c.K2)(function(e,t){var s,i,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(i=e[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(e[0].length),this.matched+=e[0],s=this.performAction.call(this,this.yy,this,t,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},"test_match"),next:(0,c.K2)(function(){if(this.done)return this.EOF;var e,t,s,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;r<n.length;r++)if((s=this._input.match(this.rules[n[r]]))&&(!t||s[0].length>t[0].length)){if(t=s,i=r,this.options.backtrack_lexer){if(!1!==(e=this.test_match(s,n[r])))return e;if(this._backtrack){t=!1;continue}return!1}if(!this.options.flex)break}return t?!1!==(e=this.test_match(t,n[i]))&&e:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:(0,c.K2)(function(){var e=this.next();return e||this.lex()},"lex"),begin:(0,c.K2)(function(e){this.conditionStack.push(e)},"begin"),popState:(0,c.K2)(function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:(0,c.K2)(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:(0,c.K2)(function(e){return(e=this.conditionStack.length-1-Math.abs(e||0))>=0?this.conditionStack[e]:"INITIAL"},"topState"),pushState:(0,c.K2)(function(e){this.begin(e)},"pushState"),stateStackSize:(0,c.K2)(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,c.K2)(function(e,t,s,i){switch(s){case 0:return"title";case 1:return this.begin("acc_title"),9;case 2:return this.popState(),"acc_title_value";case 3:return this.begin("acc_descr"),11;case 4:return this.popState(),"acc_descr_value";case 5:this.begin("acc_descr_multiline");break;case 6:case 58:case 65:this.popState();break;case 7:return"acc_descr_multiline_value";case 8:return 21;case 9:return 22;case 10:return 23;case 11:return 24;case 12:return 5;case 13:case 14:case 15:case 56:break;case 16:return 8;case 17:return 6;case 18:return 27;case 19:return 40;case 20:return 29;case 21:return 32;case 22:return 31;case 23:return 34;case 24:return 36;case 25:return 38;case 26:return 41;case 27:return 42;case 28:return 43;case 29:return 44;case 30:return 45;case 31:return 46;case 32:return 47;case 33:return 48;case 34:return 49;case 35:return 50;case 36:return 51;case 37:return 52;case 38:return 53;case 39:return 54;case 40:return 65;case 41:return 66;case 42:return 67;case 43:return 68;case 44:return 69;case 45:return 70;case 46:return 71;case 47:return 57;case 48:return 59;case 49:return this.begin("style"),77;case 50:case 68:return 75;case 51:return 81;case 52:return 88;case 53:return"PERCENT";case 54:return 86;case 55:return 84;case 57:case 64:this.begin("string");break;case 59:return this.begin("style"),72;case 60:return this.begin("style"),74;case 61:return 61;case 62:return 64;case 63:return 63;case 66:return"qString";case 67:return t.yytext=t.yytext.trim(),89;case 69:return 80;case 70:return 76}},"anonymous"),rules:[/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:$)/i,/^(?:requirementDiagram\b)/i,/^(?:\{)/i,/^(?:\})/i,/^(?::{3})/i,/^(?::)/i,/^(?:id\b)/i,/^(?:text\b)/i,/^(?:risk\b)/i,/^(?:verifyMethod\b)/i,/^(?:requirement\b)/i,/^(?:functionalRequirement\b)/i,/^(?:interfaceRequirement\b)/i,/^(?:performanceRequirement\b)/i,/^(?:physicalRequirement\b)/i,/^(?:designConstraint\b)/i,/^(?:low\b)/i,/^(?:medium\b)/i,/^(?:high\b)/i,/^(?:analysis\b)/i,/^(?:demonstration\b)/i,/^(?:inspection\b)/i,/^(?:test\b)/i,/^(?:element\b)/i,/^(?:contains\b)/i,/^(?:copies\b)/i,/^(?:derives\b)/i,/^(?:satisfies\b)/i,/^(?:verifies\b)/i,/^(?:refines\b)/i,/^(?:traces\b)/i,/^(?:type\b)/i,/^(?:docref\b)/i,/^(?:style\b)/i,/^(?:\w+)/i,/^(?::)/i,/^(?:;)/i,/^(?:%)/i,/^(?:-)/i,/^(?:#)/i,/^(?: )/i,/^(?:["])/i,/^(?:\n)/i,/^(?:classDef\b)/i,/^(?:class\b)/i,/^(?:<-)/i,/^(?:->)/i,/^(?:-)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[\w][^:,\r\n\{\<\>\-\=]*)/i,/^(?:\w+)/i,/^(?:[0-9]+)/i,/^(?:,)/i],conditions:{acc_descr_multiline:{rules:[6,7,68,69,70],inclusive:!1},acc_descr:{rules:[4,68,69,70],inclusive:!1},acc_title:{rules:[2,68,69,70],inclusive:!1},style:{rules:[50,51,52,53,54,55,56,57,58,68,69,70],inclusive:!1},unqString:{rules:[68,69,70],inclusive:!1},token:{rules:[68,69,70],inclusive:!1},string:{rules:[65,66,68,69,70],inclusive:!1},INITIAL:{rules:[0,1,3,5,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,59,60,61,62,63,64,67,68,69,70],inclusive:!0}}}}();function ue(){this.yy={}}return oe.lexer=he,(0,c.K2)(ue,"Parser"),ue.prototype=oe,oe.Parser=ue,new ue}();o.parser=o;var h=o,u=class{constructor(){this.relations=[],this.latestRequirement=this.getInitialRequirement(),this.requirements=new Map,this.latestElement=this.getInitialElement(),this.elements=new Map,this.classes=new Map,this.direction="TB",this.RequirementType={REQUIREMENT:"Requirement",FUNCTIONAL_REQUIREMENT:"Functional Requirement",INTERFACE_REQUIREMENT:"Interface Requirement",PERFORMANCE_REQUIREMENT:"Performance Requirement",PHYSICAL_REQUIREMENT:"Physical Requirement",DESIGN_CONSTRAINT:"Design Constraint"},this.RiskLevel={LOW_RISK:"Low",MED_RISK:"Medium",HIGH_RISK:"High"},this.VerifyType={VERIFY_ANALYSIS:"Analysis",VERIFY_DEMONSTRATION:"Demonstration",VERIFY_INSPECTION:"Inspection",VERIFY_TEST:"Test"},this.Relationships={CONTAINS:"contains",COPIES:"copies",DERIVES:"derives",SATISFIES:"satisfies",VERIFIES:"verifies",REFINES:"refines",TRACES:"traces"},this.setAccTitle=l.SV,this.getAccTitle=l.iN,this.setAccDescription=l.EI,this.getAccDescription=l.m7,this.setDiagramTitle=l.ke,this.getDiagramTitle=l.ab,this.getConfig=(0,c.K2)(()=>(0,l.D7)().requirement,"getConfig"),this.clear(),this.setDirection=this.setDirection.bind(this),this.addRequirement=this.addRequirement.bind(this),this.setNewReqId=this.setNewReqId.bind(this),this.setNewReqRisk=this.setNewReqRisk.bind(this),this.setNewReqText=this.setNewReqText.bind(this),this.setNewReqVerifyMethod=this.setNewReqVerifyMethod.bind(this),this.addElement=this.addElement.bind(this),this.setNewElementType=this.setNewElementType.bind(this),this.setNewElementDocRef=this.setNewElementDocRef.bind(this),this.addRelationship=this.addRelationship.bind(this),this.setCssStyle=this.setCssStyle.bind(this),this.setClass=this.setClass.bind(this),this.defineClass=this.defineClass.bind(this),this.setAccTitle=this.setAccTitle.bind(this),this.setAccDescription=this.setAccDescription.bind(this)}static{(0,c.K2)(this,"RequirementDB")}getDirection(){return this.direction}setDirection(e){this.direction=e}resetLatestRequirement(){this.latestRequirement=this.getInitialRequirement()}resetLatestElement(){this.latestElement=this.getInitialElement()}getInitialRequirement(){return{requirementId:"",text:"",risk:"",verifyMethod:"",name:"",type:"",cssStyles:[],classes:["default"]}}getInitialElement(){return{name:"",type:"",docRef:"",cssStyles:[],classes:["default"]}}addRequirement(e,t){return this.requirements.has(e)||this.requirements.set(e,{name:e,type:t,requirementId:this.latestRequirement.requirementId,text:this.latestRequirement.text,risk:this.latestRequirement.risk,verifyMethod:this.latestRequirement.verifyMethod,cssStyles:[],classes:["default"]}),this.resetLatestRequirement(),this.requirements.get(e)}getRequirements(){return this.requirements}setNewReqId(e){void 0!==this.latestRequirement&&(this.latestRequirement.requirementId=e)}setNewReqText(e){void 0!==this.latestRequirement&&(this.latestRequirement.text=e)}setNewReqRisk(e){void 0!==this.latestRequirement&&(this.latestRequirement.risk=e)}setNewReqVerifyMethod(e){void 0!==this.latestRequirement&&(this.latestRequirement.verifyMethod=e)}addElement(e){return this.elements.has(e)||(this.elements.set(e,{name:e,type:this.latestElement.type,docRef:this.latestElement.docRef,cssStyles:[],classes:["default"]}),c.Rm.info("Added new element: ",e)),this.resetLatestElement(),this.elements.get(e)}getElements(){return this.elements}setNewElementType(e){void 0!==this.latestElement&&(this.latestElement.type=e)}setNewElementDocRef(e){void 0!==this.latestElement&&(this.latestElement.docRef=e)}addRelationship(e,t,s){this.relations.push({type:e,src:t,dst:s})}getRelationships(){return this.relations}clear(){this.relations=[],this.resetLatestRequirement(),this.requirements=new Map,this.resetLatestElement(),this.elements=new Map,this.classes=new Map,(0,l.IU)()}setCssStyle(e,t){for(const s of e){const e=this.requirements.get(s)??this.elements.get(s);if(!t||!e)return;for(const s of t)s.includes(",")?e.cssStyles.push(...s.split(",")):e.cssStyles.push(s)}}setClass(e,t){for(const s of e){const e=this.requirements.get(s)??this.elements.get(s);if(e)for(const s of t){e.classes.push(s);const t=this.classes.get(s)?.styles;t&&e.cssStyles.push(...t)}}}defineClass(e,t){for(const s of e){let e=this.classes.get(s);void 0===e&&(e={id:s,styles:[],textStyles:[]},this.classes.set(s,e)),t&&t.forEach(function(t){if(/color/.exec(t)){const s=t.replace("fill","bgFill");e.textStyles.push(s)}e.styles.push(t)}),this.requirements.forEach(e=>{e.classes.includes(s)&&e.cssStyles.push(...t.flatMap(e=>e.split(",")))}),this.elements.forEach(e=>{e.classes.includes(s)&&e.cssStyles.push(...t.flatMap(e=>e.split(",")))})}}getClasses(){return this.classes}getData(){const e=(0,l.D7)(),t=[],s=[];for(const i of this.requirements.values()){const s=i;s.id=i.name,s.cssStyles=i.cssStyles,s.cssClasses=i.classes.join(" "),s.shape="requirementBox",s.look=e.look,t.push(s)}for(const i of this.elements.values()){const s=i;s.shape="requirementBox",s.look=e.look,s.id=i.name,s.cssStyles=i.cssStyles,s.cssClasses=i.classes.join(" "),t.push(s)}for(const i of this.relations){let t=0;const n=i.type===this.Relationships.CONTAINS,r={id:`${i.src}-${i.dst}-${t}`,start:this.requirements.get(i.src)?.name??this.elements.get(i.src)?.name,end:this.requirements.get(i.dst)?.name??this.elements.get(i.dst)?.name,label:`<<${i.type}>>`,classes:"relationshipLine",style:["fill:none",n?"":"stroke-dasharray: 10,7"],labelpos:"c",thickness:"normal",type:"normal",pattern:n?"normal":"dashed",arrowTypeStart:n?"requirement_contains":"",arrowTypeEnd:n?"":"requirement_arrow",look:e.look};s.push(r),t++}return{nodes:t,edges:s,other:{},config:e,direction:this.getDirection()}}},y=(0,c.K2)(e=>`\n\n marker {\n fill: ${e.relationColor};\n stroke: ${e.relationColor};\n }\n\n marker.cross {\n stroke: ${e.lineColor};\n }\n\n svg {\n font-family: ${e.fontFamily};\n font-size: ${e.fontSize};\n }\n\n .reqBox {\n fill: ${e.requirementBackground};\n fill-opacity: 1.0;\n stroke: ${e.requirementBorderColor};\n stroke-width: ${e.requirementBorderSize};\n }\n \n .reqTitle, .reqLabel{\n fill: ${e.requirementTextColor};\n }\n .reqLabelBox {\n fill: ${e.relationLabelBackground};\n fill-opacity: 1.0;\n }\n\n .req-title-line {\n stroke: ${e.requirementBorderColor};\n stroke-width: ${e.requirementBorderSize};\n }\n .relationshipLine {\n stroke: ${e.relationColor};\n stroke-width: 1;\n }\n .relationshipLabel {\n fill: ${e.relationLabelColor};\n }\n .divider {\n stroke: ${e.nodeBorder};\n stroke-width: 1;\n }\n .label {\n font-family: ${e.fontFamily};\n color: ${e.nodeTextColor||e.textColor};\n }\n .label text,span {\n fill: ${e.nodeTextColor||e.textColor};\n color: ${e.nodeTextColor||e.textColor};\n }\n .labelBkg {\n background-color: ${e.edgeLabelBackground};\n }\n\n`,"getStyles"),m={};(0,c.VA)(m,{draw:()=>d});var d=(0,c.K2)(async function(e,t,s,o){c.Rm.info("REF0:"),c.Rm.info("Drawing requirement diagram (unified)",t);const{securityLevel:h,state:u,layout:y}=(0,l.D7)(),m=o.db.getData(),d=(0,i.A)(t,h);m.type=o.type,m.layoutAlgorithm=(0,r.q7)(y),m.nodeSpacing=u?.nodeSpacing??50,m.rankSpacing=u?.rankSpacing??50,m.markers=["requirement_contains","requirement_arrow"],m.diagramId=t,await(0,r.XX)(m,d);a._K.insertTitle(d,"requirementDiagramTitleText",u?.titleTopMargin??25,o.db.getDiagramTitle()),(0,n.P)(d,8,"requirementDiagram",u?.useMaxWidth??!0)},"draw"),E={parser:h,get db(){return new u},renderer:m,styles:y}},89625:(e,t,s)=>{s.d(t,{A:()=>r});var i=s(40797),n=s(70451),r=(0,i.K2)((e,t)=>{let s;"sandbox"===t&&(s=(0,n.Ltv)("#i"+e));return("sandbox"===t?(0,n.Ltv)(s.nodes()[0].contentDocument.body):(0,n.Ltv)("body")).select(`[id="${e}"]`)},"getDiagramElement")}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/311067ef.a0fdf84a.js b/pr-preview/pr-4027/assets/js/311067ef.a0fdf84a.js deleted file mode 100644 index cfc281d81..000000000 --- a/pr-preview/pr-4027/assets/js/311067ef.a0fdf84a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7856],{28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>i});var s=t(96540);const o={},r=s.createContext(o);function a(e){const n=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(r.Provider,{value:n},e.children)}},66565:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"workflows/lb","title":"Expose a service","description":"Constellation integrates the native load balancers of each CSP. Therefore, to expose a service simply create a service of type LoadBalancer.","source":"@site/docs/workflows/lb.md","sourceDirName":"workflows","slug":"/workflows/lb","permalink":"/constellation/pr-preview/pr-4027/next/workflows/lb","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/workflows/lb.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Upgrade your cluster","permalink":"/constellation/pr-preview/pr-4027/next/workflows/upgrade"},"next":{"title":"Install cert-manager","permalink":"/constellation/pr-preview/pr-4027/next/workflows/cert-manager"}}');var o=t(74848),r=t(28453);const a={},i="Expose a service",c={},l=[{value:"Internet-facing LB service on AWS",id:"internet-facing-lb-service-on-aws",level:2},{value:"Ingress on AWS",id:"ingress-on-aws",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"expose-a-service",children:"Expose a service"})}),"\n",(0,o.jsxs)(n.p,{children:["Constellation integrates the native load balancers of each CSP. Therefore, to expose a service simply ",(0,o.jsxs)(n.a,{href:"https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer",children:["create a service of type ",(0,o.jsx)(n.code,{children:"LoadBalancer"})]}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"internet-facing-lb-service-on-aws",children:"Internet-facing LB service on AWS"}),"\n",(0,o.jsxs)(n.p,{children:["To expose your application service externally you might want to use a Kubernetes Service of type ",(0,o.jsx)(n.code,{children:"LoadBalancer"}),". On AWS, load-balancing is achieved through the ",(0,o.jsx)(n.a,{href:"https://kubernetes-sigs.github.io/aws-load-balancer-controller",children:"AWS Load Balancer Controller"})," as in the managed EKS."]}),"\n",(0,o.jsxs)(n.p,{children:["Since recent versions, the controller deploy an internal LB by default requiring to set an annotation ",(0,o.jsx)(n.code,{children:"service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing"})," to have an internet-facing LB. For more details, see the ",(0,o.jsx)(n.a,{href:"https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.7/guide/service/nlb/",children:"official docs"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["For general information on LB with AWS see ",(0,o.jsx)(n.a,{href:"https://docs.aws.amazon.com/eks/latest/userguide/network-load-balancing.html",children:"Network load balancing on Amazon EKS"}),"."]}),"\n",(0,o.jsx)(n.admonition,{type:"caution",children:(0,o.jsx)(n.p,{children:"Before terminating the cluster, all LB backed services should be deleted, so that the controller can cleanup the related resources."})}),"\n",(0,o.jsx)(n.h2,{id:"ingress-on-aws",children:"Ingress on AWS"}),"\n",(0,o.jsxs)(n.p,{children:["The AWS Load Balancer Controller also provisions ",(0,o.jsx)(n.code,{children:"Ingress"})," resources of class ",(0,o.jsx)(n.code,{children:"alb"}),".\nAWS Application Load Balancers (ALBs) can be configured with a ",(0,o.jsx)(n.a,{href:"https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.7/guide/ingress/annotations/#target-type",children:(0,o.jsx)(n.code,{children:"target-type"})}),".\nThe target type ",(0,o.jsx)(n.code,{children:"ip"})," requires using the EKS container network solution, which makes it incompatible with Constellation.\nIf a service can be exposed on a ",(0,o.jsx)(n.code,{children:"NodePort"}),", the target type ",(0,o.jsx)(n.code,{children:"instance"})," can be used."]}),"\n",(0,o.jsxs)(n.p,{children:["See ",(0,o.jsx)(n.a,{href:"https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html",children:"Application load balancing on Amazon EKS"})," for more information."]}),"\n",(0,o.jsx)(n.admonition,{type:"caution",children:(0,o.jsx)(n.p,{children:"Ingress handlers backed by AWS ALBs reside outside the Constellation cluster, so they shouldn't be handling sensitive traffic!"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/31840164.0097030a.js b/pr-preview/pr-4027/assets/js/31840164.0097030a.js deleted file mode 100644 index 4e1408307..000000000 --- a/pr-preview/pr-4027/assets/js/31840164.0097030a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3440],{28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>r});var a=s(96540);const n={},l=a.createContext(n);function o(e){const t=a.useContext(l);return a.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),a.createElement(l.Provider,{value:t},e.children)}},73865:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>c});const a=JSON.parse('{"id":"getting-started/marketplaces","title":"Using Constellation via Cloud Marketplaces","description":"Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please contact us.","source":"@site/docs/getting-started/marketplaces.md","sourceDirName":"getting-started","slug":"/getting-started/marketplaces","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/marketplaces","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/getting-started/marketplaces.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"First steps (local)","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/first-steps-local"},"next":{"title":"Examples","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/examples"}}');var n=s(74848),l=s(28453);const o={},r="Using Constellation via Cloud Marketplaces",i={},c=[];function p(e){const t={a:"a",code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,l.R)(),...e.components},{TabItem:s,Tabs:a}=t;return s||h("TabItem",!0),a||h("Tabs",!0),(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"using-constellation-via-cloud-marketplaces",children:"Using Constellation via Cloud Marketplaces"})}),"\n",(0,n.jsxs)(t.p,{children:["Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please ",(0,n.jsx)(t.a,{href:"https://www.edgeless.systems/enterprise-support/",children:"contact us"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"This document explains how to run Constellation with the dynamically billed cloud marketplace images."}),"\n",(0,n.jsxs)(a,{groupId:"csp",children:[(0,n.jsxs)(s,{value:"aws",label:"AWS",children:[(0,n.jsxs)(t.p,{children:["To use Constellation's marketplace images, ensure that you are subscribed to the ",(0,n.jsx)(t.a,{href:"https://aws.amazon.com/marketplace/pp/prodview-2mbn65nv57oys",children:"marketplace offering"})," through the web portal."]}),(0,n.jsxs)(t.p,{children:["Then, enable the use of marketplace images in your Constellation ",(0,n.jsx)(t.code,{children:"constellation-conf.yaml"})," ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/config",children:"config file"}),":"]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:'yq eval -i ".provider.aws.useMarketplaceImage = true" constellation-conf.yaml\n'})})]}),(0,n.jsxs)(s,{value:"azure",label:"Azure",children:[(0,n.jsxs)(t.p,{children:["Constellation has a private marketplace plan. Please ",(0,n.jsx)(t.a,{href:"https://www.edgeless.systems/enterprise-support/",children:"contact us"})," to gain access."]}),(0,n.jsxs)(t.p,{children:["To use a marketplace image, you need to accept the marketplace image's terms once for your subscription with the ",(0,n.jsx)(t.a,{href:"https://learn.microsoft.com/en-us/cli/azure/vm/image/terms?view=azure-cli-latest",children:"Azure CLI"}),":"]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"az vm image terms accept --publisher edgelesssystems --offer constellation --plan constellation\n"})}),(0,n.jsxs)(t.p,{children:["Then, enable the use of marketplace images in your Constellation ",(0,n.jsx)(t.code,{children:"constellation-conf.yaml"})," ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/config",children:"config file"}),":"]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:'yq eval -i ".provider.azure.useMarketplaceImage = true" constellation-conf.yaml\n'})})]}),(0,n.jsxs)(s,{value:"gcp",label:"GCP",children:[(0,n.jsxs)(t.p,{children:["To use a marketplace image, ensure that the account is entitled to use marketplace images by Edgeless Systems by accepting the terms through the ",(0,n.jsx)(t.a,{href:"https://console.cloud.google.com/marketplace/vm/config/edgeless-systems-public/constellation",children:"web portal"}),"."]}),(0,n.jsxs)(t.p,{children:["Then, enable the use of marketplace images in your Constellation ",(0,n.jsx)(t.code,{children:"constellation-conf.yaml"})," ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/config",children:"config file"}),":"]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:'yq eval -i ".provider.gcp.useMarketplaceImage = true" constellation-conf.yaml\n'})})]}),(0,n.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,n.jsx)(t.p,{children:"On STACKIT, the selected Constellation image is always a marketplace image. You can find more information on the STACKIT portal."})})]}),"\n",(0,n.jsxs)(t.p,{children:["Ensure that the cluster uses an official release image version (i.e., ",(0,n.jsx)(t.code,{children:".image=vX.Y.Z"})," in the ",(0,n.jsx)(t.code,{children:"constellation-conf.yaml"})," file)."]}),"\n",(0,n.jsxs)(t.p,{children:["From there, you can proceed with the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/create",children:"cluster creation"})," as usual."]})]})}function d(e={}){const{wrapper:t}={...(0,l.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}function h(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/31cc4483.6741e272.js b/pr-preview/pr-4027/assets/js/31cc4483.6741e272.js deleted file mode 100644 index 4459fcd08..000000000 --- a/pr-preview/pr-4027/assets/js/31cc4483.6741e272.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2398],{28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>s});var t=r(96540);const o={},l=t.createContext(o);function i(e){const n=t.useContext(l);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),t.createElement(l.Provider,{value:n},e.children)}},32256:(e,n,r)=>{r.d(n,{A:()=>t});const t=r.p+"assets/images/recovery-gcp-serial-console-link-d31487c5a5e88fbcde9dcc33e876838d.png"},38967:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>t,toc:()=>a});const t=JSON.parse('{"id":"workflows/recovery","title":"Recover your cluster","description":"Recovery of a Constellation cluster means getting it back into a healthy state after too many concurrent node failures in the control plane.","source":"@site/versioned_docs/version-2.24/workflows/recovery.md","sourceDirName":"workflows","slug":"/workflows/recovery","permalink":"/constellation/pr-preview/pr-4027/workflows/recovery","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/workflows/recovery.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Terminate your cluster","permalink":"/constellation/pr-preview/pr-4027/workflows/terminate"},"next":{"title":"Verify your cluster","permalink":"/constellation/pr-preview/pr-4027/workflows/verify-cluster"}}');var o=r(74848),l=r(28453);const i={},s="Recover your cluster",c={},a=[{value:"Identify unhealthy clusters",id:"identify-unhealthy-clusters",level:2},{value:"Recover a cluster",id:"recover-a-cluster",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,l.R)(),...e.components},{TabItem:t,Tabs:i}=n;return t||g("TabItem",!0),i||g("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"recover-your-cluster",children:"Recover your cluster"})}),"\n",(0,o.jsxs)(n.p,{children:["Recovery of a Constellation cluster means getting it back into a healthy state after too many concurrent node failures in the control plane.\nReasons for an unhealthy cluster can vary from a power outage, or planned reboot, to migration of nodes and regions.\nRecovery events are rare, because Constellation is built for high availability and automatically and securely replaces failed nodes. When a node is replaced, Constellation's control plane first verifies the new node before it sends the node the cryptographic keys required to decrypt its ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/images#state-disk",children:"state disk"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Constellation provides a recovery mechanism for cases where the control plane has failed and is unable to replace nodes.\nThe ",(0,o.jsx)(n.code,{children:"constellation recover"})," command securely connects to all nodes in need of recovery using ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/attestation#attested-tls-atls",children:"attested TLS"})," and provides them with the keys to decrypt their state disks and continue booting."]}),"\n",(0,o.jsx)(n.h2,{id:"identify-unhealthy-clusters",children:"Identify unhealthy clusters"}),"\n",(0,o.jsx)(n.p,{children:"The first step to recovery is identifying when a cluster becomes unhealthy.\nUsually, this can be first observed when the Kubernetes API server becomes unresponsive."}),"\n",(0,o.jsx)(n.p,{children:"You can check the health status of the nodes via the cloud service provider (CSP).\nConstellation provides logging information on the boot process and status via serial console output.\nIn the following, you'll find detailed descriptions for identifying clusters stuck in recovery for each CSP."}),"\n",(0,o.jsxs)(i,{groupId:"csp",children:[(0,o.jsxs)(t,{value:"aws",label:"AWS",children:[(0,o.jsxs)(n.p,{children:["First, open the AWS console to view all Auto Scaling Groups (ASGs) in the region of your cluster. Select the ASG of the control plane ",(0,o.jsx)(n.code,{children:"<cluster-name>-<UID>-control-plane"})," and check that enough members are in a ",(0,o.jsx)(n.em,{children:"Running"})," state."]}),(0,o.jsxs)(n.p,{children:["Second, check the boot logs of these ",(0,o.jsx)(n.em,{children:"Instances"}),". In the ASG's ",(0,o.jsx)(n.em,{children:"Instance management"})," view, select each desired instance. In the upper right corner, select ",(0,o.jsx)(n.strong,{children:"Action > Monitor and troubleshoot > Get system log"}),"."]}),(0,o.jsxs)(n.p,{children:["In the serial console output, search for ",(0,o.jsx)(n.code,{children:"Waiting for decryption key"}),".\nSimilar output to the following means your node was restarted and needs to decrypt the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/images#state-disk",children:"state disk"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"gcp"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}\n'})}),(0,o.jsxs)(n.p,{children:["The node will then try to connect to the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#joinservice",children:(0,o.jsx)(n.em,{children:"JoinService"})})," and obtain the decryption key.\nIf this fails due to an unhealthy control plane, you will see log messages similar to the following:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["192.168.178.4:30090","192.168.178.2:30090"]}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.4:30090"}\n{"level":"WARN","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.4:30090: connect: connection refused\\"","endpoint":"192.168.178.4:30090"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.2:30090"}\n{"level":"WARN","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.2:30090: i/o timeout\\"","endpoint":"192.168.178.2:30090"}\n{"level":"ERROR","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}\n'})}),(0,o.jsx)(n.p,{children:"This means that you have to recover the node manually."})]}),(0,o.jsxs)(t,{value:"azure",label:"Azure",children:[(0,o.jsxs)(n.p,{children:["In the Azure portal, find the cluster's resource group.\nInside the resource group, open the control plane ",(0,o.jsx)(n.em,{children:"Virtual machine scale set"})," ",(0,o.jsx)(n.code,{children:"constellation-scale-set-controlplanes-<suffix>"}),".\nOn the left, go to ",(0,o.jsx)(n.strong,{children:"Settings"})," > ",(0,o.jsx)(n.strong,{children:"Instances"})," and check that enough members are in a ",(0,o.jsx)(n.em,{children:"Running"})," state."]}),(0,o.jsxs)(n.p,{children:["Second, check the boot logs of these ",(0,o.jsx)(n.em,{children:"Instances"}),".\nIn the scale set's ",(0,o.jsx)(n.em,{children:"Instances"})," view, open the details page of the desired instance.\nOn the left, go to ",(0,o.jsx)(n.strong,{children:"Support + troubleshooting"})," > ",(0,o.jsx)(n.strong,{children:"Serial console"}),"."]}),(0,o.jsxs)(n.p,{children:["In the serial console output, search for ",(0,o.jsx)(n.code,{children:"Waiting for decryption key"}),".\nSimilar output to the following means your node was restarted and needs to decrypt the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/images#state-disk",children:"state disk"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T09:56:41Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"azure"}\n{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}\n{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}\n{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}\n'})}),(0,o.jsxs)(n.p,{children:["The node will then try to connect to the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#joinservice",children:(0,o.jsx)(n.em,{children:"JoinService"})})," and obtain the decryption key.\nIf this fails due to an unhealthy control plane, you will see log messages similar to the following:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["10.9.0.5:30090","10.9.0.6:30090"]}\n{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"10.9.0.5:30090"}\n{"level":"WARN","ts":"2022-09-08T09:57:03Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 10.9.0.5:30090: i/o timeout\\"","endpoint":"10.9.0.5:30090"}\n{"level":"INFO","ts":"2022-09-08T09:57:03Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"10.9.0.6:30090"}\n{"level":"WARN","ts":"2022-09-08T09:57:23Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 10.9.0.6:30090: i/o timeout\\"","endpoint":"10.9.0.6:30090"}\n{"level":"ERROR","ts":"2022-09-08T09:57:23Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}\n'})}),(0,o.jsx)(n.p,{children:"This means that you have to recover the node manually."})]}),(0,o.jsxs)(t,{value:"gcp",label:"GCP",children:[(0,o.jsxs)(n.p,{children:["First, check that the control plane ",(0,o.jsx)(n.em,{children:"Instance Group"})," has enough members in a ",(0,o.jsx)(n.em,{children:"Ready"})," state.\nIn the GCP Console, go to ",(0,o.jsx)(n.strong,{children:"Instance Groups"})," and check the group for the cluster's control plane ",(0,o.jsx)(n.code,{children:"<cluster-name>-control-plane-<suffix>"}),"."]}),(0,o.jsxs)(n.p,{children:["Second, check the status of the ",(0,o.jsx)(n.em,{children:"VM Instances"}),".\nGo to ",(0,o.jsx)(n.strong,{children:"VM Instances"})," and open the details of the desired instance.\nCheck the serial console output of that instance by opening the ",(0,o.jsx)(n.strong,{children:"Logs"})," > ",(0,o.jsx)(n.strong,{children:"Serial port 1 (console)"})," page:"]}),(0,o.jsx)(n.p,{children:(0,o.jsx)(n.img,{alt:"GCP portal serial console link",src:r(32256).A+"",width:"846",height:"415"})}),(0,o.jsxs)(n.p,{children:["In the serial console output, search for ",(0,o.jsx)(n.code,{children:"Waiting for decryption key"}),".\nSimilar output to the following means your node was restarted and needs to decrypt the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/images#state-disk",children:"state disk"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"gcp"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}\n'})}),(0,o.jsxs)(n.p,{children:["The node will then try to connect to the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#joinservice",children:(0,o.jsx)(n.em,{children:"JoinService"})})," and obtain the decryption key.\nIf this fails due to an unhealthy control plane, you will see log messages similar to the following:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["192.168.178.4:30090","192.168.178.2:30090"]}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.4:30090"}\n{"level":"WARN","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.4:30090: connect: connection refused\\"","endpoint":"192.168.178.4:30090"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.2:30090"}\n{"level":"WARN","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.2:30090: i/o timeout\\"","endpoint":"192.168.178.2:30090"}\n{"level":"ERROR","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}\n'})}),(0,o.jsx)(n.p,{children:"This means that you have to recover the node manually."})]}),(0,o.jsxs)(t,{value:"stackit",label:"STACKIT",children:[(0,o.jsxs)(n.p,{children:["First, open the STACKIT portal to view all servers in your project. Select individual control plane nodes ",(0,o.jsx)(n.code,{children:"<cluster-name>-<UID>-control-plane-<UID>-<index>"})," and check that enough members are in a ",(0,o.jsx)(n.em,{children:"Running"})," state."]}),(0,o.jsxs)(n.p,{children:["Second, check the boot logs of these servers. Click on a server name and select ",(0,o.jsx)(n.strong,{children:"Overview"}),". Find the ",(0,o.jsx)(n.strong,{children:"Machine Setup"})," section and click on ",(0,o.jsx)(n.strong,{children:"Web console"})," > ",(0,o.jsx)(n.strong,{children:"Open console"}),"."]}),(0,o.jsxs)(n.p,{children:["In the serial console output, search for ",(0,o.jsx)(n.code,{children:"Waiting for decryption key"}),".\nSimilar output to the following means your node was restarted and needs to decrypt the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/images#state-disk",children:"state disk"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"gcp"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}\n'})}),(0,o.jsxs)(n.p,{children:["The node will then try to connect to the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#joinservice",children:(0,o.jsx)(n.em,{children:"JoinService"})})," and obtain the decryption key.\nIf this fails due to an unhealthy control plane, you will see log messages similar to the following:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["192.168.178.4:30090","192.168.178.2:30090"]}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.4:30090"}\n{"level":"WARN","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.4:30090: connect: connection refused\\"","endpoint":"192.168.178.4:30090"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.2:30090"}\n{"level":"WARN","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.2:30090: i/o timeout\\"","endpoint":"192.168.178.2:30090"}\n{"level":"ERROR","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}\n'})}),(0,o.jsx)(n.p,{children:"This means that you have to recover the node manually."})]})]}),"\n",(0,o.jsx)(n.h2,{id:"recover-a-cluster",children:"Recover a cluster"}),"\n",(0,o.jsx)(n.p,{children:"Recovering a cluster requires the following parameters:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The ",(0,o.jsx)(n.code,{children:"constellation-state.yaml"})," file in your working directory or the cluster's endpoint"]}),"\n",(0,o.jsx)(n.li,{children:"The master secret of the cluster"}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"A cluster can be recovered like this:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"$ constellation recover\nPushed recovery key.\nPushed recovery key.\nPushed recovery key.\nRecovered 3 control-plane nodes.\n"})}),"\n",(0,o.jsx)(n.p,{children:"In the serial console output of the node you'll see a similar output to the following:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer","caller":"recoveryserver/server.go:93","msg":"Received recover call"}\n{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer","caller":"recoveryserver/server.go:125","msg":"Received state disk key and measurement secret, shutting down server"}\n{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer.gRPC","caller":"zap/server_interceptors.go:61","msg":"finished streaming call with code OK","grpc.start_time":"2022-09-08T10:26:59Z","system":"grpc","span.kind":"server","grpc.service":"recoverproto.API","grpc.method":"Recover","peer.address":"192.0.2.3:41752","grpc.code":"OK","grpc.time_ms":15.701}\n{"level":"INFO","ts":"2022-09-08T10:27:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:87","msg":"RejoinClient stopped"}\n'})})]})}function h(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}function g(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3305fd99.2ac95a3b.js b/pr-preview/pr-4027/assets/js/3305fd99.2ac95a3b.js deleted file mode 100644 index 006522614..000000000 --- a/pr-preview/pr-4027/assets/js/3305fd99.2ac95a3b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3092],{293:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"getting-started/first-steps","title":"First steps with Constellation","description":"The following steps guide you through the process of creating a cluster and deploying a sample app. This example assumes that you have successfully installed and set up Constellation,","source":"@site/versioned_docs/version-2.23/getting-started/first-steps.md","sourceDirName":"getting-started","slug":"/getting-started/first-steps","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/getting-started/first-steps.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Installation","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/install"},"next":{"title":"First steps (local)","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps-local"}}');var i=s(74848),l=s(28453);const o={},r="First steps with Constellation",a={},c=[{value:"Create a cluster",id:"create-a-cluster",level:2},{value:"Deploy a sample application",id:"deploy-a-sample-application",level:2},{value:"Terminate your cluster",id:"terminate-your-cluster",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,l.R)(),...e.components},{TabItem:s,Tabs:t}=n;return s||u("TabItem",!0),t||u("Tabs",!0),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"first-steps-with-constellation",children:"First steps with Constellation"})}),"\n",(0,i.jsxs)(n.p,{children:["The following steps guide you through the process of creating a cluster and deploying a sample app. This example assumes that you have successfully ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/install",children:"installed and set up Constellation"}),",\nand have access to a cloud subscription."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["If you don't have a cloud subscription, you can also set up a ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps-local",children:"local Constellation cluster using virtualization"})," for testing."]})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["If you encounter any problem with the following steps, make sure to use the ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/releases/latest",children:"latest release"})," and check out the ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"known issues"}),"."]})}),"\n",(0,i.jsx)(n.h2,{id:"create-a-cluster",children:"Create a cluster"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Create the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/config",children:"configuration file"})," and state file for your cloud provider. If you are following the steps of this guide, there is no need to edit the file."]}),"\n",(0,i.jsxs)(t,{groupId:"csp",children:[(0,i.jsx)(s,{value:"aws",label:"AWS",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation config generate aws\n"})})}),(0,i.jsx)(s,{value:"azure",label:"Azure",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation config generate azure\n"})})}),(0,i.jsx)(s,{value:"gcp",label:"GCP",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation config generate gcp\n"})})}),(0,i.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation config generate stackit\n"})})})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Create your ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/config#creating-an-iam-configuration",children:"IAM configuration"}),"."]}),"\n",(0,i.jsxs)(t,{groupId:"csp",children:[(0,i.jsxs)(s,{value:"aws",label:"AWS",children:[(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation iam create aws --zone=us-east-2a --prefix=constellTest --update-config\n"})}),(0,i.jsxs)(n.p,{children:["This command creates IAM configuration for the AWS zone ",(0,i.jsx)(n.code,{children:"us-east-2a"})," using the prefix ",(0,i.jsx)(n.code,{children:"constellTest"})," for all named resources being created. It also updates the configuration file ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"})," in your current directory with the IAM values filled in."]}),(0,i.jsxs)(n.p,{children:["Depending on the attestation variant selected on config generation, different regions are available.\nAMD SEV-SNP machines (requires the default attestation variant ",(0,i.jsx)(n.code,{children:"awsSEVSNP"}),") are currently available in the following regions:"]}),(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"eu-west-1"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"us-east-2"})}),"\n"]}),(0,i.jsxs)(n.p,{children:["You can find a list of regions that support AMD SEV-SNP in ",(0,i.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/snp-requirements.html",children:"AWS's documentation"}),"."]}),(0,i.jsxs)(n.p,{children:["NitroTPM machines (requires the attestation variant ",(0,i.jsx)(n.code,{children:"awsNitroTPM"}),") are available in all regions.\nConstellation OS images are currently replicated to the following regions:"]}),(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"eu-central-1"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"eu-west-1"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"eu-west-3"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"us-east-2"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"ap-south-1"})}),"\n"]}),(0,i.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+AWS+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),(0,i.jsxs)(n.p,{children:["You can find a list of all ",(0,i.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions",children:"regions in AWS's documentation"}),"."]})]}),(0,i.jsxs)(s,{value:"azure",label:"Azure",children:[(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation iam create azure --subscriptionID 00000000-0000-0000-0000-000000000000 --region=westus --resourceGroup=constellTest --servicePrincipal=spTest --update-config\n"})}),(0,i.jsxs)(n.p,{children:["This command creates IAM configuration on the Azure region ",(0,i.jsx)(n.code,{children:"westus"})," creating a new resource group ",(0,i.jsx)(n.code,{children:"constellTest"})," and a new service principal ",(0,i.jsx)(n.code,{children:"spTest"}),". It also updates the configuration file ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"})," in your current directory with the IAM values filled in."]}),(0,i.jsx)(n.p,{children:"CVMs are available in several Azure regions. Constellation OS images are currently replicated to the following:"}),(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"germanywestcentral"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"westus"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"eastus"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"northeurope"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"westeurope"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"southeastasia"})}),"\n"]}),(0,i.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+Azure+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),(0,i.jsxs)(n.p,{children:["You can find a list of all ",(0,i.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/global-infrastructure/services/?products=virtual-machines®ions=all",children:"regions in Azure's documentation"}),"."]})]}),(0,i.jsxs)(s,{value:"gcp",label:"GCP",children:[(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation iam create gcp --projectID=yourproject-12345 --zone=europe-west3-a --prefix=constell-test --update-config\n"})}),(0,i.jsxs)(n.p,{children:["This command creates IAM configuration in the GCP project ",(0,i.jsx)(n.code,{children:"yourproject-12345"})," on the GCP zone ",(0,i.jsx)(n.code,{children:"europe-west3-a"})," creating a new service account ",(0,i.jsx)(n.code,{children:"constell-test"}),". It also updates the configuration file ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"})," in your current directory with the IAM values filled in."]}),(0,i.jsxs)(n.p,{children:["Note that only regions offering CVMs of the ",(0,i.jsx)(n.code,{children:"C2D"})," or ",(0,i.jsx)(n.code,{children:"N2D"})," series are supported. You can find a ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones#available",children:"list of all regions in Google's documentation"}),", which you can filter by machine type ",(0,i.jsx)(n.code,{children:"C2D"})," or ",(0,i.jsx)(n.code,{children:"N2D"}),"."]})]}),(0,i.jsxs)(s,{value:"stackit",label:"STACKIT",children:[(0,i.jsxs)(n.p,{children:["To use Constellation on STACKIT, the cluster will use the User Access Token (UAT) that's generated ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/install",children:"during the install step"}),".\nAfter creating the accounts, fill in the STACKIT details in ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"})," under ",(0,i.jsx)(n.code,{children:"provider.openstack"}),":"]}),(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"stackitProjectID"}),": STACKIT project id (can be found after login on the ",(0,i.jsx)(n.a,{href:"https://portal.stackit.cloud",children:"STACKIT portal"}),")"]}),"\n"]}),(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"stackitProjectID"})," refers to the ID of your STACKIT project. The STACKIT portal also shows the OpenStack ID that's associated with your project in some places. Make sure you insert the STACKIT project ID in the ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"})," file. It's of the format ",(0,i.jsx)(n.code,{children:"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"}),"."]})})]})]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["To learn about all options you have for managing IAM resources and Constellation configuration, see the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/config",children:"Configuration workflow"}),"."]})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"3",children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Create the cluster. ",(0,i.jsx)(n.code,{children:"constellation apply"})," uses options set in ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"}),".\nIf you want to manually manage your cloud resources, for example by using ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/reference/terraform",children:"Terraform"}),", follow the corresponding instructions in the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/create",children:"Create workflow"}),"."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsx)(n.p,{children:"On Azure, you may need to wait 15+ minutes at this point for role assignments to propagate."})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation apply -y\n"})}),"\n",(0,i.jsx)(n.p,{children:"This should look similar to the following:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell-session",children:'$ constellation apply -y\nChecking for infrastructure changes\nThe following Constellation cluster will be created:\n 3 control-plane nodes of type n2d-standard-4 will be created.\n 1 worker node of type n2d-standard-4 will be created.\nCreating\nCloud infrastructure created successfully\nYour Constellation master secret was successfully written to ./constellation-mastersecret.json\nConnecting\nInitializing cluster\nInstalling Kubernetes components\nYour Constellation cluster was successfully initialized.\n\nConstellation cluster identifier g6iMP5wRU1b7mpOz2WEISlIYSfdAhB0oNaOg6XEwKFY=\nKubernetes configuration constellation-admin.conf\n\nYou can now connect to your cluster by executing:\n export KUBECONFIG="$PWD/constellation-admin.conf"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The cluster's identifier will be different in your output.\nKeep ",(0,i.jsx)(n.code,{children:"constellation-mastersecret.json"})," somewhere safe.\nThis will allow you to ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/recovery",children:"recover your cluster"})," in case of a disaster."]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["Depending on your CSP and region, ",(0,i.jsx)(n.code,{children:"constellation apply"})," may take 10+ minutes to complete."]})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Configure kubectl."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'export KUBECONFIG="$PWD/constellation-admin.conf"\n'})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"deploy-a-sample-application",children:"Deploy a sample application"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Deploy the ",(0,i.jsx)(n.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"emojivoto app"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Expose the frontend service locally"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments\nkubectl -n emojivoto port-forward svc/web-svc 8080:80 &\ncurl http://localhost:8080\nkill %1\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"terminate-your-cluster",children:"Terminate your cluster"}),"\n",(0,i.jsxs)(n.p,{children:["Use the CLI to terminate your cluster. If you manually used ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/reference/terraform",children:"Terraform"})," to manage your cloud resources, follow the corresponding instructions in the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/terminate",children:"Terminate workflow"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation terminate\n"})}),"\n",(0,i.jsx)(n.p,{children:"This should give the following output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell-session",children:"$ constellation terminate\nYou are about to terminate a Constellation cluster.\nAll of its associated resources will be DESTROYED.\nThis action is irreversible and ALL DATA WILL BE LOST.\nDo you want to continue? [y/n]:\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Confirm with ",(0,i.jsx)(n.code,{children:"y"})," to terminate the cluster:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell-session",children:"Terminating ...\nYour Constellation cluster was terminated successfully.\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Optionally, you can also ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/config#deleting-an-iam-configuration",children:"delete your IAM resources"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}function u(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>r});var t=s(96540);const i={},l=t.createContext(i);function o(e){const n=t.useContext(l);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3324b179.8b5fa325.js b/pr-preview/pr-4027/assets/js/3324b179.8b5fa325.js deleted file mode 100644 index 4606fa595..000000000 --- a/pr-preview/pr-4027/assets/js/3324b179.8b5fa325.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9528],{28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var r=n(96540);const i={},o=r.createContext(i);function s(e){const t=r.useContext(o);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),r.createElement(o.Provider,{value:t},e.children)}},54567:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>d});const r=JSON.parse('{"id":"architecture/networking","title":"Network encryption","description":"Constellation encrypts all pod communication using the container network interface (CNI).","source":"@site/versioned_docs/version-2.24/architecture/networking.md","sourceDirName":"architecture","slug":"/architecture/networking","permalink":"/constellation/pr-preview/pr-4027/architecture/networking","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/architecture/networking.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Encrypted persistent storage","permalink":"/constellation/pr-preview/pr-4027/architecture/encrypted-storage"},"next":{"title":"Observability","permalink":"/constellation/pr-preview/pr-4027/architecture/observability"}}');var i=n(74848),o=n(28453);const s={},c="Network encryption",a={},d=[];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"network-encryption",children:"Network encryption"})}),"\n",(0,i.jsxs)(t.p,{children:["Constellation encrypts all pod communication using the ",(0,i.jsx)(t.a,{href:"https://github.com/containernetworking/cni",children:"container network interface (CNI)"}),".\nTo that end, Constellation deploys, configures, and operates the ",(0,i.jsx)(t.a,{href:"https://cilium.io/",children:"Cilium"})," CNI plugin.\nCilium provides ",(0,i.jsx)(t.a,{href:"https://docs.cilium.io/en/stable/security/network/encryption",children:"transparent encryption"})," for all cluster traffic using either IPSec or ",(0,i.jsx)(t.a,{href:"https://www.wireguard.com/",children:"WireGuard"}),".\nCurrently, Constellation only supports WireGuard as the encryption engine.\nYou can read more about the cryptographic soundness of WireGuard ",(0,i.jsx)(t.a,{href:"https://www.wireguard.com/papers/wireguard.pdf",children:"in their white paper"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["Cilium is actively working on implementing a feature called ",(0,i.jsx)(t.a,{href:"https://github.com/cilium/cilium/pull/19401",children:(0,i.jsx)(t.code,{children:"host-to-host"})})," encryption mode for WireGuard.\nWith ",(0,i.jsx)(t.code,{children:"host-to-host"}),", all traffic between nodes will be tunneled via WireGuard (host-to-host, host-to-pod, pod-to-host, pod-to-pod).\nUntil the ",(0,i.jsx)(t.code,{children:"host-to-host"})," feature is released, Constellation enables ",(0,i.jsx)(t.code,{children:"pod-to-pod"})," encryption.\nThis mode encrypts all traffic between Kubernetes pods using WireGuard tunnels."]}),"\n",(0,i.jsxs)(t.p,{children:["When using Cilium in the default setup but with encryption enabled, there is a ",(0,i.jsx)(t.a,{href:"https://docs.cilium.io/en/v1.12/gettingstarted/encryption/#egress-traffic-to-not-yet-discovered-remote-endpoints-may-be-unencrypted",children:"known issue"}),"\nthat can cause pod-to-pod traffic to be unencrypted.\nTo mitigate this issue, Constellation adds a ",(0,i.jsx)(t.em,{children:"strict"})," mode to Cilium's ",(0,i.jsx)(t.code,{children:"pod-to-pod"})," encryption.\nThis mode changes the default behavior of traffic that's destined for an unknown endpoint to not be send out in plaintext, but instead being dropped.\nThe strict mode distinguishes between traffic that's send to a pod from traffic that's destined for a cluster-external endpoint by considering the pod's CIDR range."]}),"\n",(0,i.jsxs)(t.p,{children:["Traffic originating from hosts isn't encrypted yet.\nThis mainly includes health checks from Kubernetes API server.\nAlso, traffic proxied over the API server via e.g. ",(0,i.jsx)(t.code,{children:"kubectl port-forward"})," isn't encrypted."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3488.ebdc9158.js b/pr-preview/pr-4027/assets/js/3488.ebdc9158.js deleted file mode 100644 index cc5dfcfc2..000000000 --- a/pr-preview/pr-4027/assets/js/3488.ebdc9158.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3488],{93488:(e,a,t)=>{t.d(a,{diagram:()=>g});var n=t(42467),r=t(73590),s=t(67633),o=t(40797),i=t(78731),d={parse:(0,o.K2)(async e=>{const a=await(0,i.qg)("info",e);o.Rm.debug(a)},"parse")},c={version:n.n.version+""},g={parser:d,db:{getVersion:(0,o.K2)(()=>c.version,"getVersion")},renderer:{draw:(0,o.K2)((e,a,t)=>{o.Rm.debug("rendering info diagram\n"+e);const n=(0,r.D)(a);(0,s.a$)(n,100,400,!0);n.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size",32).style("text-anchor","middle").text(`v${t}`)},"draw")}}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3490.91814865.js b/pr-preview/pr-4027/assets/js/3490.91814865.js deleted file mode 100644 index 6e1dd12f3..000000000 --- a/pr-preview/pr-4027/assets/js/3490.91814865.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3490],{3490:(s,c,e)=>{e.d(c,{createInfoServices:()=>o.v});var o=e(91885);e(87960)}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/358e1fce.78bd25aa.js b/pr-preview/pr-4027/assets/js/358e1fce.78bd25aa.js deleted file mode 100644 index ac8f169b9..000000000 --- a/pr-preview/pr-4027/assets/js/358e1fce.78bd25aa.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9427],{3946:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>u,frontMatter:()=>t,metadata:()=>o,toc:()=>a});const o=JSON.parse('{"id":"workflows/scale","title":"Scale your cluster","description":"Constellation provides all features of a Kubernetes cluster including scaling and autoscaling.","source":"@site/docs/workflows/scale.md","sourceDirName":"workflows","slug":"/workflows/scale","permalink":"/constellation/pr-preview/pr-4027/next/workflows/scale","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/workflows/scale.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Create your cluster","permalink":"/constellation/pr-preview/pr-4027/next/workflows/create"},"next":{"title":"Upgrade your cluster","permalink":"/constellation/pr-preview/pr-4027/next/workflows/upgrade"}}');var l=s(74848),r=s(28453);const t={},c="Scale your cluster",i={},a=[{value:"Worker node scaling",id:"worker-node-scaling",level:2},{value:"Autoscaling",id:"autoscaling",level:3},{value:"Manual scaling",id:"manual-scaling",level:3},{value:"Control-plane node scaling",id:"control-plane-node-scaling",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,r.R)(),...e.components},{TabItem:s,Tabs:o}=n;return s||h("TabItem",!0),o||h("Tabs",!0),(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"scale-your-cluster",children:"Scale your cluster"})}),"\n",(0,l.jsx)(n.p,{children:"Constellation provides all features of a Kubernetes cluster including scaling and autoscaling."}),"\n",(0,l.jsx)(n.h2,{id:"worker-node-scaling",children:"Worker node scaling"}),"\n",(0,l.jsx)(n.h3,{id:"autoscaling",children:"Autoscaling"}),"\n",(0,l.jsx)(n.p,{children:"Constellation comes with autoscaling disabled by default. To enable autoscaling, find the scaling group of\nworker nodes:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:'kubectl get scalinggroups -o json | yq \'.items | .[] | select(.spec.role == "Worker") | [{"name": .metadata.name, "nodeGoupName": .spec.nodeGroupName}]\'\n'})}),"\n",(0,l.jsxs)(n.p,{children:["This will output a list of scaling groups with the corresponding cloud provider name (",(0,l.jsx)(n.code,{children:"name"}),") and the cloud provider agnostic name of the node group (",(0,l.jsx)(n.code,{children:"nodeGroupName"}),")."]}),"\n",(0,l.jsxs)(n.p,{children:["Then, patch the ",(0,l.jsx)(n.code,{children:"autoscaling"})," field of the scaling group resource with the desired ",(0,l.jsx)(n.code,{children:"name"})," to ",(0,l.jsx)(n.code,{children:"true"}),":"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# Replace <name> with the name of the scaling group you want to enable autoscaling for\nworker_group=<name>\nkubectl patch scalinggroups $worker_group --patch '{\"spec\":{\"autoscaling\": true}}' --type='merge'\nkubectl get scalinggroup $worker_group -o jsonpath='{.spec}' | yq -P\n"})}),"\n",(0,l.jsxs)(n.p,{children:["The cluster autoscaler now automatically provisions additional worker nodes so that all pods have a place to run.\nYou can configure the minimum and maximum number of worker nodes in the scaling group by patching the ",(0,l.jsx)(n.code,{children:"min"})," or\n",(0,l.jsx)(n.code,{children:"max"})," fields of the scaling group resource:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl patch scalinggroups $worker_group --patch '{\"spec\":{\"max\": 5}}' --type='merge'\nkubectl get scalinggroup $worker_group -o jsonpath='{.spec}' | yq -P\n"})}),"\n",(0,l.jsx)(n.p,{children:"The cluster autoscaler will now never provision more than 5 worker nodes."}),"\n",(0,l.jsx)(n.p,{children:"If you want to see the autoscaling in action, try to add a deployment with a lot of replicas, like the\nfollowing Nginx deployment. The number of replicas needed to trigger the autoscaling depends on the size of\nand count of your worker nodes. Wait for the rollout of the deployment to finish and compare the number of\nworker nodes before and after the deployment:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl create deployment nginx --image=nginx --replicas 150\nkubectl -n kube-system get nodes\nkubectl rollout status deployment nginx\nkubectl -n kube-system get nodes\n"})}),"\n",(0,l.jsx)(n.h3,{id:"manual-scaling",children:"Manual scaling"}),"\n",(0,l.jsx)(n.p,{children:"Alternatively, you can manually scale your cluster up or down:"}),"\n",(0,l.jsxs)(o,{groupId:"csp",children:[(0,l.jsx)(s,{value:"aws",label:"AWS",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Go to Auto Scaling Groups and select the worker ASG to scale up."}),"\n",(0,l.jsxs)(n.li,{children:["Click ",(0,l.jsx)(n.strong,{children:"Edit"})]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new (increased) ",(0,l.jsx)(n.strong,{children:"Desired capacity"})," and ",(0,l.jsx)(n.strong,{children:"Update"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"azure",label:"Azure",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Find your Constellation resource group."}),"\n",(0,l.jsxs)(n.li,{children:["Select the ",(0,l.jsx)(n.code,{children:"scale-set-workers"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:["Go to ",(0,l.jsx)(n.strong,{children:"settings"})," and ",(0,l.jsx)(n.strong,{children:"scaling"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new ",(0,l.jsx)(n.strong,{children:"instance count"})," and ",(0,l.jsx)(n.strong,{children:"save"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"gcp",label:"GCP",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["In Compute Engine go to ",(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/compute/instanceGroups/",children:"Instance Groups"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Edit"})," the ",(0,l.jsx)(n.strong,{children:"worker"})," instance group."]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new ",(0,l.jsx)(n.strong,{children:"number of instances"})," and ",(0,l.jsx)(n.strong,{children:"save"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,l.jsx)(n.p,{children:"Dynamic cluster scaling isn't yet supported for STACKIT.\nSupport will be introduced in one of the upcoming releases."})})]}),"\n",(0,l.jsx)(n.h2,{id:"control-plane-node-scaling",children:"Control-plane node scaling"}),"\n",(0,l.jsxs)(n.p,{children:["Control-plane nodes can ",(0,l.jsx)(n.strong,{children:"only be scaled manually and only scaled up"}),"!"]}),"\n",(0,l.jsx)(n.p,{children:"To increase the number of control-plane nodes, follow these steps:"}),"\n",(0,l.jsxs)(o,{groupId:"csp",children:[(0,l.jsx)(s,{value:"aws",label:"AWS",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Go to Auto Scaling Groups and select the control-plane ASG to scale up."}),"\n",(0,l.jsxs)(n.li,{children:["Click ",(0,l.jsx)(n.strong,{children:"Edit"})]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new (increased) ",(0,l.jsx)(n.strong,{children:"Desired capacity"})," and ",(0,l.jsx)(n.strong,{children:"Update"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"azure",label:"Azure",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Find your Constellation resource group."}),"\n",(0,l.jsxs)(n.li,{children:["Select the ",(0,l.jsx)(n.code,{children:"scale-set-controlplanes"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:["Go to ",(0,l.jsx)(n.strong,{children:"settings"})," and ",(0,l.jsx)(n.strong,{children:"scaling"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new (increased) ",(0,l.jsx)(n.strong,{children:"instance count"})," and ",(0,l.jsx)(n.strong,{children:"save"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"gcp",label:"GCP",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["In Compute Engine go to ",(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/compute/instanceGroups/",children:"Instance Groups"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Edit"})," the ",(0,l.jsx)(n.strong,{children:"control-plane"})," instance group."]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new (increased) ",(0,l.jsx)(n.strong,{children:"number of instances"})," and ",(0,l.jsx)(n.strong,{children:"save"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,l.jsx)(n.p,{children:"Dynamic cluster scaling isn't yet supported for STACKIT.\nSupport will be introduced in one of the upcoming releases."})})]}),"\n",(0,l.jsxs)(n.p,{children:["If you scale down the number of control-planes nodes, the removed nodes won't be able to exit the ",(0,l.jsx)(n.code,{children:"etcd"})," cluster correctly. This will endanger the quorum that's required to run a stable Kubernetes control plane."]})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}function h(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>c});var o=s(96540);const l={},r=o.createContext(l);function t(e){const n=o.useContext(r);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:t(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3607c499.bb98fd49.js b/pr-preview/pr-4027/assets/js/3607c499.bb98fd49.js deleted file mode 100644 index 5b21e2f8b..000000000 --- a/pr-preview/pr-4027/assets/js/3607c499.bb98fd49.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3772],{28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var s=n(96540);const r={},i=s.createContext(r);function a(e){const t=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:t},e.children)}},74085:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"overview/security-benefits","title":"Security benefits and threat model","description":"Constellation implements the Confidential Kubernetes concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be verified.","source":"@site/versioned_docs/version-2.23/overview/security-benefits.md","sourceDirName":"overview","slug":"/overview/security-benefits","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/security-benefits","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/overview/security-benefits.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential Kubernetes","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/confidential-kubernetes"},"next":{"title":"Product features","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/product"}}');var r=n(74848),i=n(28453);const a={},o="Security benefits and threat model",c={},l=[{value:"Insider access",id:"insider-access",level:2},{value:"Infrastructure-based attacks",id:"infrastructure-based-attacks",level:2},{value:"Supply chain attacks",id:"supply-chain-attacks",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",p:"p",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"security-benefits-and-threat-model",children:"Security benefits and threat model"})}),"\n",(0,r.jsxs)(t.p,{children:["Constellation implements the ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/overview/confidential-kubernetes",children:"Confidential Kubernetes"})," concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the ",(0,r.jsx)(t.em,{children:"cloud & datacenter infrastructure"})," and the ",(0,r.jsx)(t.em,{children:"physical hosts"}),", including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cluster",children:"verified"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"TCB comparison",src:n(96349).A+"",width:"3988",height:"1380"})}),"\n",(0,r.jsx)(t.p,{children:"Given this background, the following describes the concrete threat classes that Constellation addresses."}),"\n",(0,r.jsx)(t.h2,{id:"insider-access",children:"Insider access"}),"\n",(0,r.jsx)(t.p,{children:"Employees and third-party contractors of cloud service providers (CSPs) have access to different layers of the cloud infrastructure.\nThis opens up a large attack surface where workloads and data can be read, copied, or manipulated. With Constellation, Kubernetes deployments are shielded from the infrastructure and thus such accesses are prevented."}),"\n",(0,r.jsx)(t.h2,{id:"infrastructure-based-attacks",children:"Infrastructure-based attacks"}),"\n",(0,r.jsxs)(t.p,{children:['Malicious cloud users ("hackers") may break out of their tenancy and access other tenants\' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. Analogously to the ',(0,r.jsx)(t.em,{children:"insider access"})," scenario, Constellation also prevents access to a deployment's data in this scenario."]}),"\n",(0,r.jsx)(t.h2,{id:"supply-chain-attacks",children:"Supply chain attacks"}),"\n",(0,r.jsxs)(t.p,{children:["Supply chain security is receiving lots of attention recently due to an ",(0,r.jsx)(t.a,{href:"https://www.enisa.europa.eu/news/enisa-news/understanding-the-increase-in-supply-chain-security-attacks",children:"increasing number of recorded attacks"}),". For instance, a malicious actor could attempt to tamper Constellation node images (including Kubernetes and other software) before they're loaded in the confidential VMs of a cluster. Constellation uses ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation",children:"remote attestation"})," in conjunction with public ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cli",children:"transparency logs"})," to prevent this."]}),"\n",(0,r.jsx)(t.p,{children:"In the future, Constellation will extend this feature to customer workloads. This will enable cluster owners to create auditable policies that precisely define which containers can run in a given deployment."})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},96349:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/tcb-424516bbf9d20afe12576bc1305ebc29.svg"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3624.7bf76120.js b/pr-preview/pr-4027/assets/js/3624.7bf76120.js deleted file mode 100644 index 60e8ea351..000000000 --- a/pr-preview/pr-4027/assets/js/3624.7bf76120.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3624],{2634:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(t,n){for(var r=-1,e=null==t?0:t.length,o=0,c=[];++r<e;){var u=t[r];n(u,r,t)&&(c[o++]=u)}return c}},6240:(t,n,r)=>{r.d(n,{A:()=>c});var e=r(79841),o=r(38446);const c=function(t,n){return function(r,e){if(null==r)return r;if(!(0,o.A)(r))return t(r,e);for(var c=r.length,u=n?c:-1,a=Object(r);(n?u--:++u<c)&&!1!==e(a[u],u,a););return r}}(e.A)},7819:(t,n,r)=>{r.d(n,{A:()=>A});var e=r(92049),o=r(86586),c=r(46632);var u=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,a=/\\(\\)?/g;const i=function(t){var n=(0,c.A)(t,function(t){return 500===r.size&&r.clear(),t}),r=n.cache;return n}(function(t){var n=[];return 46===t.charCodeAt(0)&&n.push(""),t.replace(u,function(t,r,e,o){n.push(e?o.replace(a,"$1"):r||t)}),n});var f=r(28894);const A=function(t,n){return(0,e.A)(t)?t:(0,o.A)(t,n)?[t]:i((0,f.A)(t))}},8058:(t,n,r)=>{r.d(n,{A:()=>a});var e=r(72641),o=r(6240),c=r(99922),u=r(92049);const a=function(t,n){return((0,u.A)(t)?e.A:o.A)(t,(0,c.A)(n))}},13153:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(){return[]}},13588:(t,n,r)=>{r.d(n,{A:()=>f});var e=r(76912),o=r(241),c=r(52274),u=r(92049),a=o.A?o.A.isConcatSpreadable:void 0;const i=function(t){return(0,u.A)(t)||(0,c.A)(t)||!!(a&&t&&t[a])};const f=function t(n,r,o,c,u){var a=-1,f=n.length;for(o||(o=i),u||(u=[]);++a<f;){var A=n[a];r>0&&o(A)?r>1?t(A,r-1,o,c,u):(0,e.A)(u,A):c||(u[u.length]=A)}return u}},14792:(t,n,r)=>{r.d(n,{A:()=>a});var e=r(2634),o=r(13153),c=Object.prototype.propertyIsEnumerable,u=Object.getOwnPropertySymbols;const a=u?function(t){return null==t?[]:(t=Object(t),(0,e.A)(u(t),function(n){return c.call(t,n)}))}:o.A},19042:(t,n,r)=>{r.d(n,{A:()=>u});var e=r(33831),o=r(14792),c=r(27422);const u=function(t){return(0,e.A)(t,c.A,o.A)}},23958:(t,n,r)=>{r.d(n,{A:()=>H});var e=r(11754),o=r(62062),c=r(63736),u=r(64099);const a=function(t,n,r,e,a,i){var f=1&r,A=t.length,s=n.length;if(A!=s&&!(f&&s>A))return!1;var v=i.get(t),l=i.get(n);if(v&&l)return v==n&&l==t;var b=-1,d=!0,j=2&r?new o.A:void 0;for(i.set(t,n),i.set(n,t);++b<A;){var h=t[b],p=n[b];if(e)var y=f?e(p,h,b,n,t,i):e(h,p,b,t,n,i);if(void 0!==y){if(y)continue;d=!1;break}if(j){if(!(0,c.A)(n,function(t,n){if(!(0,u.A)(j,n)&&(h===t||a(h,t,r,e,i)))return j.push(n)})){d=!1;break}}else if(h!==p&&!a(h,p,r,e,i)){d=!1;break}}return i.delete(t),i.delete(n),d};var i=r(241),f=r(43988),A=r(66984);const s=function(t){var n=-1,r=Array(t.size);return t.forEach(function(t,e){r[++n]=[e,t]}),r};var v=r(29959),l=i.A?i.A.prototype:void 0,b=l?l.valueOf:void 0;const d=function(t,n,r,e,o,c,u){switch(r){case"[object DataView]":if(t.byteLength!=n.byteLength||t.byteOffset!=n.byteOffset)return!1;t=t.buffer,n=n.buffer;case"[object ArrayBuffer]":return!(t.byteLength!=n.byteLength||!c(new f.A(t),new f.A(n)));case"[object Boolean]":case"[object Date]":case"[object Number]":return(0,A.A)(+t,+n);case"[object Error]":return t.name==n.name&&t.message==n.message;case"[object RegExp]":case"[object String]":return t==n+"";case"[object Map]":var i=s;case"[object Set]":var l=1&e;if(i||(i=v.A),t.size!=n.size&&!l)return!1;var d=u.get(t);if(d)return d==n;e|=2,u.set(t,n);var j=a(i(t),i(n),e,o,c,u);return u.delete(t),j;case"[object Symbol]":if(b)return b.call(t)==b.call(n)}return!1};var j=r(19042),h=Object.prototype.hasOwnProperty;const p=function(t,n,r,e,o,c){var u=1&r,a=(0,j.A)(t),i=a.length;if(i!=(0,j.A)(n).length&&!u)return!1;for(var f=i;f--;){var A=a[f];if(!(u?A in n:h.call(n,A)))return!1}var s=c.get(t),v=c.get(n);if(s&&v)return s==n&&v==t;var l=!0;c.set(t,n),c.set(n,t);for(var b=u;++f<i;){var d=t[A=a[f]],p=n[A];if(e)var y=u?e(p,d,A,n,t,c):e(d,p,A,t,n,c);if(!(void 0===y?d===p||o(d,p,r,e,c):y)){l=!1;break}b||(b="constructor"==A)}if(l&&!b){var g=t.constructor,w=n.constructor;g==w||!("constructor"in t)||!("constructor"in n)||"function"==typeof g&&g instanceof g&&"function"==typeof w&&w instanceof w||(l=!1)}return c.delete(t),c.delete(n),l};var y=r(9779),g=r(92049),w=r(99912),_=r(33858),O="[object Arguments]",m="[object Array]",S="[object Object]",k=Object.prototype.hasOwnProperty;const E=function(t,n,r,o,c,u){var i=(0,g.A)(t),f=(0,g.A)(n),A=i?m:(0,y.A)(t),s=f?m:(0,y.A)(n),v=(A=A==O?S:A)==S,l=(s=s==O?S:s)==S,b=A==s;if(b&&(0,w.A)(t)){if(!(0,w.A)(n))return!1;i=!0,v=!1}if(b&&!v)return u||(u=new e.A),i||(0,_.A)(t)?a(t,n,r,o,c,u):d(t,n,A,r,o,c,u);if(!(1&r)){var j=v&&k.call(t,"__wrapped__"),h=l&&k.call(n,"__wrapped__");if(j||h){var E=j?t.value():t,x=h?n.value():n;return u||(u=new e.A),c(E,x,r,o,u)}}return!!b&&(u||(u=new e.A),p(t,n,r,o,c,u))};var x=r(53098);const I=function t(n,r,e,o,c){return n===r||(null==n||null==r||!(0,x.A)(n)&&!(0,x.A)(r)?n!=n&&r!=r:E(n,r,e,o,t,c))};const U=function(t,n,r,o){var c=r.length,u=c,a=!o;if(null==t)return!u;for(t=Object(t);c--;){var i=r[c];if(a&&i[2]?i[1]!==t[i[0]]:!(i[0]in t))return!1}for(;++c<u;){var f=(i=r[c])[0],A=t[f],s=i[1];if(a&&i[2]){if(void 0===A&&!(f in t))return!1}else{var v=new e.A;if(o)var l=o(A,s,f,t,n,v);if(!(void 0===l?I(s,A,3,o,v):l))return!1}}return!0};var B=r(23149);const C=function(t){return t==t&&!(0,B.A)(t)};var D=r(27422);const F=function(t){for(var n=(0,D.A)(t),r=n.length;r--;){var e=n[r],o=t[e];n[r]=[e,o,C(o)]}return n};const M=function(t,n){return function(r){return null!=r&&(r[t]===n&&(void 0!==n||t in Object(r)))}};const z=function(t){var n=F(t);return 1==n.length&&n[0][2]?M(n[0][0],n[0][1]):function(r){return r===t||U(r,t,n)}};var L=r(66318);const P=function(t,n,r){var e=null==t?void 0:(0,L.A)(t,n);return void 0===e?r:e};var $=r(39188),N=r(86586),R=r(30901);const V=function(t,n){return(0,N.A)(t)&&C(n)?M((0,R.A)(t),n):function(r){var e=P(r,t);return void 0===e&&e===n?(0,$.A)(r,t):I(n,e,3)}};var T=r(29008),G=r(70805);const W=function(t){return function(n){return(0,L.A)(n,t)}};const q=function(t){return(0,N.A)(t)?(0,G.A)((0,R.A)(t)):W(t)};const H=function(t){return"function"==typeof t?t:null==t?T.A:"object"==typeof t?(0,g.A)(t)?V(t[0],t[1]):z(t):q(t)}},25707:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(t,n,r,e){for(var o=t.length,c=r+(e?1:-1);e?c--:++c<o;)if(n(t[c],c,t))return c;return-1}},27422:(t,n,r)=>{r.d(n,{A:()=>u});var e=r(83607),o=r(69471),c=r(38446);const u=function(t){return(0,c.A)(t)?(0,e.A)(t):(0,o.A)(t)}},28894:(t,n,r)=>{r.d(n,{A:()=>A});var e=r(241),o=r(45572),c=r(92049),u=r(61882),a=e.A?e.A.prototype:void 0,i=a?a.toString:void 0;const f=function t(n){if("string"==typeof n)return n;if((0,c.A)(n))return(0,o.A)(n,t)+"";if((0,u.A)(n))return i?i.call(n):"";var r=n+"";return"0"==r&&1/n==-1/0?"-0":r};const A=function(t){return null==t?"":f(t)}},29959:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(t){var n=-1,r=Array(t.size);return t.forEach(function(t){r[++n]=t}),r}},30901:(t,n,r)=>{r.d(n,{A:()=>o});var e=r(61882);const o=function(t){if("string"==typeof t||(0,e.A)(t))return t;var n=t+"";return"0"==n&&1/t==-1/0?"-0":n}},33831:(t,n,r)=>{r.d(n,{A:()=>c});var e=r(76912),o=r(92049);const c=function(t,n,r){var c=n(t);return(0,o.A)(t)?c:(0,e.A)(c,r(t))}},38207:(t,n,r)=>{r.d(n,{A:()=>u});var e=r(45572);const o=function(t,n){return(0,e.A)(n,function(n){return t[n]})};var c=r(27422);const u=function(t){return null==t?[]:o(t,(0,c.A)(t))}},39188:(t,n,r)=>{r.d(n,{A:()=>c});const e=function(t,n){return null!=t&&n in Object(t)};var o=r(85054);const c=function(t,n){return null!=t&&(0,o.A)(t,n,e)}},42302:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(){}},45572:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(t,n){for(var r=-1,e=null==t?0:t.length,o=Array(e);++r<e;)o[r]=n(t[r],r,t);return o}},51790:(t,n,r)=>{r.d(n,{A:()=>o});var e=r(6240);const o=function(t,n){var r=[];return(0,e.A)(t,function(t,e,o){n(t,e,o)&&r.push(t)}),r}},60818:(t,n,r)=>{r.d(n,{A:()=>u});var e=r(25707);const o=function(t){return t!=t};const c=function(t,n,r){for(var e=r-1,o=t.length;++e<o;)if(t[e]===n)return e;return-1};const u=function(t,n,r){return n==n?c(t,n,r):(0,e.A)(t,o,r)}},61882:(t,n,r)=>{r.d(n,{A:()=>c});var e=r(88496),o=r(53098);const c=function(t){return"symbol"==typeof t||(0,o.A)(t)&&"[object Symbol]"==(0,e.A)(t)}},62062:(t,n,r)=>{r.d(n,{A:()=>a});var e=r(29471);const o=function(t){return this.__data__.set(t,"__lodash_hash_undefined__"),this};const c=function(t){return this.__data__.has(t)};function u(t){var n=-1,r=null==t?0:t.length;for(this.__data__=new e.A;++n<r;)this.add(t[n])}u.prototype.add=u.prototype.push=o,u.prototype.has=c;const a=u},63736:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(t,n){for(var r=-1,e=null==t?0:t.length;++r<e;)if(n(t[r],r,t))return!0;return!1}},64099:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(t,n){return t.has(n)}},66318:(t,n,r)=>{r.d(n,{A:()=>c});var e=r(7819),o=r(30901);const c=function(t,n){for(var r=0,c=(n=(0,e.A)(n,t)).length;null!=t&&r<c;)t=t[(0,o.A)(n[r++])];return r&&r==c?t:void 0}},68675:(t,n,r)=>{r.d(n,{A:()=>K});var e=r(11754),o=r(72641),c=r(52851),u=r(22031),a=r(27422);const i=function(t,n){return t&&(0,u.A)(n,(0,a.A)(n),t)};var f=r(55615);const A=function(t,n){return t&&(0,u.A)(n,(0,f.A)(n),t)};var s=r(80154),v=r(39759),l=r(14792);const b=function(t,n){return(0,u.A)(t,(0,l.A)(t),n)};var d=r(83511);const j=function(t,n){return(0,u.A)(t,(0,d.A)(t),n)};var h=r(19042),p=r(83973),y=r(9779),g=Object.prototype.hasOwnProperty;const w=function(t){var n=t.length,r=new t.constructor(n);return n&&"string"==typeof t[0]&&g.call(t,"index")&&(r.index=t.index,r.input=t.input),r};var _=r(90565);const O=function(t,n){var r=n?(0,_.A)(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.byteLength)};var m=/\w*$/;const S=function(t){var n=new t.constructor(t.source,m.exec(t));return n.lastIndex=t.lastIndex,n};var k=r(241),E=k.A?k.A.prototype:void 0,x=E?E.valueOf:void 0;const I=function(t){return x?Object(x.call(t)):{}};var U=r(1801);const B=function(t,n,r){var e=t.constructor;switch(n){case"[object ArrayBuffer]":return(0,_.A)(t);case"[object Boolean]":case"[object Date]":return new e(+t);case"[object DataView]":return O(t,r);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return(0,U.A)(t,r);case"[object Map]":case"[object Set]":return new e;case"[object Number]":case"[object String]":return new e(t);case"[object RegExp]":return S(t);case"[object Symbol]":return I(t)}};var C=r(18598),D=r(92049),F=r(99912),M=r(53098);const z=function(t){return(0,M.A)(t)&&"[object Map]"==(0,y.A)(t)};var L=r(52789),P=r(64841),$=P.A&&P.A.isMap;const N=$?(0,L.A)($):z;var R=r(23149);const V=function(t){return(0,M.A)(t)&&"[object Set]"==(0,y.A)(t)};var T=P.A&&P.A.isSet;const G=T?(0,L.A)(T):V;var W="[object Arguments]",q="[object Function]",H="[object Object]",J={};J[W]=J["[object Array]"]=J["[object ArrayBuffer]"]=J["[object DataView]"]=J["[object Boolean]"]=J["[object Date]"]=J["[object Float32Array]"]=J["[object Float64Array]"]=J["[object Int8Array]"]=J["[object Int16Array]"]=J["[object Int32Array]"]=J["[object Map]"]=J["[object Number]"]=J[H]=J["[object RegExp]"]=J["[object Set]"]=J["[object String]"]=J["[object Symbol]"]=J["[object Uint8Array]"]=J["[object Uint8ClampedArray]"]=J["[object Uint16Array]"]=J["[object Uint32Array]"]=!0,J["[object Error]"]=J[q]=J["[object WeakMap]"]=!1;const K=function t(n,r,u,l,d,g){var _,O=1&r,m=2&r,S=4&r;if(u&&(_=d?u(n,l,d,g):u(n)),void 0!==_)return _;if(!(0,R.A)(n))return n;var k=(0,D.A)(n);if(k){if(_=w(n),!O)return(0,v.A)(n,_)}else{var E=(0,y.A)(n),x=E==q||"[object GeneratorFunction]"==E;if((0,F.A)(n))return(0,s.A)(n,O);if(E==H||E==W||x&&!d){if(_=m||x?{}:(0,C.A)(n),!O)return m?j(n,A(_,n)):b(n,i(_,n))}else{if(!J[E])return d?n:{};_=B(n,E,O)}}g||(g=new e.A);var I=g.get(n);if(I)return I;g.set(n,_),G(n)?n.forEach(function(e){_.add(t(e,r,u,e,n,g))}):N(n)&&n.forEach(function(e,o){_.set(o,t(e,r,u,o,n,g))});var U=S?m?p.A:h.A:m?f.A:a.A,M=k?void 0:U(n);return(0,o.A)(M||n,function(e,o){M&&(e=n[o=e]),(0,c.A)(_,o,t(e,r,u,o,n,g))}),_}},69592:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(t){return void 0===t}},70805:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(t){return function(n){return null==n?void 0:n[t]}}},72641:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(t,n){for(var r=-1,e=null==t?0:t.length;++r<e&&!1!==n(t[r],r,t););return t}},76912:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(t,n){for(var r=-1,e=n.length,o=t.length;++r<e;)t[o+r]=n[r];return t}},79841:(t,n,r)=>{r.d(n,{A:()=>c});var e=r(4574),o=r(27422);const c=function(t,n){return t&&(0,e.A)(t,n,o.A)}},83149:(t,n,r)=>{r.d(n,{A:()=>o});var e=r(60818);const o=function(t,n){return!!(null==t?0:t.length)&&(0,e.A)(t,n,0)>-1}},83511:(t,n,r)=>{r.d(n,{A:()=>a});var e=r(76912),o=r(15647),c=r(14792),u=r(13153);const a=Object.getOwnPropertySymbols?function(t){for(var n=[];t;)(0,e.A)(n,(0,c.A)(t)),t=(0,o.A)(t);return n}:u.A},83973:(t,n,r)=>{r.d(n,{A:()=>u});var e=r(33831),o=r(83511),c=r(55615);const u=function(t){return(0,e.A)(t,c.A,o.A)}},85054:(t,n,r)=>{r.d(n,{A:()=>f});var e=r(7819),o=r(52274),c=r(92049),u=r(25353),a=r(5254),i=r(30901);const f=function(t,n,r){for(var f=-1,A=(n=(0,e.A)(n,t)).length,s=!1;++f<A;){var v=(0,i.A)(n[f]);if(!(s=null!=t&&r(t,v)))break;t=t[v]}return s||++f!=A?s:!!(A=null==t?0:t.length)&&(0,a.A)(A)&&(0,u.A)(v,A)&&((0,c.A)(t)||(0,o.A)(t))}},86586:(t,n,r)=>{r.d(n,{A:()=>a});var e=r(92049),o=r(61882),c=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,u=/^\w*$/;const a=function(t,n){if((0,e.A)(t))return!1;var r=typeof t;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=t&&!(0,o.A)(t))||(u.test(t)||!c.test(t)||null!=n&&t in Object(n))}},87809:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(t,n,r){for(var e=-1,o=null==t?0:t.length;++e<o;)if(r(n,t[e]))return!0;return!1}},89463:(t,n,r)=>{r.d(n,{A:()=>i});const e=function(t,n,r,e){var o=-1,c=null==t?0:t.length;for(e&&c&&(r=t[++o]);++o<c;)r=n(r,t[o],o,t);return r};var o=r(6240),c=r(23958);const u=function(t,n,r,e,o){return o(t,function(t,o,c){r=e?(e=!1,t):n(r,t,o,c)}),r};var a=r(92049);const i=function(t,n,r){var i=(0,a.A)(t)?e:u,f=arguments.length<3;return i(t,(0,c.A)(n,4),r,f,o.A)}},94092:(t,n,r)=>{r.d(n,{A:()=>a});var e=r(2634),o=r(51790),c=r(23958),u=r(92049);const a=function(t,n){return((0,u.A)(t)?e.A:o.A)(t,(0,c.A)(n,3))}},99902:(t,n,r)=>{r.d(n,{A:()=>s});var e=r(62062),o=r(83149),c=r(87809),u=r(64099),a=r(39857),i=r(42302),f=r(29959);const A=a.A&&1/(0,f.A)(new a.A([,-0]))[1]==1/0?function(t){return new a.A(t)}:i.A;const s=function(t,n,r){var a=-1,i=o.A,s=t.length,v=!0,l=[],b=l;if(r)v=!1,i=c.A;else if(s>=200){var d=n?null:A(t);if(d)return(0,f.A)(d);v=!1,i=u.A,b=new e.A}else b=n?[]:l;t:for(;++a<s;){var j=t[a],h=n?n(j):j;if(j=r||0!==j?j:0,v&&h==h){for(var p=b.length;p--;)if(b[p]===h)continue t;n&&b.push(h),l.push(j)}else i(b,h,r)||(b!==l&&b.push(h),l.push(j))}return l}},99922:(t,n,r)=>{r.d(n,{A:()=>o});var e=r(29008);const o=function(t){return"function"==typeof t?t:e.A}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/36f09204.6566cb4d.js b/pr-preview/pr-4027/assets/js/36f09204.6566cb4d.js deleted file mode 100644 index 600505471..000000000 --- a/pr-preview/pr-4027/assets/js/36f09204.6566cb4d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5423],{28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const i={},r=s.createContext(i);function o(e){const t=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:t},e.children)}},86057:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"architecture/attestation","title":"Attestation","description":"This page explains Constellation\'s attestation process and highlights the cornerstones of its trust model.","source":"@site/versioned_docs/version-2.23/architecture/attestation.md","sourceDirName":"architecture","slug":"/architecture/attestation","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/attestation","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/architecture/attestation.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Microservices","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/microservices"},"next":{"title":"Images","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/images"}}');var i=n(74848),r=n(28453);const o={},a="Attestation",d={},l=[{value:"Terms",id:"terms",level:2},{value:"Trusted Platform Module (TPM)",id:"trusted-platform-module-tpm",level:3},{value:"Runtime measurement",id:"runtime-measurement",level:3},{value:"Platform Configuration Register (PCR)",id:"platform-configuration-register-pcr",level:3},{value:"Measured boot",id:"measured-boot",level:3},{value:"Remote attestation (RA)",id:"remote-attestation-ra",level:3},{value:"Confidential virtual machine (CVM)",id:"confidential-virtual-machine-cvm",level:3},{value:"Attested TLS (aTLS)",id:"attested-tls-atls",level:3},{value:"Overview",id:"overview",level:2},{value:"Node attestation",id:"node-attestation",level:2},{value:"Runtime measurements",id:"runtime-measurements",level:3},{value:"CVM verification",id:"cvm-verification",level:3},{value:"Cluster attestation",id:"cluster-attestation",level:2},{value:"Cluster-facing attestation",id:"cluster-facing-attestation",level:3},{value:"User-facing attestation",id:"user-facing-attestation",level:3},{value:"Putting it all together",id:"putting-it-all-together",level:2},{value:"CLI and node images",id:"cli-and-node-images",level:3},{value:"Cluster creation",id:"cluster-creation",level:3},{value:"Chain of trust",id:"chain-of-trust",level:3},{value:"Upgrades",id:"upgrades",level:3},{value:"References",id:"references",level:2}];function c(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",mermaid:"mermaid",ol:"ol",p:"p",pre:"pre",section:"section",strong:"strong",sup:"sup",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components},{TabItem:n,Tabs:s}=t;return n||u("TabItem",!0),s||u("Tabs",!0),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"attestation",children:"Attestation"})}),"\n",(0,i.jsx)(t.p,{children:"This page explains Constellation's attestation process and highlights the cornerstones of its trust model."}),"\n",(0,i.jsx)(t.h2,{id:"terms",children:"Terms"}),"\n",(0,i.jsx)(t.p,{children:"The following lists terms and concepts that help to understand the attestation concept of Constellation."}),"\n",(0,i.jsx)(t.h3,{id:"trusted-platform-module-tpm",children:"Trusted Platform Module (TPM)"}),"\n",(0,i.jsxs)(t.p,{children:["A TPM chip is a dedicated tamper-resistant crypto-processor.\nIt can securely store artifacts such as passwords, certificates, encryption keys, or ",(0,i.jsx)(t.em,{children:"runtime measurements"})," (more on this below).\nWhen a TPM is implemented in software, it's typically called a ",(0,i.jsx)(t.em,{children:"virtual"})," TPM (vTPM)."]}),"\n",(0,i.jsx)(t.h3,{id:"runtime-measurement",children:"Runtime measurement"}),"\n",(0,i.jsxs)(t.p,{children:["A runtime measurement is a cryptographic hash of the memory pages of a so called ",(0,i.jsx)(t.em,{children:"runtime component"}),". Runtime components of interest typically include a system's bootloader or OS kernel."]}),"\n",(0,i.jsx)(t.h3,{id:"platform-configuration-register-pcr",children:"Platform Configuration Register (PCR)"}),"\n",(0,i.jsx)(t.p,{children:"A Platform Configuration Register (PCR) is a memory location in the TPM that has some unique properties.\nTo store a new value in a PCR, the existing value is extended with a new value as follows:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"PCR[N] = HASHalg( PCR[N] || ArgumentOfExtend )\n"})}),"\n",(0,i.jsx)(t.p,{children:"The PCRs are typically used to store runtime measurements.\nThe new value of a PCR is always an extension of the existing value.\nThus, storing the measurements of multiple components into the same PCR irreversibly links them together."}),"\n",(0,i.jsx)(t.h3,{id:"measured-boot",children:"Measured boot"}),"\n",(0,i.jsx)(t.p,{children:"Measured boot builds on the concept of chained runtime measurements.\nEach component in the boot chain loads and measures the next component into the PCR before executing it.\nBy comparing the resulting PCR values against trusted reference values, the integrity of the entire boot chain and thereby the running system can be ensured."}),"\n",(0,i.jsx)(t.h3,{id:"remote-attestation-ra",children:"Remote attestation (RA)"}),"\n",(0,i.jsx)(t.p,{children:"Remote attestation is the process of verifying certain properties of an application or platform, such as integrity and confidentiality, from a remote location.\nIn the case of a measured boot, the goal is to obtain a signed attestation statement on the PCR values of the boot measurements.\nThe statement can then be verified and compared to a set of trusted reference values.\nThis way, the integrity of the platform can be ensured before sharing secrets with it."}),"\n",(0,i.jsx)(t.h3,{id:"confidential-virtual-machine-cvm",children:"Confidential virtual machine (CVM)"}),"\n",(0,i.jsx)(t.p,{children:"Confidential computing (CC) is the protection of data in-use with hardware-based trusted execution environments (TEEs).\nWith CVMs, TEEs encapsulate entire virtual machines and isolate them against the hypervisor, other VMs, and direct memory access.\nAfter loading the initial VM image into encrypted memory, the hypervisor calls for a secure processor to measure these initial memory pages.\nThe secure processor locks these pages and generates an attestation report on the initial page measurements.\nCVM memory pages are encrypted with a key that resides inside the secure processor, which makes sure only the guest VM can access them.\nThe attestation report is signed by the secure processor and can be verified using remote attestation via the certificate authority of the hardware vendor.\nSuch an attestation statement guarantees the confidentiality and integrity of a CVM."}),"\n",(0,i.jsx)(t.h3,{id:"attested-tls-atls",children:"Attested TLS (aTLS)"}),"\n",(0,i.jsx)(t.p,{children:"In a CC environment, attested TLS (aTLS) can be used to establish secure connections between two parties using the remote attestation features of the CC components."}),"\n",(0,i.jsx)(t.p,{children:"aTLS modifies the TLS handshake by embedding an attestation statement into the TLS certificate.\nInstead of relying on a certificate authority, aTLS uses this attestation statement to establish trust in the certificate."}),"\n",(0,i.jsx)(t.p,{children:"The protocol can be used by clients to verify a server certificate, by a server to verify a client certificate, or for mutual verification (mutual aTLS)."}),"\n",(0,i.jsx)(t.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsx)(t.p,{children:"The challenge for Constellation is to lift a CVM's attestation statement to the Kubernetes software layer and make it end-to-end verifiable.\nFrom there, Constellation needs to expand the attestation from a single CVM to the entire cluster."}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#joinservice",children:(0,i.jsx)(t.em,{children:"JoinService"})})," and ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#verificationservice",children:(0,i.jsx)(t.em,{children:"VerificationService"})})," are where all runs together.\nInternally, the ",(0,i.jsx)(t.em,{children:"JoinService"})," uses remote attestation to securely join CVM nodes to the cluster.\nExternally, the ",(0,i.jsx)(t.em,{children:"VerificationService"})," provides an attestation statement for the cluster's CVMs and configuration."]}),"\n",(0,i.jsx)(t.p,{children:"The following explains the details of both steps."}),"\n",(0,i.jsx)(t.h2,{id:"node-attestation",children:"Node attestation"}),"\n",(0,i.jsx)(t.p,{children:"The idea is that Constellation nodes should have verifiable integrity from the CVM hardware measurement up to the Kubernetes software layer.\nThe solution is a verifiable boot chain and an integrity-protected runtime environment."}),"\n",(0,i.jsxs)(t.p,{children:["Constellation uses measured boot within CVMs, measuring each component in the boot process before executing it.\nOutside of CC, this is usually implemented via TPMs.\nCVM technologies differ in how they implement runtime measurements, but the general concepts are similar to those of a TPM.\nFor simplicity, TPM terminology like ",(0,i.jsx)(t.em,{children:"PCR"})," is used in the following."]}),"\n",(0,i.jsxs)(t.p,{children:["When a Constellation node image boots inside a CVM, measured boot is used for all stages and components of the boot chain.\nThis process goes up to the root filesystem.\nThe root filesystem is mounted read-only with integrity protection.\nFor the details on the image and boot stages see the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/images",children:"image architecture"})," documentation.\nAny changes to the image will inevitably also change the corresponding PCR values.\nTo create a node attestation statement, the Constellation image obtains a CVM attestation statement from the hardware.\nThis includes the runtime measurements and thereby binds the measured boot results to the CVM hardware measurement."]}),"\n",(0,i.jsxs)(t.p,{children:["In addition to the image measurements, Constellation extends a PCR during the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/create",children:"initialization phase"})," that irrevocably marks the node as initialized.\nThe measurement is created using the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys#cluster-identity",children:(0,i.jsx)(t.em,{children:"clusterID"})}),", tying all future attestation statements to this ID.\nThereby, an attestation statement is unique for every cluster and a node can be identified unambiguously as being initialized."]}),"\n",(0,i.jsxs)(t.p,{children:["To verify an attestation, the hardware's signature and a statement are verified first to establish trust in the contained runtime measurements.\nIf successful, the measurements are verified against the trusted values of the particular Constellation release version.\nFinally, the measurement of the ",(0,i.jsx)(t.em,{children:"clusterID"})," can be compared by calculating it with the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys#master-secret",children:"master secret"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"runtime-measurements",children:"Runtime measurements"}),"\n",(0,i.jsx)(t.p,{children:"Constellation uses runtime measurements to implement the measured boot approach.\nAs stated above, the underlying hardware technology and guest firmware differ in their implementations of runtime measurements.\nThe following gives a detailed description of the available measurements in the different cloud environments."}),"\n",(0,i.jsx)(t.p,{children:"The runtime measurements consist of two types of values:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Measurements produced by the cloud infrastructure and firmware of the CVM"}),":\nThese are measurements of closed-source firmware and other values controlled by the cloud provider.\nWhile not being reproducible for the user, some of them can be compared against previously observed values.\nOthers may change frequently and aren't suitable for verification.\nThe ",(0,i.jsx)(t.a,{href:"#chain-of-trust",children:"signed image measurements"})," include measurements that are known, previously observed values."]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Measurements produced by the Constellation bootloader and boot chain"}),":\nThe Constellation Bootloader takes over from the CVM firmware and ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/images",children:"measures the rest of the boot chain"}),".\nThe Constellation ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#bootstrapper",children:"Bootstrapper"})," is the first user mode component that runs in a Constellation image.\nIt extends PCR registers with the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys#cluster-identity",children:"IDs"})," of the cluster marking a node as initialized."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Constellation allows to specify in the config which measurements should be enforced during the attestation process.\nEnforcing non-reproducible measurements controlled by the cloud provider means that changes in these values require manual updates to the cluster's config.\nBy default, Constellation only enforces measurements that are stable values produced by the infrastructure or by Constellation directly."}),"\n",(0,i.jsxs)(s,{groupId:"csp",children:[(0,i.jsxs)(n,{value:"aws",label:"AWS",children:[(0,i.jsxs)(t.p,{children:["Constellation uses the ",(0,i.jsx)(t.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nitrotpm.html",children:"vTPM"})," (NitroTPM) feature of the ",(0,i.jsx)(t.a,{href:"http://aws.amazon.com/ec2/nitro/",children:"AWS Nitro System"})," on AWS for runtime measurements."]}),(0,i.jsxs)(t.p,{children:["The vTPM adheres to the ",(0,i.jsx)(t.a,{href:"https://trustedcomputinggroup.org/resource/tpm-library-specification/",children:"TPM 2.0"})," specification.\nThe VMs are attested by obtaining signed PCR values over the VM's boot configuration from the TPM and comparing them to a known, good state (measured boot)."]}),(0,i.jsx)(t.p,{children:"The following table lists all PCR values of the vTPM and the measured components.\nIt also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable.\nThe latter means that the value can be generated offline and compared to the one in the vTPM."}),(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"PCR"}),(0,i.jsx)(t.th,{children:"Components"}),(0,i.jsx)(t.th,{children:"Measured by"}),(0,i.jsx)(t.th,{children:"Reproducible and verifiable"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"0"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"2"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"3"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"4"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader, Kernel, initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"AWS, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"5"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"6"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"7"}),(0,i.jsx)(t.td,{children:"Secure Boot Policy"}),(0,i.jsx)(t.td,{children:"AWS, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"8"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"9"}),(0,i.jsx)(t.td,{children:"initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Linux Kernel"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10"}),(0,i.jsx)(t.td,{children:"User space"}),(0,i.jsx)(t.td,{children:"Linux IMA"}),(0,i.jsxs)(t.td,{children:["No",(0,i.jsx)(t.sup,{children:(0,i.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"11"}),(0,i.jsx)(t.td,{children:"Unified Kernel Image components"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"12"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(User space, Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"13"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"14"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"15"}),(0,i.jsx)(t.td,{children:"ClusterID"}),(0,i.jsx)(t.td,{children:"Constellation Bootstrapper"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"16\u201323"}),(0,i.jsx)(t.td,{children:"Unused"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]})]})]})]}),(0,i.jsxs)(n,{value:"azure",label:"Azure",children:[(0,i.jsxs)(t.p,{children:["Constellation uses the ",(0,i.jsx)(t.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/trusted-launch#vtpm",children:"vTPM"})," feature of Azure CVMs for runtime measurements.\nThis vTPM adheres to the ",(0,i.jsx)(t.a,{href:"https://trustedcomputinggroup.org/resource/tpm-library-specification/",children:"TPM 2.0"})," specification.\nIt provides a ",(0,i.jsx)(t.a,{href:"https://docs.microsoft.com/en-us/azure/security/fundamentals/measured-boot-host-attestation#measured-boot",children:"measured boot"})," verification that's based on the trusted launch feature of ",(0,i.jsx)(t.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/trusted-launch",children:"Trusted Launch VMs"}),"."]}),(0,i.jsx)(t.p,{children:"The following table lists all PCR values of the vTPM and the measured components.\nIt also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable.\nThe latter means that the value can be generated offline and compared to the one in the vTPM."}),(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"PCR"}),(0,i.jsx)(t.th,{children:"Components"}),(0,i.jsx)(t.th,{children:"Measured by"}),(0,i.jsx)(t.th,{children:"Reproducible and verifiable"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"0"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"2"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"3"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"4"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader, Kernel, initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Azure, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"5"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"6"}),(0,i.jsx)(t.td,{children:"VM Unique ID"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"7"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Azure, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"8"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"9"}),(0,i.jsx)(t.td,{children:"initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Linux Kernel"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10"}),(0,i.jsx)(t.td,{children:"User space"}),(0,i.jsx)(t.td,{children:"Linux IMA"}),(0,i.jsxs)(t.td,{children:["No",(0,i.jsx)(t.sup,{children:(0,i.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"11"}),(0,i.jsx)(t.td,{children:"Unified Kernel Image components"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"12"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(User space, Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"13"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"14"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"15"}),(0,i.jsx)(t.td,{children:"ClusterID"}),(0,i.jsx)(t.td,{children:"Constellation Bootstrapper"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"16\u201323"}),(0,i.jsx)(t.td,{children:"Unused"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]})]})]})]}),(0,i.jsxs)(n,{value:"gcp",label:"GCP",children:[(0,i.jsxs)(t.p,{children:["Constellation uses the ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/compute/confidential-vm/docs/about-cvm",children:"vTPM"})," feature of CVMs on GCP for runtime measurements.\nNote that this vTPM doesn't run inside the hardware-protected CVM context, but is emulated by the hypervisor."]}),(0,i.jsxs)(t.p,{children:["The vTPM adheres to the ",(0,i.jsx)(t.a,{href:"https://trustedcomputinggroup.org/resource/tpm-library-specification/",children:"TPM 2.0"})," specification.\nIt provides a ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/compute/confidential-vm/docs/monitoring#about_launch_attestation_report_events",children:"launch attestation report"})," that's based on the measured boot feature of ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/compute/shielded-vm/docs/shielded-vm#measured-boot",children:"Shielded VMs"}),"."]}),(0,i.jsx)(t.p,{children:"The following table lists all PCR values of the vTPM and the measured components.\nIt also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable.\nThe latter means that the value can be generated offline and compared to the one in the vTPM."}),(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"PCR"}),(0,i.jsx)(t.th,{children:"Components"}),(0,i.jsx)(t.th,{children:"Measured by"}),(0,i.jsx)(t.th,{children:"Reproducible and verifiable"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"0"}),(0,i.jsx)(t.td,{children:"CVM version and technology"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"2"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"3"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"4"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader, Kernel, initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"GCP, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"5"}),(0,i.jsx)(t.td,{children:"Disk GUID partition table"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"6"}),(0,i.jsx)(t.td,{children:"Disk GUID partition table"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"7"}),(0,i.jsx)(t.td,{children:"GCP Secure Boot Policy"}),(0,i.jsx)(t.td,{children:"GCP, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"8"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"9"}),(0,i.jsx)(t.td,{children:"initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Linux Kernel"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10"}),(0,i.jsx)(t.td,{children:"User space"}),(0,i.jsx)(t.td,{children:"Linux IMA"}),(0,i.jsxs)(t.td,{children:["No",(0,i.jsx)(t.sup,{children:(0,i.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"11"}),(0,i.jsx)(t.td,{children:"Unified Kernel Image components"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"12"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(User space, Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"13"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"14"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"15"}),(0,i.jsx)(t.td,{children:"ClusterID"}),(0,i.jsx)(t.td,{children:"Constellation Bootstrapper"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"16\u201323"}),(0,i.jsx)(t.td,{children:"Unused"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]})]})]})]}),(0,i.jsxs)(n,{value:"stackit",label:"STACKIT",children:[(0,i.jsx)(t.p,{children:"Constellation uses a hypervisor-based vTPM for runtime measurements."}),(0,i.jsxs)(t.p,{children:["The vTPM adheres to the ",(0,i.jsx)(t.a,{href:"https://trustedcomputinggroup.org/resource/tpm-library-specification/",children:"TPM 2.0"})," specification.\nThe VMs are attested by obtaining signed PCR values over the VM's boot configuration from the TPM and comparing them to a known, good state (measured boot)."]}),(0,i.jsx)(t.p,{children:"The following table lists all PCR values of the vTPM and the measured components.\nIt also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable.\nThe latter means that the value can be generated offline and compared to the one in the vTPM."}),(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"PCR"}),(0,i.jsx)(t.th,{children:"Components"}),(0,i.jsx)(t.th,{children:"Measured by"}),(0,i.jsx)(t.th,{children:"Reproducible and verifiable"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"0"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"2"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"3"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"4"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader, Kernel, initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"STACKIT, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"5"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"6"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"7"}),(0,i.jsx)(t.td,{children:"Secure Boot Policy"}),(0,i.jsx)(t.td,{children:"STACKIT, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"8"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"9"}),(0,i.jsx)(t.td,{children:"initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Linux Kernel"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10"}),(0,i.jsx)(t.td,{children:"User space"}),(0,i.jsx)(t.td,{children:"Linux IMA"}),(0,i.jsxs)(t.td,{children:["No",(0,i.jsx)(t.sup,{children:(0,i.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"11"}),(0,i.jsx)(t.td,{children:"Unified Kernel Image components"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"12"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(User space, Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"13"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"14"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"15"}),(0,i.jsx)(t.td,{children:"ClusterID"}),(0,i.jsx)(t.td,{children:"Constellation Bootstrapper"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"16\u201323"}),(0,i.jsx)(t.td,{children:"Unused"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]})]})]})]})]}),"\n",(0,i.jsx)(t.h3,{id:"cvm-verification",children:"CVM verification"}),"\n",(0,i.jsx)(t.p,{children:"To verify the integrity of the received attestation statement, a chain of trust from the CVM technology to the interface providing the statement has to be established.\nFor verification of the CVM technology, Constellation may expose additional options in its config file."}),"\n",(0,i.jsxs)(s,{groupId:"csp",children:[(0,i.jsxs)(n,{value:"aws",label:"AWS",children:[(0,i.jsx)(t.p,{children:"On AWS, AMD SEV-SNP is used to provide runtime encryption to the VMs.\nAn SEV-SNP attestation report is used to establish trust in the VM.\nYou may customize certain parameters for verification of the attestation statement using the Constellation config file."}),(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"TCB versions"}),"\n",(0,i.jsx)(t.p,{children:"You can set the minimum version numbers of components in the SEV-SNP TCB.\nUse the latest versions to enforce that only machines with the most recent firmware updates are allowed to join the cluster.\nAlternatively, you can set a lower minimum version to allow slightly out-of-date machines to still be able to join the cluster."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Root Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This certificate is the root of trust for verifying the SEV-SNP certificate chain."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Signing Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This is the intermediate certificate for verifying the SEV-SNP report's signature.\nIf it's not specified, the CLI fetches it from the AMD key distribution server."}),"\n"]}),"\n"]})]}),(0,i.jsxs)(n,{value:"azure",label:"Azure SEV-SNP",children:[(0,i.jsx)(t.p,{children:"On Azure, AMD SEV-SNP is used to provide runtime encryption to the VMs.\nAn SEV-SNP attestation report is used to establish trust in the vTPM running inside the VM.\nYou may customize certain parameters for verification of the attestation statement using the Constellation config file."}),(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"TCB versions"}),"\n",(0,i.jsx)(t.p,{children:"You can set the minimum version numbers of components in the SEV-SNP TCB.\nUse the latest versions to enforce that only machines with the most recent firmware updates are allowed to join the cluster.\nAlternatively, you can set a lower minimum version to allow slightly out-of-date machines to still be able to join the cluster."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Root Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This certificate is the root of trust for verifying the SEV-SNP certificate chain."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"Firmware Signer"}),"\n",(0,i.jsxs)(t.p,{children:["This config option allows you to specify how the firmware signer should be verified.\nMore explicitly, it controls the verification of the ",(0,i.jsx)(t.code,{children:"IDKeyDigest"})," value in the SEV-SNP attestation report.\nYou can provide a list of accepted key digests and specify a policy on how this list is compared against the reported ",(0,i.jsx)(t.code,{children:"IDKeyDigest"}),"."]}),"\n"]}),"\n"]})]}),(0,i.jsxs)(n,{value:"gcp",label:"GCP",children:[(0,i.jsx)(t.p,{children:"On GCP, AMD SEV-SNP is used to provide runtime encryption to the VMs.\nAn SEV-SNP attestation report is used to establish trust in the VM.\nYou may customize certain parameters for verification of the attestation statement using the Constellation config file."}),(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"TCB versions"}),"\n",(0,i.jsx)(t.p,{children:"You can set the minimum version numbers of components in the SEV-SNP TCB.\nUse the latest versions to enforce that only machines with the most recent firmware updates are allowed to join the cluster.\nAlternatively, you can set a lower minimum version to allow slightly out-of-date machines to still be able to join the cluster."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Root Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This certificate is the root of trust for verifying the SEV-SNP certificate chain."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Signing Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This is the intermediate certificate for verifying the SEV-SNP report's signature.\nIf it's not specified, the CLI fetches it from the AMD key distribution server."}),"\n"]}),"\n"]})]}),(0,i.jsx)(n,{value:"stackit",label:"STACKIT",children:(0,i.jsxs)(t.p,{children:["On STACKIT, AMD SEV-ES is used to provide runtime encryption to the VMs.\nThe hypervisor-based vTPM is used to establish trust in the VM via ",(0,i.jsx)(t.a,{href:"#runtime-measurements",children:"runtime measurements"}),".\nThere is no additional configuration available for STACKIT."]})})]}),"\n",(0,i.jsx)(t.h2,{id:"cluster-attestation",children:"Cluster attestation"}),"\n",(0,i.jsxs)(t.p,{children:["Cluster-facing, Constellation's ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#joinservice",children:(0,i.jsx)(t.em,{children:"JoinService"})})," verifies each node joining the cluster given the configured ground truth runtime measurements.\nUser-facing, the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#verificationservice",children:(0,i.jsx)(t.em,{children:"VerificationService"})})," provides an interface to verify a node using remote attestation.\nBy verifying the first node during the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#bootstrapper",children:"initialization"})," and configuring the ground truth measurements that are subsequently enforced by the ",(0,i.jsx)(t.em,{children:"JoinService"}),", the whole cluster is verified in a transitive way."]}),"\n",(0,i.jsx)(t.h3,{id:"cluster-facing-attestation",children:"Cluster-facing attestation"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"JoinService"})," is provided with the runtime measurements of the whitelisted Constellation image version as the ground truth.\nDuring the initialization and the cluster bootstrapping, each node connects to the ",(0,i.jsx)(t.em,{children:"JoinService"})," using ",(0,i.jsx)(t.a,{href:"#attested-tls-atls",children:"aTLS"}),".\nDuring the handshake, the node transmits an attestation statement including its runtime measurements.\nThe ",(0,i.jsx)(t.em,{children:"JoinService"})," verifies that statement and compares the measurements against the ground truth.\nFor details of the initialization process check the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices",children:"microservice descriptions"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["After the initialization, every node updates its runtime measurements with the ",(0,i.jsx)(t.em,{children:"clusterID"})," value, marking it irreversibly as initialized.\nWhen an initialized node tries to join another cluster, its measurements inevitably mismatch the measurements of an uninitialized node and it will be declined."]}),"\n",(0,i.jsx)(t.h3,{id:"user-facing-attestation",children:"User-facing attestation"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#verificationservice",children:(0,i.jsx)(t.em,{children:"VerificationService"})})," provides an endpoint for obtaining its hardware-based remote attestation statement, which includes the runtime measurements.\nA user can ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cluster",children:"verify"})," this statement and compare the measurements against the configured ground truth and, thus, verify the identity and integrity of all Constellation components and the cluster configuration. Subsequently, the user knows that the entire cluster is in the expected state and is trustworthy."]}),"\n",(0,i.jsx)(t.h2,{id:"putting-it-all-together",children:"Putting it all together"}),"\n",(0,i.jsx)(t.p,{children:"This section puts the aforementioned concepts together and illustrate how trust into a Constellation cluster is established and maintained."}),"\n",(0,i.jsx)(t.h3,{id:"cli-and-node-images",children:"CLI and node images"}),"\n",(0,i.jsxs)(t.p,{children:["It all starts with the CLI executable. The CLI is signed by Edgeless Systems. To ensure non-repudiability for CLI releases, Edgeless Systems publishes corresponding signatures to the public ledger of the ",(0,i.jsx)(t.a,{href:"https://www.sigstore.dev/",children:"sigstore project"}),". There's a ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cli",children:"step-by-step guide"})," on how to verify CLI signatures based on sigstore."]}),"\n",(0,i.jsxs)(t.p,{children:["The CLI contains the latest runtime measurements of the Constellation node image for all supported cloud platforms. In case a different version of the node image is to be used, the corresponding runtime measurements can be fetched using the CLI's ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/reference/cli#constellation-config-fetch-measurements",children:"fetch-measurements command"}),". This command downloads the runtime measurements and the corresponding signature from cdn.confidential.cloud. See for example the following files corresponding to node image v2.16.3:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://cdn.confidential.cloud/constellation/v2/ref/-/stream/stable/v2.16.3/image/measurements.json",children:"Measurements"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://cdn.confidential.cloud/constellation/v2/ref/-/stream/stable/v2.16.3/image/measurements.json.sig",children:"Signature"})}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"The CLI contains the long-term public key of Edgeless Systems to verify the signature of downloaded runtime measurements."}),"\n",(0,i.jsx)(t.h3,{id:"cluster-creation",children:"Cluster creation"}),"\n",(0,i.jsxs)(t.p,{children:["When a cluster is ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/create",children:"created"}),", the CLI automatically verifies the runtime measurements of the ",(0,i.jsx)(t.em,{children:"first node"})," using remote attestation. Based on this, the CLI and the first node set up a temporary TLS connection. This ",(0,i.jsx)(t.a,{href:"#attested-tls-atls",children:"aTLS"})," connection is used for two things:"]}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["The CLI sends the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys#master-secret",children:"master secret"})," of the to-be-created cluster to the CLI. The master secret is generated by the first node."]}),"\n",(0,i.jsxs)(t.li,{children:["The first node sends a ",(0,i.jsx)(t.a,{href:"https://www.redhat.com/sysadmin/kubeconfig",children:"kubeconfig file"})," with Kubernetes credentials to the CLI."]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["After this, the aTLS connection is closed and the first node bootstraps the Kubernetes cluster. All subsequent interactions between the CLI and the cluster go via the ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/overview/kubernetes-api/",children:"Kubernetes API"})," server running inside the cluster. The CLI (and other tools like kubectl) use the credentials referenced by the kubeconfig file to authenticate themselves towards the Kubernetes API server and to establish a mTLS connection."]}),"\n",(0,i.jsx)(t.p,{children:"The CLI connects to the Kubernetes API to write the runtime measurements for the applicable node image to etcd. The JoinService uses these runtime measurements to verify all nodes that join the cluster subsequently."}),"\n",(0,i.jsx)(t.h3,{id:"chain-of-trust",children:"Chain of trust"}),"\n",(0,i.jsx)(t.p,{children:"In summary, there's a chain of trust based on cryptographic signatures that goes from the user to the cluster via the CLI. This is illustrated in the following diagram."}),"\n",(0,i.jsx)(t.mermaid,{value:'flowchart LR\n A[User]-- "verifies" --\x3eB[CLI]\n B[CLI]-- "verifies" --\x3eC([Runtime measurements])\n D[Edgeless Systems]-- "signs" --\x3eB[CLI]\n D[Edgeless Systems]-- "signs" --\x3eC([Runtime measurements])\n B[CLI]-- "verifies (remote attestation)" --\x3eE[First node]\n E[First node]-- "verifies (remote attestation)" --\x3eF[Other nodes]\n C([Runtime measurements]) -.-> E[First node]\n C([Runtime measurements]) -.-> F[Other nodes]'}),"\n",(0,i.jsx)(t.h3,{id:"upgrades",children:"Upgrades"}),"\n",(0,i.jsxs)(t.p,{children:["Whenever a cluster is ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/upgrade",children:"upgraded"})," to a new version of the node image, the CLI sends the corresponding runtime measurements via the Kubernetes API server. The new runtime measurements are stored in etcd within the cluster and replace any previous runtime measurements. The new runtime measurements are then used automatically by the JoinService for the verification of new nodes."]}),"\n",(0,i.jsx)(t.h2,{id:"references",children:"References"}),"\n","\n",(0,i.jsxs)(t.section,{"data-footnotes":!0,className:"footnotes",children:[(0,i.jsx)(t.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{id:"user-content-fn-1",children:["\n",(0,i.jsxs)(t.p,{children:["Linux IMA produces runtime measurements of user-space binaries.\nHowever, these measurements aren't deterministic and thus, PCR[10] can't be compared to a constant value.\nInstead, a policy engine must be used to verify the TPM event log against a policy. ",(0,i.jsx)(t.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})," ",(0,i.jsxs)(t.a,{href:"#user-content-fnref-1-2","data-footnote-backref":"","aria-label":"Back to reference 1-2",className:"data-footnote-backref",children:["\u21a9",(0,i.jsx)(t.sup,{children:"2"})]})," ",(0,i.jsxs)(t.a,{href:"#user-content-fnref-1-3","data-footnote-backref":"","aria-label":"Back to reference 1-3",className:"data-footnote-backref",children:["\u21a9",(0,i.jsx)(t.sup,{children:"3"})]})," ",(0,i.jsxs)(t.a,{href:"#user-content-fnref-1-4","data-footnote-backref":"","aria-label":"Back to reference 1-4",className:"data-footnote-backref",children:["\u21a9",(0,i.jsx)(t.sup,{children:"4"})]})]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}function u(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3815.705487db.js b/pr-preview/pr-4027/assets/js/3815.705487db.js deleted file mode 100644 index 754a996c5..000000000 --- a/pr-preview/pr-4027/assets/js/3815.705487db.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3815],{53815:(s,r,a)=>{a.d(r,{diagram:()=>t});var e=a(71746),l=(a(52501),a(89625),a(21152),a(10045),a(5164),a(28698),a(5894),a(63245),a(32387),a(30092),a(13226),a(67633),a(40797)),t={parser:e._$,get db(){return new e.NM},renderer:e.Lh,styles:e.tM,init:(0,l.K2)(s=>{s.class||(s.class={}),s.class.arrowMarkerAbsolute=s.arrowMarkerAbsolute},"init")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3962f62e.52655f48.js b/pr-preview/pr-4027/assets/js/3962f62e.52655f48.js deleted file mode 100644 index 4a1c8e0de..000000000 --- a/pr-preview/pr-4027/assets/js/3962f62e.52655f48.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4200],{28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var s=n(96540);const o={},i=s.createContext(o);function r(e){const t=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(i.Provider,{value:t},e.children)}},37537:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"getting-started/examples","title":"Examples","description":"After you installed the CLI and created your first cluster, you\'re ready to deploy applications. Why not start with one of the following examples?","source":"@site/versioned_docs/version-2.24/getting-started/examples.md","sourceDirName":"getting-started","slug":"/getting-started/examples","permalink":"/constellation/pr-preview/pr-4027/getting-started/examples","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/getting-started/examples.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Cloud Marketplaces","permalink":"/constellation/pr-preview/pr-4027/getting-started/marketplaces"},"next":{"title":"Emojivoto","permalink":"/constellation/pr-preview/pr-4027/getting-started/examples/emojivoto"}}');var o=n(74848),i=n(28453);const r={},a="Examples",l={},c=[];function p(e){const t={a:"a",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"examples",children:"Examples"})}),"\n",(0,o.jsxs)(t.p,{children:["After you ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/getting-started/install",children:"installed the CLI"})," and ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/getting-started/first-steps",children:"created your first cluster"}),", you're ready to deploy applications. Why not start with one of the following examples?"]}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/getting-started/examples/emojivoto",children:"Emojivoto"}),": a simple but fun web application"]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/getting-started/examples/online-boutique",children:"Online Boutique"}),": an e-commerce demo application by Google consisting of 11 separate microservices"]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/getting-started/examples/horizontal-scaling",children:"Horizontal Pod Autoscaling"}),": an example demonstrating Constellation's autoscaling capabilities"]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3aba4a32.42c67689.js b/pr-preview/pr-4027/assets/js/3aba4a32.42c67689.js deleted file mode 100644 index 1afc06b97..000000000 --- a/pr-preview/pr-4027/assets/js/3aba4a32.42c67689.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1902],{28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}},88892:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"overview/clouds","title":"Feature status of clouds","description":"What works on which cloud? Currently, Confidential VMs (CVMs) are available in varying quality on the different clouds and software stacks.","source":"@site/versioned_docs/version-2.22/overview/clouds.md","sourceDirName":"overview","slug":"/overview/clouds","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/clouds","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/overview/clouds.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Product features","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/product"},"next":{"title":"Performance analysis of Constellation","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/performance/"}}');var r=n(74848),i=n(28453);const o={},a="Feature status of clouds",l={},d=[{value:"Amazon Web Services (AWS)",id:"amazon-web-services-aws",level:2},{value:"Microsoft Azure",id:"microsoft-azure",level:2},{value:"Google Cloud Platform (GCP)",id:"google-cloud-platform-gcp",level:2},{value:"STACKIT",id:"stackit",level:2},{value:"OpenStack",id:"openstack",level:2},{value:"Conclusion",id:"conclusion",level:2}];function c(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"feature-status-of-clouds",children:"Feature status of clouds"})}),"\n",(0,r.jsx)(t.p,{children:"What works on which cloud? Currently, Confidential VMs (CVMs) are available in varying quality on the different clouds and software stacks."}),"\n",(0,r.jsx)(t.p,{children:"For Constellation, the ideal environment provides the following:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"Ability to run arbitrary software and images inside CVMs"}),"\n",(0,r.jsx)(t.li,{children:"CVMs based on AMD SEV-SNP (available in EPYC CPUs since the Milan generation) or Intel TDX (available in Xeon CPUs since the Sapphire Rapids generation)"}),"\n",(0,r.jsx)(t.li,{children:"Ability for CVM guests to obtain raw hardware attestation statements"}),"\n",(0,r.jsx)(t.li,{children:"Reviewable, open-source firmware inside CVMs"}),"\n",(0,r.jsx)(t.li,{children:"Capability of the firmware to attest the integrity of the code it passes control to, e.g., with an embedded virtual TPM (vTPM)"}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"(1) is a functional must-have. (2)--(5) are required for remote attestation that fully keeps the infrastructure/cloud out. Constellation can work without them or with approximations, but won't protect against certain privileged attackers anymore."}),"\n",(0,r.jsx)(t.p,{children:"The following table summarizes the state of features for different infrastructures."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"Feature"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"AWS"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"Azure"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"GCP"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"STACKIT"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"OpenStack (Yoga)"})})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"1. Custom images"})}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"2. SEV-SNP or TDX"})}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Depends on kernel/HV"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"3. Raw guest attestation"})}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Depends on kernel/HV"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"4. Reviewable firmware"})}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"No*"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Depends on kernel/HV"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"5. Confidential measured boot"})}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Depends on kernel/HV"})]})]})]}),"\n",(0,r.jsx)(t.h2,{id:"amazon-web-services-aws",children:"Amazon Web Services (AWS)"}),"\n",(0,r.jsxs)(t.p,{children:["Amazon EC2 ",(0,r.jsx)(t.a,{href:"https://aws.amazon.com/de/about-aws/whats-new/2023/04/amazon-ec2-amd-sev-snp/",children:"supports AMD SEV-SNP"}),".\nRegarding (3), AWS provides direct access to attestation statements.\nHowever, regarding (5), attestation is partially based on the ",(0,r.jsx)(t.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nitrotpm.html",children:"NitroTPM"})," for ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#measured-boot",children:"measured boot"}),", which is a vTPM managed by the Nitro hypervisor.\nHence, the hypervisor is currently part of Constellation's TCB.\nRegarding (4), the ",(0,r.jsx)(t.a,{href:"https://github.com/aws/uefi",children:"firmware is open source"})," and can be reproducibly built."]}),"\n",(0,r.jsx)(t.h2,{id:"microsoft-azure",children:"Microsoft Azure"}),"\n",(0,r.jsxs)(t.p,{children:["With its ",(0,r.jsx)(t.a,{href:"https://docs.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview",children:"CVM offering"}),", Azure provides the best foundations for Constellation.\nRegarding (3), Azure provides direct access to attestation statements.\nThe firmware runs in an isolated domain inside the CVM and exposes a vTPM (5), but it's closed source (4).\nOn SEV-SNP, Azure uses VM Privilege Level (VMPL) isolation for the separation of firmware and the rest of the VM; on TDX, they use TD partitioning.\nThis firmware is signed by Azure.\nThe signature is reflected in the attestation statements of CVMs.\nThus, the Azure closed-source firmware becomes part of Constellation's trusted computing base (TCB)."]}),"\n",(0,r.jsxs)(t.p,{children:["* Recently, ",(0,r.jsx)(t.a,{href:"https://techcommunity.microsoft.com/blog/windowsosplatform/openhcl-the-new-open-source-paravisor/4273172",children:"Azure announced the open source paravisor OpenHCL"}),". It's the foundation for fully open source and verifiable CVM firmware. Once Azure provides their CVM firmware with reproducible builds based on OpenHCL, (4) switches from ",(0,r.jsx)(t.em,{children:"No"})," to ",(0,r.jsx)(t.em,{children:"Yes"}),". Constellation will support OpenHCL based firmware on Azure in the future."]}),"\n",(0,r.jsx)(t.h2,{id:"google-cloud-platform-gcp",children:"Google Cloud Platform (GCP)"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"https://cloud.google.com/confidential-computing/confidential-vm/docs/confidential-vm-overview#technologies",children:"CVMs Generally Available in GCP"})," are based on AMD SEV-ES or SEV-SNP.\nRegarding (3), with their SEV-SNP offering Google provides direct access to attestation statements.\nHowever, regarding (5), attestation is partially based on the ",(0,r.jsx)(t.a,{href:"https://cloud.google.com/compute/shielded-vm/docs/shielded-vm#vtpm",children:"Shielded VM vTPM"})," for ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#measured-boot",children:"measured boot"}),", which is a vTPM managed by Google's hypervisor.\nHence, the hypervisor is currently part of Constellation's TCB.\nRegarding (4), the CVMs still include closed-source firmware."]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://cloud.google.com/blog/products/identity-security/confidential-vms-on-intel-cpus-your-datas-new-intelligent-defense",children:"TDX on Google"})," is in public preview.\nWith it, Constellation would have a similar TCB and attestation flow as with the current SEV-SNP offering."]}),"\n",(0,r.jsx)(t.h2,{id:"stackit",children:"STACKIT"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://www.stackit.de/en/product/stackit-compute-engine/",children:"STACKIT Compute Engine"})," supports AMD SEV-ES. A vTPM is used for measured boot, which is a vTPM managed by STACKIT's hypervisor. Hence, the hypervisor is currently part of Constellation's TCB."]}),"\n",(0,r.jsx)(t.h2,{id:"openstack",children:"OpenStack"}),"\n",(0,r.jsxs)(t.p,{children:["OpenStack is an open-source cloud and infrastructure management software. It's used by many smaller CSPs and datacenters. In the latest ",(0,r.jsx)(t.em,{children:"Yoga"})," version, OpenStack has basic support for CVMs. However, much depends on the employed kernel and hypervisor. Features (2)--(4) are likely to be a ",(0,r.jsx)(t.em,{children:"Yes"})," with Linux kernel version 6.2. Thus, going forward, OpenStack on corresponding AMD or Intel hardware will be a viable underpinning for Constellation."]}),"\n",(0,r.jsx)(t.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,r.jsx)(t.p,{children:"The different clouds and software like the Linux kernel and OpenStack are in the process of building out their support for state-of-the-art CVMs. Azure has already most features in place. For Constellation, the status quo means that the TCB has different shapes on different infrastructures. With broad SEV-SNP support coming to the Linux kernel, we soon expect a normalization of features across infrastructures."})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3aca6029.1291f65f.js b/pr-preview/pr-4027/assets/js/3aca6029.1291f65f.js deleted file mode 100644 index 78a0ddbfb..000000000 --- a/pr-preview/pr-4027/assets/js/3aca6029.1291f65f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4394],{28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const i={},r=s.createContext(i);function o(e){const t=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:t},e.children)}},38693:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"architecture/attestation","title":"Attestation","description":"This page explains Constellation\'s attestation process and highlights the cornerstones of its trust model.","source":"@site/versioned_docs/version-2.24/architecture/attestation.md","sourceDirName":"architecture","slug":"/architecture/attestation","permalink":"/constellation/pr-preview/pr-4027/architecture/attestation","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/architecture/attestation.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Microservices","permalink":"/constellation/pr-preview/pr-4027/architecture/microservices"},"next":{"title":"Images","permalink":"/constellation/pr-preview/pr-4027/architecture/images"}}');var i=n(74848),r=n(28453);const o={},a="Attestation",d={},l=[{value:"Terms",id:"terms",level:2},{value:"Trusted Platform Module (TPM)",id:"trusted-platform-module-tpm",level:3},{value:"Runtime measurement",id:"runtime-measurement",level:3},{value:"Platform Configuration Register (PCR)",id:"platform-configuration-register-pcr",level:3},{value:"Measured boot",id:"measured-boot",level:3},{value:"Remote attestation (RA)",id:"remote-attestation-ra",level:3},{value:"Confidential virtual machine (CVM)",id:"confidential-virtual-machine-cvm",level:3},{value:"Attested TLS (aTLS)",id:"attested-tls-atls",level:3},{value:"Overview",id:"overview",level:2},{value:"Node attestation",id:"node-attestation",level:2},{value:"Runtime measurements",id:"runtime-measurements",level:3},{value:"CVM verification",id:"cvm-verification",level:3},{value:"Cluster attestation",id:"cluster-attestation",level:2},{value:"Cluster-facing attestation",id:"cluster-facing-attestation",level:3},{value:"User-facing attestation",id:"user-facing-attestation",level:3},{value:"Putting it all together",id:"putting-it-all-together",level:2},{value:"CLI and node images",id:"cli-and-node-images",level:3},{value:"Cluster creation",id:"cluster-creation",level:3},{value:"Chain of trust",id:"chain-of-trust",level:3},{value:"Upgrades",id:"upgrades",level:3},{value:"References",id:"references",level:2}];function c(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",mermaid:"mermaid",ol:"ol",p:"p",pre:"pre",section:"section",strong:"strong",sup:"sup",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components},{TabItem:n,Tabs:s}=t;return n||u("TabItem",!0),s||u("Tabs",!0),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"attestation",children:"Attestation"})}),"\n",(0,i.jsx)(t.p,{children:"This page explains Constellation's attestation process and highlights the cornerstones of its trust model."}),"\n",(0,i.jsx)(t.h2,{id:"terms",children:"Terms"}),"\n",(0,i.jsx)(t.p,{children:"The following lists terms and concepts that help to understand the attestation concept of Constellation."}),"\n",(0,i.jsx)(t.h3,{id:"trusted-platform-module-tpm",children:"Trusted Platform Module (TPM)"}),"\n",(0,i.jsxs)(t.p,{children:["A TPM chip is a dedicated tamper-resistant crypto-processor.\nIt can securely store artifacts such as passwords, certificates, encryption keys, or ",(0,i.jsx)(t.em,{children:"runtime measurements"})," (more on this below).\nWhen a TPM is implemented in software, it's typically called a ",(0,i.jsx)(t.em,{children:"virtual"})," TPM (vTPM)."]}),"\n",(0,i.jsx)(t.h3,{id:"runtime-measurement",children:"Runtime measurement"}),"\n",(0,i.jsxs)(t.p,{children:["A runtime measurement is a cryptographic hash of the memory pages of a so called ",(0,i.jsx)(t.em,{children:"runtime component"}),". Runtime components of interest typically include a system's bootloader or OS kernel."]}),"\n",(0,i.jsx)(t.h3,{id:"platform-configuration-register-pcr",children:"Platform Configuration Register (PCR)"}),"\n",(0,i.jsx)(t.p,{children:"A Platform Configuration Register (PCR) is a memory location in the TPM that has some unique properties.\nTo store a new value in a PCR, the existing value is extended with a new value as follows:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"PCR[N] = HASHalg( PCR[N] || ArgumentOfExtend )\n"})}),"\n",(0,i.jsx)(t.p,{children:"The PCRs are typically used to store runtime measurements.\nThe new value of a PCR is always an extension of the existing value.\nThus, storing the measurements of multiple components into the same PCR irreversibly links them together."}),"\n",(0,i.jsx)(t.h3,{id:"measured-boot",children:"Measured boot"}),"\n",(0,i.jsx)(t.p,{children:"Measured boot builds on the concept of chained runtime measurements.\nEach component in the boot chain loads and measures the next component into the PCR before executing it.\nBy comparing the resulting PCR values against trusted reference values, the integrity of the entire boot chain and thereby the running system can be ensured."}),"\n",(0,i.jsx)(t.h3,{id:"remote-attestation-ra",children:"Remote attestation (RA)"}),"\n",(0,i.jsx)(t.p,{children:"Remote attestation is the process of verifying certain properties of an application or platform, such as integrity and confidentiality, from a remote location.\nIn the case of a measured boot, the goal is to obtain a signed attestation statement on the PCR values of the boot measurements.\nThe statement can then be verified and compared to a set of trusted reference values.\nThis way, the integrity of the platform can be ensured before sharing secrets with it."}),"\n",(0,i.jsx)(t.h3,{id:"confidential-virtual-machine-cvm",children:"Confidential virtual machine (CVM)"}),"\n",(0,i.jsx)(t.p,{children:"Confidential computing (CC) is the protection of data in-use with hardware-based trusted execution environments (TEEs).\nWith CVMs, TEEs encapsulate entire virtual machines and isolate them against the hypervisor, other VMs, and direct memory access.\nAfter loading the initial VM image into encrypted memory, the hypervisor calls for a secure processor to measure these initial memory pages.\nThe secure processor locks these pages and generates an attestation report on the initial page measurements.\nCVM memory pages are encrypted with a key that resides inside the secure processor, which makes sure only the guest VM can access them.\nThe attestation report is signed by the secure processor and can be verified using remote attestation via the certificate authority of the hardware vendor.\nSuch an attestation statement guarantees the confidentiality and integrity of a CVM."}),"\n",(0,i.jsx)(t.h3,{id:"attested-tls-atls",children:"Attested TLS (aTLS)"}),"\n",(0,i.jsx)(t.p,{children:"In a CC environment, attested TLS (aTLS) can be used to establish secure connections between two parties using the remote attestation features of the CC components."}),"\n",(0,i.jsx)(t.p,{children:"aTLS modifies the TLS handshake by embedding an attestation statement into the TLS certificate.\nInstead of relying on a certificate authority, aTLS uses this attestation statement to establish trust in the certificate."}),"\n",(0,i.jsx)(t.p,{children:"The protocol can be used by clients to verify a server certificate, by a server to verify a client certificate, or for mutual verification (mutual aTLS)."}),"\n",(0,i.jsx)(t.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsx)(t.p,{children:"The challenge for Constellation is to lift a CVM's attestation statement to the Kubernetes software layer and make it end-to-end verifiable.\nFrom there, Constellation needs to expand the attestation from a single CVM to the entire cluster."}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#joinservice",children:(0,i.jsx)(t.em,{children:"JoinService"})})," and ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#verificationservice",children:(0,i.jsx)(t.em,{children:"VerificationService"})})," are where all runs together.\nInternally, the ",(0,i.jsx)(t.em,{children:"JoinService"})," uses remote attestation to securely join CVM nodes to the cluster.\nExternally, the ",(0,i.jsx)(t.em,{children:"VerificationService"})," provides an attestation statement for the cluster's CVMs and configuration."]}),"\n",(0,i.jsx)(t.p,{children:"The following explains the details of both steps."}),"\n",(0,i.jsx)(t.h2,{id:"node-attestation",children:"Node attestation"}),"\n",(0,i.jsx)(t.p,{children:"The idea is that Constellation nodes should have verifiable integrity from the CVM hardware measurement up to the Kubernetes software layer.\nThe solution is a verifiable boot chain and an integrity-protected runtime environment."}),"\n",(0,i.jsxs)(t.p,{children:["Constellation uses measured boot within CVMs, measuring each component in the boot process before executing it.\nOutside of CC, this is usually implemented via TPMs.\nCVM technologies differ in how they implement runtime measurements, but the general concepts are similar to those of a TPM.\nFor simplicity, TPM terminology like ",(0,i.jsx)(t.em,{children:"PCR"})," is used in the following."]}),"\n",(0,i.jsxs)(t.p,{children:["When a Constellation node image boots inside a CVM, measured boot is used for all stages and components of the boot chain.\nThis process goes up to the root filesystem.\nThe root filesystem is mounted read-only with integrity protection.\nFor the details on the image and boot stages see the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/images",children:"image architecture"})," documentation.\nAny changes to the image will inevitably also change the corresponding PCR values.\nTo create a node attestation statement, the Constellation image obtains a CVM attestation statement from the hardware.\nThis includes the runtime measurements and thereby binds the measured boot results to the CVM hardware measurement."]}),"\n",(0,i.jsxs)(t.p,{children:["In addition to the image measurements, Constellation extends a PCR during the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/create",children:"initialization phase"})," that irrevocably marks the node as initialized.\nThe measurement is created using the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys#cluster-identity",children:(0,i.jsx)(t.em,{children:"clusterID"})}),", tying all future attestation statements to this ID.\nThereby, an attestation statement is unique for every cluster and a node can be identified unambiguously as being initialized."]}),"\n",(0,i.jsxs)(t.p,{children:["To verify an attestation, the hardware's signature and a statement are verified first to establish trust in the contained runtime measurements.\nIf successful, the measurements are verified against the trusted values of the particular Constellation release version.\nFinally, the measurement of the ",(0,i.jsx)(t.em,{children:"clusterID"})," can be compared by calculating it with the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys#master-secret",children:"master secret"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"runtime-measurements",children:"Runtime measurements"}),"\n",(0,i.jsx)(t.p,{children:"Constellation uses runtime measurements to implement the measured boot approach.\nAs stated above, the underlying hardware technology and guest firmware differ in their implementations of runtime measurements.\nThe following gives a detailed description of the available measurements in the different cloud environments."}),"\n",(0,i.jsx)(t.p,{children:"The runtime measurements consist of two types of values:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Measurements produced by the cloud infrastructure and firmware of the CVM"}),":\nThese are measurements of closed-source firmware and other values controlled by the cloud provider.\nWhile not being reproducible for the user, some of them can be compared against previously observed values.\nOthers may change frequently and aren't suitable for verification.\nThe ",(0,i.jsx)(t.a,{href:"#chain-of-trust",children:"signed image measurements"})," include measurements that are known, previously observed values."]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Measurements produced by the Constellation bootloader and boot chain"}),":\nThe Constellation Bootloader takes over from the CVM firmware and ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/images",children:"measures the rest of the boot chain"}),".\nThe Constellation ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#bootstrapper",children:"Bootstrapper"})," is the first user mode component that runs in a Constellation image.\nIt extends PCR registers with the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys#cluster-identity",children:"IDs"})," of the cluster marking a node as initialized."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Constellation allows to specify in the config which measurements should be enforced during the attestation process.\nEnforcing non-reproducible measurements controlled by the cloud provider means that changes in these values require manual updates to the cluster's config.\nBy default, Constellation only enforces measurements that are stable values produced by the infrastructure or by Constellation directly."}),"\n",(0,i.jsxs)(s,{groupId:"csp",children:[(0,i.jsxs)(n,{value:"aws",label:"AWS",children:[(0,i.jsxs)(t.p,{children:["Constellation uses the ",(0,i.jsx)(t.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nitrotpm.html",children:"vTPM"})," (NitroTPM) feature of the ",(0,i.jsx)(t.a,{href:"http://aws.amazon.com/ec2/nitro/",children:"AWS Nitro System"})," on AWS for runtime measurements."]}),(0,i.jsxs)(t.p,{children:["The vTPM adheres to the ",(0,i.jsx)(t.a,{href:"https://trustedcomputinggroup.org/resource/tpm-library-specification/",children:"TPM 2.0"})," specification.\nThe VMs are attested by obtaining signed PCR values over the VM's boot configuration from the TPM and comparing them to a known, good state (measured boot)."]}),(0,i.jsx)(t.p,{children:"The following table lists all PCR values of the vTPM and the measured components.\nIt also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable.\nThe latter means that the value can be generated offline and compared to the one in the vTPM."}),(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"PCR"}),(0,i.jsx)(t.th,{children:"Components"}),(0,i.jsx)(t.th,{children:"Measured by"}),(0,i.jsx)(t.th,{children:"Reproducible and verifiable"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"0"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"2"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"3"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"4"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader, Kernel, initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"AWS, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"5"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"6"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"7"}),(0,i.jsx)(t.td,{children:"Secure Boot Policy"}),(0,i.jsx)(t.td,{children:"AWS, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"8"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"9"}),(0,i.jsx)(t.td,{children:"initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Linux Kernel"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10"}),(0,i.jsx)(t.td,{children:"User space"}),(0,i.jsx)(t.td,{children:"Linux IMA"}),(0,i.jsxs)(t.td,{children:["No",(0,i.jsx)(t.sup,{children:(0,i.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"11"}),(0,i.jsx)(t.td,{children:"Unified Kernel Image components"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"12"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(User space, Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"13"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"14"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"15"}),(0,i.jsx)(t.td,{children:"ClusterID"}),(0,i.jsx)(t.td,{children:"Constellation Bootstrapper"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"16\u201323"}),(0,i.jsx)(t.td,{children:"Unused"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]})]})]})]}),(0,i.jsxs)(n,{value:"azure",label:"Azure",children:[(0,i.jsxs)(t.p,{children:["Constellation uses the ",(0,i.jsx)(t.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/trusted-launch#vtpm",children:"vTPM"})," feature of Azure CVMs for runtime measurements.\nThis vTPM adheres to the ",(0,i.jsx)(t.a,{href:"https://trustedcomputinggroup.org/resource/tpm-library-specification/",children:"TPM 2.0"})," specification.\nIt provides a ",(0,i.jsx)(t.a,{href:"https://docs.microsoft.com/en-us/azure/security/fundamentals/measured-boot-host-attestation#measured-boot",children:"measured boot"})," verification that's based on the trusted launch feature of ",(0,i.jsx)(t.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/trusted-launch",children:"Trusted Launch VMs"}),"."]}),(0,i.jsx)(t.p,{children:"The following table lists all PCR values of the vTPM and the measured components.\nIt also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable.\nThe latter means that the value can be generated offline and compared to the one in the vTPM."}),(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"PCR"}),(0,i.jsx)(t.th,{children:"Components"}),(0,i.jsx)(t.th,{children:"Measured by"}),(0,i.jsx)(t.th,{children:"Reproducible and verifiable"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"0"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"2"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"3"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"4"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader, Kernel, initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Azure, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"5"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"6"}),(0,i.jsx)(t.td,{children:"VM Unique ID"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"7"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Azure, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"8"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"9"}),(0,i.jsx)(t.td,{children:"initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Linux Kernel"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10"}),(0,i.jsx)(t.td,{children:"User space"}),(0,i.jsx)(t.td,{children:"Linux IMA"}),(0,i.jsxs)(t.td,{children:["No",(0,i.jsx)(t.sup,{children:(0,i.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"11"}),(0,i.jsx)(t.td,{children:"Unified Kernel Image components"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"12"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(User space, Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"13"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"14"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"15"}),(0,i.jsx)(t.td,{children:"ClusterID"}),(0,i.jsx)(t.td,{children:"Constellation Bootstrapper"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"16\u201323"}),(0,i.jsx)(t.td,{children:"Unused"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]})]})]})]}),(0,i.jsxs)(n,{value:"gcp",label:"GCP",children:[(0,i.jsxs)(t.p,{children:["Constellation uses the ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/compute/confidential-vm/docs/about-cvm",children:"vTPM"})," feature of CVMs on GCP for runtime measurements.\nNote that this vTPM doesn't run inside the hardware-protected CVM context, but is emulated by the hypervisor."]}),(0,i.jsxs)(t.p,{children:["The vTPM adheres to the ",(0,i.jsx)(t.a,{href:"https://trustedcomputinggroup.org/resource/tpm-library-specification/",children:"TPM 2.0"})," specification.\nIt provides a ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/compute/confidential-vm/docs/monitoring#about_launch_attestation_report_events",children:"launch attestation report"})," that's based on the measured boot feature of ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/compute/shielded-vm/docs/shielded-vm#measured-boot",children:"Shielded VMs"}),"."]}),(0,i.jsx)(t.p,{children:"The following table lists all PCR values of the vTPM and the measured components.\nIt also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable.\nThe latter means that the value can be generated offline and compared to the one in the vTPM."}),(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"PCR"}),(0,i.jsx)(t.th,{children:"Components"}),(0,i.jsx)(t.th,{children:"Measured by"}),(0,i.jsx)(t.th,{children:"Reproducible and verifiable"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"0"}),(0,i.jsx)(t.td,{children:"CVM version and technology"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"2"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"3"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"4"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader, Kernel, initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"GCP, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"5"}),(0,i.jsx)(t.td,{children:"Disk GUID partition table"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"6"}),(0,i.jsx)(t.td,{children:"Disk GUID partition table"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"7"}),(0,i.jsx)(t.td,{children:"GCP Secure Boot Policy"}),(0,i.jsx)(t.td,{children:"GCP, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"8"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"9"}),(0,i.jsx)(t.td,{children:"initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Linux Kernel"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10"}),(0,i.jsx)(t.td,{children:"User space"}),(0,i.jsx)(t.td,{children:"Linux IMA"}),(0,i.jsxs)(t.td,{children:["No",(0,i.jsx)(t.sup,{children:(0,i.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"11"}),(0,i.jsx)(t.td,{children:"Unified Kernel Image components"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"12"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(User space, Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"13"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"14"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"15"}),(0,i.jsx)(t.td,{children:"ClusterID"}),(0,i.jsx)(t.td,{children:"Constellation Bootstrapper"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"16\u201323"}),(0,i.jsx)(t.td,{children:"Unused"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]})]})]})]}),(0,i.jsxs)(n,{value:"stackit",label:"STACKIT",children:[(0,i.jsx)(t.p,{children:"Constellation uses a hypervisor-based vTPM for runtime measurements."}),(0,i.jsxs)(t.p,{children:["The vTPM adheres to the ",(0,i.jsx)(t.a,{href:"https://trustedcomputinggroup.org/resource/tpm-library-specification/",children:"TPM 2.0"})," specification.\nThe VMs are attested by obtaining signed PCR values over the VM's boot configuration from the TPM and comparing them to a known, good state (measured boot)."]}),(0,i.jsx)(t.p,{children:"The following table lists all PCR values of the vTPM and the measured components.\nIt also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable.\nThe latter means that the value can be generated offline and compared to the one in the vTPM."}),(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"PCR"}),(0,i.jsx)(t.th,{children:"Components"}),(0,i.jsx)(t.th,{children:"Measured by"}),(0,i.jsx)(t.th,{children:"Reproducible and verifiable"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"0"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"2"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"3"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"4"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader, Kernel, initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"STACKIT, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"5"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"6"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"7"}),(0,i.jsx)(t.td,{children:"Secure Boot Policy"}),(0,i.jsx)(t.td,{children:"STACKIT, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"8"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"9"}),(0,i.jsx)(t.td,{children:"initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Linux Kernel"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10"}),(0,i.jsx)(t.td,{children:"User space"}),(0,i.jsx)(t.td,{children:"Linux IMA"}),(0,i.jsxs)(t.td,{children:["No",(0,i.jsx)(t.sup,{children:(0,i.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"11"}),(0,i.jsx)(t.td,{children:"Unified Kernel Image components"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"12"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(User space, Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"13"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"14"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"15"}),(0,i.jsx)(t.td,{children:"ClusterID"}),(0,i.jsx)(t.td,{children:"Constellation Bootstrapper"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"16\u201323"}),(0,i.jsx)(t.td,{children:"Unused"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]})]})]})]})]}),"\n",(0,i.jsx)(t.h3,{id:"cvm-verification",children:"CVM verification"}),"\n",(0,i.jsx)(t.p,{children:"To verify the integrity of the received attestation statement, a chain of trust from the CVM technology to the interface providing the statement has to be established.\nFor verification of the CVM technology, Constellation may expose additional options in its config file."}),"\n",(0,i.jsxs)(s,{groupId:"csp",children:[(0,i.jsxs)(n,{value:"aws",label:"AWS",children:[(0,i.jsx)(t.p,{children:"On AWS, AMD SEV-SNP is used to provide runtime encryption to the VMs.\nAn SEV-SNP attestation report is used to establish trust in the VM.\nYou may customize certain parameters for verification of the attestation statement using the Constellation config file."}),(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"TCB versions"}),"\n",(0,i.jsx)(t.p,{children:"You can set the minimum version numbers of components in the SEV-SNP TCB.\nUse the latest versions to enforce that only machines with the most recent firmware updates are allowed to join the cluster.\nAlternatively, you can set a lower minimum version to allow slightly out-of-date machines to still be able to join the cluster."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Root Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This certificate is the root of trust for verifying the SEV-SNP certificate chain."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Signing Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This is the intermediate certificate for verifying the SEV-SNP report's signature.\nIf it's not specified, the CLI fetches it from the AMD key distribution server."}),"\n"]}),"\n"]})]}),(0,i.jsxs)(n,{value:"azure",label:"Azure SEV-SNP",children:[(0,i.jsx)(t.p,{children:"On Azure, AMD SEV-SNP is used to provide runtime encryption to the VMs.\nAn SEV-SNP attestation report is used to establish trust in the vTPM running inside the VM.\nYou may customize certain parameters for verification of the attestation statement using the Constellation config file."}),(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"TCB versions"}),"\n",(0,i.jsx)(t.p,{children:"You can set the minimum version numbers of components in the SEV-SNP TCB.\nUse the latest versions to enforce that only machines with the most recent firmware updates are allowed to join the cluster.\nAlternatively, you can set a lower minimum version to allow slightly out-of-date machines to still be able to join the cluster."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Root Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This certificate is the root of trust for verifying the SEV-SNP certificate chain."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"Firmware Signer"}),"\n",(0,i.jsxs)(t.p,{children:["This config option allows you to specify how the firmware signer should be verified.\nMore explicitly, it controls the verification of the ",(0,i.jsx)(t.code,{children:"IDKeyDigest"})," value in the SEV-SNP attestation report.\nYou can provide a list of accepted key digests and specify a policy on how this list is compared against the reported ",(0,i.jsx)(t.code,{children:"IDKeyDigest"}),"."]}),"\n"]}),"\n"]})]}),(0,i.jsxs)(n,{value:"gcp",label:"GCP",children:[(0,i.jsx)(t.p,{children:"On GCP, AMD SEV-SNP is used to provide runtime encryption to the VMs.\nAn SEV-SNP attestation report is used to establish trust in the VM.\nYou may customize certain parameters for verification of the attestation statement using the Constellation config file."}),(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"TCB versions"}),"\n",(0,i.jsx)(t.p,{children:"You can set the minimum version numbers of components in the SEV-SNP TCB.\nUse the latest versions to enforce that only machines with the most recent firmware updates are allowed to join the cluster.\nAlternatively, you can set a lower minimum version to allow slightly out-of-date machines to still be able to join the cluster."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Root Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This certificate is the root of trust for verifying the SEV-SNP certificate chain."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Signing Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This is the intermediate certificate for verifying the SEV-SNP report's signature.\nIf it's not specified, the CLI fetches it from the AMD key distribution server."}),"\n"]}),"\n"]})]}),(0,i.jsx)(n,{value:"stackit",label:"STACKIT",children:(0,i.jsxs)(t.p,{children:["On STACKIT, AMD SEV-ES is used to provide runtime encryption to the VMs.\nThe hypervisor-based vTPM is used to establish trust in the VM via ",(0,i.jsx)(t.a,{href:"#runtime-measurements",children:"runtime measurements"}),".\nThere is no additional configuration available for STACKIT."]})})]}),"\n",(0,i.jsx)(t.h2,{id:"cluster-attestation",children:"Cluster attestation"}),"\n",(0,i.jsxs)(t.p,{children:["Cluster-facing, Constellation's ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#joinservice",children:(0,i.jsx)(t.em,{children:"JoinService"})})," verifies each node joining the cluster given the configured ground truth runtime measurements.\nUser-facing, the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#verificationservice",children:(0,i.jsx)(t.em,{children:"VerificationService"})})," provides an interface to verify a node using remote attestation.\nBy verifying the first node during the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#bootstrapper",children:"initialization"})," and configuring the ground truth measurements that are subsequently enforced by the ",(0,i.jsx)(t.em,{children:"JoinService"}),", the whole cluster is verified in a transitive way."]}),"\n",(0,i.jsx)(t.h3,{id:"cluster-facing-attestation",children:"Cluster-facing attestation"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"JoinService"})," is provided with the runtime measurements of the whitelisted Constellation image version as the ground truth.\nDuring the initialization and the cluster bootstrapping, each node connects to the ",(0,i.jsx)(t.em,{children:"JoinService"})," using ",(0,i.jsx)(t.a,{href:"#attested-tls-atls",children:"aTLS"}),".\nDuring the handshake, the node transmits an attestation statement including its runtime measurements.\nThe ",(0,i.jsx)(t.em,{children:"JoinService"})," verifies that statement and compares the measurements against the ground truth.\nFor details of the initialization process check the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices",children:"microservice descriptions"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["After the initialization, every node updates its runtime measurements with the ",(0,i.jsx)(t.em,{children:"clusterID"})," value, marking it irreversibly as initialized.\nWhen an initialized node tries to join another cluster, its measurements inevitably mismatch the measurements of an uninitialized node and it will be declined."]}),"\n",(0,i.jsx)(t.h3,{id:"user-facing-attestation",children:"User-facing attestation"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#verificationservice",children:(0,i.jsx)(t.em,{children:"VerificationService"})})," provides an endpoint for obtaining its hardware-based remote attestation statement, which includes the runtime measurements.\nA user can ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/verify-cluster",children:"verify"})," this statement and compare the measurements against the configured ground truth and, thus, verify the identity and integrity of all Constellation components and the cluster configuration. Subsequently, the user knows that the entire cluster is in the expected state and is trustworthy."]}),"\n",(0,i.jsx)(t.h2,{id:"putting-it-all-together",children:"Putting it all together"}),"\n",(0,i.jsx)(t.p,{children:"This section puts the aforementioned concepts together and illustrate how trust into a Constellation cluster is established and maintained."}),"\n",(0,i.jsx)(t.h3,{id:"cli-and-node-images",children:"CLI and node images"}),"\n",(0,i.jsxs)(t.p,{children:["It all starts with the CLI executable. The CLI is signed by Edgeless Systems. To ensure non-repudiability for CLI releases, Edgeless Systems publishes corresponding signatures to the public ledger of the ",(0,i.jsx)(t.a,{href:"https://www.sigstore.dev/",children:"sigstore project"}),". There's a ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/verify-cli",children:"step-by-step guide"})," on how to verify CLI signatures based on sigstore."]}),"\n",(0,i.jsxs)(t.p,{children:["The CLI contains the latest runtime measurements of the Constellation node image for all supported cloud platforms. In case a different version of the node image is to be used, the corresponding runtime measurements can be fetched using the CLI's ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/reference/cli#constellation-config-fetch-measurements",children:"fetch-measurements command"}),". This command downloads the runtime measurements and the corresponding signature from cdn.confidential.cloud. See for example the following files corresponding to node image v2.16.3:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://cdn.confidential.cloud/constellation/v2/ref/-/stream/stable/v2.16.3/image/measurements.json",children:"Measurements"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://cdn.confidential.cloud/constellation/v2/ref/-/stream/stable/v2.16.3/image/measurements.json.sig",children:"Signature"})}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"The CLI contains the long-term public key of Edgeless Systems to verify the signature of downloaded runtime measurements."}),"\n",(0,i.jsx)(t.h3,{id:"cluster-creation",children:"Cluster creation"}),"\n",(0,i.jsxs)(t.p,{children:["When a cluster is ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/create",children:"created"}),", the CLI automatically verifies the runtime measurements of the ",(0,i.jsx)(t.em,{children:"first node"})," using remote attestation. Based on this, the CLI and the first node set up a temporary TLS connection. This ",(0,i.jsx)(t.a,{href:"#attested-tls-atls",children:"aTLS"})," connection is used for two things:"]}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["The CLI sends the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys#master-secret",children:"master secret"})," of the to-be-created cluster to the CLI. The master secret is generated by the first node."]}),"\n",(0,i.jsxs)(t.li,{children:["The first node sends a ",(0,i.jsx)(t.a,{href:"https://www.redhat.com/sysadmin/kubeconfig",children:"kubeconfig file"})," with Kubernetes credentials to the CLI."]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["After this, the aTLS connection is closed and the first node bootstraps the Kubernetes cluster. All subsequent interactions between the CLI and the cluster go via the ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/overview/kubernetes-api/",children:"Kubernetes API"})," server running inside the cluster. The CLI (and other tools like kubectl) use the credentials referenced by the kubeconfig file to authenticate themselves towards the Kubernetes API server and to establish a mTLS connection."]}),"\n",(0,i.jsx)(t.p,{children:"The CLI connects to the Kubernetes API to write the runtime measurements for the applicable node image to etcd. The JoinService uses these runtime measurements to verify all nodes that join the cluster subsequently."}),"\n",(0,i.jsx)(t.h3,{id:"chain-of-trust",children:"Chain of trust"}),"\n",(0,i.jsx)(t.p,{children:"In summary, there's a chain of trust based on cryptographic signatures that goes from the user to the cluster via the CLI. This is illustrated in the following diagram."}),"\n",(0,i.jsx)(t.mermaid,{value:'flowchart LR\n A[User]-- "verifies" --\x3eB[CLI]\n B[CLI]-- "verifies" --\x3eC([Runtime measurements])\n D[Edgeless Systems]-- "signs" --\x3eB[CLI]\n D[Edgeless Systems]-- "signs" --\x3eC([Runtime measurements])\n B[CLI]-- "verifies (remote attestation)" --\x3eE[First node]\n E[First node]-- "verifies (remote attestation)" --\x3eF[Other nodes]\n C([Runtime measurements]) -.-> E[First node]\n C([Runtime measurements]) -.-> F[Other nodes]'}),"\n",(0,i.jsx)(t.h3,{id:"upgrades",children:"Upgrades"}),"\n",(0,i.jsxs)(t.p,{children:["Whenever a cluster is ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/upgrade",children:"upgraded"})," to a new version of the node image, the CLI sends the corresponding runtime measurements via the Kubernetes API server. The new runtime measurements are stored in etcd within the cluster and replace any previous runtime measurements. The new runtime measurements are then used automatically by the JoinService for the verification of new nodes."]}),"\n",(0,i.jsx)(t.h2,{id:"references",children:"References"}),"\n","\n",(0,i.jsxs)(t.section,{"data-footnotes":!0,className:"footnotes",children:[(0,i.jsx)(t.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{id:"user-content-fn-1",children:["\n",(0,i.jsxs)(t.p,{children:["Linux IMA produces runtime measurements of user-space binaries.\nHowever, these measurements aren't deterministic and thus, PCR[10] can't be compared to a constant value.\nInstead, a policy engine must be used to verify the TPM event log against a policy. ",(0,i.jsx)(t.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})," ",(0,i.jsxs)(t.a,{href:"#user-content-fnref-1-2","data-footnote-backref":"","aria-label":"Back to reference 1-2",className:"data-footnote-backref",children:["\u21a9",(0,i.jsx)(t.sup,{children:"2"})]})," ",(0,i.jsxs)(t.a,{href:"#user-content-fnref-1-3","data-footnote-backref":"","aria-label":"Back to reference 1-3",className:"data-footnote-backref",children:["\u21a9",(0,i.jsx)(t.sup,{children:"3"})]})," ",(0,i.jsxs)(t.a,{href:"#user-content-fnref-1-4","data-footnote-backref":"","aria-label":"Back to reference 1-4",className:"data-footnote-backref",children:["\u21a9",(0,i.jsx)(t.sup,{children:"4"})]})]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}function u(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3b1b22d5.476e1074.js b/pr-preview/pr-4027/assets/js/3b1b22d5.476e1074.js deleted file mode 100644 index 156cf1c89..000000000 --- a/pr-preview/pr-4027/assets/js/3b1b22d5.476e1074.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3456],{28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>i});var o=n(96540);const s={},a=o.createContext(s);function r(e){const t=o.useContext(a);return o.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(a.Provider,{value:t},e.children)}},81788:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>r,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"workflows/cert-manager","title":"Install cert-manager","description":"If you want to use cert-manager with Constellation, pay attention to the following to avoid potential pitfalls.","source":"@site/versioned_docs/version-2.22/workflows/cert-manager.md","sourceDirName":"workflows","slug":"/workflows/cert-manager","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/cert-manager","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/workflows/cert-manager.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Expose a service","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/lb"},"next":{"title":"Install s3proxy","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/s3proxy"}}');var s=n(74848),a=n(28453);const r={},i="Install cert-manager",l={},c=[];function d(e){const t={admonition:"admonition",code:"code",h1:"h1",header:"header",p:"p",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"install-cert-manager",children:"Install cert-manager"})}),"\n",(0,s.jsx)(t.admonition,{type:"caution",children:(0,s.jsx)(t.p,{children:"If you want to use cert-manager with Constellation, pay attention to the following to avoid potential pitfalls."})}),"\n",(0,s.jsxs)(t.p,{children:["Constellation ships with cert-manager preinstalled.\nThe default installation is part of the ",(0,s.jsx)(t.code,{children:"kube-system"})," namespace, as all other Constellation-managed microservices.\nYou are free to install more instances of cert-manager into other namespaces.\nHowever, be aware that any new installation needs to use the same version as the one installed with Constellation or rely on the same CRD versions.\nAlso remember to set the ",(0,s.jsx)(t.code,{children:"installCRDs"})," value to ",(0,s.jsx)(t.code,{children:"false"})," when installing new cert-manager instances.\nIt will create problems if you have two installations of cert-manager depending on different versions of the installed CRDs.\nCRDs are cluster-wide resources and cert-manager depends on specific versions of those CRDs for each release."]})]})}function p(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3b28b3cc.94d205c2.js b/pr-preview/pr-4027/assets/js/3b28b3cc.94d205c2.js deleted file mode 100644 index 83ebf2aea..000000000 --- a/pr-preview/pr-4027/assets/js/3b28b3cc.94d205c2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8205],{27006:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"getting-started/first-steps-local","title":"First steps with a local cluster","description":"A local cluster lets you deploy and test Constellation without a cloud subscription.","source":"@site/docs/getting-started/first-steps-local.md","sourceDirName":"getting-started","slug":"/getting-started/first-steps-local","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/first-steps-local","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/getting-started/first-steps-local.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"First steps (cloud)","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/first-steps"},"next":{"title":"Cloud Marketplaces","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/marketplaces"}}');var l=s(74848),i=s(28453);const o={},r="First steps with a local cluster",a={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Software installation on Ubuntu",id:"software-installation-on-ubuntu",level:3},{value:"Create a cluster",id:"create-a-cluster",level:2},{value:"Connect to the cluster",id:"connect-to-the-cluster",level:2},{value:"Deploy a sample application",id:"deploy-a-sample-application",level:2},{value:"Terminate your cluster",id:"terminate-your-cluster",level:2},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"VMs have no internet access / CLI remains in "Initializing cluster" state",id:"vms-have-no-internet-access--cli-remains-in-initializing-cluster-state",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components},{TabItem:s,Tabs:t}=n;return s||h("TabItem",!0),t||h("Tabs",!0),(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"first-steps-with-a-local-cluster",children:"First steps with a local cluster"})}),"\n",(0,l.jsx)(n.p,{children:"A local cluster lets you deploy and test Constellation without a cloud subscription.\nYou have two options:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Use MiniConstellation to automatically deploy a two-node cluster."}),"\n",(0,l.jsx)(n.li,{children:"For more fine-grained control, create the cluster using the QEMU provider."}),"\n"]}),"\n",(0,l.jsxs)(n.p,{children:["Both options use virtualization to create a local cluster with control-plane nodes and worker nodes. They ",(0,l.jsx)(n.strong,{children:"don't"})," require hardware with Confidential VM (CVM) support. For attestation, they currently use a software-based vTPM provided by KVM/QEMU."]}),"\n",(0,l.jsx)(n.p,{children:"You need an x64 machine with a Linux OS.\nYou can use a VM, but it needs nested virtualization."}),"\n",(0,l.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Machine requirements:","\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"An x86-64 CPU with at least 4 cores (6 cores are recommended)"}),"\n",(0,l.jsx)(n.li,{children:"At least 4 GB RAM (6 GB are recommended)"}),"\n",(0,l.jsx)(n.li,{children:"20 GB of free disk space"}),"\n",(0,l.jsx)(n.li,{children:"Hardware virtualization enabled in the BIOS/UEFI (often referred to as Intel VT-x or AMD-V/SVM) / nested-virtualization support when using a VM"}),"\n"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["Software requirements:","\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Linux OS with ",(0,l.jsx)(n.a,{href:"https://www.linux-kvm.org/page/Main_Page",children:"KVM kernel module"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Recommended: Ubuntu 22.04 LTS"}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://docs.docker.com/engine/install/",children:"Docker"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://gitlab.gnome.org/GNOME/libxslt/-/wikis/home",children:"xsltproc"})}),"\n",(0,l.jsxs)(n.li,{children:["(Optional) ",(0,l.jsx)(n.a,{href:"https://www.libvirt.org/manpages/virsh.html",children:"virsh"})," to observe and access your nodes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"software-installation-on-ubuntu",children:"Software installation on Ubuntu"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:'# install Docker\ncurl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg\necho "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null\nsudo apt update\nsudo apt install docker-ce\n# install other dependencies\nsudo apt install xsltproc\nsudo snap install kubectl --classic\n# install Constellation CLI\ncurl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-amd64\nsudo install constellation-linux-amd64 /usr/local/bin/constellation\n# do not drop forwarded packages\nsudo iptables -P FORWARD ACCEPT\n'})}),"\n",(0,l.jsx)(n.h2,{id:"create-a-cluster",children:"Create a cluster"}),"\n",(0,l.jsxs)(t,{groupId:"csp",children:[(0,l.jsxs)(s,{value:"mini",label:"MiniConstellation",children:[(0,l.jsxs)(n.p,{children:["With the ",(0,l.jsx)(n.code,{children:"constellation mini"})," command, you can deploy and test Constellation locally. This mode is called MiniConstellation. Conceptually, MiniConstellation is similar to ",(0,l.jsx)(n.a,{href:"https://microk8s.io/",children:"MicroK8s"}),", ",(0,l.jsx)(n.a,{href:"https://k3s.io/",children:"K3s"}),", and ",(0,l.jsx)(n.a,{href:"https://minikube.sigs.k8s.io/docs/",children:"minikube"}),"."]}),(0,l.jsx)(n.admonition,{type:"caution",children:(0,l.jsxs)(n.p,{children:["MiniConstellation has specific soft- and hardware requirements such as a Linux OS running on an x86-64 CPU. Pay attention to all ",(0,l.jsx)(n.a,{href:"#prerequisites",children:"prerequisites"})," when setting up."]})}),(0,l.jsx)(n.admonition,{type:"note",children:(0,l.jsx)(n.p,{children:"Since MiniConstellation runs on your local system, cloud features such as load balancing,\nattaching persistent storage, or autoscaling aren't available."})}),(0,l.jsx)(n.p,{children:"The following creates your MiniConstellation cluster (may take up to 10 minutes to complete):"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation mini up\n"})}),(0,l.jsxs)(n.p,{children:["This will configure your current directory as the ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/orchestration#workspaces",children:"workspace"})," for this cluster.\nAll ",(0,l.jsx)(n.code,{children:"constellation"})," commands concerning this cluster need to be issued from this directory."]})]}),(0,l.jsxs)(s,{value:"qemu",label:"QEMU",children:[(0,l.jsxs)(n.p,{children:["With the QEMU provider, you can create a local Constellation cluster as if it were in the cloud. The provider uses ",(0,l.jsx)(n.a,{href:"https://www.qemu.org/",children:"QEMU"})," to create multiple VMs for the cluster nodes, which interact with each other."]}),(0,l.jsx)(n.admonition,{type:"caution",children:(0,l.jsxs)(n.p,{children:["Constellation on QEMU has specific soft- and hardware requirements such as a Linux OS running on an x86-64 CPU. Pay attention to all ",(0,l.jsx)(n.a,{href:"#prerequisites",children:"prerequisites"})," when setting up."]})}),(0,l.jsx)(n.admonition,{type:"note",children:(0,l.jsx)(n.p,{children:"Since Constellation on QEMU runs on your local system, cloud features such as load balancing,\nattaching persistent storage, or autoscaling aren't available."})}),(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"To set up your local cluster, you need to create a configuration file for Constellation first."}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation config generate qemu\n"})}),(0,l.jsxs)(n.p,{children:["This creates a ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/config",children:"configuration file"})," for QEMU called ",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"}),". After that, your current folder also becomes your ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/orchestration#workspaces",children:"workspace"}),". All ",(0,l.jsx)(n.code,{children:"constellation"})," commands for your cluster need to be executed from this directory."]}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["Now you can create your cluster and its nodes. ",(0,l.jsx)(n.code,{children:"constellation apply"})," uses the options set in ",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"}),"."]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation apply -y\n"})}),(0,l.jsx)(n.p,{children:"The Output should look like the following:"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:'$ constellation apply -y\nChecking for infrastructure changes\nThe following Constellation cluster will be created:\n 3 control-plane nodes of type 2-vCPUs will be created.\n 1 worker node of type 2-vCPUs will be created.\nCreating\nCloud infrastructure created successfully.\nYour Constellation master secret was successfully written to ./constellation-mastersecret.json\nConnecting\nInitializing cluster\nInstalling Kubernetes components\nYour Constellation cluster was successfully initialized.\n\nConstellation cluster identifier g6iMP5wRU1b7mpOz2WEISlIYSfdAhB0oNaOg6XEwKFY=\nKubernetes configuration constellation-admin.conf\n\nYou can now connect to your cluster by executing:\n export KUBECONFIG="$PWD/constellation-admin.conf"\n'})}),(0,l.jsxs)(n.p,{children:["The cluster's identifier will be different in your output.\nKeep ",(0,l.jsx)(n.code,{children:"constellation-mastersecret.json"})," somewhere safe.\nThis will allow you to ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/recovery",children:"recover your cluster"})," in case of a disaster."]}),(0,l.jsx)(n.admonition,{type:"info",children:(0,l.jsxs)(n.p,{children:["Depending on your setup, ",(0,l.jsx)(n.code,{children:"constellation apply"})," may take 10+ minutes to complete."]})}),(0,l.jsxs)(n.ol,{start:"3",children:["\n",(0,l.jsx)(n.li,{children:"Configure kubectl"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:'export KUBECONFIG="$PWD/constellation-admin.conf"\n'})})]})]}),"\n",(0,l.jsx)(n.h2,{id:"connect-to-the-cluster",children:"Connect to the cluster"}),"\n",(0,l.jsx)(n.p,{children:"Your cluster initially consists of a single control-plane node:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"$ kubectl get nodes\nNAME STATUS ROLES AGE VERSION\ncontrol-plane-0 Ready control-plane 66s v1.24.6\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Additional nodes will request to join the cluster shortly. Before each additional node is allowed to join the cluster, its state is verified using remote attestation by the ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#joinservice",children:"JoinService"}),".\nIf verification passes successfully, the new node receives keys and certificates to join the cluster."]}),"\n",(0,l.jsx)(n.p,{children:"You can follow this process by viewing the logs of the JoinService:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:'$ kubectl logs -n kube-system daemonsets/join-service -f\n{"level":"INFO","ts":"2022-10-14T09:32:20Z","caller":"cmd/main.go:48","msg":"Constellation Node Join Service","version":"2.1.0","cloudProvider":"qemu"}\n{"level":"INFO","ts":"2022-10-14T09:32:20Z","logger":"validator","caller":"watcher/validator.go:96","msg":"Updating expected measurements"}\n...\n'})}),"\n",(0,l.jsx)(n.p,{children:"Once all nodes have joined your cluster, it may take a couple of minutes for all resources to become available.\nYou can check on the state of your cluster by running the following:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"$ kubectl get nodes\nNAME STATUS ROLES AGE VERSION\ncontrol-plane-0 Ready control-plane 2m59s v1.24.6\nworker-0 Ready <none> 32s v1.24.6\n"})}),"\n",(0,l.jsx)(n.h2,{id:"deploy-a-sample-application",children:"Deploy a sample application"}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["Deploy the ",(0,l.jsx)(n.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"emojivoto app"})]}),"\n"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment\n"})}),"\n",(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsx)(n.li,{children:"Expose the frontend service locally"}),"\n"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments\nkubectl -n emojivoto port-forward svc/web-svc 8080:80 &\ncurl http://localhost:8080\nkill %1\n"})}),"\n",(0,l.jsx)(n.h2,{id:"terminate-your-cluster",children:"Terminate your cluster"}),"\n",(0,l.jsxs)(t,{groupId:"csp",children:[(0,l.jsxs)(s,{value:"mini",label:"MiniConstellation",children:[(0,l.jsx)(n.p,{children:"Once you are done, you can clean up the created resources using the following command:"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation mini down\n"})}),(0,l.jsxs)(n.p,{children:["This will destroy your cluster and clean up your workspace.\nThe VM image and cluster configuration file (",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"}),") will be kept and may be reused to create new clusters."]})]}),(0,l.jsxs)(s,{value:"qemu",label:"QEMU",children:[(0,l.jsx)(n.p,{children:"Once you are done, you can clean up the created resources using the following command:"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation terminate\n"})}),(0,l.jsx)(n.p,{children:"This should give the following output:"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"$ constellation terminate\nYou are about to terminate a Constellation cluster.\nAll of its associated resources will be DESTROYED.\nThis action is irreversible and ALL DATA WILL BE LOST.\nDo you want to continue? [y/n]:\n"})}),(0,l.jsxs)(n.p,{children:["Confirm with ",(0,l.jsx)(n.code,{children:"y"})," to terminate the cluster:"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"Terminating ...\nYour Constellation cluster was terminated successfully.\n"})}),(0,l.jsxs)(n.p,{children:["This will destroy your cluster and clean up your workspace.\nThe VM image and cluster configuration file (",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"}),") will be kept and may be reused to create new clusters."]})]})]}),"\n",(0,l.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,l.jsxs)(n.p,{children:["Make sure to use the ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/releases/latest",children:"latest release"})," and check out the ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"known issues"}),"."]}),"\n",(0,l.jsx)(n.h3,{id:"vms-have-no-internet-access--cli-remains-in-initializing-cluster-state",children:'VMs have no internet access / CLI remains in "Initializing cluster" state'}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:"iptables"})," rules may prevent your VMs from accessing the internet.\nMake sure your rules aren't dropping forwarded packages."]}),"\n",(0,l.jsx)(n.p,{children:"List your rules:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo iptables -S\n"})}),"\n",(0,l.jsx)(n.p,{children:"The output may look similar to the following:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"-P INPUT ACCEPT\n-P FORWARD DROP\n-P OUTPUT ACCEPT\n-N DOCKER\n-N DOCKER-ISOLATION-STAGE-1\n-N DOCKER-ISOLATION-STAGE-2\n-N DOCKER-USER\n"})}),"\n",(0,l.jsxs)(n.p,{children:["If your ",(0,l.jsx)(n.code,{children:"FORWARD"})," chain is set to ",(0,l.jsx)(n.code,{children:"DROP"}),", you need to update your rules:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo iptables -P FORWARD ACCEPT\n"})})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}function h(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>r});var t=s(96540);const l={},i=t.createContext(l);function o(e){const n=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3bcf7932.910a9d7e.js b/pr-preview/pr-4027/assets/js/3bcf7932.910a9d7e.js deleted file mode 100644 index a652305e8..000000000 --- a/pr-preview/pr-4027/assets/js/3bcf7932.910a9d7e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8048],{28453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>o});var i=s(96540);const l={},r=i.createContext(l);function t(e){const n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:t(e.components),i.createElement(r.Provider,{value:n},e.children)}},34842:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>t,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"getting-started/install","title":"Installation and setup","description":"Constellation runs entirely in your cloud environment and can be controlled via a dedicated command-line interface (CLI) or a Terraform provider.","source":"@site/versioned_docs/version-2.22/getting-started/install.md","sourceDirName":"getting-started","slug":"/getting-started/install","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/install","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/getting-started/install.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Getting started","permalink":"/constellation/pr-preview/pr-4027/2.22/category/getting-started"},"next":{"title":"First steps (cloud)","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps"}}');var l=s(74848),r=s(28453);const t={},o="Installation and setup",c={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install the Constellation CLI",id:"install-the-constellation-cli",level:2},{value:"Set up cloud credentials",id:"set-up-cloud-credentials",level:2},{value:"Required permissions",id:"required-permissions",level:3},{value:"Authentication",id:"authentication",level:3},{value:"Next steps",id:"next-steps",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components},{TabItem:s,Tabs:i}=n;return s||u("TabItem",!0),i||u("Tabs",!0),(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"installation-and-setup",children:"Installation and setup"})}),"\n",(0,l.jsxs)(n.p,{children:["Constellation runs entirely in your cloud environment and can be controlled via a dedicated ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/reference/cli",children:"command-line interface (CLI)"})," or a ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/terraform-provider",children:"Terraform provider"}),"."]}),"\n",(0,l.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,l.jsx)(n.p,{children:"Make sure the following requirements are met:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Your machine is running Linux, macOS, or Windows"}),"\n",(0,l.jsx)(n.li,{children:"You have admin rights on your machine"}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/tools/",children:"kubectl"})," is installed"]}),"\n",(0,l.jsx)(n.li,{children:"Your CSP is Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), or STACKIT"}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"install-the-constellation-cli",children:"Install the Constellation CLI"}),"\n",(0,l.jsx)(n.admonition,{type:"tip",children:(0,l.jsxs)(n.p,{children:["If you prefer to use Terraform, you can alternatively use the ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/terraform-provider",children:"Terraform provider"})," to manage the cluster's lifecycle."]})}),"\n",(0,l.jsxs)(n.p,{children:["The CLI executable is available at ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub"}),".\nInstall it with the following commands:"]}),"\n",(0,l.jsxs)(i,{children:[(0,l.jsxs)(s,{value:"linux-amd64",label:"Linux (amd64)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-amd64\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Install the CLI to your PATH:"}),"\n"]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo install constellation-linux-amd64 /usr/local/bin/constellation\n"})})]}),(0,l.jsxs)(s,{value:"linux-arm64",label:"Linux (arm64)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-arm64\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Install the CLI to your PATH:"}),"\n"]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo install constellation-linux-arm64 /usr/local/bin/constellation\n"})})]}),(0,l.jsxs)(s,{value:"darwin-arm64",label:"macOS (Apple Silicon)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-darwin-arm64\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Install the CLI to your PATH:"}),"\n"]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo install constellation-darwin-arm64 /usr/local/bin/constellation\n"})})]}),(0,l.jsxs)(s,{value:"darwin-amd64",label:"macOS (Intel)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-darwin-amd64\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Install the CLI to your PATH:"}),"\n"]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo install constellation-darwin-amd64 /usr/local/bin/constellation\n"})})]}),(0,l.jsxs)(s,{value:"windows-amd64",label:"Windows (amd64)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"Invoke-WebRequest -OutFile ./constellation.exe -Uri 'https://github.com/edgelesssys/constellation/releases/latest/download/constellation-windows-amd64.exe'\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Install the CLI under ",(0,l.jsx)(n.code,{children:"C:\\Program Files\\Constellation\\bin\\constellation.exe"})]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Add the CLI to your PATH:"}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["Open ",(0,l.jsx)(n.code,{children:"Advanced system settings"})," by searching for the App in the Windows search"]}),"\n",(0,l.jsxs)(n.li,{children:["Go to the ",(0,l.jsx)(n.code,{children:"Advanced"})," tab"]}),"\n",(0,l.jsxs)(n.li,{children:["Click ",(0,l.jsx)(n.code,{children:"Environment Variables\u2026"})]}),"\n",(0,l.jsxs)(n.li,{children:["Click variable called ",(0,l.jsx)(n.code,{children:"Path"})," and click ",(0,l.jsx)(n.code,{children:"Edit\u2026"})]}),"\n",(0,l.jsxs)(n.li,{children:["Click ",(0,l.jsx)(n.code,{children:"New"})]}),"\n",(0,l.jsxs)(n.li,{children:["Enter the path to the folder containing the binary you want on your PATH: ",(0,l.jsx)(n.code,{children:"C:\\Program Files\\Constellation\\bin"})]}),"\n"]}),"\n"]}),"\n"]})]})]}),"\n",(0,l.jsx)(n.admonition,{type:"tip",children:(0,l.jsxs)(n.p,{children:["The CLI supports autocompletion for various shells. To set it up, run ",(0,l.jsx)(n.code,{children:"constellation completion"})," and follow the given steps."]})}),"\n",(0,l.jsx)(n.h2,{id:"set-up-cloud-credentials",children:"Set up cloud credentials"}),"\n",(0,l.jsx)(n.p,{children:"Constellation makes authenticated calls to the CSP API. Therefore, you need to set up Constellation with the credentials for your CSP."}),"\n",(0,l.jsx)(n.admonition,{type:"tip",children:(0,l.jsxs)(n.p,{children:["If you don't have a cloud subscription, you can also set up a ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local",children:"local Constellation cluster using virtualization"})," for testing."]})}),"\n",(0,l.jsx)(n.h3,{id:"required-permissions",children:"Required permissions"}),"\n",(0,l.jsxs)(i,{groupId:"csp",children:[(0,l.jsxs)(s,{value:"aws",label:"AWS",children:[(0,l.jsx)(n.p,{children:"To set up a Constellation cluster, you need to perform two tasks that require permissions: create the infrastructure and create roles for cluster nodes. Both of these actions can be performed by different users, e.g., an administrator to create roles and a DevOps engineer to create the infrastructure."}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/config#creating-an-iam-configuration",children:"create the IAM configuration"})," for Constellation, you need the following permissions:"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-json",children:'{\n "Version": "2012-10-17",\n "Statement": [\n {\n "Effect": "Allow",\n "Action": [\n "ec2:DescribeAccountAttributes",\n "iam:AddRoleToInstanceProfile",\n "iam:AttachRolePolicy",\n "iam:CreateInstanceProfile",\n "iam:CreatePolicy",\n "iam:CreateRole",\n "iam:DeleteInstanceProfile",\n "iam:DeletePolicy",\n "iam:DeletePolicyVersion",\n "iam:DeleteRole",\n "iam:DetachRolePolicy",\n "iam:GetInstanceProfile",\n "iam:GetPolicy",\n "iam:GetPolicyVersion",\n "iam:GetRole",\n "iam:ListAttachedRolePolicies",\n "iam:ListInstanceProfilesForRole",\n "iam:ListPolicyVersions",\n "iam:ListRolePolicies",\n "iam:PassRole",\n "iam:RemoveRoleFromInstanceProfile",\n "sts:GetCallerIdentity"\n ],\n "Resource": "*"\n }\n ]\n}\n'})}),(0,l.jsxs)(n.p,{children:["The built-in ",(0,l.jsx)(n.code,{children:"AdministratorAccess"})," policy is a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/create",children:"create a Constellation cluster"}),", see the permissions of ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/blob/main/terraform/infrastructure/iam/aws/main.tf",children:"main.tf"}),"."]}),(0,l.jsxs)(n.p,{children:["The built-in ",(0,l.jsx)(n.code,{children:"PowerUserAccess"})," policy is a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["Follow Amazon's guide on ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html",children:"understanding"})," and ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html",children:"managing policies"}),"."]})]}),(0,l.jsxs)(s,{value:"azure",label:"Azure",children:[(0,l.jsxs)(n.p,{children:["The following ",(0,l.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/resource-providers-and-types#register-resource-provider",children:"resource providers need to be registered"})," in your subscription:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Attestation"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Compute"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Insights"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.ManagedIdentity"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network"})}),"\n"]}),(0,l.jsx)(n.p,{children:"By default, Constellation tries to register these automatically if they haven't been registered before."}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/config#creating-an-iam-configuration",children:"create the IAM configuration"})," for Constellation, you need the following permissions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"*/register/action"})," [1]"]}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Authorization/roleAssignments/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Authorization/roleDefinitions/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.ManagedIdentity/userAssignedIdentities/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Resources/subscriptions/resourcegroups/*"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["The built-in ",(0,l.jsx)(n.code,{children:"Owner"})," role is a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/create",children:"create a Constellation cluster"}),", you need the following permissions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Attestation/attestationProviders/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Compute/virtualMachineScaleSets/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Insights/components/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.ManagedIdentity/userAssignedIdentities/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/loadBalancers/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/loadBalancers/backendAddressPools/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/networkSecurityGroups/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/publicIPAddresses/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/virtualNetworks/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/virtualNetworks/subnets/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/natGateways/*"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["The built-in ",(0,l.jsx)(n.code,{children:"Contributor"})," role is a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["Follow Microsoft's guide on ",(0,l.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/role-based-access-control/role-definitions",children:"understanding"})," and ",(0,l.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments",children:"assigning roles"}),"."]}),(0,l.jsxs)(n.p,{children:["1: You can omit ",(0,l.jsx)(n.code,{children:"*/register/Action"})," if the resource providers mentioned above are already registered and the ",(0,l.jsx)(n.code,{children:"ARM_SKIP_PROVIDER_REGISTRATION"})," environment variable is set to ",(0,l.jsx)(n.code,{children:"true"})," when creating the IAM configuration."]})]}),(0,l.jsxs)(s,{value:"gcp",label:"GCP",children:[(0,l.jsxs)(n.p,{children:["Create a new project for Constellation or use an existing one.\nEnable the ",(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/apis/library/compute.googleapis.com",children:"Compute Engine API"})," on it."]}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/config#creating-an-iam-configuration",children:"create the IAM configuration"})," for Constellation, you need the following permissions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.roles.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.roles.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.roles.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccountKeys.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccountKeys.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccountKeys.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccounts.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccounts.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccounts.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"resourcemanager.projects.getIamPolicy"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"resourcemanager.projects.setIamPolicy"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["Together, the built-in roles ",(0,l.jsx)(n.code,{children:"roles/editor"})," and ",(0,l.jsx)(n.code,{children:"roles/resourcemanager.projectIamAdmin"})," form a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/create",children:"create a Constellation cluster"}),", you need the following permissions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.addresses.createInternal"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.addresses.deleteInternal"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.addresses.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.addresses.useInternal"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.backendServices.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.backendServices.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.backendServices.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.backendServices.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.disks.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.firewalls.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.firewalls.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.firewalls.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.firewalls.update"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalAddresses.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalAddresses.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalAddresses.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalAddresses.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalForwardingRules.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalForwardingRules.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalForwardingRules.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalForwardingRules.setLabels"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalOperations.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.healthChecks.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.healthChecks.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.healthChecks.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.healthChecks.useReadOnly"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroupManagers.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroupManagers.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroupManagers.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroupManagers.update"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.update"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instances.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instances.setLabels"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instances.setMetadata"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instances.setTags"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceTemplates.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceTemplates.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceTemplates.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceTemplates.useReadOnly"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.networks.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.networks.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.networks.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.networks.updatePolicy"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.routers.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.routers.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.routers.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.routers.update"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.subnetworks.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.subnetworks.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.subnetworks.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.subnetworks.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.targetTcpProxies.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.targetTcpProxies.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.targetTcpProxies.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.targetTcpProxies.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccounts.actAs"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["Together, the built-in roles ",(0,l.jsx)(n.code,{children:"roles/editor"}),", ",(0,l.jsx)(n.code,{children:"roles/compute.instanceAdmin"})," and ",(0,l.jsx)(n.code,{children:"roles/resourcemanager.projectIamAdmin"})," form a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["Follow Google's guide on ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/iam/docs/understanding-roles",children:"understanding"})," and ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/iam/docs/granting-changing-revoking-access",children:"assigning roles"}),"."]})]}),(0,l.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,l.jsxs)(n.p,{children:["Constellation on STACKIT requires a User Access Token (UAT) for the OpenStack API and a STACKIT service account.\nThe UAT already has all required permissions by default.\nThe STACKIT service account needs the ",(0,l.jsx)(n.code,{children:"editor"})," role to create STACKIT LoadBalancers.\nLook at the ",(0,l.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/getting-started-in-service-accounts-134415831.html",children:"STACKIT documentation"})," on how to create the service account and assign the role."]})})]}),"\n",(0,l.jsx)(n.h3,{id:"authentication",children:"Authentication"}),"\n",(0,l.jsxs)(n.p,{children:["You need to authenticate with your CSP. The following lists the required steps for ",(0,l.jsx)(n.em,{children:"testing"})," and ",(0,l.jsx)(n.em,{children:"production"})," environments."]}),"\n",(0,l.jsx)(n.admonition,{type:"note",children:(0,l.jsxs)(n.p,{children:["The steps for a ",(0,l.jsx)(n.em,{children:"testing"})," environment are simpler. However, they may expose secrets to the CSP. If in doubt, follow the ",(0,l.jsx)(n.em,{children:"production"})," steps."]})}),"\n",(0,l.jsxs)(i,{groupId:"csp",children:[(0,l.jsxs)(s,{value:"aws",label:"AWS",children:[(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Testing"})}),(0,l.jsxs)(n.p,{children:["You can use the ",(0,l.jsx)(n.a,{href:"https://console.aws.amazon.com/cloudshell/home",children:"AWS CloudShell"}),". Make sure you are ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/cloudshell/latest/userguide/sec-auth-with-identities.html",children:"authorized to use it"}),"."]}),(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Production"})}),(0,l.jsxs)(n.p,{children:["Use the latest version of the ",(0,l.jsx)(n.a,{href:"https://aws.amazon.com/cli/",children:"AWS CLI"})," on a trusted machine:"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"aws configure\n"})}),(0,l.jsxs)(n.p,{children:["Options and first steps are described in the ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/cli/index.html",children:"AWS CLI documentation"}),"."]})]}),(0,l.jsxs)(s,{value:"azure",label:"Azure",children:[(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Testing"})}),(0,l.jsxs)(n.p,{children:["Simply open the ",(0,l.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/cloud-shell/overview",children:"Azure Cloud Shell"}),"."]}),(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Production"})}),(0,l.jsxs)(n.p,{children:["Use the latest version of the ",(0,l.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/",children:"Azure CLI"})," on a trusted machine:"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"az login\n"})}),(0,l.jsxs)(n.p,{children:["Other options are described in Azure's ",(0,l.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli",children:"authentication guide"}),"."]})]}),(0,l.jsxs)(s,{value:"gcp",label:"GCP",children:[(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Testing"})}),(0,l.jsxs)(n.p,{children:["You can use the ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/shell",children:"Google Cloud Shell"}),". Make sure your ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/shell/docs/auth",children:"session is authorized"}),". For example, execute ",(0,l.jsx)(n.code,{children:"gsutil"})," and accept the authorization prompt."]}),(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Production"})}),(0,l.jsx)(n.p,{children:"Use one of the following options on a trusted machine:"}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Use the ",(0,l.jsxs)(n.a,{href:"https://cloud.google.com/sdk/gcloud",children:[(0,l.jsx)(n.code,{children:"gcloud"})," CLI"]})]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"gcloud auth application-default login\n"})}),"\n",(0,l.jsx)(n.p,{children:"This will ask you to log-in to your Google account and create your credentials.\nThe Constellation CLI will automatically load these credentials when needed."}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Set up a service account and pass the credentials manually"}),"\n",(0,l.jsxs)(n.p,{children:["Follow ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/docs/authentication/production#manually",children:"Google's guide"})," for setting up your credentials."]}),"\n"]}),"\n"]})]}),(0,l.jsxs)(s,{value:"stackit",label:"STACKIT",children:[(0,l.jsx)(n.p,{children:"You need to authenticate with the infrastructure API (OpenStack) and create a service account (STACKIT API)."}),(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/step-1-generating-of-user-access-token-11763726.html",children:"Follow the STACKIT documentation"})," for obtaining a User Access Token (UAT) to use the infrastructure API"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Create a configuration file with the credentials from the User Access Token under:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Linux: ",(0,l.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})]}),"\n",(0,l.jsxs)(n.li,{children:["macOS: ",(0,l.jsx)(n.code,{children:"/Users/<user>/Library/Application Support/openstack/clouds.yaml"})," or ",(0,l.jsx)(n.code,{children:"/etc/openstack/clouds.yaml"})]}),"\n",(0,l.jsxs)(n.li,{children:["Windows: ",(0,l.jsx)(n.code,{children:"%AppData%\\openstack\\clouds.yaml"})]}),"\n"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",children:"clouds:\n stackit:\n auth:\n auth_url: https://keystone.api.iaas.eu01.stackit.cloud/v3\n username: REPLACE_WITH_UAT_USERNAME\n password: REPLACE_WITH_UAT_PASSWORD\n project_id: REPLACE_WITH_OPENSTACK_PROJECT_ID\n project_name: REPLACE_WITH_STACKIT_PROJECT_NAME\n user_domain_name: portal_mvp\n project_domain_name: portal_mvp\n region_name: RegionOne\n identity_api_version: 3\n"})}),"\n"]}),"\n"]}),(0,l.jsx)(n.admonition,{type:"caution",children:(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:"project_id"})," refers to the ID of your OpenStack project. The STACKIT portal also shows the STACKIT ID that's associated with your project in some places. Make sure you insert the OpenStack project ID in the ",(0,l.jsx)(n.code,{children:"clouds.yaml"})," file."]})}),(0,l.jsxs)(n.ol,{start:"3",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/getting-started-in-service-accounts-134415831.html",children:"Follow the STACKIT documentation"})," for creating a service account and an access token"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Assign the ",(0,l.jsx)(n.code,{children:"editor"})," role to the service account by ",(0,l.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/getting-started-in-service-accounts-134415831.html",children:"following the documentation"})]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Create a configuration file under ",(0,l.jsx)(n.code,{children:"~/.stackit/credentials.json"})," (",(0,l.jsx)(n.code,{children:"%USERPROFILE%\\.stackit\\credentials.json"})," on Windows)"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-json",children:'{"STACKIT_SERVICE_ACCOUNT_TOKEN":"REPLACE_WITH_TOKEN"}\n'})}),"\n"]}),"\n"]})]})]}),"\n",(0,l.jsx)(n.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,l.jsxs)(n.p,{children:["You are now ready to ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps",children:"deploy your first confidential Kubernetes cluster and application"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(a,{...e})}):a(e)}function u(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3e0d8e9d.ceac1b01.js b/pr-preview/pr-4027/assets/js/3e0d8e9d.ceac1b01.js deleted file mode 100644 index 7ce45e882..000000000 --- a/pr-preview/pr-4027/assets/js/3e0d8e9d.ceac1b01.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7861],{21071:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"reference/terraform","title":"Terraform usage","description":"Terraform is an Infrastructure as Code (IaC) framework to manage cloud resources. This page explains how Constellation uses it internally and how advanced users may manually use it to have more control over the resource creation.","source":"@site/docs/reference/terraform.md","sourceDirName":"reference","slug":"/reference/terraform","permalink":"/constellation/pr-preview/pr-4027/next/reference/terraform","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/reference/terraform.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Configuration migrations","permalink":"/constellation/pr-preview/pr-4027/next/reference/migration"},"next":{"title":"SLSA adoption","permalink":"/constellation/pr-preview/pr-4027/next/reference/slsa"}}');var o=t(74848),s=t(28453);const a={},i="Terraform usage",l={},c=[{value:"Terraform state files",id:"terraform-state-files",level:2},{value:"Interacting with Terraform manually",id:"interacting-with-terraform-manually",level:2},{value:"Terraform debugging",id:"terraform-debugging",level:2}];function d(e){const r={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(r.header,{children:(0,o.jsx)(r.h1,{id:"terraform-usage",children:"Terraform usage"})}),"\n",(0,o.jsxs)(r.p,{children:[(0,o.jsx)(r.a,{href:"https://www.terraform.io/",children:"Terraform"})," is an Infrastructure as Code (IaC) framework to manage cloud resources. This page explains how Constellation uses it internally and how advanced users may manually use it to have more control over the resource creation."]}),"\n",(0,o.jsx)(r.admonition,{type:"info",children:(0,o.jsxs)(r.p,{children:["Information on this page is intended for users who are familiar with Terraform.\nIt's not required for common usage of Constellation.\nSee the ",(0,o.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/docs",children:"Terraform documentation"})," if you want to learn more about it."]})}),"\n",(0,o.jsx)(r.h2,{id:"terraform-state-files",children:"Terraform state files"}),"\n",(0,o.jsx)(r.p,{children:"Constellation keeps Terraform state files in subdirectories of the workspace together with the corresponding Terraform configuration files and metadata.\nThe subdirectories are created on the first Constellation CLI action that uses Terraform internally."}),"\n",(0,o.jsx)(r.p,{children:"Currently, these subdirectories are:"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.code,{children:"constellation-terraform"})," - Terraform state files for the resources of the Constellation cluster"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.code,{children:"constellation-iam-terraform"})," - Terraform state files for IAM configuration"]}),"\n"]}),"\n",(0,o.jsxs)(r.p,{children:["As with all commands, commands that work with these files (e.g., ",(0,o.jsx)(r.code,{children:"apply"}),", ",(0,o.jsx)(r.code,{children:"terminate"}),", ",(0,o.jsx)(r.code,{children:"iam"}),") have to be executed from the root of the cluster's ",(0,o.jsx)(r.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/orchestration#workspaces",children:"workspace directory"}),". You usually don't need and shouldn't manipulate or delete the subdirectories manually."]}),"\n",(0,o.jsx)(r.h2,{id:"interacting-with-terraform-manually",children:"Interacting with Terraform manually"}),"\n",(0,o.jsxs)(r.p,{children:["Manual interaction with Terraform state created by Constellation (i.e., via the Terraform CLI) should only be performed by experienced users. It may lead to unrecoverable loss of cloud resources. For the majority of users and use cases, the interaction done by the ",(0,o.jsx)(r.a,{href:"/constellation/pr-preview/pr-4027/next/reference/cli",children:"Constellation CLI"})," is sufficient."]}),"\n",(0,o.jsx)(r.h2,{id:"terraform-debugging",children:"Terraform debugging"}),"\n",(0,o.jsxs)(r.p,{children:["To debug Terraform issues, the Constellation CLI offers the ",(0,o.jsx)(r.code,{children:"tf-log"})," flag. You can set it to any of ",(0,o.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform's log levels"}),":"]}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.code,{children:"JSON"})," (JSON-formatted logs at ",(0,o.jsx)(r.code,{children:"TRACE"})," level)"]}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"TRACE"})}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"DEBUG"})}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"INFO"})}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"WARN"})}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"ERROR"})}),"\n"]}),"\n",(0,o.jsxs)(r.p,{children:["The log output is written to the ",(0,o.jsx)(r.code,{children:"terraform.log"})," file in the workspace directory. The output is appended to the file on each run."]})]})}function h(e={}){const{wrapper:r}={...(0,s.R)(),...e.components};return r?(0,o.jsx)(r,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,r,t)=>{t.d(r,{R:()=>a,x:()=>i});var n=t(96540);const o={},s=n.createContext(o);function a(e){const r=n.useContext(s);return n.useMemo(function(){return"function"==typeof e?e(r):{...r,...e}},[r,e])}function i(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),n.createElement(s.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3e6faa8e.77fa12c2.js b/pr-preview/pr-4027/assets/js/3e6faa8e.77fa12c2.js deleted file mode 100644 index 87bcb59b0..000000000 --- a/pr-preview/pr-4027/assets/js/3e6faa8e.77fa12c2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3280],{28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>i});var o=s(96540);const t={},r=o.createContext(t);function a(e){const n=o.useContext(r);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),o.createElement(r.Provider,{value:n},e.children)}},31327:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"workflows/lb","title":"Expose a service","description":"Constellation integrates the native load balancers of each CSP. Therefore, to expose a service simply create a service of type LoadBalancer.","source":"@site/versioned_docs/version-2.24/workflows/lb.md","sourceDirName":"workflows","slug":"/workflows/lb","permalink":"/constellation/pr-preview/pr-4027/workflows/lb","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/workflows/lb.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Upgrade your cluster","permalink":"/constellation/pr-preview/pr-4027/workflows/upgrade"},"next":{"title":"Install cert-manager","permalink":"/constellation/pr-preview/pr-4027/workflows/cert-manager"}}');var t=s(74848),r=s(28453);const a={},i="Expose a service",c={},l=[{value:"Internet-facing LB service on AWS",id:"internet-facing-lb-service-on-aws",level:2},{value:"Ingress on AWS",id:"ingress-on-aws",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"expose-a-service",children:"Expose a service"})}),"\n",(0,t.jsxs)(n.p,{children:["Constellation integrates the native load balancers of each CSP. Therefore, to expose a service simply ",(0,t.jsxs)(n.a,{href:"https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer",children:["create a service of type ",(0,t.jsx)(n.code,{children:"LoadBalancer"})]}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"internet-facing-lb-service-on-aws",children:"Internet-facing LB service on AWS"}),"\n",(0,t.jsxs)(n.p,{children:["To expose your application service externally you might want to use a Kubernetes Service of type ",(0,t.jsx)(n.code,{children:"LoadBalancer"}),". On AWS, load-balancing is achieved through the ",(0,t.jsx)(n.a,{href:"https://kubernetes-sigs.github.io/aws-load-balancer-controller",children:"AWS Load Balancer Controller"})," as in the managed EKS."]}),"\n",(0,t.jsxs)(n.p,{children:["Since recent versions, the controller deploy an internal LB by default requiring to set an annotation ",(0,t.jsx)(n.code,{children:"service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing"})," to have an internet-facing LB. For more details, see the ",(0,t.jsx)(n.a,{href:"https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.7/guide/service/nlb/",children:"official docs"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["For general information on LB with AWS see ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/eks/latest/userguide/network-load-balancing.html",children:"Network load balancing on Amazon EKS"}),"."]}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsx)(n.p,{children:"Before terminating the cluster, all LB backed services should be deleted, so that the controller can cleanup the related resources."})}),"\n",(0,t.jsx)(n.h2,{id:"ingress-on-aws",children:"Ingress on AWS"}),"\n",(0,t.jsxs)(n.p,{children:["The AWS Load Balancer Controller also provisions ",(0,t.jsx)(n.code,{children:"Ingress"})," resources of class ",(0,t.jsx)(n.code,{children:"alb"}),".\nAWS Application Load Balancers (ALBs) can be configured with a ",(0,t.jsx)(n.a,{href:"https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.7/guide/ingress/annotations/#target-type",children:(0,t.jsx)(n.code,{children:"target-type"})}),".\nThe target type ",(0,t.jsx)(n.code,{children:"ip"})," requires using the EKS container network solution, which makes it incompatible with Constellation.\nIf a service can be exposed on a ",(0,t.jsx)(n.code,{children:"NodePort"}),", the target type ",(0,t.jsx)(n.code,{children:"instance"})," can be used."]}),"\n",(0,t.jsxs)(n.p,{children:["See ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html",children:"Application load balancing on Amazon EKS"})," for more information."]}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsx)(n.p,{children:"Ingress handlers backed by AWS ALBs reside outside the Constellation cluster, so they shouldn't be handling sensitive traffic!"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3ee8c4d1.cff371e1.js b/pr-preview/pr-4027/assets/js/3ee8c4d1.cff371e1.js deleted file mode 100644 index a804509ab..000000000 --- a/pr-preview/pr-4027/assets/js/3ee8c4d1.cff371e1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6032],{28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>a});var t=s(96540);const i={},o=t.createContext(i);function r(e){const n=t.useContext(o);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),t.createElement(o.Provider,{value:n},e.children)}},54648:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"workflows/troubleshooting","title":"Troubleshooting","description":"This section aids you in finding problems when working with Constellation.","source":"@site/versioned_docs/version-2.22/workflows/troubleshooting.md","sourceDirName":"workflows","slug":"/workflows/troubleshooting","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/workflows/troubleshooting.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Reproduce release artifacts","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/reproducible-builds"},"next":{"title":"Architecture","permalink":"/constellation/pr-preview/pr-4027/2.22/category/architecture"}}');var i=s(74848),o=s(28453);const r={},a="Troubleshooting",l={},c=[{value:"Common issues",id:"common-issues",level:2},{value:"Issues with creating new clusters",id:"issues-with-creating-new-clusters",level:3},{value:"Azure: Resource Providers can't be registered",id:"azure-resource-providers-cant-be-registered",level:3},{value:"Azure: Can't update attestation policy",id:"azure-cant-update-attestation-policy",level:3},{value:"Nodes fail to join with error <code>untrusted measurement value</code>",id:"nodes-fail-to-join-with-error-untrusted-measurement-value",level:3},{value:"Upgrading Kubernetes resources fails",id:"upgrading-kubernetes-resources-fails",level:3},{value:"Diagnosing issues",id:"diagnosing-issues",level:2},{value:"Logs",id:"logs",level:3},{value:"Node shell access",id:"node-shell-access",level:3},{value:"Emergency SSH access",id:"emergency-ssh-access",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"troubleshooting",children:"Troubleshooting"})}),"\n",(0,i.jsx)(n.p,{children:"This section aids you in finding problems when working with Constellation."}),"\n",(0,i.jsx)(n.h2,{id:"common-issues",children:"Common issues"}),"\n",(0,i.jsx)(n.h3,{id:"issues-with-creating-new-clusters",children:"Issues with creating new clusters"}),"\n",(0,i.jsxs)(n.p,{children:["When you create a new cluster, you should always use the ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/releases/latest",children:"latest release"}),".\nIf something doesn't work, check out the ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"known issues"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"azure-resource-providers-cant-be-registered",children:"Azure: Resource Providers can't be registered"}),"\n",(0,i.jsxs)(n.p,{children:["On Azure, you may receive the following error when running ",(0,i.jsx)(n.code,{children:"apply"})," or ",(0,i.jsx)(n.code,{children:"terminate"})," with limited IAM permissions:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell-session",children:"Error: Error ensuring Resource Providers are registered.\n\nTerraform automatically attempts to register the Resource Providers it supports to\nensure it's able to provision resources.\n\nIf you don't have permission to register Resource Providers you may wish to use the\n\"skip_provider_registration\" flag in the Provider block to disable this functionality.\n\n[...]\n"})}),"\n",(0,i.jsxs)(n.p,{children:["To continue, please ensure that the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/install#required-permissions",children:"required resource providers"})," have been registered in your subscription by your administrator."]}),"\n",(0,i.jsxs)(n.p,{children:["Afterward, set ",(0,i.jsx)(n.code,{children:"ARM_SKIP_PROVIDER_REGISTRATION=true"})," as an environment variable and either run ",(0,i.jsx)(n.code,{children:"apply"})," or ",(0,i.jsx)(n.code,{children:"terminate"})," again.\nFor example:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"ARM_SKIP_PROVIDER_REGISTRATION=true constellation apply\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Or alternatively, for ",(0,i.jsx)(n.code,{children:"terminate"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"ARM_SKIP_PROVIDER_REGISTRATION=true constellation terminate\n"})}),"\n",(0,i.jsx)(n.h3,{id:"azure-cant-update-attestation-policy",children:"Azure: Can't update attestation policy"}),"\n",(0,i.jsxs)(n.p,{children:["On Azure, you may receive the following error when running ",(0,i.jsx)(n.code,{children:"apply"})," from within an Azure environment, e.g., an Azure VM:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell-session",children:"An error occurred: patching policies: updating attestation policy: unexpected status code: 403 Forbidden\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The problem occurs because the Azure SDK we use internally attempts to ",(0,i.jsx)(n.a,{href:"https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#DefaultAzureCredential",children:"authenticate towards the Azure API with the managed identity of your current environment instead of the Azure CLI token"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"We decided not to deviate from this behavior and comply with the ordering of credentials."}),"\n",(0,i.jsxs)(n.p,{children:["A solution is to add the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/install#required-permissions",children:"required permissions"})," to the managed identity of your environment. For example, the managed identity of your Azure VM, instead of the account that you've authenticated with in the Azure CLI."]}),"\n",(0,i.jsx)(n.p,{children:"If your setup requires a change in the ordering of credentials, please open an issue and explain your desired behavior."}),"\n",(0,i.jsxs)(n.h3,{id:"nodes-fail-to-join-with-error-untrusted-measurement-value",children:["Nodes fail to join with error ",(0,i.jsx)(n.code,{children:"untrusted measurement value"})]}),"\n",(0,i.jsxs)(n.p,{children:["This error indicates that a node's ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation",children:"attestation statement"})," contains measurements that don't match the trusted values expected by the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#joinservice",children:"JoinService"}),".\nThis may for example happen if the cloud provider updates the VM's firmware such that it influences the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#runtime-measurements",children:"runtime measurements"})," in an unforeseen way.\nA failed upgrade due to an erroneous attestation config can also cause this error.\nYou can change the expected measurements to resolve the failure."]}),"\n",(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsxs)(n.p,{children:["Attestation and trusted measurements are crucial for the security of your cluster.\nBe extra careful when manually changing these settings.\nWhen in doubt, check if the encountered ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"issue is known"})," or ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation#support",children:"contact support"}),"."]})}),"\n",(0,i.jsxs)(n.admonition,{type:"tip",children:[(0,i.jsxs)(n.p,{children:["During an upgrade with modified attestation config, a backup of the current configuration is stored in the ",(0,i.jsx)(n.code,{children:"join-config"})," config map in the ",(0,i.jsx)(n.code,{children:"kube-system"})," namespace under the ",(0,i.jsx)(n.code,{children:"attestationConfig_backup"})," key. To restore the old attestation config after a failed upgrade, replace the value of ",(0,i.jsx)(n.code,{children:"attestationConfig"})," with the value from ",(0,i.jsx)(n.code,{children:"attestationConfig_backup"}),":"]}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'kubectl patch configmaps -n kube-system join-config -p "{\\"data\\":{\\"attestationConfig\\":\\"$(kubectl get configmaps -n kube-system join-config -o "jsonpath={.data.attestationConfig_backup}")\\"}}"\n'})})]}),"\n",(0,i.jsxs)(n.p,{children:["You can use the ",(0,i.jsx)(n.code,{children:"apply"})," command to change measurements of a running cluster:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Modify the ",(0,i.jsx)(n.code,{children:"measurements"})," key in your local ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"})," to the expected values."]}),"\n",(0,i.jsxs)(n.li,{children:["Run ",(0,i.jsx)(n.code,{children:"constellation apply"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Keep in mind that running ",(0,i.jsx)(n.code,{children:"apply"})," also applies any version changes from your config to the cluster."]}),"\n",(0,i.jsx)(n.p,{children:"You can run these commands to learn about the versions currently configured in the cluster:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Kubernetes API server version: ",(0,i.jsx)(n.code,{children:"kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.kubernetesClusterVersion"})]}),"\n",(0,i.jsxs)(n.li,{children:["image version: ",(0,i.jsx)(n.code,{children:"kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.imageVersion"})]}),"\n",(0,i.jsxs)(n.li,{children:["microservices versions: ",(0,i.jsx)(n.code,{children:"helm list --filter 'constellation-services' -n kube-system"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"upgrading-kubernetes-resources-fails",children:"Upgrading Kubernetes resources fails"}),"\n",(0,i.jsxs)(n.p,{children:["Constellation manages its Kubernetes resources using Helm.\nWhen applying an upgrade, the charts that are about to be installed, and a values override file ",(0,i.jsx)(n.code,{children:"overrides.yaml"}),",\nare saved to disk in your current workspace under ",(0,i.jsx)(n.code,{children:"constellation-upgrade/upgrade-<timestamp>/helm-charts/"}),".\nIf upgrading the charts using the Constellation CLI fails, you can review these charts and try to manually apply the upgrade."]}),"\n",(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsxs)(n.p,{children:["Changing and manually applying the charts may destroy cluster resources and can lead to broken Constellation deployments.\nProceed with caution and when in doubt,\ncheck if the encountered ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"issue is known"})," or ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation#support",children:"contact support"}),"."]})}),"\n",(0,i.jsx)(n.h2,{id:"diagnosing-issues",children:"Diagnosing issues"}),"\n",(0,i.jsx)(n.h3,{id:"logs",children:"Logs"}),"\n",(0,i.jsxs)(n.p,{children:["To get started on diagnosing issues with Constellation, it's often helpful to collect logs from nodes, pods, or other resources in the cluster. Most logs are available through Kubernetes' standard\n",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/logging/",children:"logging interfaces"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"To debug issues occurring at boot time of the nodes, you can use the serial console interface of the CSP while the machine boots to get a read-only view of the boot logs."}),"\n",(0,i.jsxs)(n.p,{children:["Apart from that, Constellation also offers further ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/observability",children:"observability integrations"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"node-shell-access",children:"Node shell access"}),"\n",(0,i.jsxs)(n.p,{children:["Debugging via a shell on a node is ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/debug/debug-application/debug-running-pod/#node-shell-session",children:"directly supported by Kubernetes"}),"."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Figure out which node to connect to:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl get nodes\n# or to see more information, such as IPs:\nkubectl get nodes -o wide\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Connect to the node:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl debug node/constell-worker-xksa0-000000 -it --image=busybox\n"})}),"\n",(0,i.jsx)(n.p,{children:"You will be presented with a prompt."}),"\n",(0,i.jsxs)(n.p,{children:["The nodes file system is mounted at ",(0,i.jsx)(n.code,{children:"/host"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Once finished, clean up the debug pod:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl delete pod node-debugger-constell-worker-xksa0-000000-bjthj\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"emergency-ssh-access",children:"Emergency SSH access"}),"\n",(0,i.jsx)(n.p,{children:"Emergency SSH access to nodes can be useful to diagnose issues or download important data even if the Kubernetes API isn't reachable anymore."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Enter the ",(0,i.jsx)(n.code,{children:"constellation-terraform"})," directory in your Constellation workspace and enable emergency SSH access to the cluster:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:' cd constellation-terraform\n echo "emergency_ssh = true" >> ./terraform.tfvars\n terraform apply\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Sign an existing SSH key with your master secret:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd ../ # go back to your Constellation workspace\nconstellation ssh --key your_public_key.pub\n"})}),"\n",(0,i.jsxs)(n.p,{children:["A certificate is written to ",(0,i.jsx)(n.code,{children:"constellation_cert.pub"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The certificate is valid for 24 hours and enables you to access your Constellation nodes using\n",(0,i.jsx)(n.a,{href:"https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Certificate-based_Authentication",children:"certificate based authentication"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Now you can connect to any Constellation node using your certificate and your private key."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"ssh -o CertificateFile=constellation_cert.pub -i <your private key> root@<ip of constellation node>\n"})}),"\n",(0,i.jsx)(n.p,{children:"Normally, you don't have access to the Constellation nodes since they reside in a private network.\nTo access those nodes anyways, you can use your Constellation load balancer as a proxy jump host.\nFor this, use something along the following SSH client configuration:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-text",children:"Host <LB domain name>\n ProxyJump none\n\nHost *\n IdentityFile <your private key>\n PreferredAuthentications publickey\n CertificateFile=constellation_cert.pub\n User root\n ProxyJump <LB domain name>\n"})}),"\n",(0,i.jsxs)(n.p,{children:["With this configuration you can connect to a Constellation node using ",(0,i.jsx)(n.code,{children:"ssh -F <this config> <private node IP>"}),".\nYou can obtain the private node IP and the domain name of the load balancer using your CSP's web UI."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3fddd266.5afedcea.js b/pr-preview/pr-4027/assets/js/3fddd266.5afedcea.js deleted file mode 100644 index 39bc04b72..000000000 --- a/pr-preview/pr-4027/assets/js/3fddd266.5afedcea.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9414],{28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>l});var s=t(96540);const r={},i=s.createContext(r);function o(e){const n=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:n},e.children)}},73129:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"workflows/verify-cluster","title":"Verify your cluster","description":"Constellation\'s attestation feature allows you, or a third party, to verify the integrity and confidentiality of your Constellation cluster.","source":"@site/versioned_docs/version-2.24/workflows/verify-cluster.md","sourceDirName":"workflows","slug":"/workflows/verify-cluster","permalink":"/constellation/pr-preview/pr-4027/workflows/verify-cluster","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/workflows/verify-cluster.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Recover your cluster","permalink":"/constellation/pr-preview/pr-4027/workflows/recovery"},"next":{"title":"Use persistent storage","permalink":"/constellation/pr-preview/pr-4027/workflows/storage"}}');var r=t(74848),i=t(28453);const o={},l="Verify your cluster",a={},c=[{value:"Fetch measurements",id:"fetch-measurements",level:2},{value:"The <em>verify</em> command",id:"the-verify-command",level:2},{value:"Custom arguments",id:"custom-arguments",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"verify-your-cluster",children:"Verify your cluster"})}),"\n",(0,r.jsxs)(n.p,{children:["Constellation's ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/attestation",children:"attestation feature"})," allows you, or a third party, to verify the integrity and confidentiality of your Constellation cluster."]}),"\n",(0,r.jsx)(n.h2,{id:"fetch-measurements",children:"Fetch measurements"}),"\n",(0,r.jsx)(n.p,{children:"To verify the integrity of Constellation you need trusted measurements to verify against. For each node image released by Edgeless Systems, there are signed measurements, which you can download using the CLI:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"constellation config fetch-measurements\n"})}),"\n",(0,r.jsx)(n.p,{children:"This command performs the following steps:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Download the signed measurements for the configured image. By default, this will use Edgeless Systems' public measurement registry."}),"\n",(0,r.jsxs)(n.li,{children:["Verify the signature of the measurements. This will use Edgeless Systems' ",(0,r.jsx)(n.a,{href:"https://edgeless.systems/es.pub",children:"public key"}),"."]}),"\n",(0,r.jsx)(n.li,{children:"Write measurements into configuration file."}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["The configuration file then contains a list of ",(0,r.jsx)(n.code,{children:"measurements"})," similar to the following:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'# ...\nmeasurements:\n 0:\n expected: "0f35c214608d93c7a6e68ae7359b4a8be5a0e99eea9107ece427c4dea4e439cf"\n warnOnly: false\n 4:\n expected: "02c7a67c01ec70ffaf23d73a12f749ab150a8ac6dc529bda2fe1096a98bf42ea"\n warnOnly: false\n 5:\n expected: "e6949026b72e5045706cd1318889b3874480f7a3f7c5c590912391a2d15e6975"\n warnOnly: true\n 8:\n expected: "0000000000000000000000000000000000000000000000000000000000000000"\n warnOnly: false\n 9:\n expected: "f0a6e8601b00e2fdc57195686cd4ef45eb43a556ac1209b8e25d993213d68384"\n warnOnly: false\n 11:\n expected: "0000000000000000000000000000000000000000000000000000000000000000"\n warnOnly: false\n 12:\n expected: "da99eb6cf7c7fbb692067c87fd5ca0b7117dc293578e4fea41f95d3d3d6af5e2"\n warnOnly: false\n 13:\n expected: "0000000000000000000000000000000000000000000000000000000000000000"\n warnOnly: false\n 14:\n expected: "d7c4cc7ff7933022f013e03bdee875b91720b5b86cf1753cad830f95e791926f"\n warnOnly: true\n 15:\n expected: "0000000000000000000000000000000000000000000000000000000000000000"\n warnOnly: false\n# ...\n'})}),"\n",(0,r.jsxs)(n.p,{children:["Each entry specifies the expected value of the Constellation node, and whether the measurement should be enforced (",(0,r.jsx)(n.code,{children:"warnOnly: false"}),"), or only a warning should be logged (",(0,r.jsx)(n.code,{children:"warnOnly: true"}),").\nBy default, the subset of the ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/attestation#runtime-measurements",children:"available measurements"})," that can be locally reproduced and verified is enforced."]}),"\n",(0,r.jsxs)(n.p,{children:["During attestation, the validating side (CLI or ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#joinservice",children:"join service"}),") compares each measurement reported by the issuing side (first node or joining node) individually.\nFor mismatching measurements that have set ",(0,r.jsx)(n.code,{children:"warnOnly"})," to ",(0,r.jsx)(n.code,{children:"true"})," only a warning is emitted.\nFor mismatching measurements that have set ",(0,r.jsx)(n.code,{children:"warnOnly"})," to ",(0,r.jsx)(n.code,{children:"false"})," an error is emitted and attestation fails.\nIf attestation fails for a new node, it isn't permitted to join the cluster."]}),"\n",(0,r.jsxs)(n.h2,{id:"the-verify-command",children:["The ",(0,r.jsx)(n.em,{children:"verify"})," command"]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["The steps below are purely optional. They're automatically executed by ",(0,r.jsx)(n.code,{children:"constellation apply"})," when you initialize your cluster. The ",(0,r.jsx)(n.code,{children:"constellation verify"})," command mostly has an illustrative purpose."]})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"verify"})," command obtains and verifies an attestation statement from a running Constellation cluster."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"constellation verify [--cluster-id ...]\n"})}),"\n",(0,r.jsx)(n.p,{children:"From the attestation statement, the command verifies the following properties:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"The cluster is using the correct Confidential VM (CVM) type."}),"\n",(0,r.jsx)(n.li,{children:"Inside the CVMs, the correct node images are running. The node images are identified through the measurements obtained in the previous step."}),"\n",(0,r.jsxs)(n.li,{children:["The unique ID of the cluster matches the one from your ",(0,r.jsx)(n.code,{children:"constellation-state.yaml"})," file or passed in via ",(0,r.jsx)(n.code,{children:"--cluster-id"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Once the above properties are verified, you know that you are talking to the right Constellation cluster and it's in a good and trustworthy shape."}),"\n",(0,r.jsx)(n.h3,{id:"custom-arguments",children:"Custom arguments"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"verify"})," command also allows you to verify any Constellation deployment that you have network access to. For this you need the following:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The IP address of a running Constellation cluster's ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#verificationservice",children:"VerificationService"}),". The ",(0,r.jsx)(n.code,{children:"VerificationService"})," is exposed via a ",(0,r.jsx)(n.code,{children:"NodePort"})," service using the external IP address of your cluster. Run ",(0,r.jsx)(n.code,{children:"kubectl get nodes -o wide"})," and look for ",(0,r.jsx)(n.code,{children:"EXTERNAL-IP"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["The cluster's ",(0,r.jsx)(n.em,{children:"clusterID"}),". See ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys#cluster-identity",children:"cluster identity"})," for more details."]}),"\n",(0,r.jsxs)(n.li,{children:["A ",(0,r.jsx)(n.code,{children:"constellation-conf.yaml"})," file with the expected measurements of the cluster in your working directory."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"For example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-shell-session",children:"constellation verify -e 192.0.2.1 --cluster-id Q29uc3RlbGxhdGlvbkRvY3VtZW50YXRpb25TZWNyZXQ=\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/3fe7bb19.4ae2f002.js b/pr-preview/pr-4027/assets/js/3fe7bb19.4ae2f002.js deleted file mode 100644 index 8970afe22..000000000 --- a/pr-preview/pr-4027/assets/js/3fe7bb19.4ae2f002.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7018],{28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var r=n(96540);const i={},o=r.createContext(i);function s(e){const t=r.useContext(o);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),r.createElement(o.Provider,{value:t},e.children)}},42605:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>d});const r=JSON.parse('{"id":"architecture/networking","title":"Network encryption","description":"Constellation encrypts all pod communication using the container network interface (CNI).","source":"@site/versioned_docs/version-2.22/architecture/networking.md","sourceDirName":"architecture","slug":"/architecture/networking","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/networking","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/architecture/networking.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Encrypted persistent storage","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage"},"next":{"title":"Observability","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/observability"}}');var i=n(74848),o=n(28453);const s={},c="Network encryption",a={},d=[];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"network-encryption",children:"Network encryption"})}),"\n",(0,i.jsxs)(t.p,{children:["Constellation encrypts all pod communication using the ",(0,i.jsx)(t.a,{href:"https://github.com/containernetworking/cni",children:"container network interface (CNI)"}),".\nTo that end, Constellation deploys, configures, and operates the ",(0,i.jsx)(t.a,{href:"https://cilium.io/",children:"Cilium"})," CNI plugin.\nCilium provides ",(0,i.jsx)(t.a,{href:"https://docs.cilium.io/en/stable/security/network/encryption",children:"transparent encryption"})," for all cluster traffic using either IPSec or ",(0,i.jsx)(t.a,{href:"https://www.wireguard.com/",children:"WireGuard"}),".\nCurrently, Constellation only supports WireGuard as the encryption engine.\nYou can read more about the cryptographic soundness of WireGuard ",(0,i.jsx)(t.a,{href:"https://www.wireguard.com/papers/wireguard.pdf",children:"in their white paper"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["Cilium is actively working on implementing a feature called ",(0,i.jsx)(t.a,{href:"https://github.com/cilium/cilium/pull/19401",children:(0,i.jsx)(t.code,{children:"host-to-host"})})," encryption mode for WireGuard.\nWith ",(0,i.jsx)(t.code,{children:"host-to-host"}),", all traffic between nodes will be tunneled via WireGuard (host-to-host, host-to-pod, pod-to-host, pod-to-pod).\nUntil the ",(0,i.jsx)(t.code,{children:"host-to-host"})," feature is released, Constellation enables ",(0,i.jsx)(t.code,{children:"pod-to-pod"})," encryption.\nThis mode encrypts all traffic between Kubernetes pods using WireGuard tunnels."]}),"\n",(0,i.jsxs)(t.p,{children:["When using Cilium in the default setup but with encryption enabled, there is a ",(0,i.jsx)(t.a,{href:"https://docs.cilium.io/en/v1.12/gettingstarted/encryption/#egress-traffic-to-not-yet-discovered-remote-endpoints-may-be-unencrypted",children:"known issue"}),"\nthat can cause pod-to-pod traffic to be unencrypted.\nTo mitigate this issue, Constellation adds a ",(0,i.jsx)(t.em,{children:"strict"})," mode to Cilium's ",(0,i.jsx)(t.code,{children:"pod-to-pod"})," encryption.\nThis mode changes the default behavior of traffic that's destined for an unknown endpoint to not be send out in plaintext, but instead being dropped.\nThe strict mode distinguishes between traffic that's send to a pod from traffic that's destined for a cluster-external endpoint by considering the pod's CIDR range."]}),"\n",(0,i.jsxs)(t.p,{children:["Traffic originating from hosts isn't encrypted yet.\nThis mainly includes health checks from Kubernetes API server.\nAlso, traffic proxied over the API server via e.g. ",(0,i.jsx)(t.code,{children:"kubectl port-forward"})," isn't encrypted."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/401e1ad9.fd632f9c.js b/pr-preview/pr-4027/assets/js/401e1ad9.fd632f9c.js deleted file mode 100644 index e529a7f3b..000000000 --- a/pr-preview/pr-4027/assets/js/401e1ad9.fd632f9c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1006],{29318:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"2.24","label":"2.24","banner":null,"badge":true,"noIndex":false,"className":"docs-version-2.24","isLast":true,"docsSidebars":{"docs":[{"type":"link","href":"/constellation/pr-preview/pr-4027/","label":"Introduction","docId":"intro","unlisted":false},{"type":"category","label":"Basics","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/overview/confidential-kubernetes","label":"Confidential Kubernetes","docId":"overview/confidential-kubernetes","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/overview/security-benefits","label":"Security benefits","docId":"overview/security-benefits","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/overview/product","label":"Product features","docId":"overview/product","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/overview/clouds","label":"Feature status of clouds","docId":"overview/clouds","unlisted":false},{"type":"category","label":"Performance","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/overview/performance/compute","label":"Compute benchmarks","docId":"overview/performance/compute","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/overview/performance/io","label":"I/O benchmarks","docId":"overview/performance/io","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/overview/performance/application","label":"Application benchmarks","docId":"overview/performance/application","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/overview/performance/"},{"type":"link","href":"/constellation/pr-preview/pr-4027/overview/license","label":"License","docId":"overview/license","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/category/basics"},{"type":"category","label":"Getting started","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/getting-started/install","label":"Installation","docId":"getting-started/install","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/getting-started/first-steps","label":"First steps (cloud)","docId":"getting-started/first-steps","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/getting-started/first-steps-local","label":"First steps (local)","docId":"getting-started/first-steps-local","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/getting-started/marketplaces","label":"Cloud Marketplaces","docId":"getting-started/marketplaces","unlisted":false},{"type":"category","label":"Examples","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/getting-started/examples/emojivoto","label":"Emojivoto","docId":"getting-started/examples/emojivoto","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/getting-started/examples/online-boutique","label":"Online Boutique","docId":"getting-started/examples/online-boutique","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/getting-started/examples/horizontal-scaling","label":"Horizontal Pod Autoscaling","docId":"getting-started/examples/horizontal-scaling","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/getting-started/examples/filestash-s3proxy","label":"Filestash with s3proxy","docId":"getting-started/examples/filestash-s3proxy","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/getting-started/examples"}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/category/getting-started"},{"type":"category","label":"Workflows","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/workflows/verify-cli","label":"Verify the CLI","docId":"workflows/verify-cli","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/workflows/config","label":"Configure your cluster","docId":"workflows/config","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/workflows/create","label":"Create your cluster","docId":"workflows/create","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/workflows/scale","label":"Scale your cluster","docId":"workflows/scale","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/workflows/upgrade","label":"Upgrade your cluster","docId":"workflows/upgrade","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/workflows/lb","label":"Expose a service","docId":"workflows/lb","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/workflows/cert-manager","label":"Install cert-manager","docId":"workflows/cert-manager","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/workflows/s3proxy","label":"Install s3proxy","docId":"workflows/s3proxy","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/workflows/terminate","label":"Terminate your cluster","docId":"workflows/terminate","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/workflows/recovery","label":"Recover your cluster","docId":"workflows/recovery","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/workflows/verify-cluster","label":"Verify your cluster","docId":"workflows/verify-cluster","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/workflows/storage","label":"Use persistent storage","docId":"workflows/storage","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/workflows/terraform-provider","label":"Use the Terraform provider","docId":"workflows/terraform-provider","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/workflows/sbom","label":"Consume SBOMs","docId":"workflows/sbom","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/workflows/reproducible-builds","label":"Reproduce release artifacts","docId":"workflows/reproducible-builds","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/workflows/troubleshooting","label":"Troubleshooting","docId":"workflows/troubleshooting","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/category/workflows"},{"type":"category","label":"Architecture","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/architecture/overview","label":"Overview","docId":"architecture/overview","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/architecture/orchestration","label":"Cluster orchestration","docId":"architecture/orchestration","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/architecture/versions","label":"Versions and support","docId":"architecture/versions","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/architecture/microservices","label":"Microservices","docId":"architecture/microservices","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/architecture/attestation","label":"Attestation","docId":"architecture/attestation","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/architecture/images","label":"Images","docId":"architecture/images","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/architecture/keys","label":"Keys and cryptographic primitives","docId":"architecture/keys","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/architecture/encrypted-storage","label":"Encrypted persistent storage","docId":"architecture/encrypted-storage","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/architecture/networking","label":"Networking","docId":"architecture/networking","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/architecture/observability","label":"Observability","docId":"architecture/observability","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/category/architecture"},{"type":"category","label":"Reference","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/reference/cli","label":"CLI","docId":"reference/cli","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/reference/migration","label":"Configuration migrations","docId":"reference/migration","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/reference/terraform","label":"Terraform usage","docId":"reference/terraform","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/reference/slsa","label":"SLSA adoption","docId":"reference/slsa","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/category/reference"}]},"docs":{"architecture/attestation":{"id":"architecture/attestation","title":"Attestation","description":"This page explains Constellation\'s attestation process and highlights the cornerstones of its trust model.","sidebar":"docs"},"architecture/encrypted-storage":{"id":"architecture/encrypted-storage","title":"Encrypted persistent storage","description":"Confidential VMs provide runtime memory encryption to protect data in use.","sidebar":"docs"},"architecture/images":{"id":"architecture/images","title":"Constellation images","description":"Constellation uses a minimal version of Fedora as the operating system running inside confidential VMs. This Linux distribution is optimized for containers and designed to be stateless.","sidebar":"docs"},"architecture/keys":{"id":"architecture/keys","title":"Key management and cryptographic primitives","description":"Constellation protects and isolates your cluster and workloads.","sidebar":"docs"},"architecture/microservices":{"id":"architecture/microservices","title":"Microservices","description":"Constellation takes care of bootstrapping and initializing a Confidential Kubernetes cluster.","sidebar":"docs"},"architecture/networking":{"id":"architecture/networking","title":"Network encryption","description":"Constellation encrypts all pod communication using the container network interface (CNI).","sidebar":"docs"},"architecture/observability":{"id":"architecture/observability","title":"Observability","description":"In Kubernetes, observability is the ability to gain insight into the behavior and performance of applications.","sidebar":"docs"},"architecture/orchestration":{"id":"architecture/orchestration","title":"Orchestrating Constellation clusters","description":"You can use the CLI to create a cluster on the supported cloud platforms.","sidebar":"docs"},"architecture/overview":{"id":"architecture/overview","title":"Overview","description":"Constellation is a cloud-based confidential orchestration platform.","sidebar":"docs"},"architecture/versions":{"id":"architecture/versions","title":"Versions and support policy","description":"All components of Constellation use a three-digit version number of the form v...","sidebar":"docs"},"getting-started/examples":{"id":"getting-started/examples","title":"Examples","description":"After you installed the CLI and created your first cluster, you\'re ready to deploy applications. Why not start with one of the following examples?","sidebar":"docs"},"getting-started/examples/emojivoto":{"id":"getting-started/examples/emojivoto","title":"Emojivoto","description":"Emojivoto is a simple and fun application that\'s well suited to test the basic functionality of your cluster.","sidebar":"docs"},"getting-started/examples/filestash-s3proxy":{"id":"getting-started/examples/filestash-s3proxy","title":"Deploying Filestash","description":"Filestash is a web frontend for different storage backends, including S3.","sidebar":"docs"},"getting-started/examples/horizontal-scaling":{"id":"getting-started/examples/horizontal-scaling","title":"Horizontal Pod Autoscaling","description":"This example demonstrates Constellation\'s autoscaling capabilities. It\'s based on the Kubernetes HorizontalPodAutoscaler Walkthrough. During the following steps, Constellation will spawn new VMs on demand, verify them, add them to the cluster, and delete them again when the load has settled down.","sidebar":"docs"},"getting-started/examples/online-boutique":{"id":"getting-started/examples/online-boutique","title":"Online Boutique","description":"Online Boutique is an e-commerce demo application by Google consisting of 11 separate microservices. In this demo, Constellation automatically sets up a load balancer on your CSP, making it easy to expose services from your confidential cluster.","sidebar":"docs"},"getting-started/first-steps":{"id":"getting-started/first-steps","title":"First steps with Constellation","description":"The following steps guide you through the process of creating a cluster and deploying a sample app. This example assumes that you have successfully installed and set up Constellation,","sidebar":"docs"},"getting-started/first-steps-local":{"id":"getting-started/first-steps-local","title":"First steps with a local cluster","description":"A local cluster lets you deploy and test Constellation without a cloud subscription.","sidebar":"docs"},"getting-started/install":{"id":"getting-started/install","title":"Installation and setup","description":"Constellation runs entirely in your cloud environment and can be controlled via a dedicated command-line interface (CLI) or a Terraform provider.","sidebar":"docs"},"getting-started/marketplaces":{"id":"getting-started/marketplaces","title":"Using Constellation via Cloud Marketplaces","description":"Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please contact us.","sidebar":"docs"},"intro":{"id":"intro","title":"Introduction","description":"Constellation is no longer actively maintained by Edgeless Systems.","sidebar":"docs"},"overview/clouds":{"id":"overview/clouds","title":"Feature status of clouds","description":"What works on which cloud? Currently, Confidential VMs (CVMs) are available in varying quality on the different clouds and software stacks.","sidebar":"docs"},"overview/confidential-kubernetes":{"id":"overview/confidential-kubernetes","title":"Confidential Kubernetes","description":"We use the term Confidential Kubernetes to refer to the concept of using confidential-computing technology to shield entire Kubernetes clusters from the infrastructure. The three defining properties of this concept are:","sidebar":"docs"},"overview/license":{"id":"overview/license","title":"License","description":"Constellation is available under the Business Source License 1.1.","sidebar":"docs"},"overview/performance/application":{"id":"overview/performance/application","title":"Application benchmarks","description":"HashiCorp Vault","sidebar":"docs"},"overview/performance/compute":{"id":"overview/performance/compute","title":"Impact of runtime encryption on compute performance","description":"All nodes in a Constellation cluster are executed inside Confidential VMs (CVMs). Consequently, the performance of Constellation is inherently linked to the performance of these CVMs.","sidebar":"docs"},"overview/performance/io":{"id":"overview/performance/io","title":"I/O performance benchmarks","description":"To assess the overall performance of Constellation, this benchmark evaluates Constellation v2.6.0 in terms of storage I/O using fio and network performance using the Kubernetes Network Benchmark.","sidebar":"docs"},"overview/performance/performance":{"id":"overview/performance/performance","title":"Performance analysis of Constellation","description":"This section provides a comprehensive examination of the performance characteristics of Constellation.","sidebar":"docs"},"overview/product":{"id":"overview/product","title":"Product features","description":"Constellation is a Kubernetes engine that aims to provide the best possible data security in combination with enterprise-grade scalability and reliability features---and a smooth user experience.","sidebar":"docs"},"overview/security-benefits":{"id":"overview/security-benefits","title":"Security benefits and threat model","description":"Constellation implements the Confidential Kubernetes concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be verified.","sidebar":"docs"},"reference/cli":{"id":"reference/cli","title":"CLI reference","description":"Use the Constellation CLI to create and manage your clusters.","sidebar":"docs"},"reference/migration":{"id":"reference/migration","title":"Migrations","description":"This document describes breaking changes and migrations between Constellation releases.","sidebar":"docs"},"reference/slsa":{"id":"reference/slsa","title":"Supply chain levels for software artifacts (SLSA) adoption","description":"Supply chain Levels for Software Artifacts, or SLSA (salsa) is a framework for improving and grading a project\'s build system and engineering processes. SLSA focuses on security improvements for source code storage as well as build system definition, execution, and observation. SLSA is structured in four levels. This page describes the adoption of SLSA for Constellation.","sidebar":"docs"},"reference/terraform":{"id":"reference/terraform","title":"Terraform usage","description":"Terraform is an Infrastructure as Code (IaC) framework to manage cloud resources. This page explains how Constellation uses it internally and how advanced users may manually use it to have more control over the resource creation.","sidebar":"docs"},"workflows/cert-manager":{"id":"workflows/cert-manager","title":"Install cert-manager","description":"If you want to use cert-manager with Constellation, pay attention to the following to avoid potential pitfalls.","sidebar":"docs"},"workflows/config":{"id":"workflows/config","title":"Configure your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","sidebar":"docs"},"workflows/create":{"id":"workflows/create","title":"Create your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","sidebar":"docs"},"workflows/lb":{"id":"workflows/lb","title":"Expose a service","description":"Constellation integrates the native load balancers of each CSP. Therefore, to expose a service simply create a service of type LoadBalancer.","sidebar":"docs"},"workflows/recovery":{"id":"workflows/recovery","title":"Recover your cluster","description":"Recovery of a Constellation cluster means getting it back into a healthy state after too many concurrent node failures in the control plane.","sidebar":"docs"},"workflows/reproducible-builds":{"id":"workflows/reproducible-builds","title":"Reproduce released artifacts","description":"Constellation has first-class support for reproducible builds.","sidebar":"docs"},"workflows/s3proxy":{"id":"workflows/s3proxy","title":"Install s3proxy","description":"Constellation includes a transparent client-side encryption proxy for AWS S3 and compatible stores.","sidebar":"docs"},"workflows/sbom":{"id":"workflows/sbom","title":"Consume software bill of materials (SBOMs)","description":"---","sidebar":"docs"},"workflows/scale":{"id":"workflows/scale","title":"Scale your cluster","description":"Constellation provides all features of a Kubernetes cluster including scaling and autoscaling.","sidebar":"docs"},"workflows/storage":{"id":"workflows/storage","title":"Use persistent storage","description":"Persistent storage in Kubernetes requires cloud-specific configuration.","sidebar":"docs"},"workflows/terminate":{"id":"workflows/terminate","title":"Terminate your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","sidebar":"docs"},"workflows/terraform-provider":{"id":"workflows/terraform-provider","title":"Use the Terraform provider","description":"The Constellation Terraform provider allows to manage the full lifecycle of a Constellation cluster (namely creation, upgrades, and deletion) via Terraform.","sidebar":"docs"},"workflows/troubleshooting":{"id":"workflows/troubleshooting","title":"Troubleshooting","description":"This section aids you in finding problems when working with Constellation.","sidebar":"docs"},"workflows/trusted-launch":{"id":"workflows/trusted-launch","title":"Use Azure trusted launch VMs","description":"Constellation also supports trusted launch VMs on Microsoft Azure. Trusted launch VMs don\'t offer the same level of security as Confidential VMs, but are available in more regions and in larger quantities. The main difference between trusted launch VMs and normal VMs is that the former offer vTPM-based remote attestation. When used with trusted launch VMs, Constellation relies on vTPM-based remote attestation to verify nodes."},"workflows/upgrade":{"id":"workflows/upgrade","title":"Upgrade your cluster","description":"Constellation provides an easy way to upgrade all components of your cluster, without disrupting its availability.","sidebar":"docs"},"workflows/verify-cli":{"id":"workflows/verify-cli","title":"Verify the CLI","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","sidebar":"docs"},"workflows/verify-cluster":{"id":"workflows/verify-cluster","title":"Verify your cluster","description":"Constellation\'s attestation feature allows you, or a third party, to verify the integrity and confidentiality of your Constellation cluster.","sidebar":"docs"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/40c738e9.e56e6bc5.js b/pr-preview/pr-4027/assets/js/40c738e9.e56e6bc5.js deleted file mode 100644 index 6789ec8d0..000000000 --- a/pr-preview/pr-4027/assets/js/40c738e9.e56e6bc5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8598],{6106:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>c,contentTitle:()=>l,default:()=>p,frontMatter:()=>i,metadata:()=>n,toc:()=>a});const n=JSON.parse('{"id":"architecture/versions","title":"Versions and support policy","description":"All components of Constellation use a three-digit version number of the form v...","source":"@site/versioned_docs/version-2.24/architecture/versions.md","sourceDirName":"architecture","slug":"/architecture/versions","permalink":"/constellation/pr-preview/pr-4027/architecture/versions","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/architecture/versions.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Cluster orchestration","permalink":"/constellation/pr-preview/pr-4027/architecture/orchestration"},"next":{"title":"Microservices","permalink":"/constellation/pr-preview/pr-4027/architecture/microservices"}}');var t=r(74848),o=r(28453);const i={},l="Versions and support policy",c={},a=[{value:"Kubernetes support policy",id:"kubernetes-support-policy",level:2}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"versions-and-support-policy",children:"Versions and support policy"})}),"\n",(0,t.jsxs)(s.p,{children:["All components of Constellation use a three-digit version number of the form ",(0,t.jsx)(s.code,{children:"v<MAJOR>.<MINOR>.<PATCH>"}),".\nThe components are released in lock step, usually on the first Tuesday of every month. This release primarily introduces new features, but may also include security or performance improvements. The ",(0,t.jsx)(s.code,{children:"MINOR"})," version will be incremented as part of this release."]}),"\n",(0,t.jsxs)(s.p,{children:["Additional ",(0,t.jsx)(s.code,{children:"PATCH"})," releases may be created on demand, to fix security issues or bugs before the next ",(0,t.jsx)(s.code,{children:"MINOR"})," release window."]}),"\n",(0,t.jsxs)(s.p,{children:["New releases are published on ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"kubernetes-support-policy",children:"Kubernetes support policy"}),"\n",(0,t.jsxs)(s.p,{children:["Constellation is aligned to the ",(0,t.jsx)(s.a,{href:"https://kubernetes.io/releases/version-skew-policy/#supported-versions",children:"version support policy of Kubernetes"}),", and therefore usually supports the most recent three minor versions.\nWhen a new minor version of Kubernetes is released, support is added to the next Constellation release, and that version then supports four Kubernetes versions.\nSubsequent Constellation releases drop support for the oldest (and deprecated) Kubernetes version."]}),"\n",(0,t.jsx)(s.p,{children:"The following Kubernetes versions are currently supported:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"v1.30.14"}),"\n",(0,t.jsx)(s.li,{children:"v1.31.12"}),"\n",(0,t.jsx)(s.li,{children:"v1.32.8"}),"\n"]})]})}function p(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>i,x:()=>l});var n=r(96540);const t={},o=n.createContext(t);function i(e){const s=n.useContext(o);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),n.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/42298223.9ca426d3.js b/pr-preview/pr-4027/assets/js/42298223.9ca426d3.js deleted file mode 100644 index 73ca486d6..000000000 --- a/pr-preview/pr-4027/assets/js/42298223.9ca426d3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7373],{2391:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Workflows","slug":"/category/workflows","permalink":"/constellation/pr-preview/pr-4027/2.23/category/workflows","sidebar":"docs","navigation":{"previous":{"title":"Filestash with s3proxy","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/filestash-s3proxy"},"next":{"title":"Verify the CLI","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cli"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/4250.0d4c2516.js b/pr-preview/pr-4027/assets/js/4250.0d4c2516.js deleted file mode 100644 index 0c3b23b45..000000000 --- a/pr-preview/pr-4027/assets/js/4250.0d4c2516.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4250],{81869:(s,a,c)=>{c.d(a,{createGitGraphServices:()=>e.b});var e=c(67539);c(87960)}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/42888a29.52b6655b.js b/pr-preview/pr-4027/assets/js/42888a29.52b6655b.js deleted file mode 100644 index 915102df7..000000000 --- a/pr-preview/pr-4027/assets/js/42888a29.52b6655b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2719],{2401:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/concept-constellation-f869032711a972295d5ddce42c37995c.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var r=n(96540);const i={},s=r.createContext(i);function o(e){const t=r.useContext(s);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(s.Provider,{value:t},e.children)}},50819:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/concept-managed-33482ac199f949182872dc32d69bd3bc.svg"},60911:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"overview/confidential-kubernetes","title":"Confidential Kubernetes","description":"We use the term Confidential Kubernetes to refer to the concept of using confidential-computing technology to shield entire Kubernetes clusters from the infrastructure. The three defining properties of this concept are:","source":"@site/versioned_docs/version-2.24/overview/confidential-kubernetes.md","sourceDirName":"overview","slug":"/overview/confidential-kubernetes","permalink":"/constellation/pr-preview/pr-4027/overview/confidential-kubernetes","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/overview/confidential-kubernetes.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Basics","permalink":"/constellation/pr-preview/pr-4027/category/basics"},"next":{"title":"Security benefits","permalink":"/constellation/pr-preview/pr-4027/overview/security-benefits"}}');var i=n(74848),s=n(28453);const o={},a="Confidential Kubernetes",l={},c=[{value:"Constellation security features",id:"constellation-security-features",level:2},{value:"Comparison: Managed Kubernetes with CVMs",id:"comparison-managed-kubernetes-with-cvms",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"confidential-kubernetes",children:"Confidential Kubernetes"})}),"\n",(0,i.jsxs)(t.p,{children:["We use the term ",(0,i.jsx)(t.em,{children:"Confidential Kubernetes"})," to refer to the concept of using confidential-computing technology to shield entire Kubernetes clusters from the infrastructure. The three defining properties of this concept are:"]}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Workload shielding"}),": the confidentiality and integrity of all workload-related data and code are enforced."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Control plane shielding"}),": the confidentiality and integrity of the cluster's control plane, state, and workload configuration are enforced."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Attestation and verifiability"}),": the two properties above can be verified remotely based on hardware-rooted cryptographic certificates."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Each of the above properties is equally important. Only with all three in conjunction, an entire cluster can be shielded without gaps."}),"\n",(0,i.jsx)(t.h2,{id:"constellation-security-features",children:"Constellation security features"}),"\n",(0,i.jsx)(t.p,{children:"Constellation implements the Confidential Kubernetes concept with the following security features."}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Runtime encryption"}),": Constellation runs all Kubernetes nodes inside Confidential VMs (CVMs). This gives runtime encryption for the entire cluster."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Network and storage encryption"}),": Constellation augments this with transparent encryption of the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/networking",children:"network"}),", ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/encrypted-storage",children:"persistent storage"}),", and other managed storage like ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/encrypted-storage#encrypted-s3-object-storage",children:"AWS S3"}),". Thus, workloads and control plane are truly end-to-end encrypted: at rest, in transit, and at runtime."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Transparent key management"}),": Constellation manages the corresponding ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys",children:"cryptographic keys"})," inside CVMs."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Node attestation and verification"}),": Constellation verifies the integrity of each new CVM-based node using ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/attestation",children:"remote attestation"}),'. Only "good" nodes receive the cryptographic keys required to access the network and storage of a cluster.']}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Confidential computing-optimized images"}),': A node is "good" if it\'s running a signed Constellation ',(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/images",children:"node image"})," inside a CVM and is in the expected state. (Node images are hardware-measured during boot. The measurements are reflected in the attestation statements that are produced by nodes and verified by Constellation.)"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:'"Whole cluster" attestation'}),": Towards the DevOps engineer, Constellation provides a single hardware-rooted certificate from which all of the above can be verified."]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["With the above, Constellation wraps an entire cluster into one coherent and verifiable ",(0,i.jsx)(t.em,{children:"confidential context"}),". The concept is depicted in the following."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Confidential Kubernetes",src:n(2401).A+"",width:"3767",height:"1902"})}),"\n",(0,i.jsx)(t.h2,{id:"comparison-managed-kubernetes-with-cvms",children:"Comparison: Managed Kubernetes with CVMs"}),"\n",(0,i.jsxs)(t.p,{children:["In comparison, managed Kubernetes with CVMs, as it's for example offered in ",(0,i.jsx)(t.a,{href:"https://azure.microsoft.com/en-us/services/kubernetes-service/",children:"AKS"})," and ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/kubernetes-engine",children:"GKE"}),", only provides runtime encryption for certain worker nodes. Here, each worker node is a separate (and typically unverified) confidential context. This only provides limited security benefits as it only prevents direct access to a worker node's memory. The large majority of potential attacks through the infrastructure remain unaffected. This includes attacks through the control plane, access to external key management, and the corruption of worker node images. This leaves many problems unsolved. For instance, ",(0,i.jsx)(t.em,{children:"Node A"})," has no means to verify if ",(0,i.jsx)(t.em,{children:"Node B"}),' is "good" and if it\'s OK to share data with it. Consequently, this approach leaves a large attack surface, as is depicted in the following.']}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Concept: Managed Kubernetes plus CVMs",src:n(50819).A+"",width:"3767",height:"1902"})}),"\n",(0,i.jsx)(t.p,{children:"The following table highlights the key differences in terms of features."}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{}),(0,i.jsx)(t.th,{children:"Managed Kubernetes with CVMs"}),(0,i.jsx)(t.th,{children:"Confidential Kubernetes (Constellation\u2728)"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Runtime encryption"}),(0,i.jsx)(t.td,{children:"Partial (data plane only)"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Node image verification"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Full cluster attestation"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Transparent network encryption"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Transparent storage encryption"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Confidential key management"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Cloud agnostic / multi-cloud"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/4379.4c9173a3.js b/pr-preview/pr-4027/assets/js/4379.4c9173a3.js deleted file mode 100644 index 6b16eaddb..000000000 --- a/pr-preview/pr-4027/assets/js/4379.4c9173a3.js +++ /dev/null @@ -1 +0,0 @@ -(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4379],{64379:(t,e,n)=>{"use strict";n.d(e,{diagram:()=>It});var i=n(13226),s=n(67633),r=n(40797),a=n(16750),o=n(74353),c=n(68313),l=n(90445),d=n(97375),u=n(70451),h=function(){var t=(0,r.K2)(function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},"o"),e=[6,8,10,12,13,14,15,16,17,18,20,21,22,23,24,25,26,27,28,29,30,31,33,35,36,38,40],n=[1,26],i=[1,27],s=[1,28],a=[1,29],o=[1,30],c=[1,31],l=[1,32],d=[1,33],u=[1,34],h=[1,9],f=[1,10],y=[1,11],k=[1,12],m=[1,13],p=[1,14],g=[1,15],b=[1,16],v=[1,19],T=[1,20],x=[1,21],w=[1,22],_=[1,23],D=[1,25],$=[1,35],C={trace:(0,r.K2)(function(){},"trace"),yy:{},symbols_:{error:2,start:3,gantt:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NL:10,weekday:11,weekday_monday:12,weekday_tuesday:13,weekday_wednesday:14,weekday_thursday:15,weekday_friday:16,weekday_saturday:17,weekday_sunday:18,weekend:19,weekend_friday:20,weekend_saturday:21,dateFormat:22,inclusiveEndDates:23,topAxis:24,axisFormat:25,tickInterval:26,excludes:27,includes:28,todayMarker:29,title:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,section:36,clickStatement:37,taskTxt:38,taskData:39,click:40,callbackname:41,callbackargs:42,href:43,clickStatementDebug:44,$accept:0,$end:1},terminals_:{2:"error",4:"gantt",6:"EOF",8:"SPACE",10:"NL",12:"weekday_monday",13:"weekday_tuesday",14:"weekday_wednesday",15:"weekday_thursday",16:"weekday_friday",17:"weekday_saturday",18:"weekday_sunday",20:"weekend_friday",21:"weekend_saturday",22:"dateFormat",23:"inclusiveEndDates",24:"topAxis",25:"axisFormat",26:"tickInterval",27:"excludes",28:"includes",29:"todayMarker",30:"title",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",36:"section",38:"taskTxt",39:"taskData",40:"click",41:"callbackname",42:"callbackargs",43:"href"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[19,1],[19,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,2],[37,2],[37,3],[37,3],[37,4],[37,3],[37,4],[37,2],[44,2],[44,3],[44,3],[44,4],[44,3],[44,4],[44,2]],performAction:(0,r.K2)(function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 2:case 6:case 7:this.$=[];break;case 3:r[o-1].push(r[o]),this.$=r[o-1];break;case 4:case 5:this.$=r[o];break;case 8:i.setWeekday("monday");break;case 9:i.setWeekday("tuesday");break;case 10:i.setWeekday("wednesday");break;case 11:i.setWeekday("thursday");break;case 12:i.setWeekday("friday");break;case 13:i.setWeekday("saturday");break;case 14:i.setWeekday("sunday");break;case 15:i.setWeekend("friday");break;case 16:i.setWeekend("saturday");break;case 17:i.setDateFormat(r[o].substr(11)),this.$=r[o].substr(11);break;case 18:i.enableInclusiveEndDates(),this.$=r[o].substr(18);break;case 19:i.TopAxis(),this.$=r[o].substr(8);break;case 20:i.setAxisFormat(r[o].substr(11)),this.$=r[o].substr(11);break;case 21:i.setTickInterval(r[o].substr(13)),this.$=r[o].substr(13);break;case 22:i.setExcludes(r[o].substr(9)),this.$=r[o].substr(9);break;case 23:i.setIncludes(r[o].substr(9)),this.$=r[o].substr(9);break;case 24:i.setTodayMarker(r[o].substr(12)),this.$=r[o].substr(12);break;case 27:i.setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 28:this.$=r[o].trim(),i.setAccTitle(this.$);break;case 29:case 30:this.$=r[o].trim(),i.setAccDescription(this.$);break;case 31:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 33:i.addTask(r[o-1],r[o]),this.$="task";break;case 34:this.$=r[o-1],i.setClickEvent(r[o-1],r[o],null);break;case 35:this.$=r[o-2],i.setClickEvent(r[o-2],r[o-1],r[o]);break;case 36:this.$=r[o-2],i.setClickEvent(r[o-2],r[o-1],null),i.setLink(r[o-2],r[o]);break;case 37:this.$=r[o-3],i.setClickEvent(r[o-3],r[o-2],r[o-1]),i.setLink(r[o-3],r[o]);break;case 38:this.$=r[o-2],i.setClickEvent(r[o-2],r[o],null),i.setLink(r[o-2],r[o-1]);break;case 39:this.$=r[o-3],i.setClickEvent(r[o-3],r[o-1],r[o]),i.setLink(r[o-3],r[o-2]);break;case 40:this.$=r[o-1],i.setLink(r[o-1],r[o]);break;case 41:case 47:this.$=r[o-1]+" "+r[o];break;case 42:case 43:case 45:this.$=r[o-2]+" "+r[o-1]+" "+r[o];break;case 44:case 46:this.$=r[o-3]+" "+r[o-2]+" "+r[o-1]+" "+r[o]}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:17,12:n,13:i,14:s,15:a,16:o,17:c,18:l,19:18,20:d,21:u,22:h,23:f,24:y,25:k,26:m,27:p,28:g,29:b,30:v,31:T,33:x,35:w,36:_,37:24,38:D,40:$},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:36,11:17,12:n,13:i,14:s,15:a,16:o,17:c,18:l,19:18,20:d,21:u,22:h,23:f,24:y,25:k,26:m,27:p,28:g,29:b,30:v,31:T,33:x,35:w,36:_,37:24,38:D,40:$},t(e,[2,5]),t(e,[2,6]),t(e,[2,17]),t(e,[2,18]),t(e,[2,19]),t(e,[2,20]),t(e,[2,21]),t(e,[2,22]),t(e,[2,23]),t(e,[2,24]),t(e,[2,25]),t(e,[2,26]),t(e,[2,27]),{32:[1,37]},{34:[1,38]},t(e,[2,30]),t(e,[2,31]),t(e,[2,32]),{39:[1,39]},t(e,[2,8]),t(e,[2,9]),t(e,[2,10]),t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),t(e,[2,15]),t(e,[2,16]),{41:[1,40],43:[1,41]},t(e,[2,4]),t(e,[2,28]),t(e,[2,29]),t(e,[2,33]),t(e,[2,34],{42:[1,42],43:[1,43]}),t(e,[2,40],{41:[1,44]}),t(e,[2,35],{43:[1,45]}),t(e,[2,36]),t(e,[2,38],{42:[1,46]}),t(e,[2,37]),t(e,[2,39])],defaultActions:{},parseError:(0,r.K2)(function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},"parseError"),parse:(0,r.K2)(function(t){var e=this,n=[0],i=[],s=[null],a=[],o=this.table,c="",l=0,d=0,u=0,h=a.slice.call(arguments,1),f=Object.create(this.lexer),y={yy:{}};for(var k in this.yy)Object.prototype.hasOwnProperty.call(this.yy,k)&&(y.yy[k]=this.yy[k]);f.setInput(t,y.yy),y.yy.lexer=f,y.yy.parser=this,void 0===f.yylloc&&(f.yylloc={});var m=f.yylloc;a.push(m);var p=f.options&&f.options.ranges;function g(){var t;return"number"!=typeof(t=i.pop()||f.lex()||1)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,r.K2)(function(t){n.length=n.length-2*t,s.length=s.length-t,a.length=a.length-t},"popStack"),(0,r.K2)(g,"lex");for(var b,v,T,x,w,_,D,$,C,S={};;){if(T=n[n.length-1],this.defaultActions[T]?x=this.defaultActions[T]:(null==b&&(b=g()),x=o[T]&&o[T][b]),void 0===x||!x.length||!x[0]){var K="";for(_ in C=[],o[T])this.terminals_[_]&&_>2&&C.push("'"+this.terminals_[_]+"'");K=f.showPosition?"Parse error on line "+(l+1)+":\n"+f.showPosition()+"\nExpecting "+C.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(K,{text:f.match,token:this.terminals_[b]||b,line:f.yylineno,loc:m,expected:C})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+T+", token: "+b);switch(x[0]){case 1:n.push(b),s.push(f.yytext),a.push(f.yylloc),n.push(x[1]),b=null,v?(b=v,v=null):(d=f.yyleng,c=f.yytext,l=f.yylineno,m=f.yylloc,u>0&&u--);break;case 2:if(D=this.productions_[x[1]][1],S.$=s[s.length-D],S._$={first_line:a[a.length-(D||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(D||1)].first_column,last_column:a[a.length-1].last_column},p&&(S._$.range=[a[a.length-(D||1)].range[0],a[a.length-1].range[1]]),void 0!==(w=this.performAction.apply(S,[c,d,l,y.yy,x[1],s,a].concat(h))))return w;D&&(n=n.slice(0,-1*D*2),s=s.slice(0,-1*D),a=a.slice(0,-1*D)),n.push(this.productions_[x[1]][0]),s.push(S.$),a.push(S._$),$=o[n[n.length-2]][n[n.length-1]],n.push($);break;case 3:return!0}}return!0},"parse")},S=function(){return{EOF:1,parseError:(0,r.K2)(function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},"parseError"),setInput:(0,r.K2)(function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:(0,r.K2)(function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},"input"),unput:(0,r.K2)(function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},"unput"),more:(0,r.K2)(function(){return this._more=!0,this},"more"),reject:(0,r.K2)(function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"reject"),less:(0,r.K2)(function(t){this.unput(this.match.slice(t))},"less"),pastInput:(0,r.K2)(function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:(0,r.K2)(function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:(0,r.K2)(function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},"showPosition"),test_match:(0,r.K2)(function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},"test_match"),next:(0,r.K2)(function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((n=this._input.match(this.rules[s[r]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:(0,r.K2)(function(){var t=this.next();return t||this.lex()},"lex"),begin:(0,r.K2)(function(t){this.conditionStack.push(t)},"begin"),popState:(0,r.K2)(function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:(0,r.K2)(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:(0,r.K2)(function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},"topState"),pushState:(0,r.K2)(function(t){this.begin(t)},"pushState"),stateStackSize:(0,r.K2)(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,r.K2)(function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),"open_directive";case 1:return this.begin("acc_title"),31;case 2:return this.popState(),"acc_title_value";case 3:return this.begin("acc_descr"),33;case 4:return this.popState(),"acc_descr_value";case 5:this.begin("acc_descr_multiline");break;case 6:case 15:case 18:case 21:case 24:this.popState();break;case 7:return"acc_descr_multiline_value";case 8:case 9:case 10:case 12:case 13:break;case 11:return 10;case 14:this.begin("href");break;case 16:return 43;case 17:this.begin("callbackname");break;case 19:this.popState(),this.begin("callbackargs");break;case 20:return 41;case 22:return 42;case 23:this.begin("click");break;case 25:return 40;case 26:return 4;case 27:return 22;case 28:return 23;case 29:return 24;case 30:return 25;case 31:return 26;case 32:return 28;case 33:return 27;case 34:return 29;case 35:return 12;case 36:return 13;case 37:return 14;case 38:return 15;case 39:return 16;case 40:return 17;case 41:return 18;case 42:return 20;case 43:return 21;case 44:return"date";case 45:return 30;case 46:return"accDescription";case 47:return 36;case 48:return 38;case 49:return 39;case 50:return":";case 51:return 6;case 52:return"INVALID"}},"anonymous"),rules:[/^(?:%%\{)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%(?!\{)*[^\n]*)/i,/^(?:[^\}]%%*[^\n]*)/i,/^(?:%%*[^\n]*[\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:%[^\n]*)/i,/^(?:href[\s]+["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:call[\s]+)/i,/^(?:\([\s]*\))/i,/^(?:\()/i,/^(?:[^(]*)/i,/^(?:\))/i,/^(?:[^)]*)/i,/^(?:click[\s]+)/i,/^(?:[\s\n])/i,/^(?:[^\s\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:inclusiveEndDates\b)/i,/^(?:topAxis\b)/i,/^(?:axisFormat\s[^#\n;]+)/i,/^(?:tickInterval\s[^#\n;]+)/i,/^(?:includes\s[^#\n;]+)/i,/^(?:excludes\s[^#\n;]+)/i,/^(?:todayMarker\s[^\n;]+)/i,/^(?:weekday\s+monday\b)/i,/^(?:weekday\s+tuesday\b)/i,/^(?:weekday\s+wednesday\b)/i,/^(?:weekday\s+thursday\b)/i,/^(?:weekday\s+friday\b)/i,/^(?:weekday\s+saturday\b)/i,/^(?:weekday\s+sunday\b)/i,/^(?:weekend\s+friday\b)/i,/^(?:weekend\s+saturday\b)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^\n]+)/i,/^(?:accDescription\s[^#\n;]+)/i,/^(?:section\s[^\n]+)/i,/^(?:[^:\n]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[6,7],inclusive:!1},acc_descr:{rules:[4],inclusive:!1},acc_title:{rules:[2],inclusive:!1},callbackargs:{rules:[21,22],inclusive:!1},callbackname:{rules:[18,19,20],inclusive:!1},href:{rules:[15,16],inclusive:!1},click:{rules:[24,25],inclusive:!1},INITIAL:{rules:[0,1,3,5,8,9,10,11,12,13,14,17,23,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52],inclusive:!0}}}}();function K(){this.yy={}}return C.lexer=S,(0,r.K2)(K,"Parser"),K.prototype=C,C.Parser=K,new K}();h.parser=h;var f=h;o.extend(c),o.extend(l),o.extend(d);var y,k,m={friday:5,saturday:6},p="",g="",b=void 0,v="",T=[],x=[],w=new Map,_=[],D=[],$="",C="",S=["active","done","crit","milestone","vert"],K=[],E=!1,M=!1,A="sunday",L="saturday",Y=0,I=(0,r.K2)(function(){_=[],D=[],$="",K=[],ft=0,y=void 0,k=void 0,pt=[],p="",g="",C="",b=void 0,v="",T=[],x=[],E=!1,M=!1,Y=0,w=new Map,(0,s.IU)(),A="sunday",L="saturday"},"clear"),W=(0,r.K2)(function(t){g=t},"setAxisFormat"),F=(0,r.K2)(function(){return g},"getAxisFormat"),O=(0,r.K2)(function(t){b=t},"setTickInterval"),P=(0,r.K2)(function(){return b},"getTickInterval"),B=(0,r.K2)(function(t){v=t},"setTodayMarker"),z=(0,r.K2)(function(){return v},"getTodayMarker"),N=(0,r.K2)(function(t){p=t},"setDateFormat"),G=(0,r.K2)(function(){E=!0},"enableInclusiveEndDates"),H=(0,r.K2)(function(){return E},"endDatesAreInclusive"),R=(0,r.K2)(function(){M=!0},"enableTopAxis"),j=(0,r.K2)(function(){return M},"topAxisEnabled"),U=(0,r.K2)(function(t){C=t},"setDisplayMode"),V=(0,r.K2)(function(){return C},"getDisplayMode"),Z=(0,r.K2)(function(){return p},"getDateFormat"),X=(0,r.K2)(function(t){T=t.toLowerCase().split(/[\s,]+/)},"setIncludes"),q=(0,r.K2)(function(){return T},"getIncludes"),Q=(0,r.K2)(function(t){x=t.toLowerCase().split(/[\s,]+/)},"setExcludes"),J=(0,r.K2)(function(){return x},"getExcludes"),tt=(0,r.K2)(function(){return w},"getLinks"),et=(0,r.K2)(function(t){$=t,_.push(t)},"addSection"),nt=(0,r.K2)(function(){return _},"getSections"),it=(0,r.K2)(function(){let t=xt();let e=0;for(;!t&&e<10;)t=xt(),e++;return D=pt},"getTasks"),st=(0,r.K2)(function(t,e,n,i){const s=t.format(e.trim()),r=t.format("YYYY-MM-DD");return!i.includes(s)&&!i.includes(r)&&(!(!n.includes("weekends")||t.isoWeekday()!==m[L]&&t.isoWeekday()!==m[L]+1)||(!!n.includes(t.format("dddd").toLowerCase())||(n.includes(s)||n.includes(r))))},"isInvalidDate"),rt=(0,r.K2)(function(t){A=t},"setWeekday"),at=(0,r.K2)(function(){return A},"getWeekday"),ot=(0,r.K2)(function(t){L=t},"setWeekend"),ct=(0,r.K2)(function(t,e,n,i){if(!n.length||t.manualEndTime)return;let s,r;s=t.startTime instanceof Date?o(t.startTime):o(t.startTime,e,!0),s=s.add(1,"d"),r=t.endTime instanceof Date?o(t.endTime):o(t.endTime,e,!0);const[a,c]=lt(s,r,e,n,i);t.endTime=a.toDate(),t.renderEndTime=c},"checkTaskDates"),lt=(0,r.K2)(function(t,e,n,i,s){let r=!1,a=null;for(;t<=e;)r||(a=e.toDate()),r=st(t,n,i,s),r&&(e=e.add(1,"d")),t=t.add(1,"d");return[e,a]},"fixTaskDates"),dt=(0,r.K2)(function(t,e,n){if(n=n.trim(),("x"===e.trim()||"X"===e.trim())&&/^\d+$/.test(n))return new Date(Number(n));const i=/^after\s+(?<ids>[\d\w- ]+)/.exec(n);if(null!==i){let t=null;for(const n of i.groups.ids.split(" ")){let e=vt(n);void 0!==e&&(!t||e.endTime>t.endTime)&&(t=e)}if(t)return t.endTime;const e=new Date;return e.setHours(0,0,0,0),e}let s=o(n,e.trim(),!0);if(s.isValid())return s.toDate();{r.Rm.debug("Invalid date:"+n),r.Rm.debug("With date format:"+e.trim());const t=new Date(n);if(void 0===t||isNaN(t.getTime())||t.getFullYear()<-1e4||t.getFullYear()>1e4)throw new Error("Invalid date:"+n);return t}},"getStartDate"),ut=(0,r.K2)(function(t){const e=/^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(t.trim());return null!==e?[Number.parseFloat(e[1]),e[2]]:[NaN,"ms"]},"parseDuration"),ht=(0,r.K2)(function(t,e,n,i=!1){n=n.trim();const s=/^until\s+(?<ids>[\d\w- ]+)/.exec(n);if(null!==s){let t=null;for(const n of s.groups.ids.split(" ")){let e=vt(n);void 0!==e&&(!t||e.startTime<t.startTime)&&(t=e)}if(t)return t.startTime;const e=new Date;return e.setHours(0,0,0,0),e}let r=o(n,e.trim(),!0);if(r.isValid())return i&&(r=r.add(1,"d")),r.toDate();let a=o(t);const[c,l]=ut(n);if(!Number.isNaN(c)){const t=a.add(c,l);t.isValid()&&(a=t)}return a.toDate()},"getEndDate"),ft=0,yt=(0,r.K2)(function(t){return void 0===t?"task"+(ft+=1):t},"parseId"),kt=(0,r.K2)(function(t,e){let n;n=":"===e.substr(0,1)?e.substr(1,e.length):e;const i=n.split(","),s={};Et(i,s,S);for(let a=0;a<i.length;a++)i[a]=i[a].trim();let r="";switch(i.length){case 1:s.id=yt(),s.startTime=t.endTime,r=i[0];break;case 2:s.id=yt(),s.startTime=dt(void 0,p,i[0]),r=i[1];break;case 3:s.id=yt(i[0]),s.startTime=dt(void 0,p,i[1]),r=i[2]}return r&&(s.endTime=ht(s.startTime,p,r,E),s.manualEndTime=o(r,"YYYY-MM-DD",!0).isValid(),ct(s,p,x,T)),s},"compileData"),mt=(0,r.K2)(function(t,e){let n;n=":"===e.substr(0,1)?e.substr(1,e.length):e;const i=n.split(","),s={};Et(i,s,S);for(let r=0;r<i.length;r++)i[r]=i[r].trim();switch(i.length){case 1:s.id=yt(),s.startTime={type:"prevTaskEnd",id:t},s.endTime={data:i[0]};break;case 2:s.id=yt(),s.startTime={type:"getStartDate",startData:i[0]},s.endTime={data:i[1]};break;case 3:s.id=yt(i[0]),s.startTime={type:"getStartDate",startData:i[1]},s.endTime={data:i[2]}}return s},"parseData"),pt=[],gt={},bt=(0,r.K2)(function(t,e){const n={section:$,type:$,processed:!1,manualEndTime:!1,renderEndTime:null,raw:{data:e},task:t,classes:[]},i=mt(k,e);n.raw.startTime=i.startTime,n.raw.endTime=i.endTime,n.id=i.id,n.prevTaskId=k,n.active=i.active,n.done=i.done,n.crit=i.crit,n.milestone=i.milestone,n.vert=i.vert,n.order=Y,Y++;const s=pt.push(n);k=n.id,gt[n.id]=s-1},"addTask"),vt=(0,r.K2)(function(t){const e=gt[t];return pt[e]},"findTaskById"),Tt=(0,r.K2)(function(t,e){const n={section:$,type:$,description:t,task:t,classes:[]},i=kt(y,e);n.startTime=i.startTime,n.endTime=i.endTime,n.id=i.id,n.active=i.active,n.done=i.done,n.crit=i.crit,n.milestone=i.milestone,n.vert=i.vert,y=n,D.push(n)},"addTaskOrg"),xt=(0,r.K2)(function(){const t=(0,r.K2)(function(t){const e=pt[t];let n="";switch(pt[t].raw.startTime.type){case"prevTaskEnd":{const t=vt(e.prevTaskId);e.startTime=t.endTime;break}case"getStartDate":n=dt(void 0,p,pt[t].raw.startTime.startData),n&&(pt[t].startTime=n)}return pt[t].startTime&&(pt[t].endTime=ht(pt[t].startTime,p,pt[t].raw.endTime.data,E),pt[t].endTime&&(pt[t].processed=!0,pt[t].manualEndTime=o(pt[t].raw.endTime.data,"YYYY-MM-DD",!0).isValid(),ct(pt[t],p,x,T))),pt[t].processed},"compileTask");let e=!0;for(const[n,i]of pt.entries())t(n),e=e&&i.processed;return e},"compileTasks"),wt=(0,r.K2)(function(t,e){let n=e;"loose"!==(0,s.D7)().securityLevel&&(n=(0,a.J)(e)),t.split(",").forEach(function(t){void 0!==vt(t)&&($t(t,()=>{window.open(n,"_self")}),w.set(t,n))}),_t(t,"clickable")},"setLink"),_t=(0,r.K2)(function(t,e){t.split(",").forEach(function(t){let n=vt(t);void 0!==n&&n.classes.push(e)})},"setClass"),Dt=(0,r.K2)(function(t,e,n){if("loose"!==(0,s.D7)().securityLevel)return;if(void 0===e)return;let r=[];if("string"==typeof n){r=n.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t<r.length;t++){let e=r[t].trim();e.startsWith('"')&&e.endsWith('"')&&(e=e.substr(1,e.length-2)),r[t]=e}}0===r.length&&r.push(t),void 0!==vt(t)&&$t(t,()=>{i._K.runFunc(e,...r)})},"setClickFun"),$t=(0,r.K2)(function(t,e){K.push(function(){const n=document.querySelector(`[id="${t}"]`);null!==n&&n.addEventListener("click",function(){e()})},function(){const n=document.querySelector(`[id="${t}-text"]`);null!==n&&n.addEventListener("click",function(){e()})})},"pushFun"),Ct=(0,r.K2)(function(t,e,n){t.split(",").forEach(function(t){Dt(t,e,n)}),_t(t,"clickable")},"setClickEvent"),St=(0,r.K2)(function(t){K.forEach(function(e){e(t)})},"bindFunctions"),Kt={getConfig:(0,r.K2)(()=>(0,s.D7)().gantt,"getConfig"),clear:I,setDateFormat:N,getDateFormat:Z,enableInclusiveEndDates:G,endDatesAreInclusive:H,enableTopAxis:R,topAxisEnabled:j,setAxisFormat:W,getAxisFormat:F,setTickInterval:O,getTickInterval:P,setTodayMarker:B,getTodayMarker:z,setAccTitle:s.SV,getAccTitle:s.iN,setDiagramTitle:s.ke,getDiagramTitle:s.ab,setDisplayMode:U,getDisplayMode:V,setAccDescription:s.EI,getAccDescription:s.m7,addSection:et,getSections:nt,getTasks:it,addTask:bt,findTaskById:vt,addTaskOrg:Tt,setIncludes:X,getIncludes:q,setExcludes:Q,getExcludes:J,setClickEvent:Ct,setLink:wt,getLinks:tt,bindFunctions:St,parseDuration:ut,isInvalidDate:st,setWeekday:rt,getWeekday:at,setWeekend:ot};function Et(t,e,n){let i=!0;for(;i;)i=!1,n.forEach(function(n){const s=new RegExp("^\\s*"+n+"\\s*$");t[0].match(s)&&(e[n]=!0,t.shift(1),i=!0)})}(0,r.K2)(Et,"getTaskTags");var Mt,At=(0,r.K2)(function(){r.Rm.debug("Something is calling, setConf, remove the call")},"setConf"),Lt={monday:u.ABi,tuesday:u.PGu,wednesday:u.GuW,thursday:u.Mol,friday:u.TUC,saturday:u.rGn,sunday:u.YPH},Yt=(0,r.K2)((t,e)=>{let n=[...t].map(()=>-1/0),i=[...t].sort((t,e)=>t.startTime-e.startTime||t.order-e.order),s=0;for(const r of i)for(let t=0;t<n.length;t++)if(r.startTime>=n[t]){n[t]=r.endTime,r.order=t+e,t>s&&(s=t);break}return s},"getMaxIntersections"),It={parser:f,db:Kt,renderer:{setConf:At,draw:(0,r.K2)(function(t,e,n,i){const a=(0,s.D7)().gantt,c=(0,s.D7)().securityLevel;let l;"sandbox"===c&&(l=(0,u.Ltv)("#i"+e));const d="sandbox"===c?(0,u.Ltv)(l.nodes()[0].contentDocument.body):(0,u.Ltv)("body"),h="sandbox"===c?l.nodes()[0].contentDocument:document,f=h.getElementById(e);void 0===(Mt=f.parentElement.offsetWidth)&&(Mt=1200),void 0!==a.useWidth&&(Mt=a.useWidth);const y=i.db.getTasks();let k=[];for(const s of y)k.push(s.type);k=C(k);const m={};let p=2*a.topPadding;if("compact"===i.db.getDisplayMode()||"compact"===a.displayMode){const t={};for(const n of y)void 0===t[n.section]?t[n.section]=[n]:t[n.section].push(n);let e=0;for(const n of Object.keys(t)){const i=Yt(t[n],e)+1;e+=i,p+=i*(a.barHeight+a.barGap),m[n]=i}}else{p+=y.length*(a.barHeight+a.barGap);for(const t of k)m[t]=y.filter(e=>e.type===t).length}f.setAttribute("viewBox","0 0 "+Mt+" "+p);const g=d.select(`[id="${e}"]`),b=(0,u.w7C)().domain([(0,u.jkA)(y,function(t){return t.startTime}),(0,u.T9B)(y,function(t){return t.endTime})]).rangeRound([0,Mt-a.leftPadding-a.rightPadding]);function v(t,e){const n=t.startTime,i=e.startTime;let s=0;return n>i?s=1:n<i&&(s=-1),s}function T(t,e,n){const s=a.barHeight,r=s+a.barGap,o=a.topPadding,c=a.leftPadding,l=(0,u.m4Y)().domain([0,k.length]).range(["#00B9FA","#F95002"]).interpolate(u.bEH);w(r,o,c,e,n,t,i.db.getExcludes(),i.db.getIncludes()),_(c,o,e,n),x(t,r,o,c,s,l,e),D(r,o),$(c,o,e,n)}function x(t,n,r,o,c,l,d){t.sort((t,e)=>t.vert===e.vert?0:t.vert?1:-1);const h=[...new Set(t.map(t=>t.order))].map(e=>t.find(t=>t.order===e));g.append("g").selectAll("rect").data(h).enter().append("rect").attr("x",0).attr("y",function(t,e){return t.order*n+r-2}).attr("width",function(){return d-a.rightPadding/2}).attr("height",n).attr("class",function(t){for(const[e,n]of k.entries())if(t.type===n)return"section section"+e%a.numberSectionStyles;return"section section0"}).enter();const f=g.append("g").selectAll("rect").data(t).enter(),m=i.db.getLinks();f.append("rect").attr("id",function(t){return t.id}).attr("rx",3).attr("ry",3).attr("x",function(t){return t.milestone?b(t.startTime)+o+.5*(b(t.endTime)-b(t.startTime))-.5*c:b(t.startTime)+o}).attr("y",function(t,e){return e=t.order,t.vert?a.gridLineStartPadding:e*n+r}).attr("width",function(t){return t.milestone?c:t.vert?.08*c:b(t.renderEndTime||t.endTime)-b(t.startTime)}).attr("height",function(t){return t.vert?y.length*(a.barHeight+a.barGap)+2*a.barHeight:c}).attr("transform-origin",function(t,e){return e=t.order,(b(t.startTime)+o+.5*(b(t.endTime)-b(t.startTime))).toString()+"px "+(e*n+r+.5*c).toString()+"px"}).attr("class",function(t){let e="";t.classes.length>0&&(e=t.classes.join(" "));let n=0;for(const[s,r]of k.entries())t.type===r&&(n=s%a.numberSectionStyles);let i="";return t.active?t.crit?i+=" activeCrit":i=" active":t.done?i=t.crit?" doneCrit":" done":t.crit&&(i+=" crit"),0===i.length&&(i=" task"),t.milestone&&(i=" milestone "+i),t.vert&&(i=" vert "+i),i+=n,i+=" "+e,"task"+i}),f.append("text").attr("id",function(t){return t.id+"-text"}).text(function(t){return t.task}).attr("font-size",a.fontSize).attr("x",function(t){let e=b(t.startTime),n=b(t.renderEndTime||t.endTime);if(t.milestone&&(e+=.5*(b(t.endTime)-b(t.startTime))-.5*c,n=e+c),t.vert)return b(t.startTime)+o;const i=this.getBBox().width;return i>n-e?n+i+1.5*a.leftPadding>d?e+o-5:n+o+5:(n-e)/2+e+o}).attr("y",function(t,e){return t.vert?a.gridLineStartPadding+y.length*(a.barHeight+a.barGap)+60:t.order*n+a.barHeight/2+(a.fontSize/2-2)+r}).attr("text-height",c).attr("class",function(t){const e=b(t.startTime);let n=b(t.endTime);t.milestone&&(n=e+c);const i=this.getBBox().width;let s="";t.classes.length>0&&(s=t.classes.join(" "));let r=0;for(const[c,l]of k.entries())t.type===l&&(r=c%a.numberSectionStyles);let o="";return t.active&&(o=t.crit?"activeCritText"+r:"activeText"+r),t.done?o=t.crit?o+" doneCritText"+r:o+" doneText"+r:t.crit&&(o=o+" critText"+r),t.milestone&&(o+=" milestoneText"),t.vert&&(o+=" vertText"),i>n-e?n+i+1.5*a.leftPadding>d?s+" taskTextOutsideLeft taskTextOutside"+r+" "+o:s+" taskTextOutsideRight taskTextOutside"+r+" "+o+" width-"+i:s+" taskText taskText"+r+" "+o+" width-"+i});if("sandbox"===(0,s.D7)().securityLevel){let t;t=(0,u.Ltv)("#i"+e);const n=t.nodes()[0].contentDocument;f.filter(function(t){return m.has(t.id)}).each(function(t){var e=n.querySelector("#"+t.id),i=n.querySelector("#"+t.id+"-text");const s=e.parentNode;var r=n.createElement("a");r.setAttribute("xlink:href",m.get(t.id)),r.setAttribute("target","_top"),s.appendChild(r),r.appendChild(e),r.appendChild(i)})}}function w(t,e,n,s,c,l,d,u){if(0===d.length&&0===u.length)return;let h,f;for(const{startTime:i,endTime:r}of l)(void 0===h||i<h)&&(h=i),(void 0===f||r>f)&&(f=r);if(!h||!f)return;if(o(f).diff(o(h),"year")>5)return void r.Rm.warn("The difference between the min and max time is more than 5 years. This will cause performance issues. Skipping drawing exclude days.");const y=i.db.getDateFormat(),k=[];let m=null,p=o(h);for(;p.valueOf()<=f;)i.db.isInvalidDate(p,y,d,u)?m?m.end=p:m={start:p,end:p}:m&&(k.push(m),m=null),p=p.add(1,"d");g.append("g").selectAll("rect").data(k).enter().append("rect").attr("id",t=>"exclude-"+t.start.format("YYYY-MM-DD")).attr("x",t=>b(t.start.startOf("day"))+n).attr("y",a.gridLineStartPadding).attr("width",t=>b(t.end.endOf("day"))-b(t.start.startOf("day"))).attr("height",c-e-a.gridLineStartPadding).attr("transform-origin",function(e,i){return(b(e.start)+n+.5*(b(e.end)-b(e.start))).toString()+"px "+(i*t+.5*c).toString()+"px"}).attr("class","exclude-range")}function _(t,e,n,s){const r=i.db.getDateFormat(),o=i.db.getAxisFormat();let c;c=o||("D"===r?"%d":a.axisFormat??"%Y-%m-%d");let l=(0,u.l78)(b).tickSize(-s+e+a.gridLineStartPadding).tickFormat((0,u.DCK)(c));const d=/^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/.exec(i.db.getTickInterval()||a.tickInterval);if(null!==d){const t=d[1],e=d[2],n=i.db.getWeekday()||a.weekday;switch(e){case"millisecond":l.ticks(u.t6C.every(t));break;case"second":l.ticks(u.ucG.every(t));break;case"minute":l.ticks(u.wXd.every(t));break;case"hour":l.ticks(u.Agd.every(t));break;case"day":l.ticks(u.UAC.every(t));break;case"week":l.ticks(Lt[n].every(t));break;case"month":l.ticks(u.Ui6.every(t))}}if(g.append("g").attr("class","grid").attr("transform","translate("+t+", "+(s-50)+")").call(l).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10).attr("dy","1em"),i.db.topAxisEnabled()||a.topAxis){let n=(0,u.tlR)(b).tickSize(-s+e+a.gridLineStartPadding).tickFormat((0,u.DCK)(c));if(null!==d){const t=d[1],e=d[2],s=i.db.getWeekday()||a.weekday;switch(e){case"millisecond":n.ticks(u.t6C.every(t));break;case"second":n.ticks(u.ucG.every(t));break;case"minute":n.ticks(u.wXd.every(t));break;case"hour":n.ticks(u.Agd.every(t));break;case"day":n.ticks(u.UAC.every(t));break;case"week":n.ticks(Lt[s].every(t));break;case"month":n.ticks(u.Ui6.every(t))}}g.append("g").attr("class","grid").attr("transform","translate("+t+", "+e+")").call(n).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10)}}function D(t,e){let n=0;const i=Object.keys(m).map(t=>[t,m[t]]);g.append("g").selectAll("text").data(i).enter().append(function(t){const e=t[0].split(s.Y2.lineBreakRegex),n=-(e.length-1)/2,i=h.createElementNS("http://www.w3.org/2000/svg","text");i.setAttribute("dy",n+"em");for(const[s,r]of e.entries()){const t=h.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttribute("alignment-baseline","central"),t.setAttribute("x","10"),s>0&&t.setAttribute("dy","1em"),t.textContent=r,i.appendChild(t)}return i}).attr("x",10).attr("y",function(s,r){if(!(r>0))return s[1]*t/2+e;for(let a=0;a<r;a++)return n+=i[r-1][1],s[1]*t/2+n*t+e}).attr("font-size",a.sectionFontSize).attr("class",function(t){for(const[e,n]of k.entries())if(t[0]===n)return"sectionTitle sectionTitle"+e%a.numberSectionStyles;return"sectionTitle"})}function $(t,e,n,s){const r=i.db.getTodayMarker();if("off"===r)return;const o=g.append("g").attr("class","today"),c=new Date,l=o.append("line");l.attr("x1",b(c)+t).attr("x2",b(c)+t).attr("y1",a.titleTopMargin).attr("y2",s-a.titleTopMargin).attr("class","today"),""!==r&&l.attr("style",r.replace(/,/g,";"))}function C(t){const e={},n=[];for(let i=0,s=t.length;i<s;++i)Object.prototype.hasOwnProperty.call(e,t[i])||(e[t[i]]=!0,n.push(t[i]));return n}(0,r.K2)(v,"taskCompare"),y.sort(v),T(y,Mt,p),(0,s.a$)(g,p,Mt,a.useMaxWidth),g.append("text").text(i.db.getDiagramTitle()).attr("x",Mt/2).attr("y",a.titleTopMargin).attr("class","titleText"),(0,r.K2)(T,"makeGantt"),(0,r.K2)(x,"drawRects"),(0,r.K2)(w,"drawExcludeDays"),(0,r.K2)(_,"makeGrid"),(0,r.K2)(D,"vertLabels"),(0,r.K2)($,"drawToday"),(0,r.K2)(C,"checkUnique")},"draw")},styles:(0,r.K2)(t=>`\n .mermaid-main-font {\n font-family: ${t.fontFamily};\n }\n\n .exclude-range {\n fill: ${t.excludeBkgColor};\n }\n\n .section {\n stroke: none;\n opacity: 0.2;\n }\n\n .section0 {\n fill: ${t.sectionBkgColor};\n }\n\n .section2 {\n fill: ${t.sectionBkgColor2};\n }\n\n .section1,\n .section3 {\n fill: ${t.altSectionBkgColor};\n opacity: 0.2;\n }\n\n .sectionTitle0 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle1 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle2 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle3 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle {\n text-anchor: start;\n font-family: ${t.fontFamily};\n }\n\n\n /* Grid and axis */\n\n .grid .tick {\n stroke: ${t.gridColor};\n opacity: 0.8;\n shape-rendering: crispEdges;\n }\n\n .grid .tick text {\n font-family: ${t.fontFamily};\n fill: ${t.textColor};\n }\n\n .grid path {\n stroke-width: 0;\n }\n\n\n /* Today line */\n\n .today {\n fill: none;\n stroke: ${t.todayLineColor};\n stroke-width: 2px;\n }\n\n\n /* Task styling */\n\n /* Default task */\n\n .task {\n stroke-width: 2;\n }\n\n .taskText {\n text-anchor: middle;\n font-family: ${t.fontFamily};\n }\n\n .taskTextOutsideRight {\n fill: ${t.taskTextDarkColor};\n text-anchor: start;\n font-family: ${t.fontFamily};\n }\n\n .taskTextOutsideLeft {\n fill: ${t.taskTextDarkColor};\n text-anchor: end;\n }\n\n\n /* Special case clickable */\n\n .task.clickable {\n cursor: pointer;\n }\n\n .taskText.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideLeft.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideRight.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n\n /* Specific task settings for the sections*/\n\n .taskText0,\n .taskText1,\n .taskText2,\n .taskText3 {\n fill: ${t.taskTextColor};\n }\n\n .task0,\n .task1,\n .task2,\n .task3 {\n fill: ${t.taskBkgColor};\n stroke: ${t.taskBorderColor};\n }\n\n .taskTextOutside0,\n .taskTextOutside2\n {\n fill: ${t.taskTextOutsideColor};\n }\n\n .taskTextOutside1,\n .taskTextOutside3 {\n fill: ${t.taskTextOutsideColor};\n }\n\n\n /* Active task */\n\n .active0,\n .active1,\n .active2,\n .active3 {\n fill: ${t.activeTaskBkgColor};\n stroke: ${t.activeTaskBorderColor};\n }\n\n .activeText0,\n .activeText1,\n .activeText2,\n .activeText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Completed task */\n\n .done0,\n .done1,\n .done2,\n .done3 {\n stroke: ${t.doneTaskBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneText0,\n .doneText1,\n .doneText2,\n .doneText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Tasks on the critical line */\n\n .crit0,\n .crit1,\n .crit2,\n .crit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.critBkgColor};\n stroke-width: 2;\n }\n\n .activeCrit0,\n .activeCrit1,\n .activeCrit2,\n .activeCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.activeTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneCrit0,\n .doneCrit1,\n .doneCrit2,\n .doneCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n cursor: pointer;\n shape-rendering: crispEdges;\n }\n\n .milestone {\n transform: rotate(45deg) scale(0.8,0.8);\n }\n\n .milestoneText {\n font-style: italic;\n }\n .doneCritText0,\n .doneCritText1,\n .doneCritText2,\n .doneCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .vert {\n stroke: ${t.vertLineColor};\n }\n\n .vertText {\n font-size: 15px;\n text-anchor: middle;\n fill: ${t.vertLineColor} !important;\n }\n\n .activeCritText0,\n .activeCritText1,\n .activeCritText2,\n .activeCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .titleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.titleColor||t.textColor};\n font-family: ${t.fontFamily};\n }\n`,"getStyles")}},68313:function(t){t.exports=function(){"use strict";var t="day";return function(e,n,i){var s=function(e){return e.add(4-e.isoWeekday(),t)},r=n.prototype;r.isoWeekYear=function(){return s(this).year()},r.isoWeek=function(e){if(!this.$utils().u(e))return this.add(7*(e-this.isoWeek()),t);var n,r,a,o=s(this),c=(n=this.isoWeekYear(),a=4-(r=(this.$u?i.utc:i)().year(n).startOf("year")).isoWeekday(),r.isoWeekday()>4&&(a+=7),r.add(a,t));return o.diff(c,"week")+1},r.isoWeekday=function(t){return this.$utils().u(t)?this.day()||7:this.day(this.day()%7?t:t-7)};var a=r.startOf;r.startOf=function(t,e){var n=this.$utils(),i=!!n.u(e)||e;return"isoweek"===n.p(t)?i?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):a.bind(this)(t,e)}}}()},90445:function(t){t.exports=function(){"use strict";var t={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},e=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|Q|YYYY|YY?|ww?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,n=/\d/,i=/\d\d/,s=/\d\d?/,r=/\d*[^-_:/,()\s\d]+/,a={},o=function(t){return(t=+t)+(t>68?1900:2e3)},c=function(t){return function(e){this[t]=+e}},l=[/[+-]\d\d:?(\d\d)?|Z/,function(t){(this.zone||(this.zone={})).offset=function(t){if(!t)return 0;if("Z"===t)return 0;var e=t.match(/([+-]|\d\d)/g),n=60*e[1]+(+e[2]||0);return 0===n?0:"+"===e[0]?-n:n}(t)}],d=function(t){var e=a[t];return e&&(e.indexOf?e:e.s.concat(e.f))},u=function(t,e){var n,i=a.meridiem;if(i){for(var s=1;s<=24;s+=1)if(t.indexOf(i(s,0,e))>-1){n=s>12;break}}else n=t===(e?"pm":"PM");return n},h={A:[r,function(t){this.afternoon=u(t,!1)}],a:[r,function(t){this.afternoon=u(t,!0)}],Q:[n,function(t){this.month=3*(t-1)+1}],S:[n,function(t){this.milliseconds=100*+t}],SS:[i,function(t){this.milliseconds=10*+t}],SSS:[/\d{3}/,function(t){this.milliseconds=+t}],s:[s,c("seconds")],ss:[s,c("seconds")],m:[s,c("minutes")],mm:[s,c("minutes")],H:[s,c("hours")],h:[s,c("hours")],HH:[s,c("hours")],hh:[s,c("hours")],D:[s,c("day")],DD:[i,c("day")],Do:[r,function(t){var e=a.ordinal,n=t.match(/\d+/);if(this.day=n[0],e)for(var i=1;i<=31;i+=1)e(i).replace(/\[|\]/g,"")===t&&(this.day=i)}],w:[s,c("week")],ww:[i,c("week")],M:[s,c("month")],MM:[i,c("month")],MMM:[r,function(t){var e=d("months"),n=(d("monthsShort")||e.map(function(t){return t.slice(0,3)})).indexOf(t)+1;if(n<1)throw new Error;this.month=n%12||n}],MMMM:[r,function(t){var e=d("months").indexOf(t)+1;if(e<1)throw new Error;this.month=e%12||e}],Y:[/[+-]?\d+/,c("year")],YY:[i,function(t){this.year=o(t)}],YYYY:[/\d{4}/,c("year")],Z:l,ZZ:l};function f(n){var i,s;i=n,s=a&&a.formats;for(var r=(n=i.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,function(e,n,i){var r=i&&i.toUpperCase();return n||s[i]||t[i]||s[r].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,function(t,e,n){return e||n.slice(1)})})).match(e),o=r.length,c=0;c<o;c+=1){var l=r[c],d=h[l],u=d&&d[0],f=d&&d[1];r[c]=f?{regex:u,parser:f}:l.replace(/^\[|\]$/g,"")}return function(t){for(var e={},n=0,i=0;n<o;n+=1){var s=r[n];if("string"==typeof s)i+=s.length;else{var a=s.regex,c=s.parser,l=t.slice(i),d=a.exec(l)[0];c.call(e,d),t=t.replace(d,"")}}return function(t){var e=t.afternoon;if(void 0!==e){var n=t.hours;e?n<12&&(t.hours+=12):12===n&&(t.hours=0),delete t.afternoon}}(e),e}}return function(t,e,n){n.p.customParseFormat=!0,t&&t.parseTwoDigitYear&&(o=t.parseTwoDigitYear);var i=e.prototype,s=i.parse;i.parse=function(t){var e=t.date,i=t.utc,r=t.args;this.$u=i;var o=r[1];if("string"==typeof o){var c=!0===r[2],l=!0===r[3],d=c||l,u=r[2];l&&(u=r[2]),a=this.$locale(),!c&&u&&(a=n.Ls[u]),this.$d=function(t,e,n,i){try{if(["x","X"].indexOf(e)>-1)return new Date(("X"===e?1e3:1)*t);var s=f(e)(t),r=s.year,a=s.month,o=s.day,c=s.hours,l=s.minutes,d=s.seconds,u=s.milliseconds,h=s.zone,y=s.week,k=new Date,m=o||(r||a?1:k.getDate()),p=r||k.getFullYear(),g=0;r&&!a||(g=a>0?a-1:k.getMonth());var b,v=c||0,T=l||0,x=d||0,w=u||0;return h?new Date(Date.UTC(p,g,m,v,T,x,w+60*h.offset*1e3)):n?new Date(Date.UTC(p,g,m,v,T,x,w)):(b=new Date(p,g,m,v,T,x,w),y&&(b=i(b).week(y).toDate()),b)}catch(t){return new Date("")}}(e,o,i,n),this.init(),u&&!0!==u&&(this.$L=this.locale(u).$L),d&&e!=this.format(o)&&(this.$d=new Date("")),a={}}else if(o instanceof Array)for(var h=o.length,y=1;y<=h;y+=1){r[1]=o[y-1];var k=n.apply(this,r);if(k.isValid()){this.$d=k.$d,this.$L=k.$L,this.init();break}y===h&&(this.$d=new Date(""))}else s.call(this,t)}}}()},97375:function(t){t.exports=function(){"use strict";return function(t,e){var n=e.prototype,i=n.format;n.format=function(t){var e=this,n=this.$locale();if(!this.isValid())return i.bind(this)(t);var s=this.$utils(),r=(t||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,function(t){switch(t){case"Q":return Math.ceil((e.$M+1)/3);case"Do":return n.ordinal(e.$D);case"gggg":return e.weekYear();case"GGGG":return e.isoWeekYear();case"wo":return n.ordinal(e.week(),"W");case"w":case"ww":return s.s(e.week(),"w"===t?1:2,"0");case"W":case"WW":return s.s(e.isoWeek(),"W"===t?1:2,"0");case"k":case"kk":return s.s(String(0===e.$H?24:e.$H),"k"===t?1:2,"0");case"X":return Math.floor(e.$d.getTime()/1e3);case"x":return e.$d.getTime();case"z":return"["+e.offsetName()+"]";case"zzz":return"["+e.offsetName("long")+"]";default:return t}});return i.bind(this)(r)}}}()}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/452d9595.8d32ca6b.js b/pr-preview/pr-4027/assets/js/452d9595.8d32ca6b.js deleted file mode 100644 index 882281530..000000000 --- a/pr-preview/pr-4027/assets/js/452d9595.8d32ca6b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2560],{28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var s=t(96540);const o={},i=s.createContext(o);function r(e){const n=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(i.Provider,{value:n},e.children)}},96759:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"workflows/trusted-launch","title":"Use Azure trusted launch VMs","description":"Constellation also supports trusted launch VMs on Microsoft Azure. Trusted launch VMs don\'t offer the same level of security as Confidential VMs, but are available in more regions and in larger quantities. The main difference between trusted launch VMs and normal VMs is that the former offer vTPM-based remote attestation. When used with trusted launch VMs, Constellation relies on vTPM-based remote attestation to verify nodes.","source":"@site/docs/workflows/trusted-launch.md","sourceDirName":"workflows","slug":"/workflows/trusted-launch","permalink":"/constellation/pr-preview/pr-4027/next/workflows/trusted-launch","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/workflows/trusted-launch.md","tags":[],"version":"current","frontMatter":{}}');var o=t(74848),i=t(28453);const r={},a="Use Azure trusted launch VMs",l={},c=[{value:"VM images",id:"vm-images",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"use-azure-trusted-launch-vms",children:"Use Azure trusted launch VMs"})}),"\n",(0,o.jsxs)(n.p,{children:["Constellation also supports ",(0,o.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/trusted-launch",children:"trusted launch VMs"})," on Microsoft Azure. Trusted launch VMs don't offer the same level of security as Confidential VMs, but are available in more regions and in larger quantities. The main difference between trusted launch VMs and normal VMs is that the former offer vTPM-based remote attestation. When used with trusted launch VMs, Constellation relies on vTPM-based remote attestation to verify nodes."]}),"\n",(0,o.jsx)(n.admonition,{type:"caution",children:(0,o.jsx)(n.p,{children:"Trusted launch VMs don't provide runtime encryption and don't keep the cloud service provider (CSP) out of your trusted computing base."})}),"\n",(0,o.jsxs)(n.p,{children:["Constellation supports trusted launch VMs with instance types ",(0,o.jsx)(n.code,{children:"Standard_D*_v4"})," and ",(0,o.jsx)(n.code,{children:"Standard_E*_v4"}),". Run ",(0,o.jsx)(n.code,{children:"constellation config instance-types"})," for a list of all supported instance types."]}),"\n",(0,o.jsx)(n.h2,{id:"vm-images",children:"VM images"}),"\n",(0,o.jsxs)(n.p,{children:["Azure currently doesn't support ",(0,o.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/share-gallery-community",children:"community galleries for trusted launch VMs"}),". Thus, you need to manually import the Constellation node image into your cloud subscription."]}),"\n",(0,o.jsxs)(n.p,{children:["The latest image is available at ",(0,o.jsx)(n.code,{children:"https://cdn.confidential.cloud/constellation/images/azure/trusted-launch/v2.2.0/constellation.img"}),". Simply adjust the version number to download a newer version."]}),"\n",(0,o.jsxs)(n.p,{children:["After you've downloaded the image, create a resource group ",(0,o.jsx)(n.code,{children:"constellation-images"})," in your Azure subscription and import the image.\nYou can use a script to do this:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"wget https://raw.githubusercontent.com/edgelesssys/constellation/main/hack/importAzure.sh\nchmod +x importAzure.sh\nAZURE_IMAGE_VERSION=2.2.0 AZURE_RESOURCE_GROUP_NAME=constellation-images AZURE_IMAGE_FILE=./constellation.img ./importAzure.sh\n"})}),"\n",(0,o.jsx)(n.p,{children:"The script creates the following resources:"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["A new image gallery with the default name ",(0,o.jsx)(n.code,{children:"constellation-import"})]}),"\n",(0,o.jsxs)(n.li,{children:["A new image definition with the default name ",(0,o.jsx)(n.code,{children:"constellation"})]}),"\n",(0,o.jsxs)(n.li,{children:["The actual image with the provided version. In this case ",(0,o.jsx)(n.code,{children:"2.2.0"})]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Once the import is completed, use the ",(0,o.jsx)(n.code,{children:"ID"})," of the image version in your ",(0,o.jsx)(n.code,{children:"constellation-conf.yaml"})," for the ",(0,o.jsx)(n.code,{children:"image"})," field. Set ",(0,o.jsx)(n.code,{children:"confidentialVM"})," to ",(0,o.jsx)(n.code,{children:"false"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"Fetch the image measurements:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"IMAGE_VERSION=2.2.0\nURL=https://public-edgeless-constellation.s3.us-east-2.amazonaws.com//communitygalleries/constellationcvm-b3782fa0-0df7-4f2f-963e-fc7fc42663df/images/constellation/versions/$IMAGE_VERSION/measurements.yaml\nconstellation config fetch-measurements -u$URL -s$URL.sig\n"})}),"\n",(0,o.jsxs)(n.admonition,{type:"info",children:[(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/create",children:(0,o.jsx)(n.code,{children:"constellation apply"})})," command will issue a warning because manually imported images aren't recognized as production grade images:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-shell-session",children:"Configured image doesn't look like a released production image. Double check image before deploying to production.\n"})}),(0,o.jsx)(n.p,{children:"Please ignore this warning."})]})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/462332ca.224a53bd.js b/pr-preview/pr-4027/assets/js/462332ca.224a53bd.js deleted file mode 100644 index fa070f147..000000000 --- a/pr-preview/pr-4027/assets/js/462332ca.224a53bd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4723],{14313:(e,t,o)=>{o.d(t,{A:()=>n});const n=o.p+"assets/images/example-emojivoto-55d31a6fd0c07e8e44b2b51d55dac60d.jpg"},28453:(e,t,o)=>{o.d(t,{R:()=>a,x:()=>l});var n=o(96540);const s={},i=n.createContext(s);function a(e){const t=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),n.createElement(i.Provider,{value:t},e.children)}},41755:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>r,contentTitle:()=>l,default:()=>p,frontMatter:()=>a,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"getting-started/examples/emojivoto","title":"Emojivoto","description":"Emojivoto is a simple and fun application that\'s well suited to test the basic functionality of your cluster.","source":"@site/versioned_docs/version-2.22/getting-started/examples/emojivoto.md","sourceDirName":"getting-started/examples","slug":"/getting-started/examples/emojivoto","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/emojivoto","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/getting-started/examples/emojivoto.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Examples","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples"},"next":{"title":"Online Boutique","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/online-boutique"}}');var s=o(74848),i=o(28453);const a={},l="Emojivoto",r={},c=[];function d(e){const t={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"emojivoto",children:"Emojivoto"})}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"Emojivoto"})," is a simple and fun application that's well suited to test the basic functionality of your cluster."]}),"\n",(0,s.jsx)("img",{src:o(14313).A,alt:"emojivoto - Web UI",width:"552"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["Deploy the application:","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["Wait until it becomes available:","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["Forward the web service to your machine:","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"kubectl -n emojivoto port-forward svc/web-svc 8080:80\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["Visit ",(0,s.jsx)(t.a,{href:"http://localhost:8080",children:"http://localhost:8080"})]}),"\n"]})]})}function p(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/4802.9da541ee.js b/pr-preview/pr-4027/assets/js/4802.9da541ee.js deleted file mode 100644 index 0eb469f88..000000000 --- a/pr-preview/pr-4027/assets/js/4802.9da541ee.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4802],{84802:(e,t,r)=>{r.d(t,{diagram:()=>o});var a=r(54616),s=(r(89625),r(21152),r(10045),r(5164),r(28698),r(5894),r(63245),r(32387),r(30092),r(13226),r(67633),r(40797)),o={parser:a.Zk,get db(){return new a.u4(2)},renderer:a.q7,styles:a.tM,init:(0,s.K2)(e=>{e.state||(e.state={}),e.state.arrowMarkerAbsolute=e.arrowMarkerAbsolute},"init")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/481538bf.3429f708.js b/pr-preview/pr-4027/assets/js/481538bf.3429f708.js deleted file mode 100644 index 0be47ebdf..000000000 --- a/pr-preview/pr-4027/assets/js/481538bf.3429f708.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9732],{16035:(e,n,t)=>{t.d(n,{A:()=>o});const o=t.p+"assets/images/example-online-boutique-c89a9a15b1d4c086d3654bf75843295e.jpg"},28453:(e,n,t)=>{t.d(n,{R:()=>l,x:()=>a});var o=t(96540);const s={},i=o.createContext(s);function l(e){const n=o.useContext(i);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),o.createElement(i.Provider,{value:n},e.children)}},70037:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>a,default:()=>u,frontMatter:()=>l,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"getting-started/examples/online-boutique","title":"Online Boutique","description":"Online Boutique is an e-commerce demo application by Google consisting of 11 separate microservices. In this demo, Constellation automatically sets up a load balancer on your CSP, making it easy to expose services from your confidential cluster.","source":"@site/versioned_docs/version-2.24/getting-started/examples/online-boutique.md","sourceDirName":"getting-started/examples","slug":"/getting-started/examples/online-boutique","permalink":"/constellation/pr-preview/pr-4027/getting-started/examples/online-boutique","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/getting-started/examples/online-boutique.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Emojivoto","permalink":"/constellation/pr-preview/pr-4027/getting-started/examples/emojivoto"},"next":{"title":"Horizontal Pod Autoscaling","permalink":"/constellation/pr-preview/pr-4027/getting-started/examples/horizontal-scaling"}}');var s=t(74848),i=t(28453);const l={},a="Online Boutique",r={},c=[];function d(e){const n={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"online-boutique",children:"Online Boutique"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://github.com/GoogleCloudPlatform/microservices-demo",children:"Online Boutique"})," is an e-commerce demo application by Google consisting of 11 separate microservices. In this demo, Constellation automatically sets up a load balancer on your CSP, making it easy to expose services from your confidential cluster."]}),"\n",(0,s.jsx)("img",{src:t(16035).A,alt:"Online Boutique - Web UI",width:"662"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Create a namespace:","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl create ns boutique\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Deploy the application:","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl apply -n boutique -f https://github.com/GoogleCloudPlatform/microservices-demo/raw/main/release/kubernetes-manifests.yaml\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Wait for all services to become available:","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl wait --for=condition=available --timeout=300s -n boutique --all deployments\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Get the frontend's external IP address:","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell-session",children:"$ kubectl get service frontend-external -n boutique | awk '{print $4}'\nEXTERNAL-IP\n<your-ip>\n"})}),"\n","(",(0,s.jsx)(n.code,{children:"<your-ip>"})," is a placeholder for the IP assigned by your CSP.)"]}),"\n",(0,s.jsx)(n.li,{children:"Enter the IP from the result in your browser to browse the online shop."}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/48186bb1.517b63ea.js b/pr-preview/pr-4027/assets/js/48186bb1.517b63ea.js deleted file mode 100644 index cbbb37d56..000000000 --- a/pr-preview/pr-4027/assets/js/48186bb1.517b63ea.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1671],{33686:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Reference","slug":"/category/reference","permalink":"/constellation/pr-preview/pr-4027/category/reference","sidebar":"docs","navigation":{"previous":{"title":"Observability","permalink":"/constellation/pr-preview/pr-4027/architecture/observability"},"next":{"title":"CLI","permalink":"/constellation/pr-preview/pr-4027/reference/cli"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/487d2b28.a63fd0a2.js b/pr-preview/pr-4027/assets/js/487d2b28.a63fd0a2.js deleted file mode 100644 index d92c8e8cf..000000000 --- a/pr-preview/pr-4027/assets/js/487d2b28.a63fd0a2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4244],{28453:(e,t,i)=>{i.d(t,{R:()=>r,x:()=>a});var n=i(96540);const s={},o=n.createContext(s);function r(e){const t=n.useContext(o);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(o.Provider,{value:t},e.children)}},64602:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"architecture/images","title":"Constellation images","description":"Constellation uses a minimal version of Fedora as the operating system running inside confidential VMs. This Linux distribution is optimized for containers and designed to be stateless.","source":"@site/docs/architecture/images.md","sourceDirName":"architecture","slug":"/architecture/images","permalink":"/constellation/pr-preview/pr-4027/next/architecture/images","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/architecture/images.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Attestation","permalink":"/constellation/pr-preview/pr-4027/next/architecture/attestation"},"next":{"title":"Keys and cryptographic primitives","permalink":"/constellation/pr-preview/pr-4027/next/architecture/keys"}}');var s=i(74848),o=i(28453);const r={},a="Constellation images",l={},d=[{value:"Measured boot",id:"measured-boot",level:2},{value:"Firmware",id:"firmware",level:3},{value:"Bootloader",id:"bootloader",level:3},{value:"initramfs",id:"initramfs",level:3},{value:"State disk",id:"state-disk",level:2},{value:"Kubernetes components",id:"kubernetes-components",level:2}];function c(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",mermaid:"mermaid",p:"p",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"constellation-images",children:"Constellation images"})}),"\n",(0,s.jsx)(t.p,{children:"Constellation uses a minimal version of Fedora as the operating system running inside confidential VMs. This Linux distribution is optimized for containers and designed to be stateless.\nThe Constellation images provide measured boot and an immutable filesystem."}),"\n",(0,s.jsx)(t.h2,{id:"measured-boot",children:"Measured boot"}),"\n",(0,s.jsx)(t.mermaid,{value:"flowchart LR\n Firmware --\x3e Bootloader\n Bootloader --\x3e uki\n subgraph uki[Unified Kernel Image]\n Kernel[Kernel]\n initramfs[Initramfs]\n cmdline[Kernel Command Line]\n end\n uki --\x3e rootfs[Root Filesystem]"}),"\n",(0,s.jsx)(t.p,{children:"Measured boot uses a Trusted Platform Module (TPM) to measure every part of the boot process. This allows for verification of the integrity of a running system at any point in time. To ensure correct measurements of every stage, each stage is responsible to measure the next stage before transitioning."}),"\n",(0,s.jsx)(t.h3,{id:"firmware",children:"Firmware"}),"\n",(0,s.jsx)(t.p,{children:"With confidential VMs, the firmware is the root of trust and is measured automatically at boot. After initialization, the firmware will load and measure the bootloader before executing it."}),"\n",(0,s.jsx)(t.h3,{id:"bootloader",children:"Bootloader"}),"\n",(0,s.jsx)(t.p,{children:"The bootloader is the first modifiable part of the boot chain. The bootloader is tasked with loading the kernel, initramfs and setting the kernel command line. The Constellation bootloader measures these components before starting the kernel."}),"\n",(0,s.jsx)(t.h3,{id:"initramfs",children:"initramfs"}),"\n",(0,s.jsxs)(t.p,{children:["The initramfs is a small filesystem loaded to prepare the actual root filesystem. The Constellation initramfs maps the block device containing the root filesystem with ",(0,s.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"}),". The initramfs then mounts the root filesystem from the mapped block device."]}),"\n",(0,s.jsx)(t.p,{children:"dm-verity provides integrity checking using a cryptographic hash tree. When a block is read, its integrity is checked by verifying the tree against a trusted root hash. The initramfs reads this root hash from the previously measured kernel command line. Thus, if any block of the root filesystem's device is modified on disk, trying to read the modified block will result in a kernel panic at runtime."}),"\n",(0,s.jsxs)(t.p,{children:["After mounting the root filesystem, the initramfs will switch over and start the ",(0,s.jsx)(t.code,{children:"init"})," process of the integrity-protected root filesystem."]}),"\n",(0,s.jsx)(t.h2,{id:"state-disk",children:"State disk"}),"\n",(0,s.jsxs)(t.p,{children:["In addition to the read-only root filesystem, each Constellation node has a disk for storing state data.\nThis disk is mounted readable and writable by the initramfs and contains data that should persist across reboots.\nSuch data can contain sensitive information and, therefore, must be stored securely.\nTo that end, the state disk is protected by authenticated encryption.\nSee the section on ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys#storage-encryption",children:"keys and encryption"})," for more information on the cryptographic primitives in use."]}),"\n",(0,s.jsx)(t.h2,{id:"kubernetes-components",children:"Kubernetes components"}),"\n",(0,s.jsxs)(t.p,{children:["During initialization, the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#bootstrapper",children:(0,s.jsx)(t.em,{children:"Bootstrapper"})})," downloads and verifies the ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/overview/components/",children:"Kubernetes components"})," as configured by the user.\nThey're stored on the state partition and can be updated once new releases need to be installed."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/4967aec5.cea229a8.js b/pr-preview/pr-4027/assets/js/4967aec5.cea229a8.js deleted file mode 100644 index 224fe7422..000000000 --- a/pr-preview/pr-4027/assets/js/4967aec5.cea229a8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[909],{28453:(e,s,r)=>{r.d(s,{R:()=>o,x:()=>a});var n=r(96540);const t={},i=n.createContext(t);function o(e){const s=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),n.createElement(i.Provider,{value:s},e.children)}},82112:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>c,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"reference/slsa","title":"Supply chain levels for software artifacts (SLSA) adoption","description":"Supply chain Levels for Software Artifacts, or SLSA (salsa) is a framework for improving and grading a project\'s build system and engineering processes. SLSA focuses on security improvements for source code storage as well as build system definition, execution, and observation. SLSA is structured in four levels. This page describes the adoption of SLSA for Constellation.","source":"@site/versioned_docs/version-2.22/reference/slsa.md","sourceDirName":"reference","slug":"/reference/slsa","permalink":"/constellation/pr-preview/pr-4027/2.22/reference/slsa","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/reference/slsa.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Terraform usage","permalink":"/constellation/pr-preview/pr-4027/2.22/reference/terraform"}}');var t=r(74848),i=r(28453);const o={},a="Supply chain levels for software artifacts (SLSA) adoption",l={},d=[{value:"Level 1 - Adopted",id:"level-1---adopted",level:2},{value:"Level 2 - Adopted",id:"level-2---adopted",level:2},{value:"Level 3 - Adopted",id:"level-3---adopted",level:2},{value:"Level 4 - In Progress",id:"level-4---in-progress",level:2}];function h(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"supply-chain-levels-for-software-artifacts-slsa-adoption",children:"Supply chain levels for software artifacts (SLSA) adoption"})}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"https://slsa.dev/",children:"Supply chain Levels for Software Artifacts, or SLSA (salsa)"})," is a framework for improving and grading a project's build system and engineering processes. SLSA focuses on security improvements for source code storage as well as build system definition, execution, and observation. SLSA is structured in ",(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/levels",children:"four levels"}),". This page describes the adoption of SLSA for Constellation."]}),"\n",(0,t.jsx)(s.admonition,{type:"info",children:(0,t.jsx)(s.p,{children:"SLSA is still in alpha status. The presented levels and their requirements might change in the future. We will adopt any changes into our engineering processes, as they get defined."})}),"\n",(0,t.jsx)(s.h2,{id:"level-1---adopted",children:"Level 1 - Adopted"}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#scripted-build",children:"Build - Scripted"})})}),"\n",(0,t.jsxs)(s.p,{children:["All build steps are automated via ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/tree/main/bazel/ci",children:"Bazel"})," and ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/tree/main/.github",children:"GitHub Actions"}),"."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#available",children:"Provenance - Available"})})}),"\n",(0,t.jsxs)(s.p,{children:["Provenance for the CLI is generated using the ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator",children:"slsa-github-generator"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"level-2---adopted",children:"Level 2 - Adopted"}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#version-controlled",children:"Source - Version Controlled"})})}),"\n",(0,t.jsx)(s.p,{children:"Constellation is hosted on GitHub using git."}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#build-service",children:"Build - Build Service"})})}),"\n",(0,t.jsxs)(s.p,{children:["All builds are carried out by ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/tree/main/.github",children:"GitHub Actions"}),"."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#authenticated",children:"Provenance - Authenticated"})})}),"\n",(0,t.jsxs)(s.p,{children:["Provenance for the CLI is signed using the ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator",children:"slsa-github-generator"}),". Learn ",(0,t.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli",children:"how to verify the CLI"})," using the signed provenance, before using it for the first time."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#service-generated",children:"Provenance - Service Generated"})})}),"\n",(0,t.jsxs)(s.p,{children:["Provenance for the CLI is generated using the ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator",children:"slsa-github-generator"})," in GitHub Actions."]}),"\n",(0,t.jsx)(s.h2,{id:"level-3---adopted",children:"Level 3 - Adopted"}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#verified-history",children:"Source - Verified History"})})}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys",children:"Edgeless Systems"})," GitHub organization ",(0,t.jsx)(s.a,{href:"https://docs.github.com/en/organizations/keeping-your-organization-secure/managing-two-factor-authentication-for-your-organization/requiring-two-factor-authentication-in-your-organization",children:"requires two-factor authentication"})," for all members."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#retained-indefinitely",children:"Source - Retained Indefinitely"})})}),"\n",(0,t.jsxs)(s.p,{children:["Since we use GitHub to host the repository, an external person can't modify or delete the history. Before a pull request can be merged, an explicit approval from an ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys",children:"Edgeless Systems"})," team member is required."]}),"\n",(0,t.jsxs)(s.p,{children:["The same holds true for changes proposed by team members. Each change to ",(0,t.jsx)(s.code,{children:"main"})," needs to be proposed via a pull request and requires at least one approval."]}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys",children:"Edgeless Systems"})," GitHub organization admins control these settings and are able to make changes to the repository's history should legal requirements necessitate it. These changes require two-party approval following the obliterate policy."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#build-as-code",children:"Build - Build as Code"})})}),"\n",(0,t.jsxs)(s.p,{children:["All build files for Constellation are stored in ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/tree/main/.github",children:"the same repository"}),"."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#ephemeral-environment",children:"Build - Ephemeral Environment"})})}),"\n",(0,t.jsxs)(s.p,{children:["All GitHub Action workflows are executed on ",(0,t.jsx)(s.a,{href:"https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners",children:"GitHub-hosted runners"}),". These runners are only available during workflow."]}),"\n",(0,t.jsxs)(s.p,{children:["We currently don't use ",(0,t.jsx)(s.a,{href:"https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners",children:"self-hosted runners"}),"."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#isolated",children:"Build - Isolated"})})}),"\n",(0,t.jsx)(s.p,{children:"As outlined in the previous section, we use GitHub-hosted runners, which provide a new, isolated and ephemeral environment for each build."}),"\n",(0,t.jsxs)(s.p,{children:["Additionally, the ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator#generation-of-provenance",children:"SLSA GitHub generator"})," itself is run in an isolated workflow with the artifact hash as defined inputs."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#non-falsifiable",children:"Provenance - Non-falsifiable"})})}),"\n",(0,t.jsxs)(s.p,{children:["As outlined by ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator",children:"SLSA GitHub generator"})," it already fulfills the non-falsifiable requirements for SLSA Level 3. The generated provenance is signed using ",(0,t.jsx)(s.a,{href:"https://sigstore.dev/",children:"sigstore"})," with an OIDC based proof of identity."]}),"\n",(0,t.jsx)(s.h2,{id:"level-4---in-progress",children:"Level 4 - In Progress"}),"\n",(0,t.jsx)(s.p,{children:"We strive to adopt certain aspect of SLSA Level 4 that support our engineering process. At the same time, SLSA is still in alpha status and the biggest changes to SLSA are expected to be around Level 4."})]})}function c(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/4981.bdd615e7.js b/pr-preview/pr-4027/assets/js/4981.bdd615e7.js deleted file mode 100644 index f62f3f094..000000000 --- a/pr-preview/pr-4027/assets/js/4981.bdd615e7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4981],{54981:(t,e,a)=>{a.d(e,{diagram:()=>Pt});var n=a(92875),i=a(13226),r=a(67633),s=a(40797),l=a(70451),o=a(16750),h=function(){var t=(0,s.K2)(function(t,e,a,n){for(a=a||{},n=t.length;n--;a[t[n]]=e);return a},"o"),e=[1,24],a=[1,25],n=[1,26],i=[1,27],r=[1,28],l=[1,63],o=[1,64],h=[1,65],d=[1,66],u=[1,67],p=[1,68],y=[1,69],g=[1,29],f=[1,30],b=[1,31],x=[1,32],_=[1,33],m=[1,34],E=[1,35],S=[1,36],A=[1,37],C=[1,38],w=[1,39],k=[1,40],O=[1,41],T=[1,42],v=[1,43],R=[1,44],D=[1,45],N=[1,46],P=[1,47],B=[1,48],I=[1,50],M=[1,51],j=[1,52],K=[1,53],L=[1,54],Y=[1,55],U=[1,56],F=[1,57],X=[1,58],z=[1,59],W=[1,60],Q=[14,42],$=[14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],H=[12,14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],q=[1,82],V=[1,83],G=[1,84],J=[1,85],Z=[12,14,42],tt=[12,14,33,42],et=[12,14,33,42,76,77,79,80],at=[12,33],nt=[34,36,37,38,39,40,41,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],it={trace:(0,s.K2)(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mermaidDoc:4,direction:5,direction_tb:6,direction_bt:7,direction_rl:8,direction_lr:9,graphConfig:10,C4_CONTEXT:11,NEWLINE:12,statements:13,EOF:14,C4_CONTAINER:15,C4_COMPONENT:16,C4_DYNAMIC:17,C4_DEPLOYMENT:18,otherStatements:19,diagramStatements:20,otherStatement:21,title:22,accDescription:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,boundaryStatement:29,boundaryStartStatement:30,boundaryStopStatement:31,boundaryStart:32,LBRACE:33,ENTERPRISE_BOUNDARY:34,attributes:35,SYSTEM_BOUNDARY:36,BOUNDARY:37,CONTAINER_BOUNDARY:38,NODE:39,NODE_L:40,NODE_R:41,RBRACE:42,diagramStatement:43,PERSON:44,PERSON_EXT:45,SYSTEM:46,SYSTEM_DB:47,SYSTEM_QUEUE:48,SYSTEM_EXT:49,SYSTEM_EXT_DB:50,SYSTEM_EXT_QUEUE:51,CONTAINER:52,CONTAINER_DB:53,CONTAINER_QUEUE:54,CONTAINER_EXT:55,CONTAINER_EXT_DB:56,CONTAINER_EXT_QUEUE:57,COMPONENT:58,COMPONENT_DB:59,COMPONENT_QUEUE:60,COMPONENT_EXT:61,COMPONENT_EXT_DB:62,COMPONENT_EXT_QUEUE:63,REL:64,BIREL:65,REL_U:66,REL_D:67,REL_L:68,REL_R:69,REL_B:70,REL_INDEX:71,UPDATE_EL_STYLE:72,UPDATE_REL_STYLE:73,UPDATE_LAYOUT_CONFIG:74,attribute:75,STR:76,STR_KEY:77,STR_VALUE:78,ATTRIBUTE:79,ATTRIBUTE_EMPTY:80,$accept:0,$end:1},terminals_:{2:"error",6:"direction_tb",7:"direction_bt",8:"direction_rl",9:"direction_lr",11:"C4_CONTEXT",12:"NEWLINE",14:"EOF",15:"C4_CONTAINER",16:"C4_COMPONENT",17:"C4_DYNAMIC",18:"C4_DEPLOYMENT",22:"title",23:"accDescription",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"LBRACE",34:"ENTERPRISE_BOUNDARY",36:"SYSTEM_BOUNDARY",37:"BOUNDARY",38:"CONTAINER_BOUNDARY",39:"NODE",40:"NODE_L",41:"NODE_R",42:"RBRACE",44:"PERSON",45:"PERSON_EXT",46:"SYSTEM",47:"SYSTEM_DB",48:"SYSTEM_QUEUE",49:"SYSTEM_EXT",50:"SYSTEM_EXT_DB",51:"SYSTEM_EXT_QUEUE",52:"CONTAINER",53:"CONTAINER_DB",54:"CONTAINER_QUEUE",55:"CONTAINER_EXT",56:"CONTAINER_EXT_DB",57:"CONTAINER_EXT_QUEUE",58:"COMPONENT",59:"COMPONENT_DB",60:"COMPONENT_QUEUE",61:"COMPONENT_EXT",62:"COMPONENT_EXT_DB",63:"COMPONENT_EXT_QUEUE",64:"REL",65:"BIREL",66:"REL_U",67:"REL_D",68:"REL_L",69:"REL_R",70:"REL_B",71:"REL_INDEX",72:"UPDATE_EL_STYLE",73:"UPDATE_REL_STYLE",74:"UPDATE_LAYOUT_CONFIG",76:"STR",77:"STR_KEY",78:"STR_VALUE",79:"ATTRIBUTE",80:"ATTRIBUTE_EMPTY"},productions_:[0,[3,1],[3,1],[5,1],[5,1],[5,1],[5,1],[4,1],[10,4],[10,4],[10,4],[10,4],[10,4],[13,1],[13,1],[13,2],[19,1],[19,2],[19,3],[21,1],[21,1],[21,2],[21,2],[21,1],[29,3],[30,3],[30,3],[30,4],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[31,1],[20,1],[20,2],[20,3],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,1],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[35,1],[35,2],[75,1],[75,2],[75,1],[75,1]],performAction:(0,s.K2)(function(t,e,a,n,i,r,s){var l=r.length-1;switch(i){case 3:n.setDirection("TB");break;case 4:n.setDirection("BT");break;case 5:n.setDirection("RL");break;case 6:n.setDirection("LR");break;case 8:case 9:case 10:case 11:case 12:n.setC4Type(r[l-3]);break;case 19:n.setTitle(r[l].substring(6)),this.$=r[l].substring(6);break;case 20:n.setAccDescription(r[l].substring(15)),this.$=r[l].substring(15);break;case 21:this.$=r[l].trim(),n.setTitle(this.$);break;case 22:case 23:this.$=r[l].trim(),n.setAccDescription(this.$);break;case 28:r[l].splice(2,0,"ENTERPRISE"),n.addPersonOrSystemBoundary(...r[l]),this.$=r[l];break;case 29:r[l].splice(2,0,"SYSTEM"),n.addPersonOrSystemBoundary(...r[l]),this.$=r[l];break;case 30:n.addPersonOrSystemBoundary(...r[l]),this.$=r[l];break;case 31:r[l].splice(2,0,"CONTAINER"),n.addContainerBoundary(...r[l]),this.$=r[l];break;case 32:n.addDeploymentNode("node",...r[l]),this.$=r[l];break;case 33:n.addDeploymentNode("nodeL",...r[l]),this.$=r[l];break;case 34:n.addDeploymentNode("nodeR",...r[l]),this.$=r[l];break;case 35:n.popBoundaryParseStack();break;case 39:n.addPersonOrSystem("person",...r[l]),this.$=r[l];break;case 40:n.addPersonOrSystem("external_person",...r[l]),this.$=r[l];break;case 41:n.addPersonOrSystem("system",...r[l]),this.$=r[l];break;case 42:n.addPersonOrSystem("system_db",...r[l]),this.$=r[l];break;case 43:n.addPersonOrSystem("system_queue",...r[l]),this.$=r[l];break;case 44:n.addPersonOrSystem("external_system",...r[l]),this.$=r[l];break;case 45:n.addPersonOrSystem("external_system_db",...r[l]),this.$=r[l];break;case 46:n.addPersonOrSystem("external_system_queue",...r[l]),this.$=r[l];break;case 47:n.addContainer("container",...r[l]),this.$=r[l];break;case 48:n.addContainer("container_db",...r[l]),this.$=r[l];break;case 49:n.addContainer("container_queue",...r[l]),this.$=r[l];break;case 50:n.addContainer("external_container",...r[l]),this.$=r[l];break;case 51:n.addContainer("external_container_db",...r[l]),this.$=r[l];break;case 52:n.addContainer("external_container_queue",...r[l]),this.$=r[l];break;case 53:n.addComponent("component",...r[l]),this.$=r[l];break;case 54:n.addComponent("component_db",...r[l]),this.$=r[l];break;case 55:n.addComponent("component_queue",...r[l]),this.$=r[l];break;case 56:n.addComponent("external_component",...r[l]),this.$=r[l];break;case 57:n.addComponent("external_component_db",...r[l]),this.$=r[l];break;case 58:n.addComponent("external_component_queue",...r[l]),this.$=r[l];break;case 60:n.addRel("rel",...r[l]),this.$=r[l];break;case 61:n.addRel("birel",...r[l]),this.$=r[l];break;case 62:n.addRel("rel_u",...r[l]),this.$=r[l];break;case 63:n.addRel("rel_d",...r[l]),this.$=r[l];break;case 64:n.addRel("rel_l",...r[l]),this.$=r[l];break;case 65:n.addRel("rel_r",...r[l]),this.$=r[l];break;case 66:n.addRel("rel_b",...r[l]),this.$=r[l];break;case 67:r[l].splice(0,1),n.addRel("rel",...r[l]),this.$=r[l];break;case 68:n.updateElStyle("update_el_style",...r[l]),this.$=r[l];break;case 69:n.updateRelStyle("update_rel_style",...r[l]),this.$=r[l];break;case 70:n.updateLayoutConfig("update_layout_config",...r[l]),this.$=r[l];break;case 71:this.$=[r[l]];break;case 72:r[l].unshift(r[l-1]),this.$=r[l];break;case 73:case 75:this.$=r[l].trim();break;case 74:let t={};t[r[l-1].trim()]=r[l].trim(),this.$=t;break;case 76:this.$=""}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],7:[1,6],8:[1,7],9:[1,8],10:4,11:[1,9],15:[1,10],16:[1,11],17:[1,12],18:[1,13]},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,7]},{1:[2,3]},{1:[2,4]},{1:[2,5]},{1:[2,6]},{12:[1,14]},{12:[1,15]},{12:[1,16]},{12:[1,17]},{12:[1,18]},{13:19,19:20,20:21,21:22,22:e,23:a,24:n,26:i,28:r,29:49,30:61,32:62,34:l,36:o,37:h,38:d,39:u,40:p,41:y,43:23,44:g,45:f,46:b,47:x,48:_,49:m,50:E,51:S,52:A,53:C,54:w,55:k,56:O,57:T,58:v,59:R,60:D,61:N,62:P,63:B,64:I,65:M,66:j,67:K,68:L,69:Y,70:U,71:F,72:X,73:z,74:W},{13:70,19:20,20:21,21:22,22:e,23:a,24:n,26:i,28:r,29:49,30:61,32:62,34:l,36:o,37:h,38:d,39:u,40:p,41:y,43:23,44:g,45:f,46:b,47:x,48:_,49:m,50:E,51:S,52:A,53:C,54:w,55:k,56:O,57:T,58:v,59:R,60:D,61:N,62:P,63:B,64:I,65:M,66:j,67:K,68:L,69:Y,70:U,71:F,72:X,73:z,74:W},{13:71,19:20,20:21,21:22,22:e,23:a,24:n,26:i,28:r,29:49,30:61,32:62,34:l,36:o,37:h,38:d,39:u,40:p,41:y,43:23,44:g,45:f,46:b,47:x,48:_,49:m,50:E,51:S,52:A,53:C,54:w,55:k,56:O,57:T,58:v,59:R,60:D,61:N,62:P,63:B,64:I,65:M,66:j,67:K,68:L,69:Y,70:U,71:F,72:X,73:z,74:W},{13:72,19:20,20:21,21:22,22:e,23:a,24:n,26:i,28:r,29:49,30:61,32:62,34:l,36:o,37:h,38:d,39:u,40:p,41:y,43:23,44:g,45:f,46:b,47:x,48:_,49:m,50:E,51:S,52:A,53:C,54:w,55:k,56:O,57:T,58:v,59:R,60:D,61:N,62:P,63:B,64:I,65:M,66:j,67:K,68:L,69:Y,70:U,71:F,72:X,73:z,74:W},{13:73,19:20,20:21,21:22,22:e,23:a,24:n,26:i,28:r,29:49,30:61,32:62,34:l,36:o,37:h,38:d,39:u,40:p,41:y,43:23,44:g,45:f,46:b,47:x,48:_,49:m,50:E,51:S,52:A,53:C,54:w,55:k,56:O,57:T,58:v,59:R,60:D,61:N,62:P,63:B,64:I,65:M,66:j,67:K,68:L,69:Y,70:U,71:F,72:X,73:z,74:W},{14:[1,74]},t(Q,[2,13],{43:23,29:49,30:61,32:62,20:75,34:l,36:o,37:h,38:d,39:u,40:p,41:y,44:g,45:f,46:b,47:x,48:_,49:m,50:E,51:S,52:A,53:C,54:w,55:k,56:O,57:T,58:v,59:R,60:D,61:N,62:P,63:B,64:I,65:M,66:j,67:K,68:L,69:Y,70:U,71:F,72:X,73:z,74:W}),t(Q,[2,14]),t($,[2,16],{12:[1,76]}),t(Q,[2,36],{12:[1,77]}),t(H,[2,19]),t(H,[2,20]),{25:[1,78]},{27:[1,79]},t(H,[2,23]),{35:80,75:81,76:q,77:V,79:G,80:J},{35:86,75:81,76:q,77:V,79:G,80:J},{35:87,75:81,76:q,77:V,79:G,80:J},{35:88,75:81,76:q,77:V,79:G,80:J},{35:89,75:81,76:q,77:V,79:G,80:J},{35:90,75:81,76:q,77:V,79:G,80:J},{35:91,75:81,76:q,77:V,79:G,80:J},{35:92,75:81,76:q,77:V,79:G,80:J},{35:93,75:81,76:q,77:V,79:G,80:J},{35:94,75:81,76:q,77:V,79:G,80:J},{35:95,75:81,76:q,77:V,79:G,80:J},{35:96,75:81,76:q,77:V,79:G,80:J},{35:97,75:81,76:q,77:V,79:G,80:J},{35:98,75:81,76:q,77:V,79:G,80:J},{35:99,75:81,76:q,77:V,79:G,80:J},{35:100,75:81,76:q,77:V,79:G,80:J},{35:101,75:81,76:q,77:V,79:G,80:J},{35:102,75:81,76:q,77:V,79:G,80:J},{35:103,75:81,76:q,77:V,79:G,80:J},{35:104,75:81,76:q,77:V,79:G,80:J},t(Z,[2,59]),{35:105,75:81,76:q,77:V,79:G,80:J},{35:106,75:81,76:q,77:V,79:G,80:J},{35:107,75:81,76:q,77:V,79:G,80:J},{35:108,75:81,76:q,77:V,79:G,80:J},{35:109,75:81,76:q,77:V,79:G,80:J},{35:110,75:81,76:q,77:V,79:G,80:J},{35:111,75:81,76:q,77:V,79:G,80:J},{35:112,75:81,76:q,77:V,79:G,80:J},{35:113,75:81,76:q,77:V,79:G,80:J},{35:114,75:81,76:q,77:V,79:G,80:J},{35:115,75:81,76:q,77:V,79:G,80:J},{20:116,29:49,30:61,32:62,34:l,36:o,37:h,38:d,39:u,40:p,41:y,43:23,44:g,45:f,46:b,47:x,48:_,49:m,50:E,51:S,52:A,53:C,54:w,55:k,56:O,57:T,58:v,59:R,60:D,61:N,62:P,63:B,64:I,65:M,66:j,67:K,68:L,69:Y,70:U,71:F,72:X,73:z,74:W},{12:[1,118],33:[1,117]},{35:119,75:81,76:q,77:V,79:G,80:J},{35:120,75:81,76:q,77:V,79:G,80:J},{35:121,75:81,76:q,77:V,79:G,80:J},{35:122,75:81,76:q,77:V,79:G,80:J},{35:123,75:81,76:q,77:V,79:G,80:J},{35:124,75:81,76:q,77:V,79:G,80:J},{35:125,75:81,76:q,77:V,79:G,80:J},{14:[1,126]},{14:[1,127]},{14:[1,128]},{14:[1,129]},{1:[2,8]},t(Q,[2,15]),t($,[2,17],{21:22,19:130,22:e,23:a,24:n,26:i,28:r}),t(Q,[2,37],{19:20,20:21,21:22,43:23,29:49,30:61,32:62,13:131,22:e,23:a,24:n,26:i,28:r,34:l,36:o,37:h,38:d,39:u,40:p,41:y,44:g,45:f,46:b,47:x,48:_,49:m,50:E,51:S,52:A,53:C,54:w,55:k,56:O,57:T,58:v,59:R,60:D,61:N,62:P,63:B,64:I,65:M,66:j,67:K,68:L,69:Y,70:U,71:F,72:X,73:z,74:W}),t(H,[2,21]),t(H,[2,22]),t(Z,[2,39]),t(tt,[2,71],{75:81,35:132,76:q,77:V,79:G,80:J}),t(et,[2,73]),{78:[1,133]},t(et,[2,75]),t(et,[2,76]),t(Z,[2,40]),t(Z,[2,41]),t(Z,[2,42]),t(Z,[2,43]),t(Z,[2,44]),t(Z,[2,45]),t(Z,[2,46]),t(Z,[2,47]),t(Z,[2,48]),t(Z,[2,49]),t(Z,[2,50]),t(Z,[2,51]),t(Z,[2,52]),t(Z,[2,53]),t(Z,[2,54]),t(Z,[2,55]),t(Z,[2,56]),t(Z,[2,57]),t(Z,[2,58]),t(Z,[2,60]),t(Z,[2,61]),t(Z,[2,62]),t(Z,[2,63]),t(Z,[2,64]),t(Z,[2,65]),t(Z,[2,66]),t(Z,[2,67]),t(Z,[2,68]),t(Z,[2,69]),t(Z,[2,70]),{31:134,42:[1,135]},{12:[1,136]},{33:[1,137]},t(at,[2,28]),t(at,[2,29]),t(at,[2,30]),t(at,[2,31]),t(at,[2,32]),t(at,[2,33]),t(at,[2,34]),{1:[2,9]},{1:[2,10]},{1:[2,11]},{1:[2,12]},t($,[2,18]),t(Q,[2,38]),t(tt,[2,72]),t(et,[2,74]),t(Z,[2,24]),t(Z,[2,35]),t(nt,[2,25]),t(nt,[2,26],{12:[1,138]}),t(nt,[2,27])],defaultActions:{2:[2,1],3:[2,2],4:[2,7],5:[2,3],6:[2,4],7:[2,5],8:[2,6],74:[2,8],126:[2,9],127:[2,10],128:[2,11],129:[2,12]},parseError:(0,s.K2)(function(t,e){if(!e.recoverable){var a=new Error(t);throw a.hash=e,a}this.trace(t)},"parseError"),parse:(0,s.K2)(function(t){var e=this,a=[0],n=[],i=[null],r=[],l=this.table,o="",c=0,h=0,d=0,u=r.slice.call(arguments,1),p=Object.create(this.lexer),y={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(y.yy[g]=this.yy[g]);p.setInput(t,y.yy),y.yy.lexer=p,y.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var f=p.yylloc;r.push(f);var b=p.options&&p.options.ranges;function x(){var t;return"number"!=typeof(t=n.pop()||p.lex()||1)&&(t instanceof Array&&(t=(n=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,s.K2)(function(t){a.length=a.length-2*t,i.length=i.length-t,r.length=r.length-t},"popStack"),(0,s.K2)(x,"lex");for(var _,m,E,S,A,C,w,k,O,T={};;){if(E=a[a.length-1],this.defaultActions[E]?S=this.defaultActions[E]:(null==_&&(_=x()),S=l[E]&&l[E][_]),void 0===S||!S.length||!S[0]){var v="";for(C in O=[],l[E])this.terminals_[C]&&C>2&&O.push("'"+this.terminals_[C]+"'");v=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+O.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==_?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(v,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:f,expected:O})}if(S[0]instanceof Array&&S.length>1)throw new Error("Parse Error: multiple actions possible at state: "+E+", token: "+_);switch(S[0]){case 1:a.push(_),i.push(p.yytext),r.push(p.yylloc),a.push(S[1]),_=null,m?(_=m,m=null):(h=p.yyleng,o=p.yytext,c=p.yylineno,f=p.yylloc,d>0&&d--);break;case 2:if(w=this.productions_[S[1]][1],T.$=i[i.length-w],T._$={first_line:r[r.length-(w||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(w||1)].first_column,last_column:r[r.length-1].last_column},b&&(T._$.range=[r[r.length-(w||1)].range[0],r[r.length-1].range[1]]),void 0!==(A=this.performAction.apply(T,[o,h,c,y.yy,S[1],i,r].concat(u))))return A;w&&(a=a.slice(0,-1*w*2),i=i.slice(0,-1*w),r=r.slice(0,-1*w)),a.push(this.productions_[S[1]][0]),i.push(T.$),r.push(T._$),k=l[a[a.length-2]][a[a.length-1]],a.push(k);break;case 3:return!0}}return!0},"parse")},rt=function(){return{EOF:1,parseError:(0,s.K2)(function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},"parseError"),setInput:(0,s.K2)(function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:(0,s.K2)(function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},"input"),unput:(0,s.K2)(function(t){var e=t.length,a=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),a.length-1&&(this.yylineno-=a.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:a?(a.length===n.length?this.yylloc.first_column:0)+n[n.length-a.length].length-a[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},"unput"),more:(0,s.K2)(function(){return this._more=!0,this},"more"),reject:(0,s.K2)(function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"reject"),less:(0,s.K2)(function(t){this.unput(this.match.slice(t))},"less"),pastInput:(0,s.K2)(function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:(0,s.K2)(function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:(0,s.K2)(function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},"showPosition"),test_match:(0,s.K2)(function(t,e){var a,n,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],a=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),a)return a;if(this._backtrack){for(var r in i)this[r]=i[r];return!1}return!1},"test_match"),next:(0,s.K2)(function(){if(this.done)return this.EOF;var t,e,a,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),r=0;r<i.length;r++)if((a=this._input.match(this.rules[i[r]]))&&(!e||a[0].length>e[0].length)){if(e=a,n=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(a,i[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:(0,s.K2)(function(){var t=this.next();return t||this.lex()},"lex"),begin:(0,s.K2)(function(t){this.conditionStack.push(t)},"begin"),popState:(0,s.K2)(function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:(0,s.K2)(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:(0,s.K2)(function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},"topState"),pushState:(0,s.K2)(function(t){this.begin(t)},"pushState"),stateStackSize:(0,s.K2)(function(){return this.conditionStack.length},"stateStackSize"),options:{},performAction:(0,s.K2)(function(t,e,a,n){switch(a){case 0:return 6;case 1:return 7;case 2:return 8;case 3:return 9;case 4:return 22;case 5:return 23;case 6:return this.begin("acc_title"),24;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),26;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 73:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:case 16:case 70:break;case 14:c;break;case 15:return 12;case 17:return 11;case 18:return 15;case 19:return 16;case 20:return 17;case 21:return 18;case 22:return this.begin("person_ext"),45;case 23:return this.begin("person"),44;case 24:return this.begin("system_ext_queue"),51;case 25:return this.begin("system_ext_db"),50;case 26:return this.begin("system_ext"),49;case 27:return this.begin("system_queue"),48;case 28:return this.begin("system_db"),47;case 29:return this.begin("system"),46;case 30:return this.begin("boundary"),37;case 31:return this.begin("enterprise_boundary"),34;case 32:return this.begin("system_boundary"),36;case 33:return this.begin("container_ext_queue"),57;case 34:return this.begin("container_ext_db"),56;case 35:return this.begin("container_ext"),55;case 36:return this.begin("container_queue"),54;case 37:return this.begin("container_db"),53;case 38:return this.begin("container"),52;case 39:return this.begin("container_boundary"),38;case 40:return this.begin("component_ext_queue"),63;case 41:return this.begin("component_ext_db"),62;case 42:return this.begin("component_ext"),61;case 43:return this.begin("component_queue"),60;case 44:return this.begin("component_db"),59;case 45:return this.begin("component"),58;case 46:case 47:return this.begin("node"),39;case 48:return this.begin("node_l"),40;case 49:return this.begin("node_r"),41;case 50:return this.begin("rel"),64;case 51:return this.begin("birel"),65;case 52:case 53:return this.begin("rel_u"),66;case 54:case 55:return this.begin("rel_d"),67;case 56:case 57:return this.begin("rel_l"),68;case 58:case 59:return this.begin("rel_r"),69;case 60:return this.begin("rel_b"),70;case 61:return this.begin("rel_index"),71;case 62:return this.begin("update_el_style"),72;case 63:return this.begin("update_rel_style"),73;case 64:return this.begin("update_layout_config"),74;case 65:return"EOF_IN_STRUCT";case 66:return this.begin("attribute"),"ATTRIBUTE_EMPTY";case 67:this.begin("attribute");break;case 68:case 79:this.popState(),this.popState();break;case 69:case 71:return 80;case 72:this.begin("string");break;case 74:case 80:return"STR";case 75:this.begin("string_kv");break;case 76:return this.begin("string_kv_key"),"STR_KEY";case 77:this.popState(),this.begin("string_kv_value");break;case 78:return"STR_VALUE";case 81:return"LBRACE";case 82:return"RBRACE";case 83:return"SPACE";case 84:return"EOL";case 85:return 14}},"anonymous"),rules:[/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:title\s[^#\n;]+)/,/^(?:accDescription\s[^#\n;]+)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:C4Context\b)/,/^(?:C4Container\b)/,/^(?:C4Component\b)/,/^(?:C4Dynamic\b)/,/^(?:C4Deployment\b)/,/^(?:Person_Ext\b)/,/^(?:Person\b)/,/^(?:SystemQueue_Ext\b)/,/^(?:SystemDb_Ext\b)/,/^(?:System_Ext\b)/,/^(?:SystemQueue\b)/,/^(?:SystemDb\b)/,/^(?:System\b)/,/^(?:Boundary\b)/,/^(?:Enterprise_Boundary\b)/,/^(?:System_Boundary\b)/,/^(?:ContainerQueue_Ext\b)/,/^(?:ContainerDb_Ext\b)/,/^(?:Container_Ext\b)/,/^(?:ContainerQueue\b)/,/^(?:ContainerDb\b)/,/^(?:Container\b)/,/^(?:Container_Boundary\b)/,/^(?:ComponentQueue_Ext\b)/,/^(?:ComponentDb_Ext\b)/,/^(?:Component_Ext\b)/,/^(?:ComponentQueue\b)/,/^(?:ComponentDb\b)/,/^(?:Component\b)/,/^(?:Deployment_Node\b)/,/^(?:Node\b)/,/^(?:Node_L\b)/,/^(?:Node_R\b)/,/^(?:Rel\b)/,/^(?:BiRel\b)/,/^(?:Rel_Up\b)/,/^(?:Rel_U\b)/,/^(?:Rel_Down\b)/,/^(?:Rel_D\b)/,/^(?:Rel_Left\b)/,/^(?:Rel_L\b)/,/^(?:Rel_Right\b)/,/^(?:Rel_R\b)/,/^(?:Rel_Back\b)/,/^(?:RelIndex\b)/,/^(?:UpdateElementStyle\b)/,/^(?:UpdateRelStyle\b)/,/^(?:UpdateLayoutConfig\b)/,/^(?:$)/,/^(?:[(][ ]*[,])/,/^(?:[(])/,/^(?:[)])/,/^(?:,,)/,/^(?:,)/,/^(?:[ ]*["]["])/,/^(?:[ ]*["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:[ ]*[\$])/,/^(?:[^=]*)/,/^(?:[=][ ]*["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:[^,]+)/,/^(?:\{)/,/^(?:\})/,/^(?:[\s]+)/,/^(?:[\n\r]+)/,/^(?:$)/],conditions:{acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},string_kv_value:{rules:[78,79],inclusive:!1},string_kv_key:{rules:[77],inclusive:!1},string_kv:{rules:[76],inclusive:!1},string:{rules:[73,74],inclusive:!1},attribute:{rules:[68,69,70,71,72,75,80],inclusive:!1},update_layout_config:{rules:[65,66,67,68],inclusive:!1},update_rel_style:{rules:[65,66,67,68],inclusive:!1},update_el_style:{rules:[65,66,67,68],inclusive:!1},rel_b:{rules:[65,66,67,68],inclusive:!1},rel_r:{rules:[65,66,67,68],inclusive:!1},rel_l:{rules:[65,66,67,68],inclusive:!1},rel_d:{rules:[65,66,67,68],inclusive:!1},rel_u:{rules:[65,66,67,68],inclusive:!1},rel_bi:{rules:[],inclusive:!1},rel:{rules:[65,66,67,68],inclusive:!1},node_r:{rules:[65,66,67,68],inclusive:!1},node_l:{rules:[65,66,67,68],inclusive:!1},node:{rules:[65,66,67,68],inclusive:!1},index:{rules:[],inclusive:!1},rel_index:{rules:[65,66,67,68],inclusive:!1},component_ext_queue:{rules:[],inclusive:!1},component_ext_db:{rules:[65,66,67,68],inclusive:!1},component_ext:{rules:[65,66,67,68],inclusive:!1},component_queue:{rules:[65,66,67,68],inclusive:!1},component_db:{rules:[65,66,67,68],inclusive:!1},component:{rules:[65,66,67,68],inclusive:!1},container_boundary:{rules:[65,66,67,68],inclusive:!1},container_ext_queue:{rules:[65,66,67,68],inclusive:!1},container_ext_db:{rules:[65,66,67,68],inclusive:!1},container_ext:{rules:[65,66,67,68],inclusive:!1},container_queue:{rules:[65,66,67,68],inclusive:!1},container_db:{rules:[65,66,67,68],inclusive:!1},container:{rules:[65,66,67,68],inclusive:!1},birel:{rules:[65,66,67,68],inclusive:!1},system_boundary:{rules:[65,66,67,68],inclusive:!1},enterprise_boundary:{rules:[65,66,67,68],inclusive:!1},boundary:{rules:[65,66,67,68],inclusive:!1},system_ext_queue:{rules:[65,66,67,68],inclusive:!1},system_ext_db:{rules:[65,66,67,68],inclusive:!1},system_ext:{rules:[65,66,67,68],inclusive:!1},system_queue:{rules:[65,66,67,68],inclusive:!1},system_db:{rules:[65,66,67,68],inclusive:!1},system:{rules:[65,66,67,68],inclusive:!1},person_ext:{rules:[65,66,67,68],inclusive:!1},person:{rules:[65,66,67,68],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,8,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,81,82,83,84,85],inclusive:!0}}}}();function st(){this.yy={}}return it.lexer=rt,(0,s.K2)(st,"Parser"),st.prototype=it,it.Parser=st,new st}();h.parser=h;var d,u=h,p=[],y=[""],g="global",f="",b=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],x=[],_="",m=!1,E=4,S=2,A=(0,s.K2)(function(){return d},"getC4Type"),C=(0,s.K2)(function(t){let e=(0,r.jZ)(t,(0,r.D7)());d=e},"setC4Type"),w=(0,s.K2)(function(t,e,a,n,i,r,s,l,o){if(null==t||null==e||null==a||null==n)return;let c={};const h=x.find(t=>t.from===e&&t.to===a);if(h?c=h:x.push(c),c.type=t,c.from=e,c.to=a,c.label={text:n},null==i)c.techn={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];c[t]={text:e}}else c.techn={text:i};if(null==r)c.descr={text:""};else if("object"==typeof r){let[t,e]=Object.entries(r)[0];c[t]={text:e}}else c.descr={text:r};if("object"==typeof s){let[t,e]=Object.entries(s)[0];c[t]=e}else c.sprite=s;if("object"==typeof l){let[t,e]=Object.entries(l)[0];c[t]=e}else c.tags=l;if("object"==typeof o){let[t,e]=Object.entries(o)[0];c[t]=e}else c.link=o;c.wrap=H()},"addRel"),k=(0,s.K2)(function(t,e,a,n,i,r,s){if(null===e||null===a)return;let l={};const o=p.find(t=>t.alias===e);if(o&&e===o.alias?l=o:(l.alias=e,p.push(l)),l.label=null==a?{text:""}:{text:a},null==n)l.descr={text:""};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];l[t]={text:e}}else l.descr={text:n};if("object"==typeof i){let[t,e]=Object.entries(i)[0];l[t]=e}else l.sprite=i;if("object"==typeof r){let[t,e]=Object.entries(r)[0];l[t]=e}else l.tags=r;if("object"==typeof s){let[t,e]=Object.entries(s)[0];l[t]=e}else l.link=s;l.typeC4Shape={text:t},l.parentBoundary=g,l.wrap=H()},"addPersonOrSystem"),O=(0,s.K2)(function(t,e,a,n,i,r,s,l){if(null===e||null===a)return;let o={};const c=p.find(t=>t.alias===e);if(c&&e===c.alias?o=c:(o.alias=e,p.push(o)),o.label=null==a?{text:""}:{text:a},null==n)o.techn={text:""};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];o[t]={text:e}}else o.techn={text:n};if(null==i)o.descr={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.descr={text:i};if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.sprite=r;if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.tags=s;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.wrap=H(),o.typeC4Shape={text:t},o.parentBoundary=g},"addContainer"),T=(0,s.K2)(function(t,e,a,n,i,r,s,l){if(null===e||null===a)return;let o={};const c=p.find(t=>t.alias===e);if(c&&e===c.alias?o=c:(o.alias=e,p.push(o)),o.label=null==a?{text:""}:{text:a},null==n)o.techn={text:""};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];o[t]={text:e}}else o.techn={text:n};if(null==i)o.descr={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.descr={text:i};if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.sprite=r;if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.tags=s;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.wrap=H(),o.typeC4Shape={text:t},o.parentBoundary=g},"addComponent"),v=(0,s.K2)(function(t,e,a,n,i){if(null===t||null===e)return;let r={};const s=b.find(e=>e.alias===t);if(s&&t===s.alias?r=s:(r.alias=t,b.push(r)),r.label=null==e?{text:""}:{text:e},null==a)r.type={text:"system"};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];r[t]={text:e}}else r.type={text:a};if("object"==typeof n){let[t,e]=Object.entries(n)[0];r[t]=e}else r.tags=n;if("object"==typeof i){let[t,e]=Object.entries(i)[0];r[t]=e}else r.link=i;r.parentBoundary=g,r.wrap=H(),f=g,g=t,y.push(f)},"addPersonOrSystemBoundary"),R=(0,s.K2)(function(t,e,a,n,i){if(null===t||null===e)return;let r={};const s=b.find(e=>e.alias===t);if(s&&t===s.alias?r=s:(r.alias=t,b.push(r)),r.label=null==e?{text:""}:{text:e},null==a)r.type={text:"container"};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];r[t]={text:e}}else r.type={text:a};if("object"==typeof n){let[t,e]=Object.entries(n)[0];r[t]=e}else r.tags=n;if("object"==typeof i){let[t,e]=Object.entries(i)[0];r[t]=e}else r.link=i;r.parentBoundary=g,r.wrap=H(),f=g,g=t,y.push(f)},"addContainerBoundary"),D=(0,s.K2)(function(t,e,a,n,i,r,s,l){if(null===e||null===a)return;let o={};const c=b.find(t=>t.alias===e);if(c&&e===c.alias?o=c:(o.alias=e,b.push(o)),o.label=null==a?{text:""}:{text:a},null==n)o.type={text:"node"};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];o[t]={text:e}}else o.type={text:n};if(null==i)o.descr={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.descr={text:i};if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.tags=s;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.nodeType=t,o.parentBoundary=g,o.wrap=H(),f=g,g=e,y.push(f)},"addDeploymentNode"),N=(0,s.K2)(function(){g=f,y.pop(),f=y.pop(),y.push(f)},"popBoundaryParseStack"),P=(0,s.K2)(function(t,e,a,n,i,r,s,l,o,c,h){let d=p.find(t=>t.alias===e);if(void 0!==d||(d=b.find(t=>t.alias===e),void 0!==d)){if(null!=a)if("object"==typeof a){let[t,e]=Object.entries(a)[0];d[t]=e}else d.bgColor=a;if(null!=n)if("object"==typeof n){let[t,e]=Object.entries(n)[0];d[t]=e}else d.fontColor=n;if(null!=i)if("object"==typeof i){let[t,e]=Object.entries(i)[0];d[t]=e}else d.borderColor=i;if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];d[t]=e}else d.shadowing=r;if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];d[t]=e}else d.shape=s;if(null!=l)if("object"==typeof l){let[t,e]=Object.entries(l)[0];d[t]=e}else d.sprite=l;if(null!=o)if("object"==typeof o){let[t,e]=Object.entries(o)[0];d[t]=e}else d.techn=o;if(null!=c)if("object"==typeof c){let[t,e]=Object.entries(c)[0];d[t]=e}else d.legendText=c;if(null!=h)if("object"==typeof h){let[t,e]=Object.entries(h)[0];d[t]=e}else d.legendSprite=h}},"updateElStyle"),B=(0,s.K2)(function(t,e,a,n,i,r,s){const l=x.find(t=>t.from===e&&t.to===a);if(void 0!==l){if(null!=n)if("object"==typeof n){let[t,e]=Object.entries(n)[0];l[t]=e}else l.textColor=n;if(null!=i)if("object"==typeof i){let[t,e]=Object.entries(i)[0];l[t]=e}else l.lineColor=i;if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];l[t]=parseInt(e)}else l.offsetX=parseInt(r);if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];l[t]=parseInt(e)}else l.offsetY=parseInt(s)}},"updateRelStyle"),I=(0,s.K2)(function(t,e,a){let n=E,i=S;if("object"==typeof e){const t=Object.values(e)[0];n=parseInt(t)}else n=parseInt(e);if("object"==typeof a){const t=Object.values(a)[0];i=parseInt(t)}else i=parseInt(a);n>=1&&(E=n),i>=1&&(S=i)},"updateLayoutConfig"),M=(0,s.K2)(function(){return E},"getC4ShapeInRow"),j=(0,s.K2)(function(){return S},"getC4BoundaryInRow"),K=(0,s.K2)(function(){return g},"getCurrentBoundaryParse"),L=(0,s.K2)(function(){return f},"getParentBoundaryParse"),Y=(0,s.K2)(function(t){return null==t?p:p.filter(e=>e.parentBoundary===t)},"getC4ShapeArray"),U=(0,s.K2)(function(t){return p.find(e=>e.alias===t)},"getC4Shape"),F=(0,s.K2)(function(t){return Object.keys(Y(t))},"getC4ShapeKeys"),X=(0,s.K2)(function(t){return null==t?b:b.filter(e=>e.parentBoundary===t)},"getBoundaries"),z=X,W=(0,s.K2)(function(){return x},"getRels"),Q=(0,s.K2)(function(){return _},"getTitle"),$=(0,s.K2)(function(t){m=t},"setWrap"),H=(0,s.K2)(function(){return m},"autoWrap"),q=(0,s.K2)(function(){p=[],b=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],f="",g="global",y=[""],x=[],y=[""],_="",m=!1,E=4,S=2},"clear"),V=(0,s.K2)(function(t){let e=(0,r.jZ)(t,(0,r.D7)());_=e},"setTitle"),G={addPersonOrSystem:k,addPersonOrSystemBoundary:v,addContainer:O,addContainerBoundary:R,addComponent:T,addDeploymentNode:D,popBoundaryParseStack:N,addRel:w,updateElStyle:P,updateRelStyle:B,updateLayoutConfig:I,autoWrap:H,setWrap:$,getC4ShapeArray:Y,getC4Shape:U,getC4ShapeKeys:F,getBoundaries:X,getBoundarys:z,getCurrentBoundaryParse:K,getParentBoundaryParse:L,getRels:W,getTitle:Q,getC4Type:A,getC4ShapeInRow:M,getC4BoundaryInRow:j,setAccTitle:r.SV,getAccTitle:r.iN,getAccDescription:r.m7,setAccDescription:r.EI,getConfig:(0,s.K2)(()=>(0,r.D7)().c4,"getConfig"),clear:q,LINETYPE:{SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25},ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},setTitle:V,setC4Type:C},J=(0,s.K2)(function(t,e){return(0,n.tk)(t,e)},"drawRect"),Z=(0,s.K2)(function(t,e,a,n,i,r){const s=t.append("image");s.attr("width",e),s.attr("height",a),s.attr("x",n),s.attr("y",i);let l=r.startsWith("data:image/png;base64")?r:(0,o.J)(r);s.attr("xlink:href",l)},"drawImage"),tt=(0,s.K2)((t,e,a)=>{const n=t.append("g");let i=0;for(let r of e){let t=r.textColor?r.textColor:"#444444",e=r.lineColor?r.lineColor:"#444444",s=r.offsetX?parseInt(r.offsetX):0,l=r.offsetY?parseInt(r.offsetY):0,o="";if(0===i){let t=n.append("line");t.attr("x1",r.startPoint.x),t.attr("y1",r.startPoint.y),t.attr("x2",r.endPoint.x),t.attr("y2",r.endPoint.y),t.attr("stroke-width","1"),t.attr("stroke",e),t.style("fill","none"),"rel_b"!==r.type&&t.attr("marker-end","url("+o+"#arrowhead)"),"birel"!==r.type&&"rel_b"!==r.type||t.attr("marker-start","url("+o+"#arrowend)"),i=-1}else{let t=n.append("path");t.attr("fill","none").attr("stroke-width","1").attr("stroke",e).attr("d","Mstartx,starty Qcontrolx,controly stopx,stopy ".replaceAll("startx",r.startPoint.x).replaceAll("starty",r.startPoint.y).replaceAll("controlx",r.startPoint.x+(r.endPoint.x-r.startPoint.x)/2-(r.endPoint.x-r.startPoint.x)/4).replaceAll("controly",r.startPoint.y+(r.endPoint.y-r.startPoint.y)/2).replaceAll("stopx",r.endPoint.x).replaceAll("stopy",r.endPoint.y)),"rel_b"!==r.type&&t.attr("marker-end","url("+o+"#arrowhead)"),"birel"!==r.type&&"rel_b"!==r.type||t.attr("marker-start","url("+o+"#arrowend)")}let c=a.messageFont();ut(a)(r.label.text,n,Math.min(r.startPoint.x,r.endPoint.x)+Math.abs(r.endPoint.x-r.startPoint.x)/2+s,Math.min(r.startPoint.y,r.endPoint.y)+Math.abs(r.endPoint.y-r.startPoint.y)/2+l,r.label.width,r.label.height,{fill:t},c),r.techn&&""!==r.techn.text&&(c=a.messageFont(),ut(a)("["+r.techn.text+"]",n,Math.min(r.startPoint.x,r.endPoint.x)+Math.abs(r.endPoint.x-r.startPoint.x)/2+s,Math.min(r.startPoint.y,r.endPoint.y)+Math.abs(r.endPoint.y-r.startPoint.y)/2+a.messageFontSize+5+l,Math.max(r.label.width,r.techn.width),r.techn.height,{fill:t,"font-style":"italic"},c))}},"drawRels"),et=(0,s.K2)(function(t,e,a){const n=t.append("g");let i=e.bgColor?e.bgColor:"none",r=e.borderColor?e.borderColor:"#444444",s=e.fontColor?e.fontColor:"black",l={"stroke-width":1,"stroke-dasharray":"7.0,7.0"};e.nodeType&&(l={"stroke-width":1});let o={x:e.x,y:e.y,fill:i,stroke:r,width:e.width,height:e.height,rx:2.5,ry:2.5,attrs:l};J(n,o);let c=a.boundaryFont();c.fontWeight="bold",c.fontSize=c.fontSize+2,c.fontColor=s,ut(a)(e.label.text,n,e.x,e.y+e.label.Y,e.width,e.height,{fill:"#444444"},c),e.type&&""!==e.type.text&&(c=a.boundaryFont(),c.fontColor=s,ut(a)(e.type.text,n,e.x,e.y+e.type.Y,e.width,e.height,{fill:"#444444"},c)),e.descr&&""!==e.descr.text&&(c=a.boundaryFont(),c.fontSize=c.fontSize-2,c.fontColor=s,ut(a)(e.descr.text,n,e.x,e.y+e.descr.Y,e.width,e.height,{fill:"#444444"},c))},"drawBoundary"),at=(0,s.K2)(function(t,e,a){let i=e.bgColor?e.bgColor:a[e.typeC4Shape.text+"_bg_color"],r=e.borderColor?e.borderColor:a[e.typeC4Shape.text+"_border_color"],s=e.fontColor?e.fontColor:"#FFFFFF",l="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";switch(e.typeC4Shape.text){case"person":l="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";break;case"external_person":l="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAB6ElEQVR4Xu2YLY+EMBCG9+dWr0aj0Wg0Go1Go0+j8Xdv2uTCvv1gpt0ebHKPuhDaeW4605Z9mJvx4AdXUyTUdd08z+u6flmWZRnHsWkafk9DptAwDPu+f0eAYtu2PEaGWuj5fCIZrBAC2eLBAnRCsEkkxmeaJp7iDJ2QMDdHsLg8SxKFEJaAo8lAXnmuOFIhTMpxxKATebo4UiFknuNo4OniSIXQyRxEA3YsnjGCVEjVXD7yLUAqxBGUyPv/Y4W2beMgGuS7kVQIBycH0fD+oi5pezQETxdHKmQKGk1eQEYldK+jw5GxPfZ9z7Mk0Qnhf1W1m3w//EUn5BDmSZsbR44QQLBEqrBHqOrmSKaQAxdnLArCrxZcM7A7ZKs4ioRq8LFC+NpC3WCBJsvpVw5edm9iEXFuyNfxXAgSwfrFQ1c0iNda8AdejvUgnktOtJQQxmcfFzGglc5WVCj7oDgFqU18boeFSs52CUh8LE8BIVQDT1ABrB0HtgSEYlX5doJnCwv9TXocKCaKbnwhdDKPq4lf3SwU3HLq4V/+WYhHVMa/3b4IlfyikAduCkcBc7mQ3/z/Qq/cTuikhkzB12Ae/mcJC9U+Vo8Ej1gWAtgbeGgFsAMHr50BIWOLCbezvhpBFUdY6EJuJ/QDW0XoMX60zZ0AAAAASUVORK5CYII="}const o=t.append("g");o.attr("class","person-man");const c=(0,n.PB)();switch(e.typeC4Shape.text){case"person":case"external_person":case"system":case"external_system":case"container":case"external_container":case"component":case"external_component":c.x=e.x,c.y=e.y,c.fill=i,c.width=e.width,c.height=e.height,c.stroke=r,c.rx=2.5,c.ry=2.5,c.attrs={"stroke-width":.5},J(o,c);break;case"system_db":case"external_system_db":case"container_db":case"external_container_db":case"component_db":case"external_component_db":o.append("path").attr("fill",i).attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc0,-10 half,-10 half,-10c0,0 half,0 half,10l0,heightc0,10 -half,10 -half,10c0,0 -half,0 -half,-10l0,-height".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2).replaceAll("height",e.height)),o.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc0,10 half,10 half,10c0,0 half,0 half,-10".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2));break;case"system_queue":case"external_system_queue":case"container_queue":case"external_container_queue":case"component_queue":case"external_component_queue":o.append("path").attr("fill",i).attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startylwidth,0c5,0 5,half 5,halfc0,0 0,half -5,halfl-width,0c-5,0 -5,-half -5,-halfc0,0 0,-half 5,-half".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("width",e.width).replaceAll("half",e.height/2)),o.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc-5,0 -5,half -5,halfc0,half 5,half 5,half".replaceAll("startx",e.x+e.width).replaceAll("starty",e.y).replaceAll("half",e.height/2))}let h=dt(a,e.typeC4Shape.text);switch(o.append("text").attr("fill",s).attr("font-family",h.fontFamily).attr("font-size",h.fontSize-2).attr("font-style","italic").attr("lengthAdjust","spacing").attr("textLength",e.typeC4Shape.width).attr("x",e.x+e.width/2-e.typeC4Shape.width/2).attr("y",e.y+e.typeC4Shape.Y).text("<<"+e.typeC4Shape.text+">>"),e.typeC4Shape.text){case"person":case"external_person":Z(o,48,48,e.x+e.width/2-24,e.y+e.image.Y,l)}let d=a[e.typeC4Shape.text+"Font"]();return d.fontWeight="bold",d.fontSize=d.fontSize+2,d.fontColor=s,ut(a)(e.label.text,o,e.x,e.y+e.label.Y,e.width,e.height,{fill:s},d),d=a[e.typeC4Shape.text+"Font"](),d.fontColor=s,e.techn&&""!==e.techn?.text?ut(a)(e.techn.text,o,e.x,e.y+e.techn.Y,e.width,e.height,{fill:s,"font-style":"italic"},d):e.type&&""!==e.type.text&&ut(a)(e.type.text,o,e.x,e.y+e.type.Y,e.width,e.height,{fill:s,"font-style":"italic"},d),e.descr&&""!==e.descr.text&&(d=a.personFont(),d.fontColor=s,ut(a)(e.descr.text,o,e.x,e.y+e.descr.Y,e.width,e.height,{fill:s},d)),e.height},"drawC4Shape"),nt=(0,s.K2)(function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},"insertDatabaseIcon"),it=(0,s.K2)(function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},"insertComputerIcon"),rt=(0,s.K2)(function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")},"insertClockIcon"),st=(0,s.K2)(function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z")},"insertArrowHead"),lt=(0,s.K2)(function(t){t.append("defs").append("marker").attr("id","arrowend").attr("refX",1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 10 0 L 0 5 L 10 10 z")},"insertArrowEnd"),ot=(0,s.K2)(function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",18).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},"insertArrowFilledHead"),ct=(0,s.K2)(function(t){t.append("defs").append("marker").attr("id","sequencenumber").attr("refX",15).attr("refY",15).attr("markerWidth",60).attr("markerHeight",40).attr("orient","auto").append("circle").attr("cx",15).attr("cy",15).attr("r",6)},"insertDynamicNumber"),ht=(0,s.K2)(function(t){const e=t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",16).attr("refY",4);e.append("path").attr("fill","black").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 9,2 V 6 L16,4 Z"),e.append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 0,1 L 6,7 M 6,1 L 0,7")},"insertArrowCrossHead"),dt=(0,s.K2)((t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),"getC4ShapeFont"),ut=function(){function t(t,e,a,i,r,s,l){n(e.append("text").attr("x",a+r/2).attr("y",i+s/2+5).style("text-anchor","middle").text(t),l)}function e(t,e,a,i,s,l,o,c){const{fontSize:h,fontFamily:d,fontWeight:u}=c,p=t.split(r.Y2.lineBreakRegex);for(let r=0;r<p.length;r++){const t=r*h-h*(p.length-1)/2,l=e.append("text").attr("x",a+s/2).attr("y",i).style("text-anchor","middle").attr("dominant-baseline","middle").style("font-size",h).style("font-weight",u).style("font-family",d);l.append("tspan").attr("dy",t).text(p[r]).attr("alignment-baseline","mathematical"),n(l,o)}}function a(t,a,i,r,s,l,o,c){const h=a.append("switch"),d=h.append("foreignObject").attr("x",i).attr("y",r).attr("width",s).attr("height",l).append("xhtml:div").style("display","table").style("height","100%").style("width","100%");d.append("div").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,i,r,s,0,o,c),n(d,o)}function n(t,e){for(const a in e)e.hasOwnProperty(a)&&t.attr(a,e[a])}return(0,s.K2)(t,"byText"),(0,s.K2)(e,"byTspan"),(0,s.K2)(a,"byFo"),(0,s.K2)(n,"_setTextAttrs"),function(n){return"fo"===n.textPlacement?a:"old"===n.textPlacement?t:e}}(),pt={drawRect:J,drawBoundary:et,drawC4Shape:at,drawRels:tt,drawImage:Z,insertArrowHead:st,insertArrowEnd:lt,insertArrowFilledHead:ot,insertDynamicNumber:ct,insertArrowCrossHead:ht,insertDatabaseIcon:nt,insertComputerIcon:it,insertClockIcon:rt},yt=0,gt=0,ft=4,bt=2;h.yy=G;var xt={},_t=class{static{(0,s.K2)(this,"Bounds")}constructor(t){this.name="",this.data={},this.data.startx=void 0,this.data.stopx=void 0,this.data.starty=void 0,this.data.stopy=void 0,this.data.widthLimit=void 0,this.nextData={},this.nextData.startx=void 0,this.nextData.stopx=void 0,this.nextData.starty=void 0,this.nextData.stopy=void 0,this.nextData.cnt=0,mt(t.db.getConfig())}setData(t,e,a,n){this.nextData.startx=this.data.startx=t,this.nextData.stopx=this.data.stopx=e,this.nextData.starty=this.data.starty=a,this.nextData.stopy=this.data.stopy=n}updateVal(t,e,a,n){void 0===t[e]?t[e]=a:t[e]=n(a,t[e])}insert(t){this.nextData.cnt=this.nextData.cnt+1;let e=this.nextData.startx===this.nextData.stopx?this.nextData.stopx+t.margin:this.nextData.stopx+2*t.margin,a=e+t.width,n=this.nextData.starty+2*t.margin,i=n+t.height;(e>=this.data.widthLimit||a>=this.data.widthLimit||this.nextData.cnt>ft)&&(e=this.nextData.startx+t.margin+xt.nextLinePaddingX,n=this.nextData.stopy+2*t.margin,this.nextData.stopx=a=e+t.width,this.nextData.starty=this.nextData.stopy,this.nextData.stopy=i=n+t.height,this.nextData.cnt=1),t.x=e,t.y=n,this.updateVal(this.data,"startx",e,Math.min),this.updateVal(this.data,"starty",n,Math.min),this.updateVal(this.data,"stopx",a,Math.max),this.updateVal(this.data,"stopy",i,Math.max),this.updateVal(this.nextData,"startx",e,Math.min),this.updateVal(this.nextData,"starty",n,Math.min),this.updateVal(this.nextData,"stopx",a,Math.max),this.updateVal(this.nextData,"stopy",i,Math.max)}init(t){this.name="",this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,widthLimit:void 0},this.nextData={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,cnt:0},mt(t.db.getConfig())}bumpLastMargin(t){this.data.stopx+=t,this.data.stopy+=t}},mt=(0,s.K2)(function(t){(0,r.hH)(xt,t),t.fontFamily&&(xt.personFontFamily=xt.systemFontFamily=xt.messageFontFamily=t.fontFamily),t.fontSize&&(xt.personFontSize=xt.systemFontSize=xt.messageFontSize=t.fontSize),t.fontWeight&&(xt.personFontWeight=xt.systemFontWeight=xt.messageFontWeight=t.fontWeight)},"setConf"),Et=(0,s.K2)((t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),"c4ShapeFont"),St=(0,s.K2)(t=>({fontFamily:t.boundaryFontFamily,fontSize:t.boundaryFontSize,fontWeight:t.boundaryFontWeight}),"boundaryFont"),At=(0,s.K2)(t=>({fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight}),"messageFont");function Ct(t,e,a,n,s){if(!e[t].width)if(a)e[t].text=(0,i.bH)(e[t].text,s,n),e[t].textLines=e[t].text.split(r.Y2.lineBreakRegex).length,e[t].width=s,e[t].height=(0,i.ru)(e[t].text,n);else{let a=e[t].text.split(r.Y2.lineBreakRegex);e[t].textLines=a.length;let s=0;e[t].height=0,e[t].width=0;for(const r of a)e[t].width=Math.max((0,i.Un)(r,n),e[t].width),s=(0,i.ru)(r,n),e[t].height=e[t].height+s}}(0,s.K2)(Ct,"calcC4ShapeTextWH");var wt=(0,s.K2)(function(t,e,a){e.x=a.data.startx,e.y=a.data.starty,e.width=a.data.stopx-a.data.startx,e.height=a.data.stopy-a.data.starty,e.label.y=xt.c4ShapeMargin-35;let n=e.wrap&&xt.wrap,r=St(xt);r.fontSize=r.fontSize+2,r.fontWeight="bold",Ct("label",e,n,r,(0,i.Un)(e.label.text,r)),pt.drawBoundary(t,e,xt)},"drawBoundary"),kt=(0,s.K2)(function(t,e,a,n){let r=0;for(const s of n){r=0;const n=a[s];let l=Et(xt,n.typeC4Shape.text);switch(l.fontSize=l.fontSize-2,n.typeC4Shape.width=(0,i.Un)("\xab"+n.typeC4Shape.text+"\xbb",l),n.typeC4Shape.height=l.fontSize+2,n.typeC4Shape.Y=xt.c4ShapePadding,r=n.typeC4Shape.Y+n.typeC4Shape.height-4,n.image={width:0,height:0,Y:0},n.typeC4Shape.text){case"person":case"external_person":n.image.width=48,n.image.height=48,n.image.Y=r,r=n.image.Y+n.image.height}n.sprite&&(n.image.width=48,n.image.height=48,n.image.Y=r,r=n.image.Y+n.image.height);let o=n.wrap&&xt.wrap,c=xt.width-2*xt.c4ShapePadding,h=Et(xt,n.typeC4Shape.text);if(h.fontSize=h.fontSize+2,h.fontWeight="bold",Ct("label",n,o,h,c),n.label.Y=r+8,r=n.label.Y+n.label.height,n.type&&""!==n.type.text){n.type.text="["+n.type.text+"]",Ct("type",n,o,Et(xt,n.typeC4Shape.text),c),n.type.Y=r+5,r=n.type.Y+n.type.height}else if(n.techn&&""!==n.techn.text){n.techn.text="["+n.techn.text+"]",Ct("techn",n,o,Et(xt,n.techn.text),c),n.techn.Y=r+5,r=n.techn.Y+n.techn.height}let d=r,u=n.label.width;if(n.descr&&""!==n.descr.text){Ct("descr",n,o,Et(xt,n.typeC4Shape.text),c),n.descr.Y=r+20,r=n.descr.Y+n.descr.height,u=Math.max(n.label.width,n.descr.width),d=r-5*n.descr.textLines}u+=xt.c4ShapePadding,n.width=Math.max(n.width||xt.width,u,xt.width),n.height=Math.max(n.height||xt.height,d,xt.height),n.margin=n.margin||xt.c4ShapeMargin,t.insert(n),pt.drawC4Shape(e,n,xt)}t.bumpLastMargin(xt.c4ShapeMargin)},"drawC4ShapeArray"),Ot=class{static{(0,s.K2)(this,"Point")}constructor(t,e){this.x=t,this.y=e}},Tt=(0,s.K2)(function(t,e){let a=t.x,n=t.y,i=e.x,r=e.y,s=a+t.width/2,l=n+t.height/2,o=Math.abs(a-i),c=Math.abs(n-r),h=c/o,d=t.height/t.width,u=null;return n==r&&a<i?u=new Ot(a+t.width,l):n==r&&a>i?u=new Ot(a,l):a==i&&n<r?u=new Ot(s,n+t.height):a==i&&n>r&&(u=new Ot(s,n)),a>i&&n<r?u=d>=h?new Ot(a,l+h*t.width/2):new Ot(s-o/c*t.height/2,n+t.height):a<i&&n<r?u=d>=h?new Ot(a+t.width,l+h*t.width/2):new Ot(s+o/c*t.height/2,n+t.height):a<i&&n>r?u=d>=h?new Ot(a+t.width,l-h*t.width/2):new Ot(s+t.height/2*o/c,n):a>i&&n>r&&(u=d>=h?new Ot(a,l-t.width/2*h):new Ot(s-t.height/2*o/c,n)),u},"getIntersectPoint"),vt=(0,s.K2)(function(t,e){let a={x:0,y:0};a.x=e.x+e.width/2,a.y=e.y+e.height/2;let n=Tt(t,a);return a.x=t.x+t.width/2,a.y=t.y+t.height/2,{startPoint:n,endPoint:Tt(e,a)}},"getIntersectPoints"),Rt=(0,s.K2)(function(t,e,a,n){let r=0;for(let s of e){r+=1;let t=s.wrap&&xt.wrap,e=At(xt);"C4Dynamic"===n.db.getC4Type()&&(s.label.text=r+": "+s.label.text);let l=(0,i.Un)(s.label.text,e);Ct("label",s,t,e,l),s.techn&&""!==s.techn.text&&(l=(0,i.Un)(s.techn.text,e),Ct("techn",s,t,e,l)),s.descr&&""!==s.descr.text&&(l=(0,i.Un)(s.descr.text,e),Ct("descr",s,t,e,l));let o=a(s.from),c=a(s.to),h=vt(o,c);s.startPoint=h.startPoint,s.endPoint=h.endPoint}pt.drawRels(t,e,xt)},"drawRels");function Dt(t,e,a,n,i){let r=new _t(i);r.data.widthLimit=a.data.widthLimit/Math.min(bt,n.length);for(let[s,l]of n.entries()){let n=0;l.image={width:0,height:0,Y:0},l.sprite&&(l.image.width=48,l.image.height=48,l.image.Y=n,n=l.image.Y+l.image.height);let o=l.wrap&&xt.wrap,c=St(xt);if(c.fontSize=c.fontSize+2,c.fontWeight="bold",Ct("label",l,o,c,r.data.widthLimit),l.label.Y=n+8,n=l.label.Y+l.label.height,l.type&&""!==l.type.text){l.type.text="["+l.type.text+"]",Ct("type",l,o,St(xt),r.data.widthLimit),l.type.Y=n+5,n=l.type.Y+l.type.height}if(l.descr&&""!==l.descr.text){let t=St(xt);t.fontSize=t.fontSize-2,Ct("descr",l,o,t,r.data.widthLimit),l.descr.Y=n+20,n=l.descr.Y+l.descr.height}if(0==s||s%bt===0){let t=a.data.startx+xt.diagramMarginX,e=a.data.stopy+xt.diagramMarginY+n;r.setData(t,t,e,e)}else{let t=r.data.stopx!==r.data.startx?r.data.stopx+xt.diagramMarginX:r.data.startx,e=r.data.starty;r.setData(t,t,e,e)}r.name=l.alias;let h=i.db.getC4ShapeArray(l.alias),d=i.db.getC4ShapeKeys(l.alias);d.length>0&&kt(r,t,h,d),e=l.alias;let u=i.db.getBoundaries(e);u.length>0&&Dt(t,e,r,u,i),"global"!==l.alias&&wt(t,l,r),a.data.stopy=Math.max(r.data.stopy+xt.c4ShapeMargin,a.data.stopy),a.data.stopx=Math.max(r.data.stopx+xt.c4ShapeMargin,a.data.stopx),yt=Math.max(yt,a.data.stopx),gt=Math.max(gt,a.data.stopy)}}(0,s.K2)(Dt,"drawInsideBoundary");var Nt={drawPersonOrSystemArray:kt,drawBoundary:wt,setConf:mt,draw:(0,s.K2)(function(t,e,a,n){xt=(0,r.D7)().c4;const i=(0,r.D7)().securityLevel;let o;"sandbox"===i&&(o=(0,l.Ltv)("#i"+e));const c="sandbox"===i?(0,l.Ltv)(o.nodes()[0].contentDocument.body):(0,l.Ltv)("body");let h=n.db;n.db.setWrap(xt.wrap),ft=h.getC4ShapeInRow(),bt=h.getC4BoundaryInRow(),s.Rm.debug(`C:${JSON.stringify(xt,null,2)}`);const d="sandbox"===i?c.select(`[id="${e}"]`):(0,l.Ltv)(`[id="${e}"]`);pt.insertComputerIcon(d),pt.insertDatabaseIcon(d),pt.insertClockIcon(d);let u=new _t(n);u.setData(xt.diagramMarginX,xt.diagramMarginX,xt.diagramMarginY,xt.diagramMarginY),u.data.widthLimit=screen.availWidth,yt=xt.diagramMarginX,gt=xt.diagramMarginY;const p=n.db.getTitle();Dt(d,"",u,n.db.getBoundaries(""),n),pt.insertArrowHead(d),pt.insertArrowEnd(d),pt.insertArrowCrossHead(d),pt.insertArrowFilledHead(d),Rt(d,n.db.getRels(),n.db.getC4Shape,n),u.data.stopx=yt,u.data.stopy=gt;const y=u.data;let g=y.stopy-y.starty+2*xt.diagramMarginY;const f=y.stopx-y.startx+2*xt.diagramMarginX;p&&d.append("text").text(p).attr("x",(y.stopx-y.startx)/2-4*xt.diagramMarginX).attr("y",y.starty+xt.diagramMarginY),(0,r.a$)(d,g,f,xt.useMaxWidth);const b=p?60:0;d.attr("viewBox",y.startx-xt.diagramMarginX+" -"+(xt.diagramMarginY+b)+" "+f+" "+(g+b)),s.Rm.debug("models:",y)},"draw")},Pt={parser:u,db:G,renderer:Nt,styles:(0,s.K2)(t=>`.person {\n stroke: ${t.personBorder};\n fill: ${t.personBkg};\n }\n`,"getStyles"),init:(0,s.K2)(({c4:t,wrap:e})=>{Nt.setConf(t),G.setWrap(e)},"init")}},92875:(t,e,a)=>{a.d(e,{CP:()=>h,HT:()=>u,PB:()=>d,aC:()=>c,lC:()=>l,m:()=>o,tk:()=>s});var n=a(67633),i=a(40797),r=a(16750),s=(0,i.K2)((t,e)=>{const a=t.append("rect");if(a.attr("x",e.x),a.attr("y",e.y),a.attr("fill",e.fill),a.attr("stroke",e.stroke),a.attr("width",e.width),a.attr("height",e.height),e.name&&a.attr("name",e.name),e.rx&&a.attr("rx",e.rx),e.ry&&a.attr("ry",e.ry),void 0!==e.attrs)for(const n in e.attrs)a.attr(n,e.attrs[n]);return e.class&&a.attr("class",e.class),a},"drawRect"),l=(0,i.K2)((t,e)=>{const a={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};s(t,a).lower()},"drawBackgroundRect"),o=(0,i.K2)((t,e)=>{const a=e.text.replace(n.H1," "),i=t.append("text");i.attr("x",e.x),i.attr("y",e.y),i.attr("class","legend"),i.style("text-anchor",e.anchor),e.class&&i.attr("class",e.class);const r=i.append("tspan");return r.attr("x",e.x+2*e.textMargin),r.text(a),i},"drawText"),c=(0,i.K2)((t,e,a,n)=>{const i=t.append("image");i.attr("x",e),i.attr("y",a);const s=(0,r.J)(n);i.attr("xlink:href",s)},"drawImage"),h=(0,i.K2)((t,e,a,n)=>{const i=t.append("use");i.attr("x",e),i.attr("y",a);const s=(0,r.J)(n);i.attr("xlink:href",`#${s}`)},"drawEmbeddedImage"),d=(0,i.K2)(()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),"getNoteRect"),u=(0,i.K2)(()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0}),"getTextObj")}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/4a51e885.f99201b8.js b/pr-preview/pr-4027/assets/js/4a51e885.f99201b8.js deleted file mode 100644 index e2175b933..000000000 --- a/pr-preview/pr-4027/assets/js/4a51e885.f99201b8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9514],{28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>a});var o=r(96540);const n={},s=o.createContext(n);function i(e){const t=o.useContext(s);return o.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),o.createElement(s.Provider,{value:t},e.children)}},85076:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"overview/product","title":"Product features","description":"Constellation is a Kubernetes engine that aims to provide the best possible data security in combination with enterprise-grade scalability and reliability features---and a smooth user experience.","source":"@site/docs/overview/product.md","sourceDirName":"overview","slug":"/overview/product","permalink":"/constellation/pr-preview/pr-4027/next/overview/product","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/overview/product.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Security benefits","permalink":"/constellation/pr-preview/pr-4027/next/overview/security-benefits"},"next":{"title":"Feature status of clouds","permalink":"/constellation/pr-preview/pr-4027/next/overview/clouds"}}');var n=r(74848),s=r(28453);const i={},a="Product features",l={},c=[];function u(e){const t={a:"a",h1:"h1",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"product-features",children:"Product features"})}),"\n",(0,n.jsx)(t.p,{children:"Constellation is a Kubernetes engine that aims to provide the best possible data security in combination with enterprise-grade scalability and reliability features---and a smooth user experience."}),"\n",(0,n.jsxs)(t.p,{children:["From a security perspective, Constellation implements the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/overview/confidential-kubernetes",children:"Confidential Kubernetes"})," concept and corresponding security features, which shield your entire cluster from the underlying infrastructure."]}),"\n",(0,n.jsx)(t.p,{children:"From an operational perspective, Constellation provides the following key features:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"Native support for different clouds"}),": Constellation works on Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), and STACKIT. Support for OpenStack-based environments is coming with a future release. Constellation securely interfaces with the cloud infrastructure to provide ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler",children:"cluster autoscaling"}),", ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/storage/dynamic-provisioning/",children:"dynamic persistent volumes"}),", and ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer",children:"service load balancing"}),"."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"High availability"}),": Constellation uses a ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/",children:"multi-master architecture"})," with a ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/ha-topology/#stacked-etcd-topology",children:"stacked etcd topology"})," to ensure high availability."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"Integrated Day-2 operations"}),": Constellation lets you securely ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/upgrade",children:"upgrade"})," your cluster to a new release. It also lets you securely ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/recovery",children:"recover"})," a failed cluster. Both with a single command."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"Support for Terraform"}),": Constellation includes a ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/terraform-provider",children:"Terraform provider"})," that lets you manage the full lifecycle of your cluster via Terraform."]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/4b669f2d.a0ccaa76.js b/pr-preview/pr-4027/assets/js/4b669f2d.a0ccaa76.js deleted file mode 100644 index abc5cc075..000000000 --- a/pr-preview/pr-4027/assets/js/4b669f2d.a0ccaa76.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[386],{12268:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"architecture/attestation","title":"Attestation","description":"This page explains Constellation\'s attestation process and highlights the cornerstones of its trust model.","source":"@site/versioned_docs/version-2.22/architecture/attestation.md","sourceDirName":"architecture","slug":"/architecture/attestation","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/architecture/attestation.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Microservices","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/microservices"},"next":{"title":"Images","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/images"}}');var i=n(74848),r=n(28453);const o={},a="Attestation",d={},l=[{value:"Terms",id:"terms",level:2},{value:"Trusted Platform Module (TPM)",id:"trusted-platform-module-tpm",level:3},{value:"Runtime measurement",id:"runtime-measurement",level:3},{value:"Platform Configuration Register (PCR)",id:"platform-configuration-register-pcr",level:3},{value:"Measured boot",id:"measured-boot",level:3},{value:"Remote attestation (RA)",id:"remote-attestation-ra",level:3},{value:"Confidential virtual machine (CVM)",id:"confidential-virtual-machine-cvm",level:3},{value:"Attested TLS (aTLS)",id:"attested-tls-atls",level:3},{value:"Overview",id:"overview",level:2},{value:"Node attestation",id:"node-attestation",level:2},{value:"Runtime measurements",id:"runtime-measurements",level:3},{value:"CVM verification",id:"cvm-verification",level:3},{value:"Cluster attestation",id:"cluster-attestation",level:2},{value:"Cluster-facing attestation",id:"cluster-facing-attestation",level:3},{value:"User-facing attestation",id:"user-facing-attestation",level:3},{value:"Putting it all together",id:"putting-it-all-together",level:2},{value:"CLI and node images",id:"cli-and-node-images",level:3},{value:"Cluster creation",id:"cluster-creation",level:3},{value:"Chain of trust",id:"chain-of-trust",level:3},{value:"Upgrades",id:"upgrades",level:3},{value:"References",id:"references",level:2}];function c(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",mermaid:"mermaid",ol:"ol",p:"p",pre:"pre",section:"section",strong:"strong",sup:"sup",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components},{TabItem:n,Tabs:s}=t;return n||u("TabItem",!0),s||u("Tabs",!0),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"attestation",children:"Attestation"})}),"\n",(0,i.jsx)(t.p,{children:"This page explains Constellation's attestation process and highlights the cornerstones of its trust model."}),"\n",(0,i.jsx)(t.h2,{id:"terms",children:"Terms"}),"\n",(0,i.jsx)(t.p,{children:"The following lists terms and concepts that help to understand the attestation concept of Constellation."}),"\n",(0,i.jsx)(t.h3,{id:"trusted-platform-module-tpm",children:"Trusted Platform Module (TPM)"}),"\n",(0,i.jsxs)(t.p,{children:["A TPM chip is a dedicated tamper-resistant crypto-processor.\nIt can securely store artifacts such as passwords, certificates, encryption keys, or ",(0,i.jsx)(t.em,{children:"runtime measurements"})," (more on this below).\nWhen a TPM is implemented in software, it's typically called a ",(0,i.jsx)(t.em,{children:"virtual"})," TPM (vTPM)."]}),"\n",(0,i.jsx)(t.h3,{id:"runtime-measurement",children:"Runtime measurement"}),"\n",(0,i.jsxs)(t.p,{children:["A runtime measurement is a cryptographic hash of the memory pages of a so called ",(0,i.jsx)(t.em,{children:"runtime component"}),". Runtime components of interest typically include a system's bootloader or OS kernel."]}),"\n",(0,i.jsx)(t.h3,{id:"platform-configuration-register-pcr",children:"Platform Configuration Register (PCR)"}),"\n",(0,i.jsx)(t.p,{children:"A Platform Configuration Register (PCR) is a memory location in the TPM that has some unique properties.\nTo store a new value in a PCR, the existing value is extended with a new value as follows:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"PCR[N] = HASHalg( PCR[N] || ArgumentOfExtend )\n"})}),"\n",(0,i.jsx)(t.p,{children:"The PCRs are typically used to store runtime measurements.\nThe new value of a PCR is always an extension of the existing value.\nThus, storing the measurements of multiple components into the same PCR irreversibly links them together."}),"\n",(0,i.jsx)(t.h3,{id:"measured-boot",children:"Measured boot"}),"\n",(0,i.jsx)(t.p,{children:"Measured boot builds on the concept of chained runtime measurements.\nEach component in the boot chain loads and measures the next component into the PCR before executing it.\nBy comparing the resulting PCR values against trusted reference values, the integrity of the entire boot chain and thereby the running system can be ensured."}),"\n",(0,i.jsx)(t.h3,{id:"remote-attestation-ra",children:"Remote attestation (RA)"}),"\n",(0,i.jsx)(t.p,{children:"Remote attestation is the process of verifying certain properties of an application or platform, such as integrity and confidentiality, from a remote location.\nIn the case of a measured boot, the goal is to obtain a signed attestation statement on the PCR values of the boot measurements.\nThe statement can then be verified and compared to a set of trusted reference values.\nThis way, the integrity of the platform can be ensured before sharing secrets with it."}),"\n",(0,i.jsx)(t.h3,{id:"confidential-virtual-machine-cvm",children:"Confidential virtual machine (CVM)"}),"\n",(0,i.jsx)(t.p,{children:"Confidential computing (CC) is the protection of data in-use with hardware-based trusted execution environments (TEEs).\nWith CVMs, TEEs encapsulate entire virtual machines and isolate them against the hypervisor, other VMs, and direct memory access.\nAfter loading the initial VM image into encrypted memory, the hypervisor calls for a secure processor to measure these initial memory pages.\nThe secure processor locks these pages and generates an attestation report on the initial page measurements.\nCVM memory pages are encrypted with a key that resides inside the secure processor, which makes sure only the guest VM can access them.\nThe attestation report is signed by the secure processor and can be verified using remote attestation via the certificate authority of the hardware vendor.\nSuch an attestation statement guarantees the confidentiality and integrity of a CVM."}),"\n",(0,i.jsx)(t.h3,{id:"attested-tls-atls",children:"Attested TLS (aTLS)"}),"\n",(0,i.jsx)(t.p,{children:"In a CC environment, attested TLS (aTLS) can be used to establish secure connections between two parties using the remote attestation features of the CC components."}),"\n",(0,i.jsx)(t.p,{children:"aTLS modifies the TLS handshake by embedding an attestation statement into the TLS certificate.\nInstead of relying on a certificate authority, aTLS uses this attestation statement to establish trust in the certificate."}),"\n",(0,i.jsx)(t.p,{children:"The protocol can be used by clients to verify a server certificate, by a server to verify a client certificate, or for mutual verification (mutual aTLS)."}),"\n",(0,i.jsx)(t.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsx)(t.p,{children:"The challenge for Constellation is to lift a CVM's attestation statement to the Kubernetes software layer and make it end-to-end verifiable.\nFrom there, Constellation needs to expand the attestation from a single CVM to the entire cluster."}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#joinservice",children:(0,i.jsx)(t.em,{children:"JoinService"})})," and ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#verificationservice",children:(0,i.jsx)(t.em,{children:"VerificationService"})})," are where all runs together.\nInternally, the ",(0,i.jsx)(t.em,{children:"JoinService"})," uses remote attestation to securely join CVM nodes to the cluster.\nExternally, the ",(0,i.jsx)(t.em,{children:"VerificationService"})," provides an attestation statement for the cluster's CVMs and configuration."]}),"\n",(0,i.jsx)(t.p,{children:"The following explains the details of both steps."}),"\n",(0,i.jsx)(t.h2,{id:"node-attestation",children:"Node attestation"}),"\n",(0,i.jsx)(t.p,{children:"The idea is that Constellation nodes should have verifiable integrity from the CVM hardware measurement up to the Kubernetes software layer.\nThe solution is a verifiable boot chain and an integrity-protected runtime environment."}),"\n",(0,i.jsxs)(t.p,{children:["Constellation uses measured boot within CVMs, measuring each component in the boot process before executing it.\nOutside of CC, this is usually implemented via TPMs.\nCVM technologies differ in how they implement runtime measurements, but the general concepts are similar to those of a TPM.\nFor simplicity, TPM terminology like ",(0,i.jsx)(t.em,{children:"PCR"})," is used in the following."]}),"\n",(0,i.jsxs)(t.p,{children:["When a Constellation node image boots inside a CVM, measured boot is used for all stages and components of the boot chain.\nThis process goes up to the root filesystem.\nThe root filesystem is mounted read-only with integrity protection.\nFor the details on the image and boot stages see the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/images",children:"image architecture"})," documentation.\nAny changes to the image will inevitably also change the corresponding PCR values.\nTo create a node attestation statement, the Constellation image obtains a CVM attestation statement from the hardware.\nThis includes the runtime measurements and thereby binds the measured boot results to the CVM hardware measurement."]}),"\n",(0,i.jsxs)(t.p,{children:["In addition to the image measurements, Constellation extends a PCR during the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/create",children:"initialization phase"})," that irrevocably marks the node as initialized.\nThe measurement is created using the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys#cluster-identity",children:(0,i.jsx)(t.em,{children:"clusterID"})}),", tying all future attestation statements to this ID.\nThereby, an attestation statement is unique for every cluster and a node can be identified unambiguously as being initialized."]}),"\n",(0,i.jsxs)(t.p,{children:["To verify an attestation, the hardware's signature and a statement are verified first to establish trust in the contained runtime measurements.\nIf successful, the measurements are verified against the trusted values of the particular Constellation release version.\nFinally, the measurement of the ",(0,i.jsx)(t.em,{children:"clusterID"})," can be compared by calculating it with the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys#master-secret",children:"master secret"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"runtime-measurements",children:"Runtime measurements"}),"\n",(0,i.jsx)(t.p,{children:"Constellation uses runtime measurements to implement the measured boot approach.\nAs stated above, the underlying hardware technology and guest firmware differ in their implementations of runtime measurements.\nThe following gives a detailed description of the available measurements in the different cloud environments."}),"\n",(0,i.jsx)(t.p,{children:"The runtime measurements consist of two types of values:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Measurements produced by the cloud infrastructure and firmware of the CVM"}),":\nThese are measurements of closed-source firmware and other values controlled by the cloud provider.\nWhile not being reproducible for the user, some of them can be compared against previously observed values.\nOthers may change frequently and aren't suitable for verification.\nThe ",(0,i.jsx)(t.a,{href:"#chain-of-trust",children:"signed image measurements"})," include measurements that are known, previously observed values."]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Measurements produced by the Constellation bootloader and boot chain"}),":\nThe Constellation Bootloader takes over from the CVM firmware and ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/images",children:"measures the rest of the boot chain"}),".\nThe Constellation ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#bootstrapper",children:"Bootstrapper"})," is the first user mode component that runs in a Constellation image.\nIt extends PCR registers with the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys#cluster-identity",children:"IDs"})," of the cluster marking a node as initialized."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Constellation allows to specify in the config which measurements should be enforced during the attestation process.\nEnforcing non-reproducible measurements controlled by the cloud provider means that changes in these values require manual updates to the cluster's config.\nBy default, Constellation only enforces measurements that are stable values produced by the infrastructure or by Constellation directly."}),"\n",(0,i.jsxs)(s,{groupId:"csp",children:[(0,i.jsxs)(n,{value:"aws",label:"AWS",children:[(0,i.jsxs)(t.p,{children:["Constellation uses the ",(0,i.jsx)(t.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nitrotpm.html",children:"vTPM"})," (NitroTPM) feature of the ",(0,i.jsx)(t.a,{href:"http://aws.amazon.com/ec2/nitro/",children:"AWS Nitro System"})," on AWS for runtime measurements."]}),(0,i.jsxs)(t.p,{children:["The vTPM adheres to the ",(0,i.jsx)(t.a,{href:"https://trustedcomputinggroup.org/resource/tpm-library-specification/",children:"TPM 2.0"})," specification.\nThe VMs are attested by obtaining signed PCR values over the VM's boot configuration from the TPM and comparing them to a known, good state (measured boot)."]}),(0,i.jsx)(t.p,{children:"The following table lists all PCR values of the vTPM and the measured components.\nIt also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable.\nThe latter means that the value can be generated offline and compared to the one in the vTPM."}),(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"PCR"}),(0,i.jsx)(t.th,{children:"Components"}),(0,i.jsx)(t.th,{children:"Measured by"}),(0,i.jsx)(t.th,{children:"Reproducible and verifiable"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"0"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"2"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"3"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"4"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader, Kernel, initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"AWS, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"5"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"6"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"7"}),(0,i.jsx)(t.td,{children:"Secure Boot Policy"}),(0,i.jsx)(t.td,{children:"AWS, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"8"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"9"}),(0,i.jsx)(t.td,{children:"initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Linux Kernel"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10"}),(0,i.jsx)(t.td,{children:"User space"}),(0,i.jsx)(t.td,{children:"Linux IMA"}),(0,i.jsxs)(t.td,{children:["No",(0,i.jsx)(t.sup,{children:(0,i.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"11"}),(0,i.jsx)(t.td,{children:"Unified Kernel Image components"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"12"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(User space, Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"13"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"14"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"15"}),(0,i.jsx)(t.td,{children:"ClusterID"}),(0,i.jsx)(t.td,{children:"Constellation Bootstrapper"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"16\u201323"}),(0,i.jsx)(t.td,{children:"Unused"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]})]})]})]}),(0,i.jsxs)(n,{value:"azure",label:"Azure",children:[(0,i.jsxs)(t.p,{children:["Constellation uses the ",(0,i.jsx)(t.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/trusted-launch#vtpm",children:"vTPM"})," feature of Azure CVMs for runtime measurements.\nThis vTPM adheres to the ",(0,i.jsx)(t.a,{href:"https://trustedcomputinggroup.org/resource/tpm-library-specification/",children:"TPM 2.0"})," specification.\nIt provides a ",(0,i.jsx)(t.a,{href:"https://docs.microsoft.com/en-us/azure/security/fundamentals/measured-boot-host-attestation#measured-boot",children:"measured boot"})," verification that's based on the trusted launch feature of ",(0,i.jsx)(t.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/trusted-launch",children:"Trusted Launch VMs"}),"."]}),(0,i.jsx)(t.p,{children:"The following table lists all PCR values of the vTPM and the measured components.\nIt also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable.\nThe latter means that the value can be generated offline and compared to the one in the vTPM."}),(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"PCR"}),(0,i.jsx)(t.th,{children:"Components"}),(0,i.jsx)(t.th,{children:"Measured by"}),(0,i.jsx)(t.th,{children:"Reproducible and verifiable"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"0"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"2"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"3"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"4"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader, Kernel, initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Azure, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"5"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"6"}),(0,i.jsx)(t.td,{children:"VM Unique ID"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"7"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Azure, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"8"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"9"}),(0,i.jsx)(t.td,{children:"initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Linux Kernel"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10"}),(0,i.jsx)(t.td,{children:"User space"}),(0,i.jsx)(t.td,{children:"Linux IMA"}),(0,i.jsxs)(t.td,{children:["No",(0,i.jsx)(t.sup,{children:(0,i.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"11"}),(0,i.jsx)(t.td,{children:"Unified Kernel Image components"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"12"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(User space, Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"13"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"14"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"15"}),(0,i.jsx)(t.td,{children:"ClusterID"}),(0,i.jsx)(t.td,{children:"Constellation Bootstrapper"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"16\u201323"}),(0,i.jsx)(t.td,{children:"Unused"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]})]})]})]}),(0,i.jsxs)(n,{value:"gcp",label:"GCP",children:[(0,i.jsxs)(t.p,{children:["Constellation uses the ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/compute/confidential-vm/docs/about-cvm",children:"vTPM"})," feature of CVMs on GCP for runtime measurements.\nNote that this vTPM doesn't run inside the hardware-protected CVM context, but is emulated by the hypervisor."]}),(0,i.jsxs)(t.p,{children:["The vTPM adheres to the ",(0,i.jsx)(t.a,{href:"https://trustedcomputinggroup.org/resource/tpm-library-specification/",children:"TPM 2.0"})," specification.\nIt provides a ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/compute/confidential-vm/docs/monitoring#about_launch_attestation_report_events",children:"launch attestation report"})," that's based on the measured boot feature of ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/compute/shielded-vm/docs/shielded-vm#measured-boot",children:"Shielded VMs"}),"."]}),(0,i.jsx)(t.p,{children:"The following table lists all PCR values of the vTPM and the measured components.\nIt also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable.\nThe latter means that the value can be generated offline and compared to the one in the vTPM."}),(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"PCR"}),(0,i.jsx)(t.th,{children:"Components"}),(0,i.jsx)(t.th,{children:"Measured by"}),(0,i.jsx)(t.th,{children:"Reproducible and verifiable"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"0"}),(0,i.jsx)(t.td,{children:"CVM version and technology"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"2"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"3"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"4"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader, Kernel, initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"GCP, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"5"}),(0,i.jsx)(t.td,{children:"Disk GUID partition table"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"6"}),(0,i.jsx)(t.td,{children:"Disk GUID partition table"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"7"}),(0,i.jsx)(t.td,{children:"GCP Secure Boot Policy"}),(0,i.jsx)(t.td,{children:"GCP, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"8"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"9"}),(0,i.jsx)(t.td,{children:"initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Linux Kernel"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10"}),(0,i.jsx)(t.td,{children:"User space"}),(0,i.jsx)(t.td,{children:"Linux IMA"}),(0,i.jsxs)(t.td,{children:["No",(0,i.jsx)(t.sup,{children:(0,i.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"11"}),(0,i.jsx)(t.td,{children:"Unified Kernel Image components"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"12"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(User space, Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"13"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"14"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"15"}),(0,i.jsx)(t.td,{children:"ClusterID"}),(0,i.jsx)(t.td,{children:"Constellation Bootstrapper"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"16\u201323"}),(0,i.jsx)(t.td,{children:"Unused"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]})]})]})]}),(0,i.jsxs)(n,{value:"stackit",label:"STACKIT",children:[(0,i.jsx)(t.p,{children:"Constellation uses a hypervisor-based vTPM for runtime measurements."}),(0,i.jsxs)(t.p,{children:["The vTPM adheres to the ",(0,i.jsx)(t.a,{href:"https://trustedcomputinggroup.org/resource/tpm-library-specification/",children:"TPM 2.0"})," specification.\nThe VMs are attested by obtaining signed PCR values over the VM's boot configuration from the TPM and comparing them to a known, good state (measured boot)."]}),(0,i.jsx)(t.p,{children:"The following table lists all PCR values of the vTPM and the measured components.\nIt also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable.\nThe latter means that the value can be generated offline and compared to the one in the vTPM."}),(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"PCR"}),(0,i.jsx)(t.th,{children:"Components"}),(0,i.jsx)(t.th,{children:"Measured by"}),(0,i.jsx)(t.th,{children:"Reproducible and verifiable"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"0"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"2"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"3"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"4"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader, Kernel, initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"STACKIT, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"5"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"6"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"7"}),(0,i.jsx)(t.td,{children:"Secure Boot Policy"}),(0,i.jsx)(t.td,{children:"STACKIT, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"8"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"9"}),(0,i.jsx)(t.td,{children:"initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Linux Kernel"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10"}),(0,i.jsx)(t.td,{children:"User space"}),(0,i.jsx)(t.td,{children:"Linux IMA"}),(0,i.jsxs)(t.td,{children:["No",(0,i.jsx)(t.sup,{children:(0,i.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"11"}),(0,i.jsx)(t.td,{children:"Unified Kernel Image components"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"12"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(User space, Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"13"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"14"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"15"}),(0,i.jsx)(t.td,{children:"ClusterID"}),(0,i.jsx)(t.td,{children:"Constellation Bootstrapper"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"16\u201323"}),(0,i.jsx)(t.td,{children:"Unused"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]})]})]})]})]}),"\n",(0,i.jsx)(t.h3,{id:"cvm-verification",children:"CVM verification"}),"\n",(0,i.jsx)(t.p,{children:"To verify the integrity of the received attestation statement, a chain of trust from the CVM technology to the interface providing the statement has to be established.\nFor verification of the CVM technology, Constellation may expose additional options in its config file."}),"\n",(0,i.jsxs)(s,{groupId:"csp",children:[(0,i.jsxs)(n,{value:"aws",label:"AWS",children:[(0,i.jsx)(t.p,{children:"On AWS, AMD SEV-SNP is used to provide runtime encryption to the VMs.\nAn SEV-SNP attestation report is used to establish trust in the VM.\nYou may customize certain parameters for verification of the attestation statement using the Constellation config file."}),(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"TCB versions"}),"\n",(0,i.jsx)(t.p,{children:"You can set the minimum version numbers of components in the SEV-SNP TCB.\nUse the latest versions to enforce that only machines with the most recent firmware updates are allowed to join the cluster.\nAlternatively, you can set a lower minimum version to allow slightly out-of-date machines to still be able to join the cluster."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Root Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This certificate is the root of trust for verifying the SEV-SNP certificate chain."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Signing Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This is the intermediate certificate for verifying the SEV-SNP report's signature.\nIf it's not specified, the CLI fetches it from the AMD key distribution server."}),"\n"]}),"\n"]})]}),(0,i.jsxs)(n,{value:"azure",label:"Azure SEV-SNP",children:[(0,i.jsx)(t.p,{children:"On Azure, AMD SEV-SNP is used to provide runtime encryption to the VMs.\nAn SEV-SNP attestation report is used to establish trust in the vTPM running inside the VM.\nYou may customize certain parameters for verification of the attestation statement using the Constellation config file."}),(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"TCB versions"}),"\n",(0,i.jsx)(t.p,{children:"You can set the minimum version numbers of components in the SEV-SNP TCB.\nUse the latest versions to enforce that only machines with the most recent firmware updates are allowed to join the cluster.\nAlternatively, you can set a lower minimum version to allow slightly out-of-date machines to still be able to join the cluster."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Root Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This certificate is the root of trust for verifying the SEV-SNP certificate chain."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"Firmware Signer"}),"\n",(0,i.jsxs)(t.p,{children:["This config option allows you to specify how the firmware signer should be verified.\nMore explicitly, it controls the verification of the ",(0,i.jsx)(t.code,{children:"IDKeyDigest"})," value in the SEV-SNP attestation report.\nYou can provide a list of accepted key digests and specify a policy on how this list is compared against the reported ",(0,i.jsx)(t.code,{children:"IDKeyDigest"}),"."]}),"\n"]}),"\n"]})]}),(0,i.jsxs)(n,{value:"gcp",label:"GCP",children:[(0,i.jsx)(t.p,{children:"On GCP, AMD SEV-SNP is used to provide runtime encryption to the VMs.\nAn SEV-SNP attestation report is used to establish trust in the VM.\nYou may customize certain parameters for verification of the attestation statement using the Constellation config file."}),(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"TCB versions"}),"\n",(0,i.jsx)(t.p,{children:"You can set the minimum version numbers of components in the SEV-SNP TCB.\nUse the latest versions to enforce that only machines with the most recent firmware updates are allowed to join the cluster.\nAlternatively, you can set a lower minimum version to allow slightly out-of-date machines to still be able to join the cluster."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Root Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This certificate is the root of trust for verifying the SEV-SNP certificate chain."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Signing Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This is the intermediate certificate for verifying the SEV-SNP report's signature.\nIf it's not specified, the CLI fetches it from the AMD key distribution server."}),"\n"]}),"\n"]})]}),(0,i.jsx)(n,{value:"stackit",label:"STACKIT",children:(0,i.jsxs)(t.p,{children:["On STACKIT, AMD SEV-ES is used to provide runtime encryption to the VMs.\nThe hypervisor-based vTPM is used to establish trust in the VM via ",(0,i.jsx)(t.a,{href:"#runtime-measurements",children:"runtime measurements"}),".\nThere is no additional configuration available for STACKIT."]})})]}),"\n",(0,i.jsx)(t.h2,{id:"cluster-attestation",children:"Cluster attestation"}),"\n",(0,i.jsxs)(t.p,{children:["Cluster-facing, Constellation's ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#joinservice",children:(0,i.jsx)(t.em,{children:"JoinService"})})," verifies each node joining the cluster given the configured ground truth runtime measurements.\nUser-facing, the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#verificationservice",children:(0,i.jsx)(t.em,{children:"VerificationService"})})," provides an interface to verify a node using remote attestation.\nBy verifying the first node during the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#bootstrapper",children:"initialization"})," and configuring the ground truth measurements that are subsequently enforced by the ",(0,i.jsx)(t.em,{children:"JoinService"}),", the whole cluster is verified in a transitive way."]}),"\n",(0,i.jsx)(t.h3,{id:"cluster-facing-attestation",children:"Cluster-facing attestation"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"JoinService"})," is provided with the runtime measurements of the whitelisted Constellation image version as the ground truth.\nDuring the initialization and the cluster bootstrapping, each node connects to the ",(0,i.jsx)(t.em,{children:"JoinService"})," using ",(0,i.jsx)(t.a,{href:"#attested-tls-atls",children:"aTLS"}),".\nDuring the handshake, the node transmits an attestation statement including its runtime measurements.\nThe ",(0,i.jsx)(t.em,{children:"JoinService"})," verifies that statement and compares the measurements against the ground truth.\nFor details of the initialization process check the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices",children:"microservice descriptions"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["After the initialization, every node updates its runtime measurements with the ",(0,i.jsx)(t.em,{children:"clusterID"})," value, marking it irreversibly as initialized.\nWhen an initialized node tries to join another cluster, its measurements inevitably mismatch the measurements of an uninitialized node and it will be declined."]}),"\n",(0,i.jsx)(t.h3,{id:"user-facing-attestation",children:"User-facing attestation"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#verificationservice",children:(0,i.jsx)(t.em,{children:"VerificationService"})})," provides an endpoint for obtaining its hardware-based remote attestation statement, which includes the runtime measurements.\nA user can ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cluster",children:"verify"})," this statement and compare the measurements against the configured ground truth and, thus, verify the identity and integrity of all Constellation components and the cluster configuration. Subsequently, the user knows that the entire cluster is in the expected state and is trustworthy."]}),"\n",(0,i.jsx)(t.h2,{id:"putting-it-all-together",children:"Putting it all together"}),"\n",(0,i.jsx)(t.p,{children:"This section puts the aforementioned concepts together and illustrate how trust into a Constellation cluster is established and maintained."}),"\n",(0,i.jsx)(t.h3,{id:"cli-and-node-images",children:"CLI and node images"}),"\n",(0,i.jsxs)(t.p,{children:["It all starts with the CLI executable. The CLI is signed by Edgeless Systems. To ensure non-repudiability for CLI releases, Edgeless Systems publishes corresponding signatures to the public ledger of the ",(0,i.jsx)(t.a,{href:"https://www.sigstore.dev/",children:"sigstore project"}),". There's a ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli",children:"step-by-step guide"})," on how to verify CLI signatures based on sigstore."]}),"\n",(0,i.jsxs)(t.p,{children:["The CLI contains the latest runtime measurements of the Constellation node image for all supported cloud platforms. In case a different version of the node image is to be used, the corresponding runtime measurements can be fetched using the CLI's ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-config-fetch-measurements",children:"fetch-measurements command"}),". This command downloads the runtime measurements and the corresponding signature from cdn.confidential.cloud. See for example the following files corresponding to node image v2.16.3:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://cdn.confidential.cloud/constellation/v2/ref/-/stream/stable/v2.16.3/image/measurements.json",children:"Measurements"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://cdn.confidential.cloud/constellation/v2/ref/-/stream/stable/v2.16.3/image/measurements.json.sig",children:"Signature"})}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"The CLI contains the long-term public key of Edgeless Systems to verify the signature of downloaded runtime measurements."}),"\n",(0,i.jsx)(t.h3,{id:"cluster-creation",children:"Cluster creation"}),"\n",(0,i.jsxs)(t.p,{children:["When a cluster is ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/create",children:"created"}),", the CLI automatically verifies the runtime measurements of the ",(0,i.jsx)(t.em,{children:"first node"})," using remote attestation. Based on this, the CLI and the first node set up a temporary TLS connection. This ",(0,i.jsx)(t.a,{href:"#attested-tls-atls",children:"aTLS"})," connection is used for two things:"]}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["The CLI sends the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys#master-secret",children:"master secret"})," of the to-be-created cluster to the CLI. The master secret is generated by the first node."]}),"\n",(0,i.jsxs)(t.li,{children:["The first node sends a ",(0,i.jsx)(t.a,{href:"https://www.redhat.com/sysadmin/kubeconfig",children:"kubeconfig file"})," with Kubernetes credentials to the CLI."]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["After this, the aTLS connection is closed and the first node bootstraps the Kubernetes cluster. All subsequent interactions between the CLI and the cluster go via the ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/overview/kubernetes-api/",children:"Kubernetes API"})," server running inside the cluster. The CLI (and other tools like kubectl) use the credentials referenced by the kubeconfig file to authenticate themselves towards the Kubernetes API server and to establish a mTLS connection."]}),"\n",(0,i.jsx)(t.p,{children:"The CLI connects to the Kubernetes API to write the runtime measurements for the applicable node image to etcd. The JoinService uses these runtime measurements to verify all nodes that join the cluster subsequently."}),"\n",(0,i.jsx)(t.h3,{id:"chain-of-trust",children:"Chain of trust"}),"\n",(0,i.jsx)(t.p,{children:"In summary, there's a chain of trust based on cryptographic signatures that goes from the user to the cluster via the CLI. This is illustrated in the following diagram."}),"\n",(0,i.jsx)(t.mermaid,{value:'flowchart LR\n A[User]-- "verifies" --\x3eB[CLI]\n B[CLI]-- "verifies" --\x3eC([Runtime measurements])\n D[Edgeless Systems]-- "signs" --\x3eB[CLI]\n D[Edgeless Systems]-- "signs" --\x3eC([Runtime measurements])\n B[CLI]-- "verifies (remote attestation)" --\x3eE[First node]\n E[First node]-- "verifies (remote attestation)" --\x3eF[Other nodes]\n C([Runtime measurements]) -.-> E[First node]\n C([Runtime measurements]) -.-> F[Other nodes]'}),"\n",(0,i.jsx)(t.h3,{id:"upgrades",children:"Upgrades"}),"\n",(0,i.jsxs)(t.p,{children:["Whenever a cluster is ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade",children:"upgraded"})," to a new version of the node image, the CLI sends the corresponding runtime measurements via the Kubernetes API server. The new runtime measurements are stored in etcd within the cluster and replace any previous runtime measurements. The new runtime measurements are then used automatically by the JoinService for the verification of new nodes."]}),"\n",(0,i.jsx)(t.h2,{id:"references",children:"References"}),"\n","\n",(0,i.jsxs)(t.section,{"data-footnotes":!0,className:"footnotes",children:[(0,i.jsx)(t.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{id:"user-content-fn-1",children:["\n",(0,i.jsxs)(t.p,{children:["Linux IMA produces runtime measurements of user-space binaries.\nHowever, these measurements aren't deterministic and thus, PCR[10] can't be compared to a constant value.\nInstead, a policy engine must be used to verify the TPM event log against a policy. ",(0,i.jsx)(t.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})," ",(0,i.jsxs)(t.a,{href:"#user-content-fnref-1-2","data-footnote-backref":"","aria-label":"Back to reference 1-2",className:"data-footnote-backref",children:["\u21a9",(0,i.jsx)(t.sup,{children:"2"})]})," ",(0,i.jsxs)(t.a,{href:"#user-content-fnref-1-3","data-footnote-backref":"","aria-label":"Back to reference 1-3",className:"data-footnote-backref",children:["\u21a9",(0,i.jsx)(t.sup,{children:"3"})]})," ",(0,i.jsxs)(t.a,{href:"#user-content-fnref-1-4","data-footnote-backref":"","aria-label":"Back to reference 1-4",className:"data-footnote-backref",children:["\u21a9",(0,i.jsx)(t.sup,{children:"4"})]})]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}function u(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const i={},r=s.createContext(i);function o(e){const t=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/4bfed142.f1329705.js b/pr-preview/pr-4027/assets/js/4bfed142.f1329705.js deleted file mode 100644 index a320ba46d..000000000 --- a/pr-preview/pr-4027/assets/js/4bfed142.f1329705.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[417],{28453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>c});var o=s(96540);const l={},r=o.createContext(l);function t(e){const n=o.useContext(r);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:t(e.components),o.createElement(r.Provider,{value:n},e.children)}},54775:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>u,frontMatter:()=>t,metadata:()=>o,toc:()=>a});const o=JSON.parse('{"id":"workflows/scale","title":"Scale your cluster","description":"Constellation provides all features of a Kubernetes cluster including scaling and autoscaling.","source":"@site/versioned_docs/version-2.22/workflows/scale.md","sourceDirName":"workflows","slug":"/workflows/scale","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/scale","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/workflows/scale.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Create your cluster","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/create"},"next":{"title":"Upgrade your cluster","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade"}}');var l=s(74848),r=s(28453);const t={},c="Scale your cluster",i={},a=[{value:"Worker node scaling",id:"worker-node-scaling",level:2},{value:"Autoscaling",id:"autoscaling",level:3},{value:"Manual scaling",id:"manual-scaling",level:3},{value:"Control-plane node scaling",id:"control-plane-node-scaling",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,r.R)(),...e.components},{TabItem:s,Tabs:o}=n;return s||h("TabItem",!0),o||h("Tabs",!0),(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"scale-your-cluster",children:"Scale your cluster"})}),"\n",(0,l.jsx)(n.p,{children:"Constellation provides all features of a Kubernetes cluster including scaling and autoscaling."}),"\n",(0,l.jsx)(n.h2,{id:"worker-node-scaling",children:"Worker node scaling"}),"\n",(0,l.jsx)(n.h3,{id:"autoscaling",children:"Autoscaling"}),"\n",(0,l.jsx)(n.p,{children:"Constellation comes with autoscaling disabled by default. To enable autoscaling, find the scaling group of\nworker nodes:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:'kubectl get scalinggroups -o json | yq \'.items | .[] | select(.spec.role == "Worker") | [{"name": .metadata.name, "nodeGoupName": .spec.nodeGroupName}]\'\n'})}),"\n",(0,l.jsxs)(n.p,{children:["This will output a list of scaling groups with the corresponding cloud provider name (",(0,l.jsx)(n.code,{children:"name"}),") and the cloud provider agnostic name of the node group (",(0,l.jsx)(n.code,{children:"nodeGroupName"}),")."]}),"\n",(0,l.jsxs)(n.p,{children:["Then, patch the ",(0,l.jsx)(n.code,{children:"autoscaling"})," field of the scaling group resource with the desired ",(0,l.jsx)(n.code,{children:"name"})," to ",(0,l.jsx)(n.code,{children:"true"}),":"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# Replace <name> with the name of the scaling group you want to enable autoscaling for\nworker_group=<name>\nkubectl patch scalinggroups $worker_group --patch '{\"spec\":{\"autoscaling\": true}}' --type='merge'\nkubectl get scalinggroup $worker_group -o jsonpath='{.spec}' | yq -P\n"})}),"\n",(0,l.jsxs)(n.p,{children:["The cluster autoscaler now automatically provisions additional worker nodes so that all pods have a place to run.\nYou can configure the minimum and maximum number of worker nodes in the scaling group by patching the ",(0,l.jsx)(n.code,{children:"min"})," or\n",(0,l.jsx)(n.code,{children:"max"})," fields of the scaling group resource:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl patch scalinggroups $worker_group --patch '{\"spec\":{\"max\": 5}}' --type='merge'\nkubectl get scalinggroup $worker_group -o jsonpath='{.spec}' | yq -P\n"})}),"\n",(0,l.jsx)(n.p,{children:"The cluster autoscaler will now never provision more than 5 worker nodes."}),"\n",(0,l.jsx)(n.p,{children:"If you want to see the autoscaling in action, try to add a deployment with a lot of replicas, like the\nfollowing Nginx deployment. The number of replicas needed to trigger the autoscaling depends on the size of\nand count of your worker nodes. Wait for the rollout of the deployment to finish and compare the number of\nworker nodes before and after the deployment:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl create deployment nginx --image=nginx --replicas 150\nkubectl -n kube-system get nodes\nkubectl rollout status deployment nginx\nkubectl -n kube-system get nodes\n"})}),"\n",(0,l.jsx)(n.h3,{id:"manual-scaling",children:"Manual scaling"}),"\n",(0,l.jsx)(n.p,{children:"Alternatively, you can manually scale your cluster up or down:"}),"\n",(0,l.jsxs)(o,{groupId:"csp",children:[(0,l.jsx)(s,{value:"aws",label:"AWS",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Go to Auto Scaling Groups and select the worker ASG to scale up."}),"\n",(0,l.jsxs)(n.li,{children:["Click ",(0,l.jsx)(n.strong,{children:"Edit"})]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new (increased) ",(0,l.jsx)(n.strong,{children:"Desired capacity"})," and ",(0,l.jsx)(n.strong,{children:"Update"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"azure",label:"Azure",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Find your Constellation resource group."}),"\n",(0,l.jsxs)(n.li,{children:["Select the ",(0,l.jsx)(n.code,{children:"scale-set-workers"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:["Go to ",(0,l.jsx)(n.strong,{children:"settings"})," and ",(0,l.jsx)(n.strong,{children:"scaling"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new ",(0,l.jsx)(n.strong,{children:"instance count"})," and ",(0,l.jsx)(n.strong,{children:"save"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"gcp",label:"GCP",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["In Compute Engine go to ",(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/compute/instanceGroups/",children:"Instance Groups"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Edit"})," the ",(0,l.jsx)(n.strong,{children:"worker"})," instance group."]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new ",(0,l.jsx)(n.strong,{children:"number of instances"})," and ",(0,l.jsx)(n.strong,{children:"save"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,l.jsx)(n.p,{children:"Dynamic cluster scaling isn't yet supported for STACKIT.\nSupport will be introduced in one of the upcoming releases."})})]}),"\n",(0,l.jsx)(n.h2,{id:"control-plane-node-scaling",children:"Control-plane node scaling"}),"\n",(0,l.jsxs)(n.p,{children:["Control-plane nodes can ",(0,l.jsx)(n.strong,{children:"only be scaled manually and only scaled up"}),"!"]}),"\n",(0,l.jsx)(n.p,{children:"To increase the number of control-plane nodes, follow these steps:"}),"\n",(0,l.jsxs)(o,{groupId:"csp",children:[(0,l.jsx)(s,{value:"aws",label:"AWS",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Go to Auto Scaling Groups and select the control-plane ASG to scale up."}),"\n",(0,l.jsxs)(n.li,{children:["Click ",(0,l.jsx)(n.strong,{children:"Edit"})]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new (increased) ",(0,l.jsx)(n.strong,{children:"Desired capacity"})," and ",(0,l.jsx)(n.strong,{children:"Update"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"azure",label:"Azure",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Find your Constellation resource group."}),"\n",(0,l.jsxs)(n.li,{children:["Select the ",(0,l.jsx)(n.code,{children:"scale-set-controlplanes"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:["Go to ",(0,l.jsx)(n.strong,{children:"settings"})," and ",(0,l.jsx)(n.strong,{children:"scaling"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new (increased) ",(0,l.jsx)(n.strong,{children:"instance count"})," and ",(0,l.jsx)(n.strong,{children:"save"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"gcp",label:"GCP",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["In Compute Engine go to ",(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/compute/instanceGroups/",children:"Instance Groups"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Edit"})," the ",(0,l.jsx)(n.strong,{children:"control-plane"})," instance group."]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new (increased) ",(0,l.jsx)(n.strong,{children:"number of instances"})," and ",(0,l.jsx)(n.strong,{children:"save"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,l.jsx)(n.p,{children:"Dynamic cluster scaling isn't yet supported for STACKIT.\nSupport will be introduced in one of the upcoming releases."})})]}),"\n",(0,l.jsxs)(n.p,{children:["If you scale down the number of control-planes nodes, the removed nodes won't be able to exit the ",(0,l.jsx)(n.code,{children:"etcd"})," cluster correctly. This will endanger the quorum that's required to run a stable Kubernetes control plane."]})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}function h(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/4c9525de.7cf5dfaf.js b/pr-preview/pr-4027/assets/js/4c9525de.7cf5dfaf.js deleted file mode 100644 index f266e52a8..000000000 --- a/pr-preview/pr-4027/assets/js/4c9525de.7cf5dfaf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7356],{28453:(e,n,o)=>{o.d(n,{R:()=>a,x:()=>s});var r=o(96540);const t={},i=r.createContext(t);function a(e){const n=r.useContext(i);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),r.createElement(i.Provider,{value:n},e.children)}},63344:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>m,frontMatter:()=>a,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"overview/performance/performance","title":"Performance analysis of Constellation","description":"This section provides a comprehensive examination of the performance characteristics of Constellation.","source":"@site/versioned_docs/version-2.24/overview/performance/performance.md","sourceDirName":"overview/performance","slug":"/overview/performance/","permalink":"/constellation/pr-preview/pr-4027/overview/performance/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/overview/performance/performance.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Feature status of clouds","permalink":"/constellation/pr-preview/pr-4027/overview/clouds"},"next":{"title":"Compute benchmarks","permalink":"/constellation/pr-preview/pr-4027/overview/performance/compute"}}');var t=o(74848),i=o(28453);const a={},s="Performance analysis of Constellation",c={},l=[{value:"Runtime encryption",id:"runtime-encryption",level:2},{value:"I/O performance benchmarks",id:"io-performance-benchmarks",level:2},{value:"Application benchmarking",id:"application-benchmarking",level:2}];function p(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"performance-analysis-of-constellation",children:"Performance analysis of Constellation"})}),"\n",(0,t.jsx)(n.p,{children:"This section provides a comprehensive examination of the performance characteristics of Constellation."}),"\n",(0,t.jsx)(n.h2,{id:"runtime-encryption",children:"Runtime encryption"}),"\n",(0,t.jsxs)(n.p,{children:["Runtime encryption affects compute performance. ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/overview/performance/compute",children:"Benchmarks by Azure and Google"})," show that the performance degradation of Confidential VMs (CVMs) is small, ranging from 2% to 8% for compute-intensive workloads."]}),"\n",(0,t.jsx)(n.h2,{id:"io-performance-benchmarks",children:"I/O performance benchmarks"}),"\n",(0,t.jsxs)(n.p,{children:["We evaluated the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/overview/performance/io",children:"I/O performance"})," of Constellation, utilizing a collection of synthetic benchmarks targeting networking and storage.\nWe further compared this performance to native managed Kubernetes offerings from various cloud providers, to better understand how Constellation stands in relation to standard practices."]}),"\n",(0,t.jsx)(n.h2,{id:"application-benchmarking",children:"Application benchmarking"}),"\n",(0,t.jsxs)(n.p,{children:["To gauge Constellation's applicability to well-known applications, we performed a ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/overview/performance/application",children:"benchmark of HashiCorp Vault"})," running on Constellation.\nThe results were then compared to deployments on the managed Kubernetes offerings from different cloud providers, providing a tangible perspective on Constellation's performance in actual deployment scenarios."]})]})}function m(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/4cc5eb92.4f588dea.js b/pr-preview/pr-4027/assets/js/4cc5eb92.4f588dea.js deleted file mode 100644 index 02acff2dc..000000000 --- a/pr-preview/pr-4027/assets/js/4cc5eb92.4f588dea.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3340],{11551:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>d});const r=JSON.parse('{"id":"architecture/networking","title":"Network encryption","description":"Constellation encrypts all pod communication using the container network interface (CNI).","source":"@site/docs/architecture/networking.md","sourceDirName":"architecture","slug":"/architecture/networking","permalink":"/constellation/pr-preview/pr-4027/next/architecture/networking","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/architecture/networking.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Encrypted persistent storage","permalink":"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage"},"next":{"title":"Observability","permalink":"/constellation/pr-preview/pr-4027/next/architecture/observability"}}');var i=n(74848),o=n(28453);const s={},c="Network encryption",a={},d=[];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"network-encryption",children:"Network encryption"})}),"\n",(0,i.jsxs)(t.p,{children:["Constellation encrypts all pod communication using the ",(0,i.jsx)(t.a,{href:"https://github.com/containernetworking/cni",children:"container network interface (CNI)"}),".\nTo that end, Constellation deploys, configures, and operates the ",(0,i.jsx)(t.a,{href:"https://cilium.io/",children:"Cilium"})," CNI plugin.\nCilium provides ",(0,i.jsx)(t.a,{href:"https://docs.cilium.io/en/stable/security/network/encryption",children:"transparent encryption"})," for all cluster traffic using either IPSec or ",(0,i.jsx)(t.a,{href:"https://www.wireguard.com/",children:"WireGuard"}),".\nCurrently, Constellation only supports WireGuard as the encryption engine.\nYou can read more about the cryptographic soundness of WireGuard ",(0,i.jsx)(t.a,{href:"https://www.wireguard.com/papers/wireguard.pdf",children:"in their white paper"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["Cilium is actively working on implementing a feature called ",(0,i.jsx)(t.a,{href:"https://github.com/cilium/cilium/pull/19401",children:(0,i.jsx)(t.code,{children:"host-to-host"})})," encryption mode for WireGuard.\nWith ",(0,i.jsx)(t.code,{children:"host-to-host"}),", all traffic between nodes will be tunneled via WireGuard (host-to-host, host-to-pod, pod-to-host, pod-to-pod).\nUntil the ",(0,i.jsx)(t.code,{children:"host-to-host"})," feature is released, Constellation enables ",(0,i.jsx)(t.code,{children:"pod-to-pod"})," encryption.\nThis mode encrypts all traffic between Kubernetes pods using WireGuard tunnels."]}),"\n",(0,i.jsxs)(t.p,{children:["When using Cilium in the default setup but with encryption enabled, there is a ",(0,i.jsx)(t.a,{href:"https://docs.cilium.io/en/v1.12/gettingstarted/encryption/#egress-traffic-to-not-yet-discovered-remote-endpoints-may-be-unencrypted",children:"known issue"}),"\nthat can cause pod-to-pod traffic to be unencrypted.\nTo mitigate this issue, Constellation adds a ",(0,i.jsx)(t.em,{children:"strict"})," mode to Cilium's ",(0,i.jsx)(t.code,{children:"pod-to-pod"})," encryption.\nThis mode changes the default behavior of traffic that's destined for an unknown endpoint to not be send out in plaintext, but instead being dropped.\nThe strict mode distinguishes between traffic that's send to a pod from traffic that's destined for a cluster-external endpoint by considering the pod's CIDR range."]}),"\n",(0,i.jsxs)(t.p,{children:["Traffic originating from hosts isn't encrypted yet.\nThis mainly includes health checks from Kubernetes API server.\nAlso, traffic proxied over the API server via e.g. ",(0,i.jsx)(t.code,{children:"kubectl port-forward"})," isn't encrypted."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var r=n(96540);const i={},o=r.createContext(i);function s(e){const t=r.useContext(o);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/4cf171a2.e11e2998.js b/pr-preview/pr-4027/assets/js/4cf171a2.e11e2998.js deleted file mode 100644 index aed416b11..000000000 --- a/pr-preview/pr-4027/assets/js/4cf171a2.e11e2998.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9442],{28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>l});var s=t(96540);const r={},i=s.createContext(r);function o(e){const n=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:n},e.children)}},96588:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"workflows/verify-cluster","title":"Verify your cluster","description":"Constellation\'s attestation feature allows you, or a third party, to verify the integrity and confidentiality of your Constellation cluster.","source":"@site/versioned_docs/version-2.23/workflows/verify-cluster.md","sourceDirName":"workflows","slug":"/workflows/verify-cluster","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cluster","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/workflows/verify-cluster.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Recover your cluster","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/recovery"},"next":{"title":"Use persistent storage","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/storage"}}');var r=t(74848),i=t(28453);const o={},l="Verify your cluster",a={},c=[{value:"Fetch measurements",id:"fetch-measurements",level:2},{value:"The <em>verify</em> command",id:"the-verify-command",level:2},{value:"Custom arguments",id:"custom-arguments",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"verify-your-cluster",children:"Verify your cluster"})}),"\n",(0,r.jsxs)(n.p,{children:["Constellation's ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation",children:"attestation feature"})," allows you, or a third party, to verify the integrity and confidentiality of your Constellation cluster."]}),"\n",(0,r.jsx)(n.h2,{id:"fetch-measurements",children:"Fetch measurements"}),"\n",(0,r.jsx)(n.p,{children:"To verify the integrity of Constellation you need trusted measurements to verify against. For each node image released by Edgeless Systems, there are signed measurements, which you can download using the CLI:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"constellation config fetch-measurements\n"})}),"\n",(0,r.jsx)(n.p,{children:"This command performs the following steps:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Download the signed measurements for the configured image. By default, this will use Edgeless Systems' public measurement registry."}),"\n",(0,r.jsxs)(n.li,{children:["Verify the signature of the measurements. This will use Edgeless Systems' ",(0,r.jsx)(n.a,{href:"https://edgeless.systems/es.pub",children:"public key"}),"."]}),"\n",(0,r.jsx)(n.li,{children:"Write measurements into configuration file."}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["The configuration file then contains a list of ",(0,r.jsx)(n.code,{children:"measurements"})," similar to the following:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'# ...\nmeasurements:\n 0:\n expected: "0f35c214608d93c7a6e68ae7359b4a8be5a0e99eea9107ece427c4dea4e439cf"\n warnOnly: false\n 4:\n expected: "02c7a67c01ec70ffaf23d73a12f749ab150a8ac6dc529bda2fe1096a98bf42ea"\n warnOnly: false\n 5:\n expected: "e6949026b72e5045706cd1318889b3874480f7a3f7c5c590912391a2d15e6975"\n warnOnly: true\n 8:\n expected: "0000000000000000000000000000000000000000000000000000000000000000"\n warnOnly: false\n 9:\n expected: "f0a6e8601b00e2fdc57195686cd4ef45eb43a556ac1209b8e25d993213d68384"\n warnOnly: false\n 11:\n expected: "0000000000000000000000000000000000000000000000000000000000000000"\n warnOnly: false\n 12:\n expected: "da99eb6cf7c7fbb692067c87fd5ca0b7117dc293578e4fea41f95d3d3d6af5e2"\n warnOnly: false\n 13:\n expected: "0000000000000000000000000000000000000000000000000000000000000000"\n warnOnly: false\n 14:\n expected: "d7c4cc7ff7933022f013e03bdee875b91720b5b86cf1753cad830f95e791926f"\n warnOnly: true\n 15:\n expected: "0000000000000000000000000000000000000000000000000000000000000000"\n warnOnly: false\n# ...\n'})}),"\n",(0,r.jsxs)(n.p,{children:["Each entry specifies the expected value of the Constellation node, and whether the measurement should be enforced (",(0,r.jsx)(n.code,{children:"warnOnly: false"}),"), or only a warning should be logged (",(0,r.jsx)(n.code,{children:"warnOnly: true"}),").\nBy default, the subset of the ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation#runtime-measurements",children:"available measurements"})," that can be locally reproduced and verified is enforced."]}),"\n",(0,r.jsxs)(n.p,{children:["During attestation, the validating side (CLI or ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#joinservice",children:"join service"}),") compares each measurement reported by the issuing side (first node or joining node) individually.\nFor mismatching measurements that have set ",(0,r.jsx)(n.code,{children:"warnOnly"})," to ",(0,r.jsx)(n.code,{children:"true"})," only a warning is emitted.\nFor mismatching measurements that have set ",(0,r.jsx)(n.code,{children:"warnOnly"})," to ",(0,r.jsx)(n.code,{children:"false"})," an error is emitted and attestation fails.\nIf attestation fails for a new node, it isn't permitted to join the cluster."]}),"\n",(0,r.jsxs)(n.h2,{id:"the-verify-command",children:["The ",(0,r.jsx)(n.em,{children:"verify"})," command"]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["The steps below are purely optional. They're automatically executed by ",(0,r.jsx)(n.code,{children:"constellation apply"})," when you initialize your cluster. The ",(0,r.jsx)(n.code,{children:"constellation verify"})," command mostly has an illustrative purpose."]})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"verify"})," command obtains and verifies an attestation statement from a running Constellation cluster."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"constellation verify [--cluster-id ...]\n"})}),"\n",(0,r.jsx)(n.p,{children:"From the attestation statement, the command verifies the following properties:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"The cluster is using the correct Confidential VM (CVM) type."}),"\n",(0,r.jsx)(n.li,{children:"Inside the CVMs, the correct node images are running. The node images are identified through the measurements obtained in the previous step."}),"\n",(0,r.jsxs)(n.li,{children:["The unique ID of the cluster matches the one from your ",(0,r.jsx)(n.code,{children:"constellation-state.yaml"})," file or passed in via ",(0,r.jsx)(n.code,{children:"--cluster-id"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Once the above properties are verified, you know that you are talking to the right Constellation cluster and it's in a good and trustworthy shape."}),"\n",(0,r.jsx)(n.h3,{id:"custom-arguments",children:"Custom arguments"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"verify"})," command also allows you to verify any Constellation deployment that you have network access to. For this you need the following:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The IP address of a running Constellation cluster's ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#verificationservice",children:"VerificationService"}),". The ",(0,r.jsx)(n.code,{children:"VerificationService"})," is exposed via a ",(0,r.jsx)(n.code,{children:"NodePort"})," service using the external IP address of your cluster. Run ",(0,r.jsx)(n.code,{children:"kubectl get nodes -o wide"})," and look for ",(0,r.jsx)(n.code,{children:"EXTERNAL-IP"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["The cluster's ",(0,r.jsx)(n.em,{children:"clusterID"}),". See ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys#cluster-identity",children:"cluster identity"})," for more details."]}),"\n",(0,r.jsxs)(n.li,{children:["A ",(0,r.jsx)(n.code,{children:"constellation-conf.yaml"})," file with the expected measurements of the cluster in your working directory."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"For example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-shell-session",children:"constellation verify -e 192.0.2.1 --cluster-id Q29uc3RlbGxhdGlvbkRvY3VtZW50YXRpb25TZWNyZXQ=\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/4f0549e0.456cfea0.js b/pr-preview/pr-4027/assets/js/4f0549e0.456cfea0.js deleted file mode 100644 index b5a99fe37..000000000 --- a/pr-preview/pr-4027/assets/js/4f0549e0.456cfea0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1734],{28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var r=n(96540);const o={},s=r.createContext(o);function a(e){const t=r.useContext(s);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),r.createElement(s.Provider,{value:t},e.children)}},55256:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"workflows/terminate","title":"Terminate your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","source":"@site/versioned_docs/version-2.24/workflows/terminate.md","sourceDirName":"workflows","slug":"/workflows/terminate","permalink":"/constellation/pr-preview/pr-4027/workflows/terminate","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/workflows/terminate.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Install s3proxy","permalink":"/constellation/pr-preview/pr-4027/workflows/s3proxy"},"next":{"title":"Recover your cluster","permalink":"/constellation/pr-preview/pr-4027/workflows/recovery"}}');var o=n(74848),s=n(28453);const a={},i="Terminate your cluster",l={},c=[];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",header:"header",hr:"hr",p:"p",pre:"pre",...(0,s.R)(),...e.components},{AsciinemaWidget:n,TabItem:r,Tabs:a}=t;return n||u("AsciinemaWidget",!0),r||u("TabItem",!0),a||u("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"terminate-your-cluster",children:"Terminate your cluster"})}),"\n",(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsx)(t.p,{children:"This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details."})}),"\n",(0,o.jsx)(n,{src:"/constellation/assets/terminate-cluster.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,o.jsx)(t.hr,{}),"\n",(0,o.jsxs)(t.p,{children:["You can terminate your cluster using the CLI. For this, you need the Terraform state directory named ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/reference/terraform",children:(0,o.jsx)(t.code,{children:"constellation-terraform"})})," in the current directory."]}),"\n",(0,o.jsx)(t.admonition,{type:"danger",children:(0,o.jsx)(t.p,{children:"All ephemeral storage and state of your cluster will be lost. Make sure any data is safely stored in persistent storage. Constellation can recreate your cluster and the associated encryption keys, but won't backup your application data automatically."})}),"\n",(0,o.jsxs)(a,{groupId:"provider",children:[(0,o.jsxs)(r,{value:"cli",label:"CLI",children:[(0,o.jsx)(t.p,{children:"Terminate the cluster by running:"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation terminate\n"})}),(0,o.jsx)(t.p,{children:"Or without confirmation (e.g., for automation purposes):"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation terminate --yes\n"})}),(0,o.jsxs)(t.p,{children:["This deletes all resources created by Constellation in your cloud environment.\nAll local files created by the ",(0,o.jsx)(t.code,{children:"apply"})," command are deleted as well, except for ",(0,o.jsx)(t.code,{children:"constellation-mastersecret.json"})," and the configuration file."]}),(0,o.jsx)(t.admonition,{type:"caution",children:(0,o.jsxs)(t.p,{children:["Termination can fail if additional resources have been created that depend on the ones managed by Constellation. In this case, you need to delete these additional\nresources manually. Just run the ",(0,o.jsx)(t.code,{children:"terminate"})," command again afterward to continue the termination process of the cluster."]})})]}),(0,o.jsxs)(r,{value:"terraform",label:"Terraform",children:[(0,o.jsx)(t.p,{children:"Terminate the cluster by running:"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"terraform destroy\n"})}),(0,o.jsx)(t.p,{children:"Delete all files that are no longer needed:"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"rm constellation-state.yaml constellation-admin.conf\n"})}),(0,o.jsxs)(t.p,{children:["Only the ",(0,o.jsx)(t.code,{children:"constellation-mastersecret.json"})," and the configuration file remain."]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}function u(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/4fce284f.af8f5e7c.js b/pr-preview/pr-4027/assets/js/4fce284f.af8f5e7c.js deleted file mode 100644 index 9f81cb6e5..000000000 --- a/pr-preview/pr-4027/assets/js/4fce284f.af8f5e7c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1201],{26761:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Getting started","slug":"/category/getting-started","permalink":"/constellation/pr-preview/pr-4027/2.23/category/getting-started","sidebar":"docs","navigation":{"previous":{"title":"License","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/license"},"next":{"title":"Installation","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/install"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/508a7d2f.d99914e5.js b/pr-preview/pr-4027/assets/js/508a7d2f.d99914e5.js deleted file mode 100644 index 4bf112750..000000000 --- a/pr-preview/pr-4027/assets/js/508a7d2f.d99914e5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1376],{22396:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"getting-started/examples","title":"Examples","description":"After you installed the CLI and created your first cluster, you\'re ready to deploy applications. Why not start with one of the following examples?","source":"@site/docs/getting-started/examples.md","sourceDirName":"getting-started","slug":"/getting-started/examples","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/examples","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/getting-started/examples.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Cloud Marketplaces","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/marketplaces"},"next":{"title":"Emojivoto","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/examples/emojivoto"}}');var o=n(74848),r=n(28453);const i={},a="Examples",l={},c=[];function p(e){const t={a:"a",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"examples",children:"Examples"})}),"\n",(0,o.jsxs)(t.p,{children:["After you ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/install",children:"installed the CLI"})," and ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/first-steps",children:"created your first cluster"}),", you're ready to deploy applications. Why not start with one of the following examples?"]}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/examples/emojivoto",children:"Emojivoto"}),": a simple but fun web application"]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/examples/online-boutique",children:"Online Boutique"}),": an e-commerce demo application by Google consisting of 11 separate microservices"]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/examples/horizontal-scaling",children:"Horizontal Pod Autoscaling"}),": an example demonstrating Constellation's autoscaling capabilities"]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>a});var s=n(96540);const o={},r=s.createContext(o);function i(e){const t=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/533d31d4.7f39540d.js b/pr-preview/pr-4027/assets/js/533d31d4.7f39540d.js deleted file mode 100644 index 2f1b19b3b..000000000 --- a/pr-preview/pr-4027/assets/js/533d31d4.7f39540d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6822],{7189:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>a,default:()=>u,frontMatter:()=>l,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"getting-started/examples/online-boutique","title":"Online Boutique","description":"Online Boutique is an e-commerce demo application by Google consisting of 11 separate microservices. In this demo, Constellation automatically sets up a load balancer on your CSP, making it easy to expose services from your confidential cluster.","source":"@site/versioned_docs/version-2.23/getting-started/examples/online-boutique.md","sourceDirName":"getting-started/examples","slug":"/getting-started/examples/online-boutique","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/online-boutique","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/getting-started/examples/online-boutique.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Emojivoto","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/emojivoto"},"next":{"title":"Horizontal Pod Autoscaling","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/horizontal-scaling"}}');var s=t(74848),i=t(28453);const l={},a="Online Boutique",r={},c=[];function d(e){const n={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"online-boutique",children:"Online Boutique"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://github.com/GoogleCloudPlatform/microservices-demo",children:"Online Boutique"})," is an e-commerce demo application by Google consisting of 11 separate microservices. In this demo, Constellation automatically sets up a load balancer on your CSP, making it easy to expose services from your confidential cluster."]}),"\n",(0,s.jsx)("img",{src:t(49698).A,alt:"Online Boutique - Web UI",width:"662"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Create a namespace:","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl create ns boutique\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Deploy the application:","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl apply -n boutique -f https://github.com/GoogleCloudPlatform/microservices-demo/raw/main/release/kubernetes-manifests.yaml\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Wait for all services to become available:","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl wait --for=condition=available --timeout=300s -n boutique --all deployments\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Get the frontend's external IP address:","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell-session",children:"$ kubectl get service frontend-external -n boutique | awk '{print $4}'\nEXTERNAL-IP\n<your-ip>\n"})}),"\n","(",(0,s.jsx)(n.code,{children:"<your-ip>"})," is a placeholder for the IP assigned by your CSP.)"]}),"\n",(0,s.jsx)(n.li,{children:"Enter the IP from the result in your browser to browse the online shop."}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>l,x:()=>a});var o=t(96540);const s={},i=o.createContext(s);function l(e){const n=o.useContext(i);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),o.createElement(i.Provider,{value:n},e.children)}},49698:(e,n,t)=>{t.d(n,{A:()=>o});const o=t.p+"assets/images/example-online-boutique-c89a9a15b1d4c086d3654bf75843295e.jpg"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/53c1dfd4.9a270882.js b/pr-preview/pr-4027/assets/js/53c1dfd4.9a270882.js deleted file mode 100644 index d97b23ec5..000000000 --- a/pr-preview/pr-4027/assets/js/53c1dfd4.9a270882.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4085],{28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>o});var r=n(96540);const a={},i=r.createContext(a);function s(e){const t=r.useContext(i);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),r.createElement(i.Provider,{value:t},e.children)}},62913:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"architecture/keys","title":"Key management and cryptographic primitives","description":"Constellation protects and isolates your cluster and workloads.","source":"@site/versioned_docs/version-2.22/architecture/keys.md","sourceDirName":"architecture","slug":"/architecture/keys","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/keys","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/architecture/keys.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Images","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/images"},"next":{"title":"Encrypted persistent storage","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage"}}');var a=n(74848),i=n(28453);const s={},o="Key management and cryptographic primitives",l={},c=[{value:"Confidential VMs",id:"confidential-vms",level:2},{value:"Master secret",id:"master-secret",level:2},{value:"Cluster identity",id:"cluster-identity",level:2},{value:"Network encryption",id:"network-encryption",level:2},{value:"Storage encryption",id:"storage-encryption",level:2},{value:"Constellation-managed key management",id:"constellation-managed-key-management",level:3},{value:"Key material and key derivation",id:"key-material-and-key-derivation",level:4},{value:"State and storage",id:"state-and-storage",level:4},{value:"Availability",id:"availability",level:4},{value:"Recovery",id:"recovery",level:4},{value:"User-managed key management",id:"user-managed-key-management",level:3},{value:"Recovery and migration",id:"recovery-and-migration",level:4}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"key-management-and-cryptographic-primitives",children:"Key management and cryptographic primitives"})}),"\n",(0,a.jsx)(t.p,{children:"Constellation protects and isolates your cluster and workloads.\nTo that end, cryptography is the foundation that ensures the confidentiality and integrity of all components.\nEvaluating the security and compliance of Constellation requires a precise understanding of the cryptographic primitives and keys used.\nThe following gives an overview of the architecture and explains the technical details."}),"\n",(0,a.jsx)(t.h2,{id:"confidential-vms",children:"Confidential VMs"}),"\n",(0,a.jsx)(t.p,{children:"Confidential VM (CVM) technology comes with hardware and software components for memory encryption, isolation, and remote attestation.\nFor details on the implementations and cryptographic soundness, refer to the hardware vendors' documentation and advisories."}),"\n",(0,a.jsx)(t.h2,{id:"master-secret",children:"Master secret"}),"\n",(0,a.jsxs)(t.p,{children:["The master secret is the cryptographic material used for deriving the ",(0,a.jsx)(t.a,{href:"#cluster-identity",children:(0,a.jsx)(t.em,{children:"clusterID"})})," and the ",(0,a.jsx)(t.em,{children:"key encryption key (KEK)"})," for ",(0,a.jsx)(t.a,{href:"#storage-encryption",children:"storage encryption"}),".\nIt's generated during the bootstrapping of a Constellation cluster.\nIt can either be managed by ",(0,a.jsx)(t.a,{href:"#constellation-managed-key-management",children:"Constellation"})," or an ",(0,a.jsx)(t.a,{href:"#user-managed-key-management",children:"external key management system"}),".\nIn case of ",(0,a.jsx)(t.a,{href:"#recovery-and-migration",children:"recovery"}),", the master secret allows to decrypt the state and recover a Constellation cluster."]}),"\n",(0,a.jsx)(t.h2,{id:"cluster-identity",children:"Cluster identity"}),"\n",(0,a.jsxs)(t.p,{children:["The identity of a Constellation cluster is represented by cryptographic ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#runtime-measurements",children:"measurements"}),":"]}),"\n",(0,a.jsxs)(t.p,{children:["The ",(0,a.jsx)(t.strong,{children:"base measurements"})," represent the identity of a valid, uninitialized Constellation node.\nThey depend on the node image, but are otherwise the same for every Constellation cluster.\nOn node boot, they're determined using the CVM's attestation mechanism and ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/images",children:"measured boot up to the read-only root filesystem"}),"."]}),"\n",(0,a.jsxs)(t.p,{children:["The ",(0,a.jsx)(t.strong,{children:"clusterID"})," represents the identity of a single initialized Constellation cluster.\nIt's derived from the master secret and a cryptographically random salt and unique for every Constellation cluster.\nThe ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#bootstrapper",children:"Bootstrapper"})," measures the ",(0,a.jsx)(t.em,{children:"clusterID"})," into its own PCR before executing any code not measured as part of the ",(0,a.jsx)(t.em,{children:"base measurements"}),".\nSee ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#node-attestation",children:"Node attestation"})," for details."]}),"\n",(0,a.jsxs)(t.p,{children:["The remote attestation statement of a Constellation cluster combines the ",(0,a.jsx)(t.em,{children:"base measurements"})," and the ",(0,a.jsx)(t.em,{children:"clusterID"})," for a verifiable, unspoofable, unique identity."]}),"\n",(0,a.jsx)(t.h2,{id:"network-encryption",children:"Network encryption"}),"\n",(0,a.jsxs)(t.p,{children:["Constellation encrypts all cluster network communication using the ",(0,a.jsx)(t.a,{href:"https://github.com/containernetworking/cni",children:"container network interface (CNI)"}),".\nSee ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/networking",children:"network encryption"})," for more details."]}),"\n",(0,a.jsxs)(t.p,{children:["The Cilium agent running on each node establishes a secure ",(0,a.jsx)(t.a,{href:"https://www.wireguard.com/",children:"WireGuard"})," tunnel between it and all other known nodes in the cluster.\nEach node creates its own ",(0,a.jsx)(t.a,{href:"http://cr.yp.to/ecdh.html",children:"Curve25519"})," encryption key pair and distributes its public key via Kubernetes.\nA node uses another node's public key to decrypt and encrypt traffic from and to Cilium-managed endpoints running on that node.\nConnections are always encrypted peer-to-peer using ",(0,a.jsx)(t.a,{href:"http://cr.yp.to/chacha.html",children:"ChaCha20"})," with ",(0,a.jsx)(t.a,{href:"http://cr.yp.to/mac.html",children:"Poly1305"}),".\nWireGuard implements ",(0,a.jsx)(t.a,{href:"https://lists.zx2c4.com/pipermail/wireguard/2017-December/002141.html",children:"forward secrecy with key rotation every 2 minutes"}),"."]}),"\n",(0,a.jsx)(t.h2,{id:"storage-encryption",children:"Storage encryption"}),"\n",(0,a.jsx)(t.p,{children:"Constellation supports transparent encryption of persistent storage.\nThe Linux kernel's device mapper-based encryption features are used to encrypt the data on the block storage level.\nCurrently, the following primitives are used for block storage encryption:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-crypt.html",children:"dm-crypt"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-integrity.html",children:"dm-integrity"})}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["Adding primitives for integrity protection in the CVM attacker model are under active development and will be available in a future version of Constellation.\nSee ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage",children:"encrypted storage"})," for more details."]}),"\n",(0,a.jsxs)(t.p,{children:["As a cluster administrator, when creating a cluster, you can use the Constellation ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration",children:"installation program"})," to select one of the following methods for key management:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Constellation-managed key management"}),"\n",(0,a.jsx)(t.li,{children:"User-managed key management"}),"\n"]}),"\n",(0,a.jsx)(t.h3,{id:"constellation-managed-key-management",children:"Constellation-managed key management"}),"\n",(0,a.jsx)(t.h4,{id:"key-material-and-key-derivation",children:"Key material and key derivation"}),"\n",(0,a.jsxs)(t.p,{children:["During the creation of a Constellation cluster, the cluster's master secret is used to derive a KEK.\nThis means creating two clusters with the same master secret will yield the same KEK.\nAny data encryption key (DEK) is derived from the KEK via HKDF.\nNote that the master secret is recommended to be unique for every cluster and shouldn't be reused (except in case of ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/recovery",children:"recovering"})," a cluster)."]}),"\n",(0,a.jsx)(t.h4,{id:"state-and-storage",children:"State and storage"}),"\n",(0,a.jsx)(t.p,{children:"The KEK is derived from the master secret during the initialization.\nSubsequently, all other key material is derived from the KEK.\nGiven the same KEK, any DEK can be derived deterministically from a given identifier.\nHence, there is no need to store DEKs. They can be derived on demand.\nAfter the KEK was derived, it's stored in memory only and never leaves the CVM context."}),"\n",(0,a.jsx)(t.h4,{id:"availability",children:"Availability"}),"\n",(0,a.jsxs)(t.p,{children:["Constellation-managed key management has the same availability as the underlying Kubernetes cluster.\nTherefore, the KEK is stored in the ",(0,a.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/",children:"distributed Kubernetes etcd storage"})," to allow for unexpected but non-fatal (control-plane) node failure.\nThe etcd storage is backed by the encrypted and integrity protected ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/images#state-disk",children:"state disk"})," of the nodes."]}),"\n",(0,a.jsx)(t.h4,{id:"recovery",children:"Recovery"}),"\n",(0,a.jsxs)(t.p,{children:["Constellation clusters can be recovered in the event of a disaster, even when all node machines have been stopped and need to be rebooted.\nFor details on the process see the ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/recovery",children:"recovery workflow"}),"."]}),"\n",(0,a.jsx)(t.h3,{id:"user-managed-key-management",children:"User-managed key management"}),"\n",(0,a.jsx)(t.p,{children:"User-managed key management is under active development and will be available soon.\nIn scenarios where constellation-managed key management isn't an option, this mode allows you to keep full control of your keys.\nFor example, compliance requirements may force you to keep your KEKs in an on-prem key management system (KMS)."}),"\n",(0,a.jsx)(t.p,{children:'During the creation of a Constellation cluster, you specify a KEK present in a remote KMS.\nThis follows the common scheme of "bring your own key" (BYOK).\nConstellation will support several KMSs for managing the storage and access of your KEK.\nInitially, it will support the following KMSs:'}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://aws.amazon.com/kms/",children:"AWS KMS"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://cloud.google.com/security-key-management",children:"GCP KMS"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://azure.microsoft.com/en-us/services/key-vault/#product-overview",children:"Azure Key Vault"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=kmip",children:"KMIP-compatible KMS"})}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Storing the keys in Cloud KMS of AWS, Azure, or GCP binds the key usage to the particular cloud identity access management (IAM).\nIn the future, Constellation will support remote attestation-based access policies for Cloud KMS once available.\nNote that using a Cloud KMS limits the isolation and protection to the guarantees of the particular offering."}),"\n",(0,a.jsx)(t.p,{children:'KMIP support allows you to use your KMIP-compatible on-prem KMS and keep full control over your keys.\nThis follows the common scheme of "hold your own key" (HYOK).'}),"\n",(0,a.jsx)(t.p,{children:'The KEK is used to encrypt per-data "data encryption keys" (DEKs).\nDEKs are generated to encrypt your data before storing it on persistent storage.\nAfter being encrypted by the KEK, the DEKs are stored on dedicated cloud storage for persistence.\nCurrently, Constellation supports the following cloud storage options:'}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://aws.amazon.com/s3/",children:"AWS S3"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://cloud.google.com/storage",children:"GCP Cloud Storage"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://azure.microsoft.com/en-us/services/storage/blobs/#overview",children:"Azure Blob Storage"})}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"The DEKs are only present in plaintext form in the encrypted main memory of the CVMs.\nSimilarly, the cryptographic operations for encrypting data before writing it to persistent storage are performed in the context of the CVMs."}),"\n",(0,a.jsx)(t.h4,{id:"recovery-and-migration",children:"Recovery and migration"}),"\n",(0,a.jsx)(t.p,{children:"In the case of a disaster, the KEK can be used to decrypt the DEKs locally and subsequently use them to decrypt and retrieve the data.\nIn case of migration, configuring the same KEK will provide seamless migration of data.\nThus, only the DEK storage needs to be transferred to the new cluster alongside the encrypted data for seamless migration."})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/543a522f.17585bbf.js b/pr-preview/pr-4027/assets/js/543a522f.17585bbf.js deleted file mode 100644 index ace5d8d04..000000000 --- a/pr-preview/pr-4027/assets/js/543a522f.17585bbf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[557],{28453:(e,t,o)=>{o.d(t,{R:()=>a,x:()=>l});var n=o(96540);const s={},i=n.createContext(s);function a(e){const t=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),n.createElement(i.Provider,{value:t},e.children)}},30439:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>r,contentTitle:()=>l,default:()=>p,frontMatter:()=>a,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"getting-started/examples/emojivoto","title":"Emojivoto","description":"Emojivoto is a simple and fun application that\'s well suited to test the basic functionality of your cluster.","source":"@site/versioned_docs/version-2.23/getting-started/examples/emojivoto.md","sourceDirName":"getting-started/examples","slug":"/getting-started/examples/emojivoto","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/emojivoto","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/getting-started/examples/emojivoto.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Examples","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples"},"next":{"title":"Online Boutique","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/online-boutique"}}');var s=o(74848),i=o(28453);const a={},l="Emojivoto",r={},c=[];function d(e){const t={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"emojivoto",children:"Emojivoto"})}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"Emojivoto"})," is a simple and fun application that's well suited to test the basic functionality of your cluster."]}),"\n",(0,s.jsx)("img",{src:o(98646).A,alt:"emojivoto - Web UI",width:"552"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["Deploy the application:","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["Wait until it becomes available:","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["Forward the web service to your machine:","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"kubectl -n emojivoto port-forward svc/web-svc 8080:80\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["Visit ",(0,s.jsx)(t.a,{href:"http://localhost:8080",children:"http://localhost:8080"})]}),"\n"]})]})}function p(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},98646:(e,t,o)=>{o.d(t,{A:()=>n});const n=o.p+"assets/images/example-emojivoto-55d31a6fd0c07e8e44b2b51d55dac60d.jpg"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/5480.a964935e.js b/pr-preview/pr-4027/assets/js/5480.a964935e.js deleted file mode 100644 index 4f9535bc2..000000000 --- a/pr-preview/pr-4027/assets/js/5480.a964935e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5480],{45480:(t,e,n)=>{n.d(e,{diagram:()=>X});var i=n(92875),s=n(52501),r=n(67633),a=n(40797),o=n(70451),l=function(){var t=(0,a.K2)(function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},"o"),e=[6,8,10,11,12,14,16,17,18],n=[1,9],i=[1,10],s=[1,11],r=[1,12],o=[1,13],l=[1,14],c={trace:(0,a.K2)(function(){},"trace"),yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,taskName:18,taskData:19,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",18:"taskName",19:"taskData"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,2]],performAction:(0,a.K2)(function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 2:case 6:case 7:this.$=[];break;case 3:r[o-1].push(r[o]),this.$=r[o-1];break;case 4:case 5:this.$=r[o];break;case 8:i.setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 9:this.$=r[o].trim(),i.setAccTitle(this.$);break;case 10:case 11:this.$=r[o].trim(),i.setAccDescription(this.$);break;case 12:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 13:i.addTask(r[o-1],r[o]),this.$="task"}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:n,12:i,14:s,16:r,17:o,18:l},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:15,11:n,12:i,14:s,16:r,17:o,18:l},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,16]},{15:[1,17]},t(e,[2,11]),t(e,[2,12]),{19:[1,18]},t(e,[2,4]),t(e,[2,9]),t(e,[2,10]),t(e,[2,13])],defaultActions:{},parseError:(0,a.K2)(function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},"parseError"),parse:(0,a.K2)(function(t){var e=this,n=[0],i=[],s=[null],r=[],o=this.table,l="",c=0,h=0,u=0,y=r.slice.call(arguments,1),p=Object.create(this.lexer),d={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(d.yy[f]=this.yy[f]);p.setInput(t,d.yy),d.yy.lexer=p,d.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var g=p.yylloc;r.push(g);var x=p.options&&p.options.ranges;function m(){var t;return"number"!=typeof(t=i.pop()||p.lex()||1)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,a.K2)(function(t){n.length=n.length-2*t,s.length=s.length-t,r.length=r.length-t},"popStack"),(0,a.K2)(m,"lex");for(var k,b,_,w,v,K,$,T,M,S={};;){if(_=n[n.length-1],this.defaultActions[_]?w=this.defaultActions[_]:(null==k&&(k=m()),w=o[_]&&o[_][k]),void 0===w||!w.length||!w[0]){var C="";for(K in M=[],o[_])this.terminals_[K]&&K>2&&M.push("'"+this.terminals_[K]+"'");C=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[k]||k)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==k?"end of input":"'"+(this.terminals_[k]||k)+"'"),this.parseError(C,{text:p.match,token:this.terminals_[k]||k,line:p.yylineno,loc:g,expected:M})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+_+", token: "+k);switch(w[0]){case 1:n.push(k),s.push(p.yytext),r.push(p.yylloc),n.push(w[1]),k=null,b?(k=b,b=null):(h=p.yyleng,l=p.yytext,c=p.yylineno,g=p.yylloc,u>0&&u--);break;case 2:if($=this.productions_[w[1]][1],S.$=s[s.length-$],S._$={first_line:r[r.length-($||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-($||1)].first_column,last_column:r[r.length-1].last_column},x&&(S._$.range=[r[r.length-($||1)].range[0],r[r.length-1].range[1]]),void 0!==(v=this.performAction.apply(S,[l,h,c,d.yy,w[1],s,r].concat(y))))return v;$&&(n=n.slice(0,-1*$*2),s=s.slice(0,-1*$),r=r.slice(0,-1*$)),n.push(this.productions_[w[1]][0]),s.push(S.$),r.push(S._$),T=o[n[n.length-2]][n[n.length-1]],n.push(T);break;case 3:return!0}}return!0},"parse")},h=function(){return{EOF:1,parseError:(0,a.K2)(function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},"parseError"),setInput:(0,a.K2)(function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:(0,a.K2)(function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},"input"),unput:(0,a.K2)(function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},"unput"),more:(0,a.K2)(function(){return this._more=!0,this},"more"),reject:(0,a.K2)(function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"reject"),less:(0,a.K2)(function(t){this.unput(this.match.slice(t))},"less"),pastInput:(0,a.K2)(function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:(0,a.K2)(function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:(0,a.K2)(function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},"showPosition"),test_match:(0,a.K2)(function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},"test_match"),next:(0,a.K2)(function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((n=this._input.match(this.rules[s[r]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:(0,a.K2)(function(){var t=this.next();return t||this.lex()},"lex"),begin:(0,a.K2)(function(t){this.conditionStack.push(t)},"begin"),popState:(0,a.K2)(function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:(0,a.K2)(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:(0,a.K2)(function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},"topState"),pushState:(0,a.K2)(function(t){this.begin(t)},"pushState"),stateStackSize:(0,a.K2)(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,a.K2)(function(t,e,n,i){switch(n){case 0:case 1:case 3:case 4:break;case 2:return 10;case 5:return 4;case 6:return 11;case 7:return this.begin("acc_title"),12;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),14;case 10:return this.popState(),"acc_descr_value";case 11:this.begin("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 17;case 15:return 18;case 16:return 19;case 17:return":";case 18:return 6;case 19:return"INVALID"}},"anonymous"),rules:[/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:journey\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,9,11,14,15,16,17,18,19],inclusive:!0}}}}();function u(){this.yy={}}return c.lexer=h,(0,a.K2)(u,"Parser"),u.prototype=c,c.Parser=u,new u}();l.parser=l;var c=l,h="",u=[],y=[],p=[],d=(0,a.K2)(function(){u.length=0,y.length=0,h="",p.length=0,(0,r.IU)()},"clear"),f=(0,a.K2)(function(t){h=t,u.push(t)},"addSection"),g=(0,a.K2)(function(){return u},"getSections"),x=(0,a.K2)(function(){let t=_();let e=0;for(;!t&&e<100;)t=_(),e++;return y.push(...p),y},"getTasks"),m=(0,a.K2)(function(){const t=[];y.forEach(e=>{e.people&&t.push(...e.people)});return[...new Set(t)].sort()},"updateActors"),k=(0,a.K2)(function(t,e){const n=e.substr(1).split(":");let i=0,s=[];1===n.length?(i=Number(n[0]),s=[]):(i=Number(n[0]),s=n[1].split(","));const r=s.map(t=>t.trim()),a={section:h,type:h,people:r,task:t,score:i};p.push(a)},"addTask"),b=(0,a.K2)(function(t){const e={section:h,type:h,description:t,task:t,classes:[]};y.push(e)},"addTaskOrg"),_=(0,a.K2)(function(){const t=(0,a.K2)(function(t){return p[t].processed},"compileTask");let e=!0;for(const[n,i]of p.entries())t(n),e=e&&i.processed;return e},"compileTasks"),w=(0,a.K2)(function(){return m()},"getActors"),v={getConfig:(0,a.K2)(()=>(0,r.D7)().journey,"getConfig"),clear:d,setDiagramTitle:r.ke,getDiagramTitle:r.ab,setAccTitle:r.SV,getAccTitle:r.iN,setAccDescription:r.EI,getAccDescription:r.m7,addSection:f,getSections:g,getTasks:x,addTask:k,addTaskOrg:b,getActors:w},K=(0,a.K2)(t=>`.label {\n font-family: ${t.fontFamily};\n color: ${t.textColor};\n }\n .mouth {\n stroke: #666;\n }\n\n line {\n stroke: ${t.textColor}\n }\n\n .legend {\n fill: ${t.textColor};\n font-family: ${t.fontFamily};\n }\n\n .label text {\n fill: #333;\n }\n .label {\n color: ${t.textColor}\n }\n\n .face {\n ${t.faceColor?`fill: ${t.faceColor}`:"fill: #FFF8DC"};\n stroke: #999;\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${t.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${t.lineColor};\n stroke-width: 1.5px;\n }\n\n .flowchart-link {\n stroke: ${t.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${t.edgeLabelBackground};\n rect {\n opacity: 0.5;\n }\n text-align: center;\n }\n\n .cluster rect {\n }\n\n .cluster text {\n fill: ${t.titleColor};\n }\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${t.fontFamily};\n font-size: 12px;\n background: ${t.tertiaryColor};\n border: 1px solid ${t.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .task-type-0, .section-type-0 {\n ${t.fillType0?`fill: ${t.fillType0}`:""};\n }\n .task-type-1, .section-type-1 {\n ${t.fillType0?`fill: ${t.fillType1}`:""};\n }\n .task-type-2, .section-type-2 {\n ${t.fillType0?`fill: ${t.fillType2}`:""};\n }\n .task-type-3, .section-type-3 {\n ${t.fillType0?`fill: ${t.fillType3}`:""};\n }\n .task-type-4, .section-type-4 {\n ${t.fillType0?`fill: ${t.fillType4}`:""};\n }\n .task-type-5, .section-type-5 {\n ${t.fillType0?`fill: ${t.fillType5}`:""};\n }\n .task-type-6, .section-type-6 {\n ${t.fillType0?`fill: ${t.fillType6}`:""};\n }\n .task-type-7, .section-type-7 {\n ${t.fillType0?`fill: ${t.fillType7}`:""};\n }\n\n .actor-0 {\n ${t.actor0?`fill: ${t.actor0}`:""};\n }\n .actor-1 {\n ${t.actor1?`fill: ${t.actor1}`:""};\n }\n .actor-2 {\n ${t.actor2?`fill: ${t.actor2}`:""};\n }\n .actor-3 {\n ${t.actor3?`fill: ${t.actor3}`:""};\n }\n .actor-4 {\n ${t.actor4?`fill: ${t.actor4}`:""};\n }\n .actor-5 {\n ${t.actor5?`fill: ${t.actor5}`:""};\n }\n ${(0,s.o)()}\n`,"getStyles"),$=(0,a.K2)(function(t,e){return(0,i.tk)(t,e)},"drawRect"),T=(0,a.K2)(function(t,e){const n=15,i=t.append("circle").attr("cx",e.cx).attr("cy",e.cy).attr("class","face").attr("r",n).attr("stroke-width",2).attr("overflow","visible"),s=t.append("g");function r(t){const i=(0,o.JLW)().startAngle(Math.PI/2).endAngle(Math.PI/2*3).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+2)+")")}function l(t){const i=(0,o.JLW)().startAngle(3*Math.PI/2).endAngle(Math.PI/2*5).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+7)+")")}function c(t){t.append("line").attr("class","mouth").attr("stroke",2).attr("x1",e.cx-5).attr("y1",e.cy+7).attr("x2",e.cx+5).attr("y2",e.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}return s.append("circle").attr("cx",e.cx-5).attr("cy",e.cy-5).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),s.append("circle").attr("cx",e.cx+5).attr("cy",e.cy-5).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),(0,a.K2)(r,"smile"),(0,a.K2)(l,"sad"),(0,a.K2)(c,"ambivalent"),e.score>3?r(s):e.score<3?l(s):c(s),i},"drawFace"),M=(0,a.K2)(function(t,e){const n=t.append("circle");return n.attr("cx",e.cx),n.attr("cy",e.cy),n.attr("class","actor-"+e.pos),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("r",e.r),void 0!==n.class&&n.attr("class",n.class),void 0!==e.title&&n.append("title").text(e.title),n},"drawCircle"),S=(0,a.K2)(function(t,e){return(0,i.m)(t,e)},"drawText"),C=(0,a.K2)(function(t,e){function n(t,e,n,i,s){return t+","+e+" "+(t+n)+","+e+" "+(t+n)+","+(e+i-s)+" "+(t+n-1.2*s)+","+(e+i)+" "+t+","+(e+i)}(0,a.K2)(n,"genPoints");const i=t.append("polygon");i.attr("points",n(e.x,e.y,50,20,7)),i.attr("class","labelBox"),e.y=e.y+e.labelMargin,e.x=e.x+.5*e.labelMargin,S(t,e)},"drawLabel"),E=(0,a.K2)(function(t,e,n){const s=t.append("g"),r=(0,i.PB)();r.x=e.x,r.y=e.y,r.fill=e.fill,r.width=n.width*e.taskCount+n.diagramMarginX*(e.taskCount-1),r.height=n.height,r.class="journey-section section-type-"+e.num,r.rx=3,r.ry=3,$(s,r),j(n)(e.text,s,r.x,r.y,r.width,r.height,{class:"journey-section section-type-"+e.num},n,e.colour)},"drawSection"),I=-1,P=(0,a.K2)(function(t,e,n){const s=e.x+n.width/2,r=t.append("g");I++;r.append("line").attr("id","task"+I).attr("x1",s).attr("y1",e.y).attr("x2",s).attr("y2",450).attr("class","task-line").attr("stroke-width","1px").attr("stroke-dasharray","4 2").attr("stroke","#666"),T(r,{cx:s,cy:300+30*(5-e.score),score:e.score});const a=(0,i.PB)();a.x=e.x,a.y=e.y,a.fill=e.fill,a.width=n.width,a.height=n.height,a.class="task task-type-"+e.num,a.rx=3,a.ry=3,$(r,a);let o=e.x+14;e.people.forEach(t=>{const n=e.actors[t].color,i={cx:o,cy:e.y,r:7,fill:n,stroke:"#000",title:t,pos:e.actors[t].position};M(r,i),o+=10}),j(n)(e.task,r,a.x,a.y,a.width,a.height,{class:"task"},n,e.colour)},"drawTask"),A=(0,a.K2)(function(t,e){(0,i.lC)(t,e)},"drawBackgroundRect"),j=function(){function t(t,e,n,s,r,a,o,l){i(e.append("text").attr("x",n+r/2).attr("y",s+a/2+5).style("font-color",l).style("text-anchor","middle").text(t),o)}function e(t,e,n,s,r,a,o,l,c){const{taskFontSize:h,taskFontFamily:u}=l,y=t.split(/<br\s*\/?>/gi);for(let p=0;p<y.length;p++){const t=p*h-h*(y.length-1)/2,l=e.append("text").attr("x",n+r/2).attr("y",s).attr("fill",c).style("text-anchor","middle").style("font-size",h).style("font-family",u);l.append("tspan").attr("x",n+r/2).attr("dy",t).text(y[p]),l.attr("y",s+a/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),i(l,o)}}function n(t,n,s,r,a,o,l,c){const h=n.append("switch"),u=h.append("foreignObject").attr("x",s).attr("y",r).attr("width",a).attr("height",o).attr("position","fixed").append("xhtml:div").style("display","table").style("height","100%").style("width","100%");u.append("div").attr("class","label").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,s,r,a,o,l,c),i(u,l)}function i(t,e){for(const n in e)n in e&&t.attr(n,e[n])}return(0,a.K2)(t,"byText"),(0,a.K2)(e,"byTspan"),(0,a.K2)(n,"byFo"),(0,a.K2)(i,"_setTextAttrs"),function(i){return"fo"===i.textPlacement?n:"old"===i.textPlacement?t:e}}(),B={drawRect:$,drawCircle:M,drawSection:E,drawText:S,drawLabel:C,drawTask:P,drawBackgroundRect:A,initGraphics:(0,a.K2)(function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")},"initGraphics")},F=(0,a.K2)(function(t){Object.keys(t).forEach(function(e){R[e]=t[e]})},"setConf"),L={},D=0;function V(t){const e=(0,r.D7)().journey,n=e.maxLabelWidth;D=0;let i=60;Object.keys(L).forEach(s=>{const r=L[s].color,a={cx:20,cy:i,r:7,fill:r,stroke:"#000",pos:L[s].position};B.drawCircle(t,a);let o=t.append("text").attr("visibility","hidden").text(s);const l=o.node().getBoundingClientRect().width;o.remove();let c=[];if(l<=n)c=[s];else{const e=s.split(" ");let i="";o=t.append("text").attr("visibility","hidden"),e.forEach(t=>{const e=i?`${i} ${t}`:t;o.text(e);if(o.node().getBoundingClientRect().width>n){if(i&&c.push(i),i=t,o.text(t),o.node().getBoundingClientRect().width>n){let e="";for(const i of t)e+=i,o.text(e+"-"),o.node().getBoundingClientRect().width>n&&(c.push(e.slice(0,-1)+"-"),e=i);i=e}}else i=e}),i&&c.push(i),o.remove()}c.forEach((n,s)=>{const r={x:40,y:i+7+20*s,fill:"#666",text:n,textMargin:e.boxTextMargin??5},a=B.drawText(t,r).node().getBoundingClientRect().width;a>D&&a>e.leftMargin-a&&(D=a)}),i+=Math.max(20,20*c.length)})}(0,a.K2)(V,"drawActorLegend");var R=(0,r.D7)().journey,O=0,N=(0,a.K2)(function(t,e,n,i){const s=(0,r.D7)(),a=s.journey.titleColor,l=s.journey.titleFontSize,c=s.journey.titleFontFamily,h=s.securityLevel;let u;"sandbox"===h&&(u=(0,o.Ltv)("#i"+e));const y="sandbox"===h?(0,o.Ltv)(u.nodes()[0].contentDocument.body):(0,o.Ltv)("body");z.init();const p=y.select("#"+e);B.initGraphics(p);const d=i.db.getTasks(),f=i.db.getDiagramTitle(),g=i.db.getActors();for(const r in L)delete L[r];let x=0;g.forEach(t=>{L[t]={color:R.actorColours[x%R.actorColours.length],position:x},x++}),V(p),O=R.leftMargin+D,z.insert(0,0,O,50*Object.keys(L).length),q(p,d,0);const m=z.getBounds();f&&p.append("text").text(f).attr("x",O).attr("font-size",l).attr("font-weight","bold").attr("y",25).attr("fill",a).attr("font-family",c);const k=m.stopy-m.starty+2*R.diagramMarginY,b=O+m.stopx+2*R.diagramMarginX;(0,r.a$)(p,k,b,R.useMaxWidth),p.append("line").attr("x1",O).attr("y1",4*R.height).attr("x2",b-O-4).attr("y2",4*R.height).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)");const _=f?70:0;p.attr("viewBox",`${m.startx} -25 ${b} ${k+_}`),p.attr("preserveAspectRatio","xMinYMin meet"),p.attr("height",k+_+25)},"draw"),z={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],init:(0,a.K2)(function(){this.sequenceItems=[],this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0},"init"),updateVal:(0,a.K2)(function(t,e,n,i){void 0===t[e]?t[e]=n:t[e]=i(n,t[e])},"updateVal"),updateBounds:(0,a.K2)(function(t,e,n,i){const s=(0,r.D7)().journey,o=this;let l=0;function c(r){return(0,a.K2)(function(a){l++;const c=o.sequenceItems.length-l+1;o.updateVal(a,"starty",e-c*s.boxMargin,Math.min),o.updateVal(a,"stopy",i+c*s.boxMargin,Math.max),o.updateVal(z.data,"startx",t-c*s.boxMargin,Math.min),o.updateVal(z.data,"stopx",n+c*s.boxMargin,Math.max),"activation"!==r&&(o.updateVal(a,"startx",t-c*s.boxMargin,Math.min),o.updateVal(a,"stopx",n+c*s.boxMargin,Math.max),o.updateVal(z.data,"starty",e-c*s.boxMargin,Math.min),o.updateVal(z.data,"stopy",i+c*s.boxMargin,Math.max))},"updateItemBounds")}(0,a.K2)(c,"updateFn"),this.sequenceItems.forEach(c())},"updateBounds"),insert:(0,a.K2)(function(t,e,n,i){const s=Math.min(t,n),r=Math.max(t,n),a=Math.min(e,i),o=Math.max(e,i);this.updateVal(z.data,"startx",s,Math.min),this.updateVal(z.data,"starty",a,Math.min),this.updateVal(z.data,"stopx",r,Math.max),this.updateVal(z.data,"stopy",o,Math.max),this.updateBounds(s,a,r,o)},"insert"),bumpVerticalPos:(0,a.K2)(function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=this.verticalPos},"bumpVerticalPos"),getVerticalPos:(0,a.K2)(function(){return this.verticalPos},"getVerticalPos"),getBounds:(0,a.K2)(function(){return this.data},"getBounds")},W=R.sectionFills,Y=R.sectionColours,q=(0,a.K2)(function(t,e,n){const i=(0,r.D7)().journey;let s="";const a=n+(2*i.height+i.diagramMarginY);let o=0,l="#CCC",c="black",h=0;for(const[r,u]of e.entries()){if(s!==u.section){l=W[o%W.length],h=o%W.length,c=Y[o%Y.length];let n=0;const a=u.section;for(let t=r;t<e.length&&e[t].section==a;t++)n+=1;const y={x:r*i.taskMargin+r*i.width+O,y:50,text:u.section,fill:l,num:h,colour:c,taskCount:n};B.drawSection(t,y,i),s=u.section,o++}const n=u.people.reduce((t,e)=>(L[e]&&(t[e]=L[e]),t),{});u.x=r*i.taskMargin+r*i.width+O,u.y=a,u.width=i.diagramMarginX,u.height=i.diagramMarginY,u.colour=c,u.fill=l,u.num=h,u.actors=n,B.drawTask(t,u,i),z.insert(u.x,u.y,u.x+u.width+i.taskMargin,450)}},"drawTasks"),J={setConf:F,draw:N},X={parser:c,db:v,renderer:J,styles:K,init:(0,a.K2)(t=>{J.setConf(t.journey),v.clear()},"init")}},52501:(t,e,n)=>{n.d(e,{o:()=>i});var i=(0,n(40797).K2)(()=>"\n /* Font Awesome icon styling - consolidated */\n .label-icon {\n display: inline-block;\n height: 1em;\n overflow: visible;\n vertical-align: -0.125em;\n }\n \n .node .label-icon path {\n fill: currentColor;\n stroke: revert;\n stroke-width: revert;\n }\n","getIconStyles")},92875:(t,e,n)=>{n.d(e,{CP:()=>h,HT:()=>y,PB:()=>u,aC:()=>c,lC:()=>o,m:()=>l,tk:()=>a});var i=n(67633),s=n(40797),r=n(16750),a=(0,s.K2)((t,e)=>{const n=t.append("rect");if(n.attr("x",e.x),n.attr("y",e.y),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("width",e.width),n.attr("height",e.height),e.name&&n.attr("name",e.name),e.rx&&n.attr("rx",e.rx),e.ry&&n.attr("ry",e.ry),void 0!==e.attrs)for(const i in e.attrs)n.attr(i,e.attrs[i]);return e.class&&n.attr("class",e.class),n},"drawRect"),o=(0,s.K2)((t,e)=>{const n={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};a(t,n).lower()},"drawBackgroundRect"),l=(0,s.K2)((t,e)=>{const n=e.text.replace(i.H1," "),s=t.append("text");s.attr("x",e.x),s.attr("y",e.y),s.attr("class","legend"),s.style("text-anchor",e.anchor),e.class&&s.attr("class",e.class);const r=s.append("tspan");return r.attr("x",e.x+2*e.textMargin),r.text(n),s},"drawText"),c=(0,s.K2)((t,e,n,i)=>{const s=t.append("image");s.attr("x",e),s.attr("y",n);const a=(0,r.J)(i);s.attr("xlink:href",a)},"drawImage"),h=(0,s.K2)((t,e,n,i)=>{const s=t.append("use");s.attr("x",e),s.attr("y",n);const a=(0,r.J)(i);s.attr("xlink:href",`#${a}`)},"drawEmbeddedImage"),u=(0,s.K2)(()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),"getNoteRect"),y=(0,s.K2)(()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0}),"getTextObj")}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/54db543f.c4bc0cc5.js b/pr-preview/pr-4027/assets/js/54db543f.c4bc0cc5.js deleted file mode 100644 index 12f27a98b..000000000 --- a/pr-preview/pr-4027/assets/js/54db543f.c4bc0cc5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9074],{31798:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Workflows","slug":"/category/workflows","permalink":"/constellation/pr-preview/pr-4027/2.22/category/workflows","sidebar":"docs","navigation":{"previous":{"title":"Filestash with s3proxy","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/filestash-s3proxy"},"next":{"title":"Verify the CLI","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/5672ef9d.f3f7d6e3.js b/pr-preview/pr-4027/assets/js/5672ef9d.f3f7d6e3.js deleted file mode 100644 index 196b8bb56..000000000 --- a/pr-preview/pr-4027/assets/js/5672ef9d.f3f7d6e3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9767],{28453:(e,n,r)=>{r.d(n,{R:()=>d,x:()=>l});var i=r(96540);const s={},o=i.createContext(s);function d(e){const n=i.useContext(o);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),i.createElement(o.Provider,{value:n},e.children)}},50283:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>d,metadata:()=>i,toc:()=>t});const i=JSON.parse('{"id":"reference/migration","title":"Migrations","description":"This document describes breaking changes and migrations between Constellation releases.","source":"@site/versioned_docs/version-2.24/reference/migration.md","sourceDirName":"reference","slug":"/reference/migration","permalink":"/constellation/pr-preview/pr-4027/reference/migration","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/reference/migration.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"CLI","permalink":"/constellation/pr-preview/pr-4027/reference/cli"},"next":{"title":"Terraform usage","permalink":"/constellation/pr-preview/pr-4027/reference/terraform"}}');var s=r(74848),o=r(28453);const d={},l="Migrations",c={},t=[{value:"Migrations to v2.23.0",id:"migrations-to-v2230",level:2},{value:"GCP",id:"gcp",level:3},{value:"Migrations to v2.19.1",id:"migrations-to-v2191",level:2},{value:"Azure",id:"azure",level:3},{value:"Migrating from CLI versions before 2.21.1",id:"migrating-from-cli-versions-before-2211",level:2},{value:"AWS",id:"aws",level:3},{value:"Migrating from CLI versions before 2.19.0",id:"migrating-from-cli-versions-before-2190",level:2},{value:"Azure",id:"azure-1",level:3},{value:"Migrating from CLI versions before 2.18.0",id:"migrating-from-cli-versions-before-2180",level:2},{value:"Migrating from CLI versions before 2.10",id:"migrating-from-cli-versions-before-210",level:2},{value:"Migrating from CLI versions before 2.9",id:"migrating-from-cli-versions-before-29",level:2},{value:"Migrating from CLI versions before 2.8",id:"migrating-from-cli-versions-before-28",level:2},{value:"Migrating from CLI versions before 2.3",id:"migrating-from-cli-versions-before-23",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components},{Details:r}=n;return r||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"migrations",children:"Migrations"})}),"\n",(0,s.jsxs)(n.p,{children:["This document describes breaking changes and migrations between Constellation releases.\nUse ",(0,s.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/reference/cli#constellation-config-migrate",children:(0,s.jsx)(n.code,{children:"constellation config migrate"})})," to automatically update an old config file to a new format."]}),"\n",(0,s.jsx)(n.h2,{id:"migrations-to-v2230",children:"Migrations to v2.23.0"}),"\n",(0,s.jsx)(n.h3,{id:"gcp",children:"GCP"}),"\n",(0,s.jsxs)(n.p,{children:["GCP will require the additional permission ",(0,s.jsx)(n.code,{children:"compute.forwardingRules.list"}),". Please update your IAM roles using ",(0,s.jsx)(n.code,{children:"constellation iam upgrade apply"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"migrations-to-v2191",children:"Migrations to v2.19.1"}),"\n",(0,s.jsx)(n.h3,{id:"azure",children:"Azure"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"During the upgrade, security rules are migrated and the old ones need to be cleaned up manually by the user. The below script shows how to delete them through the Azure CLI:"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'#!/usr/bin/env bash\nname="<insert>" # the name provided in the config\nuid="<insert>" # the cluster id can be retrieved via `yq \'.infrastructure.uid\' constellation-state.yaml`\nresource_group="<insert>" # the RG can be retrieved via `yq \'.provider.azure.resourceGroup\' constellation-conf.yaml`\n\nrules=(\n "kubernetes"\n "bootstrapper"\n "verify"\n "recovery"\n "join"\n "debugd"\n "konnectivity"\n)\n\nfor rule in "${rules[@]}"; do\n echo "Deleting rule: ${rule}"\n az network nsg rule delete \\\n --resource-group "${resource_group}" \\\n --nsg-name "${name}-${uid}" \\\n --name "${rule}"\ndone\n\necho "All specified rules have been deleted."\n'})}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-2211",children:"Migrating from CLI versions before 2.21.1"}),"\n",(0,s.jsx)(n.h3,{id:"aws",children:"AWS"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["AWS clusters that use ",(0,s.jsx)(n.code,{children:"LoadBalancer"})," resources require more IAM permissions. Please upgrade your IAM roles using ",(0,s.jsx)(n.code,{children:"constellation iam upgrade apply"}),". This will show necessary changes and apply them, if desired."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-2190",children:"Migrating from CLI versions before 2.19.0"}),"\n",(0,s.jsx)(n.h3,{id:"azure-1",children:"Azure"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["To allow seamless upgrades on Azure when Kubernetes services of type ",(0,s.jsx)(n.code,{children:"LoadBalancer"})," are deployed, the target\nload balancer in which the ",(0,s.jsx)(n.code,{children:"cloud-controller-manager"})," creates load balancing rules was changed. Instead of using the load balancer\ncreated and maintained by the CLI's Terraform code, the ",(0,s.jsx)(n.code,{children:"cloud-controller-manager"})," now creates its own load balancer in Azure.\nIf your Constellation has services of type ",(0,s.jsx)(n.code,{children:"LoadBalancer"}),", please remove them before the upgrade and re-apply them\nafterward."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-2180",children:"Migrating from CLI versions before 2.18.0"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"provider.azure.appClientID"})," and ",(0,s.jsx)(n.code,{children:"provider.azure.appClientSecret"})," fields are no longer supported and should be removed."]}),"\n",(0,s.jsxs)(n.li,{children:["To keep using an existing UAMI, add the ",(0,s.jsx)(n.code,{children:"Owner"})," permission with the scope of your ",(0,s.jsx)(n.code,{children:"resourceGroup"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["Otherwise, simply ",(0,s.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/config#creating-an-iam-configuration",children:"create new Constellation IAM credentials"})," and use the created UAMI."]}),"\n",(0,s.jsxs)(n.li,{children:["To migrate the authentication for an existing cluster on Azure to an UAMI with the necessary permissions:","\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Remove the ",(0,s.jsx)(n.code,{children:"aadClientId"})," and ",(0,s.jsx)(n.code,{children:"aadClientSecret"})," from the azureconfig secret."]}),"\n",(0,s.jsxs)(n.li,{children:["Set ",(0,s.jsx)(n.code,{children:"useManagedIdentityExtension"})," to ",(0,s.jsx)(n.code,{children:"true"})," and use the ",(0,s.jsx)(n.code,{children:"userAssignedIdentity"})," from the Constellation config for the value of ",(0,s.jsx)(n.code,{children:"userAssignedIdentityID"}),"."]}),"\n",(0,s.jsx)(n.li,{children:"Restart the CSI driver, cloud controller manager, cluster autoscaler, and Constellation operator pods."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-210",children:"Migrating from CLI versions before 2.10"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["AWS cluster upgrades require additional IAM permissions for the newly introduced ",(0,s.jsx)(n.code,{children:"aws-load-balancer-controller"}),". Please upgrade your IAM roles using ",(0,s.jsx)(n.code,{children:"iam upgrade apply"}),". This will show necessary changes and apply them, if desired."]}),"\n",(0,s.jsxs)(n.li,{children:["The global ",(0,s.jsx)(n.code,{children:"nodeGroups"})," field was added."]}),"\n",(0,s.jsxs)(n.li,{children:["The fields ",(0,s.jsx)(n.code,{children:"instanceType"}),", ",(0,s.jsx)(n.code,{children:"stateDiskSizeGB"}),", and ",(0,s.jsx)(n.code,{children:"stateDiskType"})," for each cloud provider are now part of the configuration of individual node groups."]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"constellation create"})," command no longer uses the flags ",(0,s.jsx)(n.code,{children:"--control-plane-count"})," and ",(0,s.jsx)(n.code,{children:"--worker-count"}),". Instead, the initial node count is configured per node group in the ",(0,s.jsx)(n.code,{children:"nodeGroups"})," field."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-29",children:"Migrating from CLI versions before 2.9"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"provider.azure.appClientID"})," and ",(0,s.jsx)(n.code,{children:"provider.azure.clientSecretValue"})," fields were removed to enforce migration to managed identity authentication"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-28",children:"Migrating from CLI versions before 2.8"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"measurements"})," field for each cloud service provider was replaced with a global ",(0,s.jsx)(n.code,{children:"attestation"})," field."]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"confidentialVM"}),", ",(0,s.jsx)(n.code,{children:"idKeyDigest"}),", and ",(0,s.jsx)(n.code,{children:"enforceIdKeyDigest"})," fields for the Azure cloud service provider were removed in favor of using the global ",(0,s.jsx)(n.code,{children:"attestation"})," field."]}),"\n",(0,s.jsxs)(n.li,{children:["The optional global field ",(0,s.jsx)(n.code,{children:"attestationVariant"})," was replaced by the now required ",(0,s.jsx)(n.code,{children:"attestation"})," field."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"migrating-from-cli-versions-before-23",children:"Migrating from CLI versions before 2.3"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"sshUsers"})," field was deprecated in v2.2 and has been removed from the configuration in v2.3.\nAs an alternative for SSH, check the workflow section ",(0,s.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/troubleshooting#node-shell-access",children:"Connect to nodes"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"image"})," field for each cloud service provider has been replaced with a global ",(0,s.jsx)(n.code,{children:"image"})," field. Use the following mapping to migrate your configuration:"]}),"\n",(0,s.jsxs)(r,{children:[(0,s.jsx)("summary",{children:"Show all"}),(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"CSP"}),(0,s.jsx)(n.th,{children:"old image"}),(0,s.jsx)(n.th,{children:"new image"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-06b8cbf4837a0a57c"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-02e96dc04a9e438cd"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-028ead928a9034b2f"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-032ac10dd8d8266e3"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-032e0d57cc4395088"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-053c3e49e19b96bdd"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-0e27ebcefc38f648b"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-098cd37f66523b7c3"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AWS"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ami-04a87d302e2509aad"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.2"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.2"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.1"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.1"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.1.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.1.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.1.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.1.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.0.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.0.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Azure"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.0.0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.0.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"GCP"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"projects/constellation-images/global/images/constellation-v2-2-2"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"GCP"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"projects/constellation-images/global/images/constellation-v2-2-1"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"GCP"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"projects/constellation-images/global/images/constellation-v2-2-0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"GCP"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"projects/constellation-images/global/images/constellation-v2-1-0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.1.0"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"GCP"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"projects/constellation-images/global/images/constellation-v2-0-0"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"v2.0.0"})})]})]})]})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"enforcedMeasurements"})," field has been removed and merged with the ",(0,s.jsx)(n.code,{children:"measurements"})," field."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["To migrate your config containing a new image (",(0,s.jsx)(n.code,{children:"v2.3"})," or greater), remove the old ",(0,s.jsx)(n.code,{children:"measurements"})," and ",(0,s.jsx)(n.code,{children:"enforcedMeasurements"})," entries from your config and run ",(0,s.jsx)(n.code,{children:"constellation fetch-measurements"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["To migrate your config containing an image older than ",(0,s.jsx)(n.code,{children:"v2.3"}),", remove the ",(0,s.jsx)(n.code,{children:"enforcedMeasurements"})," entry and replace the entries in ",(0,s.jsx)(n.code,{children:"measurements"})," as shown in the example below:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-diff",children:"measurements:\n- 0: DzXCFGCNk8em5ornNZtKi+Wg6Z7qkQfs5CfE3qTkOc8=\n+ 0:\n+ expected: DzXCFGCNk8em5ornNZtKi+Wg6Z7qkQfs5CfE3qTkOc8=\n+ warnOnly: true\n- 8: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\n+ 8:\n+ expected: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\n+ warnOnly: false\n-enforcedMeasurements:\n- - 8\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/56806aed.deac1270.js b/pr-preview/pr-4027/assets/js/56806aed.deac1270.js deleted file mode 100644 index 470a5a629..000000000 --- a/pr-preview/pr-4027/assets/js/56806aed.deac1270.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7274],{51480:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Basics","slug":"/category/basics","permalink":"/constellation/pr-preview/pr-4027/next/category/basics","sidebar":"docs","navigation":{"previous":{"title":"Introduction","permalink":"/constellation/pr-preview/pr-4027/next/"},"next":{"title":"Confidential Kubernetes","permalink":"/constellation/pr-preview/pr-4027/next/overview/confidential-kubernetes"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/574ee69f.4e5121f7.js b/pr-preview/pr-4027/assets/js/574ee69f.4e5121f7.js deleted file mode 100644 index f79fe7d81..000000000 --- a/pr-preview/pr-4027/assets/js/574ee69f.4e5121f7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7078],{78009:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":"unreleased","badge":true,"noIndex":false,"className":"docs-version-current","isLast":false,"docsSidebars":{"docs":[{"type":"link","href":"/constellation/pr-preview/pr-4027/next/","label":"Introduction","docId":"intro","unlisted":false},{"type":"category","label":"Basics","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/next/overview/confidential-kubernetes","label":"Confidential Kubernetes","docId":"overview/confidential-kubernetes","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/overview/security-benefits","label":"Security benefits","docId":"overview/security-benefits","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/overview/product","label":"Product features","docId":"overview/product","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/overview/clouds","label":"Feature status of clouds","docId":"overview/clouds","unlisted":false},{"type":"category","label":"Performance","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/next/overview/performance/compute","label":"Compute benchmarks","docId":"overview/performance/compute","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/overview/performance/io","label":"I/O benchmarks","docId":"overview/performance/io","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/overview/performance/application","label":"Application benchmarks","docId":"overview/performance/application","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/next/overview/performance/"},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/overview/license","label":"License","docId":"overview/license","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/next/category/basics"},{"type":"category","label":"Getting started","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/next/getting-started/install","label":"Installation","docId":"getting-started/install","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/getting-started/first-steps","label":"First steps (cloud)","docId":"getting-started/first-steps","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/getting-started/first-steps-local","label":"First steps (local)","docId":"getting-started/first-steps-local","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/getting-started/marketplaces","label":"Cloud Marketplaces","docId":"getting-started/marketplaces","unlisted":false},{"type":"category","label":"Examples","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/next/getting-started/examples/emojivoto","label":"Emojivoto","docId":"getting-started/examples/emojivoto","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/getting-started/examples/online-boutique","label":"Online Boutique","docId":"getting-started/examples/online-boutique","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/getting-started/examples/horizontal-scaling","label":"Horizontal Pod Autoscaling","docId":"getting-started/examples/horizontal-scaling","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/getting-started/examples/filestash-s3proxy","label":"Filestash with s3proxy","docId":"getting-started/examples/filestash-s3proxy","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/next/getting-started/examples"}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/next/category/getting-started"},{"type":"category","label":"Workflows","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/next/workflows/verify-cli","label":"Verify the CLI","docId":"workflows/verify-cli","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/workflows/config","label":"Configure your cluster","docId":"workflows/config","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/workflows/create","label":"Create your cluster","docId":"workflows/create","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/workflows/scale","label":"Scale your cluster","docId":"workflows/scale","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/workflows/upgrade","label":"Upgrade your cluster","docId":"workflows/upgrade","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/workflows/lb","label":"Expose a service","docId":"workflows/lb","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/workflows/cert-manager","label":"Install cert-manager","docId":"workflows/cert-manager","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/workflows/s3proxy","label":"Install s3proxy","docId":"workflows/s3proxy","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/workflows/terminate","label":"Terminate your cluster","docId":"workflows/terminate","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/workflows/recovery","label":"Recover your cluster","docId":"workflows/recovery","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/workflows/verify-cluster","label":"Verify your cluster","docId":"workflows/verify-cluster","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/workflows/storage","label":"Use persistent storage","docId":"workflows/storage","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/workflows/terraform-provider","label":"Use the Terraform provider","docId":"workflows/terraform-provider","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/workflows/sbom","label":"Consume SBOMs","docId":"workflows/sbom","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/workflows/reproducible-builds","label":"Reproduce release artifacts","docId":"workflows/reproducible-builds","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/workflows/troubleshooting","label":"Troubleshooting","docId":"workflows/troubleshooting","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/next/category/workflows"},{"type":"category","label":"Architecture","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/next/architecture/overview","label":"Overview","docId":"architecture/overview","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/architecture/orchestration","label":"Cluster orchestration","docId":"architecture/orchestration","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/architecture/versions","label":"Versions and support","docId":"architecture/versions","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/architecture/microservices","label":"Microservices","docId":"architecture/microservices","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/architecture/attestation","label":"Attestation","docId":"architecture/attestation","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/architecture/images","label":"Images","docId":"architecture/images","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/architecture/keys","label":"Keys and cryptographic primitives","docId":"architecture/keys","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage","label":"Encrypted persistent storage","docId":"architecture/encrypted-storage","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/architecture/networking","label":"Networking","docId":"architecture/networking","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/architecture/observability","label":"Observability","docId":"architecture/observability","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/next/category/architecture"},{"type":"category","label":"Reference","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/next/reference/cli","label":"CLI","docId":"reference/cli","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/reference/migration","label":"Configuration migrations","docId":"reference/migration","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/reference/terraform","label":"Terraform usage","docId":"reference/terraform","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/next/reference/slsa","label":"SLSA adoption","docId":"reference/slsa","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/next/category/reference"}]},"docs":{"architecture/attestation":{"id":"architecture/attestation","title":"Attestation","description":"This page explains Constellation\'s attestation process and highlights the cornerstones of its trust model.","sidebar":"docs"},"architecture/encrypted-storage":{"id":"architecture/encrypted-storage","title":"Encrypted persistent storage","description":"Confidential VMs provide runtime memory encryption to protect data in use.","sidebar":"docs"},"architecture/images":{"id":"architecture/images","title":"Constellation images","description":"Constellation uses a minimal version of Fedora as the operating system running inside confidential VMs. This Linux distribution is optimized for containers and designed to be stateless.","sidebar":"docs"},"architecture/keys":{"id":"architecture/keys","title":"Key management and cryptographic primitives","description":"Constellation protects and isolates your cluster and workloads.","sidebar":"docs"},"architecture/microservices":{"id":"architecture/microservices","title":"Microservices","description":"Constellation takes care of bootstrapping and initializing a Confidential Kubernetes cluster.","sidebar":"docs"},"architecture/networking":{"id":"architecture/networking","title":"Network encryption","description":"Constellation encrypts all pod communication using the container network interface (CNI).","sidebar":"docs"},"architecture/observability":{"id":"architecture/observability","title":"Observability","description":"In Kubernetes, observability is the ability to gain insight into the behavior and performance of applications.","sidebar":"docs"},"architecture/orchestration":{"id":"architecture/orchestration","title":"Orchestrating Constellation clusters","description":"You can use the CLI to create a cluster on the supported cloud platforms.","sidebar":"docs"},"architecture/overview":{"id":"architecture/overview","title":"Overview","description":"Constellation is a cloud-based confidential orchestration platform.","sidebar":"docs"},"architecture/versions":{"id":"architecture/versions","title":"Versions and support policy","description":"All components of Constellation use a three-digit version number of the form v...","sidebar":"docs"},"getting-started/examples":{"id":"getting-started/examples","title":"Examples","description":"After you installed the CLI and created your first cluster, you\'re ready to deploy applications. Why not start with one of the following examples?","sidebar":"docs"},"getting-started/examples/emojivoto":{"id":"getting-started/examples/emojivoto","title":"Emojivoto","description":"Emojivoto is a simple and fun application that\'s well suited to test the basic functionality of your cluster.","sidebar":"docs"},"getting-started/examples/filestash-s3proxy":{"id":"getting-started/examples/filestash-s3proxy","title":"Deploying Filestash","description":"Filestash is a web frontend for different storage backends, including S3.","sidebar":"docs"},"getting-started/examples/horizontal-scaling":{"id":"getting-started/examples/horizontal-scaling","title":"Horizontal Pod Autoscaling","description":"This example demonstrates Constellation\'s autoscaling capabilities. It\'s based on the Kubernetes HorizontalPodAutoscaler Walkthrough. During the following steps, Constellation will spawn new VMs on demand, verify them, add them to the cluster, and delete them again when the load has settled down.","sidebar":"docs"},"getting-started/examples/online-boutique":{"id":"getting-started/examples/online-boutique","title":"Online Boutique","description":"Online Boutique is an e-commerce demo application by Google consisting of 11 separate microservices. In this demo, Constellation automatically sets up a load balancer on your CSP, making it easy to expose services from your confidential cluster.","sidebar":"docs"},"getting-started/first-steps":{"id":"getting-started/first-steps","title":"First steps with Constellation","description":"The following steps guide you through the process of creating a cluster and deploying a sample app. This example assumes that you have successfully installed and set up Constellation,","sidebar":"docs"},"getting-started/first-steps-local":{"id":"getting-started/first-steps-local","title":"First steps with a local cluster","description":"A local cluster lets you deploy and test Constellation without a cloud subscription.","sidebar":"docs"},"getting-started/install":{"id":"getting-started/install","title":"Installation and setup","description":"Constellation runs entirely in your cloud environment and can be controlled via a dedicated command-line interface (CLI) or a Terraform provider.","sidebar":"docs"},"getting-started/marketplaces":{"id":"getting-started/marketplaces","title":"Using Constellation via Cloud Marketplaces","description":"Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please contact us.","sidebar":"docs"},"intro":{"id":"intro","title":"Introduction","description":"Constellation is no longer actively maintained by Edgeless Systems.","sidebar":"docs"},"overview/clouds":{"id":"overview/clouds","title":"Feature status of clouds","description":"What works on which cloud? Currently, Confidential VMs (CVMs) are available in varying quality on the different clouds and software stacks.","sidebar":"docs"},"overview/confidential-kubernetes":{"id":"overview/confidential-kubernetes","title":"Confidential Kubernetes","description":"We use the term Confidential Kubernetes to refer to the concept of using confidential-computing technology to shield entire Kubernetes clusters from the infrastructure. The three defining properties of this concept are:","sidebar":"docs"},"overview/license":{"id":"overview/license","title":"License","description":"Constellation is available under the Business Source License 1.1.","sidebar":"docs"},"overview/performance/application":{"id":"overview/performance/application","title":"Application benchmarks","description":"HashiCorp Vault","sidebar":"docs"},"overview/performance/compute":{"id":"overview/performance/compute","title":"Impact of runtime encryption on compute performance","description":"All nodes in a Constellation cluster are executed inside Confidential VMs (CVMs). Consequently, the performance of Constellation is inherently linked to the performance of these CVMs.","sidebar":"docs"},"overview/performance/io":{"id":"overview/performance/io","title":"I/O performance benchmarks","description":"To assess the overall performance of Constellation, this benchmark evaluates Constellation v2.6.0 in terms of storage I/O using fio and network performance using the Kubernetes Network Benchmark.","sidebar":"docs"},"overview/performance/performance":{"id":"overview/performance/performance","title":"Performance analysis of Constellation","description":"This section provides a comprehensive examination of the performance characteristics of Constellation.","sidebar":"docs"},"overview/product":{"id":"overview/product","title":"Product features","description":"Constellation is a Kubernetes engine that aims to provide the best possible data security in combination with enterprise-grade scalability and reliability features---and a smooth user experience.","sidebar":"docs"},"overview/security-benefits":{"id":"overview/security-benefits","title":"Security benefits and threat model","description":"Constellation implements the Confidential Kubernetes concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be verified.","sidebar":"docs"},"reference/cli":{"id":"reference/cli","title":"CLI reference","description":"Use the Constellation CLI to create and manage your clusters.","sidebar":"docs"},"reference/migration":{"id":"reference/migration","title":"Migrations","description":"This document describes breaking changes and migrations between Constellation releases.","sidebar":"docs"},"reference/slsa":{"id":"reference/slsa","title":"Supply chain levels for software artifacts (SLSA) adoption","description":"Supply chain Levels for Software Artifacts, or SLSA (salsa) is a framework for improving and grading a project\'s build system and engineering processes. SLSA focuses on security improvements for source code storage as well as build system definition, execution, and observation. SLSA is structured in four levels. This page describes the adoption of SLSA for Constellation.","sidebar":"docs"},"reference/terraform":{"id":"reference/terraform","title":"Terraform usage","description":"Terraform is an Infrastructure as Code (IaC) framework to manage cloud resources. This page explains how Constellation uses it internally and how advanced users may manually use it to have more control over the resource creation.","sidebar":"docs"},"workflows/cert-manager":{"id":"workflows/cert-manager","title":"Install cert-manager","description":"If you want to use cert-manager with Constellation, pay attention to the following to avoid potential pitfalls.","sidebar":"docs"},"workflows/config":{"id":"workflows/config","title":"Configure your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","sidebar":"docs"},"workflows/create":{"id":"workflows/create","title":"Create your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","sidebar":"docs"},"workflows/lb":{"id":"workflows/lb","title":"Expose a service","description":"Constellation integrates the native load balancers of each CSP. Therefore, to expose a service simply create a service of type LoadBalancer.","sidebar":"docs"},"workflows/recovery":{"id":"workflows/recovery","title":"Recover your cluster","description":"Recovery of a Constellation cluster means getting it back into a healthy state after too many concurrent node failures in the control plane.","sidebar":"docs"},"workflows/reproducible-builds":{"id":"workflows/reproducible-builds","title":"Reproduce released artifacts","description":"Constellation has first-class support for reproducible builds.","sidebar":"docs"},"workflows/s3proxy":{"id":"workflows/s3proxy","title":"Install s3proxy","description":"Constellation includes a transparent client-side encryption proxy for AWS S3 and compatible stores.","sidebar":"docs"},"workflows/sbom":{"id":"workflows/sbom","title":"Consume software bill of materials (SBOMs)","description":"---","sidebar":"docs"},"workflows/scale":{"id":"workflows/scale","title":"Scale your cluster","description":"Constellation provides all features of a Kubernetes cluster including scaling and autoscaling.","sidebar":"docs"},"workflows/storage":{"id":"workflows/storage","title":"Use persistent storage","description":"Persistent storage in Kubernetes requires cloud-specific configuration.","sidebar":"docs"},"workflows/terminate":{"id":"workflows/terminate","title":"Terminate your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","sidebar":"docs"},"workflows/terraform-provider":{"id":"workflows/terraform-provider","title":"Use the Terraform provider","description":"The Constellation Terraform provider allows to manage the full lifecycle of a Constellation cluster (namely creation, upgrades, and deletion) via Terraform.","sidebar":"docs"},"workflows/troubleshooting":{"id":"workflows/troubleshooting","title":"Troubleshooting","description":"This section aids you in finding problems when working with Constellation.","sidebar":"docs"},"workflows/trusted-launch":{"id":"workflows/trusted-launch","title":"Use Azure trusted launch VMs","description":"Constellation also supports trusted launch VMs on Microsoft Azure. Trusted launch VMs don\'t offer the same level of security as Confidential VMs, but are available in more regions and in larger quantities. The main difference between trusted launch VMs and normal VMs is that the former offer vTPM-based remote attestation. When used with trusted launch VMs, Constellation relies on vTPM-based remote attestation to verify nodes."},"workflows/upgrade":{"id":"workflows/upgrade","title":"Upgrade your cluster","description":"Constellation provides an easy way to upgrade all components of your cluster, without disrupting its availability.","sidebar":"docs"},"workflows/verify-cli":{"id":"workflows/verify-cli","title":"Verify the CLI","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","sidebar":"docs"},"workflows/verify-cluster":{"id":"workflows/verify-cluster","title":"Verify your cluster","description":"Constellation\'s attestation feature allows you, or a third party, to verify the integrity and confidentiality of your Constellation cluster.","sidebar":"docs"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/5901.f3704c6f.js b/pr-preview/pr-4027/assets/js/5901.f3704c6f.js deleted file mode 100644 index 443068263..000000000 --- a/pr-preview/pr-4027/assets/js/5901.f3704c6f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5901],{75901:(e,s,a)=>{a.d(s,{createTreemapServices:()=>c.d});var c=a(51633);a(87960)}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/592bfb5e.1f7a9f64.js b/pr-preview/pr-4027/assets/js/592bfb5e.1f7a9f64.js deleted file mode 100644 index 79347e39d..000000000 --- a/pr-preview/pr-4027/assets/js/592bfb5e.1f7a9f64.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[867],{28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var s=n(96540);const o={},i=s.createContext(o);function r(e){const t=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(i.Provider,{value:t},e.children)}},48886:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"workflows/s3proxy","title":"Install s3proxy","description":"Constellation includes a transparent client-side encryption proxy for AWS S3 and compatible stores.","source":"@site/docs/workflows/s3proxy.md","sourceDirName":"workflows","slug":"/workflows/s3proxy","permalink":"/constellation/pr-preview/pr-4027/next/workflows/s3proxy","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/workflows/s3proxy.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Install cert-manager","permalink":"/constellation/pr-preview/pr-4027/next/workflows/cert-manager"},"next":{"title":"Terminate your cluster","permalink":"/constellation/pr-preview/pr-4027/next/workflows/terminate"}}');var o=n(74848),i=n(28453);const r={},a="Install s3proxy",l={},c=[{value:"Limitations",id:"limitations",level:2},{value:"Deployment",id:"deployment",level:2},{value:"Technical details",id:"technical-details",level:2},{value:"Encryption",id:"encryption",level:3},{value:"Traffic interception",id:"traffic-interception",level:3}];function p(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"install-s3proxy",children:"Install s3proxy"})}),"\n",(0,o.jsxs)(t.p,{children:["Constellation includes a transparent client-side encryption proxy for ",(0,o.jsx)(t.a,{href:"https://aws.amazon.com/de/s3/",children:"AWS S3"})," and compatible stores.\ns3proxy encrypts objects before sending them to S3 and automatically decrypts them on retrieval, without requiring changes to your application.\nWith s3proxy, you can use S3 for storage in a confidential way without having to trust the storage provider."]}),"\n",(0,o.jsx)(t.h2,{id:"limitations",children:"Limitations"}),"\n",(0,o.jsx)(t.p,{children:"Currently, s3proxy has the following limitations:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["Only ",(0,o.jsx)(t.code,{children:"PutObject"})," and ",(0,o.jsx)(t.code,{children:"GetObject"})," requests are encrypted/decrypted by s3proxy.\nBy default, s3proxy will block requests that may expose unencrypted data to S3 (e.g. UploadPart).\nThe ",(0,o.jsx)(t.code,{children:"allow-multipart"})," flag disables request blocking for evaluation purposes."]}),"\n",(0,o.jsxs)(t.li,{children:["Using the ",(0,o.jsx)(t.a,{href:"https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html#API_GetObject_RequestSyntax",children:"Range"})," header on ",(0,o.jsx)(t.code,{children:"GetObject"})," is currently not supported and will result in an error."]}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:["These limitations will be removed with future iterations of s3proxy.\nIf you want to use s3proxy but these limitations stop you from doing so, consider ",(0,o.jsx)(t.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&projects=&template=feature_request.yml",children:"opening an issue"}),"."]}),"\n",(0,o.jsx)(t.h2,{id:"deployment",children:"Deployment"}),"\n",(0,o.jsx)(t.p,{children:"You can add the s3proxy to your Constellation cluster as follows:"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsxs)(t.li,{children:["Add the Edgeless Systems chart repository:","\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"helm repo add edgeless https://helm.edgeless.systems/stable\nhelm repo update\n"})}),"\n"]}),"\n",(0,o.jsx)(t.li,{children:"Set ACCESS_KEY and ACCESS_SECRET to valid credentials you want s3proxy to use to interact with S3."}),"\n",(0,o.jsxs)(t.li,{children:["Deploy s3proxy:","\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:'helm install s3proxy edgeless/s3proxy --set awsAccessKeyID="$ACCESS_KEY" --set awsSecretAccessKey="$ACCESS_SECRET"\n'})}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:["If you want to run a demo application, check out the ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/examples/filestash-s3proxy",children:"Filestash with s3proxy"})," example."]}),"\n",(0,o.jsx)(t.h2,{id:"technical-details",children:"Technical details"}),"\n",(0,o.jsx)(t.h3,{id:"encryption",children:"Encryption"}),"\n",(0,o.jsxs)(t.p,{children:["s3proxy relies on Google's ",(0,o.jsx)(t.a,{href:"https://developers.google.com/tink",children:"Tink Cryptographic Library"})," to implement cryptographic operations securely.\nThe used cryptographic primitives are ",(0,o.jsx)(t.a,{href:"https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf",children:"NIST SP 800 38f"})," for key wrapping and ",(0,o.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Advanced_Encryption_Standard",children:"AES"}),"-",(0,o.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Galois/counter_(GCM)",children:"GCM"})," with 256 bit keys for data encryption."]}),"\n",(0,o.jsxs)(t.p,{children:["s3proxy uses ",(0,o.jsx)(t.a,{href:"https://cloud.google.com/kms/docs/envelope-encryption",children:"envelope encryption"})," to encrypt objects.\nThis means s3proxy uses a key encryption key (KEK) issued by the ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#keyservice",children:"KeyService"})," to encrypt data encryption keys (DEKs).\nEach S3 object is encrypted with its own DEK.\nThe encrypted DEK is then saved as metadata of the encrypted object.\nThis enables key rotation of the KEK without re-encrypting the data in S3.\nThe approach also allows access to objects from different locations, as long as each location has access to the KEK."]}),"\n",(0,o.jsx)(t.h3,{id:"traffic-interception",children:"Traffic interception"}),"\n",(0,o.jsx)(t.p,{children:"To use s3proxy, you have to redirect your outbound S3 traffic to s3proxy.\nThis can either be done by modifying your client application or by changing the deployment of your application."}),"\n",(0,o.jsxs)(t.p,{children:["The necessary deployment modifications are to add DNS redirection and a trusted TLS certificate to the client's trust store.\nDNS redirection can be defined for each pod, allowing you to use s3proxy for one application without changing other applications in the same cluster.\nAdding a trusted TLS certificate is necessary as clients communicate with s3proxy via HTTPS.\nTo have your client application trust s3proxy's TLS certificate, the certificate has to be added to the client's certificate trust store.\nThe ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/examples/filestash-s3proxy",children:"Filestash with s3proxy"})," example shows how to do this."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/5955.645e55a4.js b/pr-preview/pr-4027/assets/js/5955.645e55a4.js deleted file mode 100644 index 6aae8b488..000000000 --- a/pr-preview/pr-4027/assets/js/5955.645e55a4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5955],{45955:(t,i,e)=>{e.d(i,{diagram:()=>it});var s=e(73590),a=e(30092),n=e(13226),h=e(67633),o=e(40797),r=e(70451),l=function(){var t=(0,o.K2)(function(t,i,e,s){for(e=e||{},s=t.length;s--;e[t[s]]=i);return e},"o"),i=[1,10,12,14,16,18,19,21,23],e=[2,6],s=[1,3],a=[1,5],n=[1,6],h=[1,7],r=[1,5,10,12,14,16,18,19,21,23,34,35,36],l=[1,25],c=[1,26],g=[1,28],u=[1,29],x=[1,30],d=[1,31],p=[1,32],f=[1,33],y=[1,34],m=[1,35],b=[1,36],A=[1,37],w=[1,43],S=[1,42],C=[1,47],k=[1,50],_=[1,10,12,14,16,18,19,21,23,34,35,36],T=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36],R=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36,41,42,43,44,45,46,47,48,49,50],D=[1,64],L={trace:(0,o.K2)(function(){},"trace"),yy:{},symbols_:{error:2,start:3,eol:4,XYCHART:5,chartConfig:6,document:7,CHART_ORIENTATION:8,statement:9,title:10,text:11,X_AXIS:12,parseXAxis:13,Y_AXIS:14,parseYAxis:15,LINE:16,plotData:17,BAR:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,SQUARE_BRACES_START:24,commaSeparatedNumbers:25,SQUARE_BRACES_END:26,NUMBER_WITH_DECIMAL:27,COMMA:28,xAxisData:29,bandData:30,ARROW_DELIMITER:31,commaSeparatedTexts:32,yAxisData:33,NEWLINE:34,SEMI:35,EOF:36,alphaNum:37,STR:38,MD_STR:39,alphaNumToken:40,AMP:41,NUM:42,ALPHA:43,PLUS:44,EQUALS:45,MULT:46,DOT:47,BRKT:48,MINUS:49,UNDERSCORE:50,$accept:0,$end:1},terminals_:{2:"error",5:"XYCHART",8:"CHART_ORIENTATION",10:"title",12:"X_AXIS",14:"Y_AXIS",16:"LINE",18:"BAR",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"SQUARE_BRACES_START",26:"SQUARE_BRACES_END",27:"NUMBER_WITH_DECIMAL",28:"COMMA",31:"ARROW_DELIMITER",34:"NEWLINE",35:"SEMI",36:"EOF",38:"STR",39:"MD_STR",41:"AMP",42:"NUM",43:"ALPHA",44:"PLUS",45:"EQUALS",46:"MULT",47:"DOT",48:"BRKT",49:"MINUS",50:"UNDERSCORE"},productions_:[0,[3,2],[3,3],[3,2],[3,1],[6,1],[7,0],[7,2],[9,2],[9,2],[9,2],[9,2],[9,2],[9,3],[9,2],[9,3],[9,2],[9,2],[9,1],[17,3],[25,3],[25,1],[13,1],[13,2],[13,1],[29,1],[29,3],[30,3],[32,3],[32,1],[15,1],[15,2],[15,1],[33,3],[4,1],[4,1],[4,1],[11,1],[11,1],[11,1],[37,1],[37,2],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1]],performAction:(0,o.K2)(function(t,i,e,s,a,n,h){var o=n.length-1;switch(a){case 5:s.setOrientation(n[o]);break;case 9:s.setDiagramTitle(n[o].text.trim());break;case 12:s.setLineData({text:"",type:"text"},n[o]);break;case 13:s.setLineData(n[o-1],n[o]);break;case 14:s.setBarData({text:"",type:"text"},n[o]);break;case 15:s.setBarData(n[o-1],n[o]);break;case 16:this.$=n[o].trim(),s.setAccTitle(this.$);break;case 17:case 18:this.$=n[o].trim(),s.setAccDescription(this.$);break;case 19:case 27:this.$=n[o-1];break;case 20:this.$=[Number(n[o-2]),...n[o]];break;case 21:this.$=[Number(n[o])];break;case 22:s.setXAxisTitle(n[o]);break;case 23:s.setXAxisTitle(n[o-1]);break;case 24:s.setXAxisTitle({type:"text",text:""});break;case 25:s.setXAxisBand(n[o]);break;case 26:s.setXAxisRangeData(Number(n[o-2]),Number(n[o]));break;case 28:this.$=[n[o-2],...n[o]];break;case 29:this.$=[n[o]];break;case 30:s.setYAxisTitle(n[o]);break;case 31:s.setYAxisTitle(n[o-1]);break;case 32:s.setYAxisTitle({type:"text",text:""});break;case 33:s.setYAxisRangeData(Number(n[o-2]),Number(n[o]));break;case 37:case 38:this.$={text:n[o],type:"text"};break;case 39:this.$={text:n[o],type:"markdown"};break;case 40:this.$=n[o];break;case 41:this.$=n[o-1]+""+n[o]}},"anonymous"),table:[t(i,e,{3:1,4:2,7:4,5:s,34:a,35:n,36:h}),{1:[3]},t(i,e,{4:2,7:4,3:8,5:s,34:a,35:n,36:h}),t(i,e,{4:2,7:4,6:9,3:10,5:s,8:[1,11],34:a,35:n,36:h}),{1:[2,4],9:12,10:[1,13],12:[1,14],14:[1,15],16:[1,16],18:[1,17],19:[1,18],21:[1,19],23:[1,20]},t(r,[2,34]),t(r,[2,35]),t(r,[2,36]),{1:[2,1]},t(i,e,{4:2,7:4,3:21,5:s,34:a,35:n,36:h}),{1:[2,3]},t(r,[2,5]),t(i,[2,7],{4:22,34:a,35:n,36:h}),{11:23,37:24,38:l,39:c,40:27,41:g,42:u,43:x,44:d,45:p,46:f,47:y,48:m,49:b,50:A},{11:39,13:38,24:w,27:S,29:40,30:41,37:24,38:l,39:c,40:27,41:g,42:u,43:x,44:d,45:p,46:f,47:y,48:m,49:b,50:A},{11:45,15:44,27:C,33:46,37:24,38:l,39:c,40:27,41:g,42:u,43:x,44:d,45:p,46:f,47:y,48:m,49:b,50:A},{11:49,17:48,24:k,37:24,38:l,39:c,40:27,41:g,42:u,43:x,44:d,45:p,46:f,47:y,48:m,49:b,50:A},{11:52,17:51,24:k,37:24,38:l,39:c,40:27,41:g,42:u,43:x,44:d,45:p,46:f,47:y,48:m,49:b,50:A},{20:[1,53]},{22:[1,54]},t(_,[2,18]),{1:[2,2]},t(_,[2,8]),t(_,[2,9]),t(T,[2,37],{40:55,41:g,42:u,43:x,44:d,45:p,46:f,47:y,48:m,49:b,50:A}),t(T,[2,38]),t(T,[2,39]),t(R,[2,40]),t(R,[2,42]),t(R,[2,43]),t(R,[2,44]),t(R,[2,45]),t(R,[2,46]),t(R,[2,47]),t(R,[2,48]),t(R,[2,49]),t(R,[2,50]),t(R,[2,51]),t(_,[2,10]),t(_,[2,22],{30:41,29:56,24:w,27:S}),t(_,[2,24]),t(_,[2,25]),{31:[1,57]},{11:59,32:58,37:24,38:l,39:c,40:27,41:g,42:u,43:x,44:d,45:p,46:f,47:y,48:m,49:b,50:A},t(_,[2,11]),t(_,[2,30],{33:60,27:C}),t(_,[2,32]),{31:[1,61]},t(_,[2,12]),{17:62,24:k},{25:63,27:D},t(_,[2,14]),{17:65,24:k},t(_,[2,16]),t(_,[2,17]),t(R,[2,41]),t(_,[2,23]),{27:[1,66]},{26:[1,67]},{26:[2,29],28:[1,68]},t(_,[2,31]),{27:[1,69]},t(_,[2,13]),{26:[1,70]},{26:[2,21],28:[1,71]},t(_,[2,15]),t(_,[2,26]),t(_,[2,27]),{11:59,32:72,37:24,38:l,39:c,40:27,41:g,42:u,43:x,44:d,45:p,46:f,47:y,48:m,49:b,50:A},t(_,[2,33]),t(_,[2,19]),{25:73,27:D},{26:[2,28]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],72:[2,28],73:[2,20]},parseError:(0,o.K2)(function(t,i){if(!i.recoverable){var e=new Error(t);throw e.hash=i,e}this.trace(t)},"parseError"),parse:(0,o.K2)(function(t){var i=this,e=[0],s=[],a=[null],n=[],h=this.table,r="",l=0,c=0,g=0,u=n.slice.call(arguments,1),x=Object.create(this.lexer),d={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(d.yy[p]=this.yy[p]);x.setInput(t,d.yy),d.yy.lexer=x,d.yy.parser=this,void 0===x.yylloc&&(x.yylloc={});var f=x.yylloc;n.push(f);var y=x.options&&x.options.ranges;function m(){var t;return"number"!=typeof(t=s.pop()||x.lex()||1)&&(t instanceof Array&&(t=(s=t).pop()),t=i.symbols_[t]||t),t}"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,o.K2)(function(t){e.length=e.length-2*t,a.length=a.length-t,n.length=n.length-t},"popStack"),(0,o.K2)(m,"lex");for(var b,A,w,S,C,k,_,T,R,D={};;){if(w=e[e.length-1],this.defaultActions[w]?S=this.defaultActions[w]:(null==b&&(b=m()),S=h[w]&&h[w][b]),void 0===S||!S.length||!S[0]){var L="";for(k in R=[],h[w])this.terminals_[k]&&k>2&&R.push("'"+this.terminals_[k]+"'");L=x.showPosition?"Parse error on line "+(l+1)+":\n"+x.showPosition()+"\nExpecting "+R.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(L,{text:x.match,token:this.terminals_[b]||b,line:x.yylineno,loc:f,expected:R})}if(S[0]instanceof Array&&S.length>1)throw new Error("Parse Error: multiple actions possible at state: "+w+", token: "+b);switch(S[0]){case 1:e.push(b),a.push(x.yytext),n.push(x.yylloc),e.push(S[1]),b=null,A?(b=A,A=null):(c=x.yyleng,r=x.yytext,l=x.yylineno,f=x.yylloc,g>0&&g--);break;case 2:if(_=this.productions_[S[1]][1],D.$=a[a.length-_],D._$={first_line:n[n.length-(_||1)].first_line,last_line:n[n.length-1].last_line,first_column:n[n.length-(_||1)].first_column,last_column:n[n.length-1].last_column},y&&(D._$.range=[n[n.length-(_||1)].range[0],n[n.length-1].range[1]]),void 0!==(C=this.performAction.apply(D,[r,c,l,d.yy,S[1],a,n].concat(u))))return C;_&&(e=e.slice(0,-1*_*2),a=a.slice(0,-1*_),n=n.slice(0,-1*_)),e.push(this.productions_[S[1]][0]),a.push(D.$),n.push(D._$),T=h[e[e.length-2]][e[e.length-1]],e.push(T);break;case 3:return!0}}return!0},"parse")},P=function(){return{EOF:1,parseError:(0,o.K2)(function(t,i){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,i)},"parseError"),setInput:(0,o.K2)(function(t,i){return this.yy=i||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:(0,o.K2)(function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},"input"),unput:(0,o.K2)(function(t){var i=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-i),this.offset-=i;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var a=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===s.length?this.yylloc.first_column:0)+s[s.length-e.length].length-e[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[a[0],a[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},"unput"),more:(0,o.K2)(function(){return this._more=!0,this},"more"),reject:(0,o.K2)(function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"reject"),less:(0,o.K2)(function(t){this.unput(this.match.slice(t))},"less"),pastInput:(0,o.K2)(function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:(0,o.K2)(function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:(0,o.K2)(function(){var t=this.pastInput(),i=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+i+"^"},"showPosition"),test_match:(0,o.K2)(function(t,i){var e,s,a;if(this.options.backtrack_lexer&&(a={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(a.yylloc.range=this.yylloc.range.slice(0))),(s=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,i,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var n in a)this[n]=a[n];return!1}return!1},"test_match"),next:(0,o.K2)(function(){if(this.done)return this.EOF;var t,i,e,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var a=this._currentRules(),n=0;n<a.length;n++)if((e=this._input.match(this.rules[a[n]]))&&(!i||e[0].length>i[0].length)){if(i=e,s=n,this.options.backtrack_lexer){if(!1!==(t=this.test_match(e,a[n])))return t;if(this._backtrack){i=!1;continue}return!1}if(!this.options.flex)break}return i?!1!==(t=this.test_match(i,a[s]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:(0,o.K2)(function(){var t=this.next();return t||this.lex()},"lex"),begin:(0,o.K2)(function(t){this.conditionStack.push(t)},"begin"),popState:(0,o.K2)(function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:(0,o.K2)(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:(0,o.K2)(function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},"topState"),pushState:(0,o.K2)(function(t){this.begin(t)},"pushState"),stateStackSize:(0,o.K2)(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,o.K2)(function(t,i,e,s){switch(e){case 0:case 1:case 5:case 44:break;case 2:case 3:return this.popState(),34;case 4:return 34;case 6:return 10;case 7:return this.pushState("acc_title"),19;case 8:return this.popState(),"acc_title_value";case 9:return this.pushState("acc_descr"),21;case 10:return this.popState(),"acc_descr_value";case 11:this.pushState("acc_descr_multiline");break;case 12:case 26:case 28:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:case 15:return 5;case 16:return 8;case 17:return this.pushState("axis_data"),"X_AXIS";case 18:return this.pushState("axis_data"),"Y_AXIS";case 19:return this.pushState("axis_band_data"),24;case 20:return 31;case 21:return this.pushState("data"),16;case 22:return this.pushState("data"),18;case 23:return this.pushState("data_inner"),24;case 24:return 27;case 25:return this.popState(),26;case 27:this.pushState("string");break;case 29:return"STR";case 30:return 24;case 31:return 26;case 32:return 43;case 33:return"COLON";case 34:return 44;case 35:return 28;case 36:return 45;case 37:return 46;case 38:return 48;case 39:return 50;case 40:return 47;case 41:return 41;case 42:return 49;case 43:return 42;case 45:return 35;case 46:return 36}},"anonymous"),rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:(\r?\n))/i,/^(?:(\r?\n))/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:\{)/i,/^(?:[^\}]*)/i,/^(?:xychart-beta\b)/i,/^(?:xychart\b)/i,/^(?:(?:vertical|horizontal))/i,/^(?:x-axis\b)/i,/^(?:y-axis\b)/i,/^(?:\[)/i,/^(?:-->)/i,/^(?:line\b)/i,/^(?:bar\b)/i,/^(?:\[)/i,/^(?:[+-]?(?:\d+(?:\.\d+)?|\.\d+))/i,/^(?:\])/i,/^(?:(?:`\) \{ this\.pushState\(md_string\); \}\n<md_string>\(\?:\(\?!`"\)\.\)\+ \{ return MD_STR; \}\n<md_string>\(\?:`))/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:\[)/i,/^(?:\])/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s+)/i,/^(?:;)/i,/^(?:$)/i],conditions:{data_inner:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,18,21,22,24,25,26,27,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],inclusive:!0},data:{rules:[0,1,3,4,5,6,7,9,11,14,15,16,17,18,21,22,23,26,27,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],inclusive:!0},axis_band_data:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,18,21,22,25,26,27,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],inclusive:!0},axis_data:{rules:[0,1,2,4,5,6,7,9,11,14,15,16,17,18,19,20,21,22,24,26,27,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],inclusive:!0},acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},title:{rules:[],inclusive:!1},md_string:{rules:[],inclusive:!1},string:{rules:[28,29],inclusive:!1},INITIAL:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,18,21,22,26,27,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],inclusive:!0}}}}();function E(){this.yy={}}return L.lexer=P,(0,o.K2)(E,"Parser"),E.prototype=L,L.Parser=E,new E}();l.parser=l;var c=l;function g(t){return"bar"===t.type}function u(t){return"band"===t.type}function x(t){return"linear"===t.type}(0,o.K2)(g,"isBarPlot"),(0,o.K2)(u,"isBandAxisData"),(0,o.K2)(x,"isLinearAxisData");var d=class{constructor(t){this.parentGroup=t}static{(0,o.K2)(this,"TextDimensionCalculatorWithFont")}getMaxDimension(t,i){if(!this.parentGroup)return{width:t.reduce((t,i)=>Math.max(i.length,t),0)*i,height:i};const e={width:0,height:0},s=this.parentGroup.append("g").attr("visibility","hidden").attr("font-size",i);for(const n of t){const t=(0,a.W6)(s,1,n),h=t?t.width:n.length*i,o=t?t.height:i;e.width=Math.max(e.width,h),e.height=Math.max(e.height,o)}return s.remove(),e}},p=class{constructor(t,i,e,s){this.axisConfig=t,this.title=i,this.textDimensionCalculator=e,this.axisThemeConfig=s,this.boundingRect={x:0,y:0,width:0,height:0},this.axisPosition="left",this.showTitle=!1,this.showLabel=!1,this.showTick=!1,this.showAxisLine=!1,this.outerPadding=0,this.titleTextHeight=0,this.labelTextHeight=0,this.range=[0,10],this.boundingRect={x:0,y:0,width:0,height:0},this.axisPosition="left"}static{(0,o.K2)(this,"BaseAxis")}setRange(t){this.range=t,"left"===this.axisPosition||"right"===this.axisPosition?this.boundingRect.height=t[1]-t[0]:this.boundingRect.width=t[1]-t[0],this.recalculateScale()}getRange(){return[this.range[0]+this.outerPadding,this.range[1]-this.outerPadding]}setAxisPosition(t){this.axisPosition=t,this.setRange(this.range)}getTickDistance(){const t=this.getRange();return Math.abs(t[0]-t[1])/this.getTickValues().length}getAxisOuterPadding(){return this.outerPadding}getLabelDimension(){return this.textDimensionCalculator.getMaxDimension(this.getTickValues().map(t=>t.toString()),this.axisConfig.labelFontSize)}recalculateOuterPaddingToDrawBar(){.7*this.getTickDistance()>2*this.outerPadding&&(this.outerPadding=Math.floor(.7*this.getTickDistance()/2)),this.recalculateScale()}calculateSpaceIfDrawnHorizontally(t){let i=t.height;if(this.axisConfig.showAxisLine&&i>this.axisConfig.axisLineWidth&&(i-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){const e=this.getLabelDimension(),s=.2*t.width;this.outerPadding=Math.min(e.width/2,s);const a=e.height+2*this.axisConfig.labelPadding;this.labelTextHeight=e.height,a<=i&&(i-=a,this.showLabel=!0)}if(this.axisConfig.showTick&&i>=this.axisConfig.tickLength&&(this.showTick=!0,i-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){const t=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),e=t.height+2*this.axisConfig.titlePadding;this.titleTextHeight=t.height,e<=i&&(i-=e,this.showTitle=!0)}this.boundingRect.width=t.width,this.boundingRect.height=t.height-i}calculateSpaceIfDrawnVertical(t){let i=t.width;if(this.axisConfig.showAxisLine&&i>this.axisConfig.axisLineWidth&&(i-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){const e=this.getLabelDimension(),s=.2*t.height;this.outerPadding=Math.min(e.height/2,s);const a=e.width+2*this.axisConfig.labelPadding;a<=i&&(i-=a,this.showLabel=!0)}if(this.axisConfig.showTick&&i>=this.axisConfig.tickLength&&(this.showTick=!0,i-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){const t=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),e=t.height+2*this.axisConfig.titlePadding;this.titleTextHeight=t.height,e<=i&&(i-=e,this.showTitle=!0)}this.boundingRect.width=t.width-i,this.boundingRect.height=t.height}calculateSpace(t){return"left"===this.axisPosition||"right"===this.axisPosition?this.calculateSpaceIfDrawnVertical(t):this.calculateSpaceIfDrawnHorizontally(t),this.recalculateScale(),{width:this.boundingRect.width,height:this.boundingRect.height}}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}getDrawableElementsForLeftAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.x+this.boundingRect.width-this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["left-axis","axisl-line"],data:[{path:`M ${i},${this.boundingRect.y} L ${i},${this.boundingRect.y+this.boundingRect.height} `,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["left-axis","label"],data:this.getTickValues().map(t=>({text:t.toString(),x:this.boundingRect.x+this.boundingRect.width-(this.showLabel?this.axisConfig.labelPadding:0)-(this.showTick?this.axisConfig.tickLength:0)-(this.showAxisLine?this.axisConfig.axisLineWidth:0),y:this.getScaleValue(t),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"middle",horizontalPos:"right"}))}),this.showTick){const i=this.boundingRect.x+this.boundingRect.width-(this.showAxisLine?this.axisConfig.axisLineWidth:0);t.push({type:"path",groupTexts:["left-axis","ticks"],data:this.getTickValues().map(t=>({path:`M ${i},${this.getScaleValue(t)} L ${i-this.axisConfig.tickLength},${this.getScaleValue(t)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&t.push({type:"text",groupTexts:["left-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.axisConfig.titlePadding,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:270,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElementsForBottomAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.y+this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["bottom-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${i} L ${this.boundingRect.x+this.boundingRect.width},${i}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["bottom-axis","label"],data:this.getTickValues().map(t=>({text:t.toString(),x:this.getScaleValue(t),y:this.boundingRect.y+this.axisConfig.labelPadding+(this.showTick?this.axisConfig.tickLength:0)+(this.showAxisLine?this.axisConfig.axisLineWidth:0),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}))}),this.showTick){const i=this.boundingRect.y+(this.showAxisLine?this.axisConfig.axisLineWidth:0);t.push({type:"path",groupTexts:["bottom-axis","ticks"],data:this.getTickValues().map(t=>({path:`M ${this.getScaleValue(t)},${i} L ${this.getScaleValue(t)},${i+this.axisConfig.tickLength}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&t.push({type:"text",groupTexts:["bottom-axis","title"],data:[{text:this.title,x:this.range[0]+(this.range[1]-this.range[0])/2,y:this.boundingRect.y+this.boundingRect.height-this.axisConfig.titlePadding-this.titleTextHeight,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElementsForTopAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.y+this.boundingRect.height-this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["top-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${i} L ${this.boundingRect.x+this.boundingRect.width},${i}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["top-axis","label"],data:this.getTickValues().map(t=>({text:t.toString(),x:this.getScaleValue(t),y:this.boundingRect.y+(this.showTitle?this.titleTextHeight+2*this.axisConfig.titlePadding:0)+this.axisConfig.labelPadding,fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}))}),this.showTick){const i=this.boundingRect.y;t.push({type:"path",groupTexts:["top-axis","ticks"],data:this.getTickValues().map(t=>({path:`M ${this.getScaleValue(t)},${i+this.boundingRect.height-(this.showAxisLine?this.axisConfig.axisLineWidth:0)} L ${this.getScaleValue(t)},${i+this.boundingRect.height-this.axisConfig.tickLength-(this.showAxisLine?this.axisConfig.axisLineWidth:0)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&t.push({type:"text",groupTexts:["top-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.axisConfig.titlePadding,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElements(){if("left"===this.axisPosition)return this.getDrawableElementsForLeftAxis();if("right"===this.axisPosition)throw Error("Drawing of right axis is not implemented");return"bottom"===this.axisPosition?this.getDrawableElementsForBottomAxis():"top"===this.axisPosition?this.getDrawableElementsForTopAxis():[]}},f=class extends p{static{(0,o.K2)(this,"BandAxis")}constructor(t,i,e,s,a){super(t,s,a,i),this.categories=e,this.scale=(0,r.WH)().domain(this.categories).range(this.getRange())}setRange(t){super.setRange(t)}recalculateScale(){this.scale=(0,r.WH)().domain(this.categories).range(this.getRange()).paddingInner(1).paddingOuter(0).align(.5),o.Rm.trace("BandAxis axis final categories, range: ",this.categories,this.getRange())}getTickValues(){return this.categories}getScaleValue(t){return this.scale(t)??this.getRange()[0]}},y=class extends p{static{(0,o.K2)(this,"LinearAxis")}constructor(t,i,e,s,a){super(t,s,a,i),this.domain=e,this.scale=(0,r.m4Y)().domain(this.domain).range(this.getRange())}getTickValues(){return this.scale.ticks()}recalculateScale(){const t=[...this.domain];"left"===this.axisPosition&&t.reverse(),this.scale=(0,r.m4Y)().domain(t).range(this.getRange())}getScaleValue(t){return this.scale(t)}};function m(t,i,e,s){const a=new d(s);return u(t)?new f(i,e,t.categories,t.title,a):new y(i,e,[t.min,t.max],t.title,a)}(0,o.K2)(m,"getAxis");var b=class{constructor(t,i,e,s){this.textDimensionCalculator=t,this.chartConfig=i,this.chartData=e,this.chartThemeConfig=s,this.boundingRect={x:0,y:0,width:0,height:0},this.showChartTitle=!1}static{(0,o.K2)(this,"ChartTitle")}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}calculateSpace(t){const i=this.textDimensionCalculator.getMaxDimension([this.chartData.title],this.chartConfig.titleFontSize),e=Math.max(i.width,t.width),s=i.height+2*this.chartConfig.titlePadding;return i.width<=e&&i.height<=s&&this.chartConfig.showTitle&&this.chartData.title&&(this.boundingRect.width=e,this.boundingRect.height=s,this.showChartTitle=!0),{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){const t=[];return this.showChartTitle&&t.push({groupTexts:["chart-title"],type:"text",data:[{fontSize:this.chartConfig.titleFontSize,text:this.chartData.title,verticalPos:"middle",horizontalPos:"center",x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.chartThemeConfig.titleColor,rotation:0}]}),t}};function A(t,i,e,s){const a=new d(s);return new b(a,t,i,e)}(0,o.K2)(A,"getChartTitleComponent");var w=class{constructor(t,i,e,s,a){this.plotData=t,this.xAxis=i,this.yAxis=e,this.orientation=s,this.plotIndex=a}static{(0,o.K2)(this,"LinePlot")}getDrawableElement(){const t=this.plotData.data.map(t=>[this.xAxis.getScaleValue(t[0]),this.yAxis.getScaleValue(t[1])]);let i;return i="horizontal"===this.orientation?(0,r.n8j)().y(t=>t[0]).x(t=>t[1])(t):(0,r.n8j)().x(t=>t[0]).y(t=>t[1])(t),i?[{groupTexts:["plot",`line-plot-${this.plotIndex}`],type:"path",data:[{path:i,strokeFill:this.plotData.strokeFill,strokeWidth:this.plotData.strokeWidth}]}]:[]}},S=class{constructor(t,i,e,s,a,n){this.barData=t,this.boundingRect=i,this.xAxis=e,this.yAxis=s,this.orientation=a,this.plotIndex=n}static{(0,o.K2)(this,"BarPlot")}getDrawableElement(){const t=this.barData.data.map(t=>[this.xAxis.getScaleValue(t[0]),this.yAxis.getScaleValue(t[1])]),i=.95*Math.min(2*this.xAxis.getAxisOuterPadding(),this.xAxis.getTickDistance()),e=i/2;return"horizontal"===this.orientation?[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:t.map(t=>({x:this.boundingRect.x,y:t[0]-e,height:i,width:t[1]-this.boundingRect.x,fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill}))}]:[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:t.map(t=>({x:t[0]-e,y:t[1],width:i,height:this.boundingRect.y+this.boundingRect.height-t[1],fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill}))}]}},C=class{constructor(t,i,e){this.chartConfig=t,this.chartData=i,this.chartThemeConfig=e,this.boundingRect={x:0,y:0,width:0,height:0}}static{(0,o.K2)(this,"BasePlot")}setAxes(t,i){this.xAxis=t,this.yAxis=i}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}calculateSpace(t){return this.boundingRect.width=t.width,this.boundingRect.height=t.height,{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){if(!this.xAxis||!this.yAxis)throw Error("Axes must be passed to render Plots");const t=[];for(const[i,e]of this.chartData.plots.entries())switch(e.type){case"line":{const s=new w(e,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,i);t.push(...s.getDrawableElement())}break;case"bar":{const s=new S(e,this.boundingRect,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,i);t.push(...s.getDrawableElement())}}return t}};function k(t,i,e){return new C(t,i,e)}(0,o.K2)(k,"getPlotComponent");var _,T=class{constructor(t,i,e,s){this.chartConfig=t,this.chartData=i,this.componentStore={title:A(t,i,e,s),plot:k(t,i,e),xAxis:m(i.xAxis,t.xAxis,{titleColor:e.xAxisTitleColor,labelColor:e.xAxisLabelColor,tickColor:e.xAxisTickColor,axisLineColor:e.xAxisLineColor},s),yAxis:m(i.yAxis,t.yAxis,{titleColor:e.yAxisTitleColor,labelColor:e.yAxisLabelColor,tickColor:e.yAxisTickColor,axisLineColor:e.yAxisLineColor},s)}}static{(0,o.K2)(this,"Orchestrator")}calculateVerticalSpace(){let t=this.chartConfig.width,i=this.chartConfig.height,e=0,s=0,a=Math.floor(t*this.chartConfig.plotReservedSpacePercent/100),n=Math.floor(i*this.chartConfig.plotReservedSpacePercent/100),h=this.componentStore.plot.calculateSpace({width:a,height:n});t-=h.width,i-=h.height,h=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:i}),s=h.height,i-=h.height,this.componentStore.xAxis.setAxisPosition("bottom"),h=this.componentStore.xAxis.calculateSpace({width:t,height:i}),i-=h.height,this.componentStore.yAxis.setAxisPosition("left"),h=this.componentStore.yAxis.calculateSpace({width:t,height:i}),e=h.width,t-=h.width,t>0&&(a+=t,t=0),i>0&&(n+=i,i=0),this.componentStore.plot.calculateSpace({width:a,height:n}),this.componentStore.plot.setBoundingBoxXY({x:e,y:s}),this.componentStore.xAxis.setRange([e,e+a]),this.componentStore.xAxis.setBoundingBoxXY({x:e,y:s+n}),this.componentStore.yAxis.setRange([s,s+n]),this.componentStore.yAxis.setBoundingBoxXY({x:0,y:s}),this.chartData.plots.some(t=>g(t))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateHorizontalSpace(){let t=this.chartConfig.width,i=this.chartConfig.height,e=0,s=0,a=0,n=Math.floor(t*this.chartConfig.plotReservedSpacePercent/100),h=Math.floor(i*this.chartConfig.plotReservedSpacePercent/100),o=this.componentStore.plot.calculateSpace({width:n,height:h});t-=o.width,i-=o.height,o=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:i}),e=o.height,i-=o.height,this.componentStore.xAxis.setAxisPosition("left"),o=this.componentStore.xAxis.calculateSpace({width:t,height:i}),t-=o.width,s=o.width,this.componentStore.yAxis.setAxisPosition("top"),o=this.componentStore.yAxis.calculateSpace({width:t,height:i}),i-=o.height,a=e+o.height,t>0&&(n+=t,t=0),i>0&&(h+=i,i=0),this.componentStore.plot.calculateSpace({width:n,height:h}),this.componentStore.plot.setBoundingBoxXY({x:s,y:a}),this.componentStore.yAxis.setRange([s,s+n]),this.componentStore.yAxis.setBoundingBoxXY({x:s,y:e}),this.componentStore.xAxis.setRange([a,a+h]),this.componentStore.xAxis.setBoundingBoxXY({x:0,y:a}),this.chartData.plots.some(t=>g(t))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateSpace(){"horizontal"===this.chartConfig.chartOrientation?this.calculateHorizontalSpace():this.calculateVerticalSpace()}getDrawableElement(){this.calculateSpace();const t=[];this.componentStore.plot.setAxes(this.componentStore.xAxis,this.componentStore.yAxis);for(const i of Object.values(this.componentStore))t.push(...i.getDrawableElements());return t}},R=class{static{(0,o.K2)(this,"XYChartBuilder")}static build(t,i,e,s){return new T(t,i,e,s).getDrawableElement()}},D=0,L=M(),P=$(),E=z(),v=P.plotColorPalette.split(",").map(t=>t.trim()),K=!1,I=!1;function $(){const t=(0,h.P$)(),i=(0,h.zj)();return(0,n.$t)(t.xyChart,i.themeVariables.xyChart)}function M(){const t=(0,h.zj)();return(0,n.$t)(h.UI.xyChart,t.xyChart)}function z(){return{yAxis:{type:"linear",title:"",min:1/0,max:-1/0},xAxis:{type:"band",title:"",categories:[]},title:"",plots:[]}}function B(t){const i=(0,h.zj)();return(0,h.jZ)(t.trim(),i)}function W(t){_=t}function O(t){L.chartOrientation="horizontal"===t?"horizontal":"vertical"}function F(t){E.xAxis.title=B(t.text)}function N(t,i){E.xAxis={type:"linear",title:E.xAxis.title,min:t,max:i},K=!0}function X(t){E.xAxis={type:"band",title:E.xAxis.title,categories:t.map(t=>B(t.text))},K=!0}function V(t){E.yAxis.title=B(t.text)}function Y(t,i){E.yAxis={type:"linear",title:E.yAxis.title,min:t,max:i},I=!0}function H(t){const i=Math.min(...t),e=Math.max(...t),s=x(E.yAxis)?E.yAxis.min:1/0,a=x(E.yAxis)?E.yAxis.max:-1/0;E.yAxis={type:"linear",title:E.yAxis.title,min:Math.min(s,i),max:Math.max(a,e)}}function U(t){let i=[];if(0===t.length)return i;if(!K){const i=x(E.xAxis)?E.xAxis.min:1/0,e=x(E.xAxis)?E.xAxis.max:-1/0;N(Math.min(i,1),Math.max(e,t.length))}if(I||H(t),u(E.xAxis)&&(i=E.xAxis.categories.map((i,e)=>[i,t[e]])),x(E.xAxis)){const e=E.xAxis.min,s=E.xAxis.max,a=(s-e)/(t.length-1),n=[];for(let t=e;t<=s;t+=a)n.push(`${t}`);i=n.map((i,e)=>[i,t[e]])}return i}function j(t){return v[0===t?0:t%v.length]}function G(t,i){const e=U(i);E.plots.push({type:"line",strokeFill:j(D),strokeWidth:2,data:e}),D++}function Q(t,i){const e=U(i);E.plots.push({type:"bar",fill:j(D),data:e}),D++}function Z(){if(0===E.plots.length)throw Error("No Plot to render, please provide a plot with some data");return E.title=(0,h.ab)(),R.build(L,E,P,_)}function q(){return P}function J(){return L}function tt(){return E}(0,o.K2)($,"getChartDefaultThemeConfig"),(0,o.K2)(M,"getChartDefaultConfig"),(0,o.K2)(z,"getChartDefaultData"),(0,o.K2)(B,"textSanitizer"),(0,o.K2)(W,"setTmpSVGG"),(0,o.K2)(O,"setOrientation"),(0,o.K2)(F,"setXAxisTitle"),(0,o.K2)(N,"setXAxisRangeData"),(0,o.K2)(X,"setXAxisBand"),(0,o.K2)(V,"setYAxisTitle"),(0,o.K2)(Y,"setYAxisRangeData"),(0,o.K2)(H,"setYAxisRangeFromPlotData"),(0,o.K2)(U,"transformDataWithoutCategory"),(0,o.K2)(j,"getPlotColorFromPalette"),(0,o.K2)(G,"setLineData"),(0,o.K2)(Q,"setBarData"),(0,o.K2)(Z,"getDrawableElem"),(0,o.K2)(q,"getChartThemeConfig"),(0,o.K2)(J,"getChartConfig"),(0,o.K2)(tt,"getXYChartData");var it={parser:c,db:{getDrawableElem:Z,clear:(0,o.K2)(function(){(0,h.IU)(),D=0,L=M(),E={yAxis:{type:"linear",title:"",min:1/0,max:-1/0},xAxis:{type:"band",title:"",categories:[]},title:"",plots:[]},P=$(),v=P.plotColorPalette.split(",").map(t=>t.trim()),K=!1,I=!1},"clear"),setAccTitle:h.SV,getAccTitle:h.iN,setDiagramTitle:h.ke,getDiagramTitle:h.ab,getAccDescription:h.m7,setAccDescription:h.EI,setOrientation:O,setXAxisTitle:F,setXAxisRangeData:N,setXAxisBand:X,setYAxisTitle:V,setYAxisRangeData:Y,setLineData:G,setBarData:Q,setTmpSVGG:W,getChartThemeConfig:q,getChartConfig:J,getXYChartData:tt},renderer:{draw:(0,o.K2)((t,i,e,a)=>{const n=a.db,r=n.getChartThemeConfig(),l=n.getChartConfig(),c=n.getXYChartData().plots[0].data.map(t=>t[1]);function g(t){return"top"===t?"text-before-edge":"middle"}function u(t){return"left"===t?"start":"right"===t?"end":"middle"}function x(t){return`translate(${t.x}, ${t.y}) rotate(${t.rotation||0})`}(0,o.K2)(g,"getDominantBaseLine"),(0,o.K2)(u,"getTextAnchor"),(0,o.K2)(x,"getTextTransformation"),o.Rm.debug("Rendering xychart chart\n"+t);const d=(0,s.D)(i),p=d.append("g").attr("class","main"),f=p.append("rect").attr("width",l.width).attr("height",l.height).attr("class","background");(0,h.a$)(d,l.height,l.width,!0),d.attr("viewBox",`0 0 ${l.width} ${l.height}`),f.attr("fill",r.backgroundColor),n.setTmpSVGG(d.append("g").attr("class","mermaid-tmp-group"));const y=n.getDrawableElem(),m={};function b(t){let i=p,e="";for(const[s]of t.entries()){let a=p;s>0&&m[e]&&(a=m[e]),e+=t[s],i=m[e],i||(i=m[e]=a.append("g").attr("class",t[s]))}return i}(0,o.K2)(b,"getGroup");for(const s of y){if(0===s.data.length)continue;const t=b(s.groupTexts);switch(s.type){case"rect":if(t.selectAll("rect").data(s.data).enter().append("rect").attr("x",t=>t.x).attr("y",t=>t.y).attr("width",t=>t.width).attr("height",t=>t.height).attr("fill",t=>t.fill).attr("stroke",t=>t.strokeFill).attr("stroke-width",t=>t.strokeWidth),l.showDataLabel)if("horizontal"===l.chartOrientation){let i=function(t,i){const{data:s,label:a}=t;return i*a.length*e<=s.width-10};(0,o.K2)(i,"fitsHorizontally");const e=.7,a=s.data.map((t,i)=>({data:t,label:c[i].toString()})).filter(t=>t.data.width>0&&t.data.height>0),n=a.map(t=>{const{data:e}=t;let s=.7*e.height;for(;!i(t,s)&&s>0;)s-=1;return s}),h=Math.floor(Math.min(...n));t.selectAll("text").data(a).enter().append("text").attr("x",t=>t.data.x+t.data.width-10).attr("y",t=>t.data.y+t.data.height/2).attr("text-anchor","end").attr("dominant-baseline","middle").attr("fill","black").attr("font-size",`${h}px`).text(t=>t.label)}else{let i=function(t,i,e){const{data:s,label:a}=t,n=i*a.length*.7,h=s.x+s.width/2,o=h+n/2,r=h-n/2>=s.x&&o<=s.x+s.width,l=s.y+e+i<=s.y+s.height;return r&&l};(0,o.K2)(i,"fitsInBar");const e=10,a=s.data.map((t,i)=>({data:t,label:c[i].toString()})).filter(t=>t.data.width>0&&t.data.height>0),n=a.map(t=>{const{data:s,label:a}=t;let n=s.width/(.7*a.length);for(;!i(t,n,e)&&n>0;)n-=1;return n}),h=Math.floor(Math.min(...n));t.selectAll("text").data(a).enter().append("text").attr("x",t=>t.data.x+t.data.width/2).attr("y",t=>t.data.y+e).attr("text-anchor","middle").attr("dominant-baseline","hanging").attr("fill","black").attr("font-size",`${h}px`).text(t=>t.label)}break;case"text":t.selectAll("text").data(s.data).enter().append("text").attr("x",0).attr("y",0).attr("fill",t=>t.fill).attr("font-size",t=>t.fontSize).attr("dominant-baseline",t=>g(t.verticalPos)).attr("text-anchor",t=>u(t.horizontalPos)).attr("transform",t=>x(t)).text(t=>t.text);break;case"path":t.selectAll("path").data(s.data).enter().append("path").attr("d",t=>t.path).attr("fill",t=>t.fill?t.fill:"none").attr("stroke",t=>t.strokeFill).attr("stroke-width",t=>t.strokeWidth)}}},"draw")}}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/5996.cdc792ad.js b/pr-preview/pr-4027/assets/js/5996.cdc792ad.js deleted file mode 100644 index 64348df3b..000000000 --- a/pr-preview/pr-4027/assets/js/5996.cdc792ad.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5996],{697:(t,e,r)=>{r.d(e,{T:()=>a.T});var a=r(37981)},37981:(t,e,r)=>{r.d(e,{T:()=>f});var a=r(39142),s=r(89610),i=r(27422),n=r(94092),o=r(66401),l=r(8058),c=r(69592),d=r(13588),h=r(24326),g=r(99902),u=r(53533);const p=(0,h.A)(function(t){return(0,g.A)((0,d.A)(t,1,u.A,!0))});var y=r(38207),b=r(89463),x="\0";class f{constructor(t={}){this._isDirected=!Object.prototype.hasOwnProperty.call(t,"directed")||t.directed,this._isMultigraph=!!Object.prototype.hasOwnProperty.call(t,"multigraph")&&t.multigraph,this._isCompound=!!Object.prototype.hasOwnProperty.call(t,"compound")&&t.compound,this._label=void 0,this._defaultNodeLabelFn=a.A(void 0),this._defaultEdgeLabelFn=a.A(void 0),this._nodes={},this._isCompound&&(this._parent={},this._children={},this._children[x]={}),this._in={},this._preds={},this._out={},this._sucs={},this._edgeObjs={},this._edgeLabels={}}isDirected(){return this._isDirected}isMultigraph(){return this._isMultigraph}isCompound(){return this._isCompound}setGraph(t){return this._label=t,this}graph(){return this._label}setDefaultNodeLabel(t){return s.A(t)||(t=a.A(t)),this._defaultNodeLabelFn=t,this}nodeCount(){return this._nodeCount}nodes(){return i.A(this._nodes)}sources(){var t=this;return n.A(this.nodes(),function(e){return o.A(t._in[e])})}sinks(){var t=this;return n.A(this.nodes(),function(e){return o.A(t._out[e])})}setNodes(t,e){var r=arguments,a=this;return l.A(t,function(t){r.length>1?a.setNode(t,e):a.setNode(t)}),this}setNode(t,e){return Object.prototype.hasOwnProperty.call(this._nodes,t)?(arguments.length>1&&(this._nodes[t]=e),this):(this._nodes[t]=arguments.length>1?e:this._defaultNodeLabelFn(t),this._isCompound&&(this._parent[t]=x,this._children[t]={},this._children[x][t]=!0),this._in[t]={},this._preds[t]={},this._out[t]={},this._sucs[t]={},++this._nodeCount,this)}node(t){return this._nodes[t]}hasNode(t){return Object.prototype.hasOwnProperty.call(this._nodes,t)}removeNode(t){if(Object.prototype.hasOwnProperty.call(this._nodes,t)){var e=t=>this.removeEdge(this._edgeObjs[t]);delete this._nodes[t],this._isCompound&&(this._removeFromParentsChildList(t),delete this._parent[t],l.A(this.children(t),t=>{this.setParent(t)}),delete this._children[t]),l.A(i.A(this._in[t]),e),delete this._in[t],delete this._preds[t],l.A(i.A(this._out[t]),e),delete this._out[t],delete this._sucs[t],--this._nodeCount}return this}setParent(t,e){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(c.A(e))e=x;else{for(var r=e+="";!c.A(r);r=this.parent(r))if(r===t)throw new Error("Setting "+e+" as parent of "+t+" would create a cycle");this.setNode(e)}return this.setNode(t),this._removeFromParentsChildList(t),this._parent[t]=e,this._children[e][t]=!0,this}_removeFromParentsChildList(t){delete this._children[this._parent[t]][t]}parent(t){if(this._isCompound){var e=this._parent[t];if(e!==x)return e}}children(t){if(c.A(t)&&(t=x),this._isCompound){var e=this._children[t];if(e)return i.A(e)}else{if(t===x)return this.nodes();if(this.hasNode(t))return[]}}predecessors(t){var e=this._preds[t];if(e)return i.A(e)}successors(t){var e=this._sucs[t];if(e)return i.A(e)}neighbors(t){var e=this.predecessors(t);if(e)return p(e,this.successors(t))}isLeaf(t){return 0===(this.isDirected()?this.successors(t):this.neighbors(t)).length}filterNodes(t){var e=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});e.setGraph(this.graph());var r=this;l.A(this._nodes,function(r,a){t(a)&&e.setNode(a,r)}),l.A(this._edgeObjs,function(t){e.hasNode(t.v)&&e.hasNode(t.w)&&e.setEdge(t,r.edge(t))});var a={};function s(t){var i=r.parent(t);return void 0===i||e.hasNode(i)?(a[t]=i,i):i in a?a[i]:s(i)}return this._isCompound&&l.A(e.nodes(),function(t){e.setParent(t,s(t))}),e}setDefaultEdgeLabel(t){return s.A(t)||(t=a.A(t)),this._defaultEdgeLabelFn=t,this}edgeCount(){return this._edgeCount}edges(){return y.A(this._edgeObjs)}setPath(t,e){var r=this,a=arguments;return b.A(t,function(t,s){return a.length>1?r.setEdge(t,s,e):r.setEdge(t,s),s}),this}setEdge(){var t,e,r,a,s=!1,i=arguments[0];"object"==typeof i&&null!==i&&"v"in i?(t=i.v,e=i.w,r=i.name,2===arguments.length&&(a=arguments[1],s=!0)):(t=i,e=arguments[1],r=arguments[3],arguments.length>2&&(a=arguments[2],s=!0)),t=""+t,e=""+e,c.A(r)||(r=""+r);var n=_(this._isDirected,t,e,r);if(Object.prototype.hasOwnProperty.call(this._edgeLabels,n))return s&&(this._edgeLabels[n]=a),this;if(!c.A(r)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(t),this.setNode(e),this._edgeLabels[n]=s?a:this._defaultEdgeLabelFn(t,e,r);var o=function(t,e,r,a){var s=""+e,i=""+r;if(!t&&s>i){var n=s;s=i,i=n}var o={v:s,w:i};a&&(o.name=a);return o}(this._isDirected,t,e,r);return t=o.v,e=o.w,Object.freeze(o),this._edgeObjs[n]=o,m(this._preds[e],t),m(this._sucs[t],e),this._in[e][n]=o,this._out[t][n]=o,this._edgeCount++,this}edge(t,e,r){var a=1===arguments.length?L(this._isDirected,arguments[0]):_(this._isDirected,t,e,r);return this._edgeLabels[a]}hasEdge(t,e,r){var a=1===arguments.length?L(this._isDirected,arguments[0]):_(this._isDirected,t,e,r);return Object.prototype.hasOwnProperty.call(this._edgeLabels,a)}removeEdge(t,e,r){var a=1===arguments.length?L(this._isDirected,arguments[0]):_(this._isDirected,t,e,r),s=this._edgeObjs[a];return s&&(t=s.v,e=s.w,delete this._edgeLabels[a],delete this._edgeObjs[a],w(this._preds[e],t),w(this._sucs[t],e),delete this._in[e][a],delete this._out[t][a],this._edgeCount--),this}inEdges(t,e){var r=this._in[t];if(r){var a=y.A(r);return e?n.A(a,function(t){return t.v===e}):a}}outEdges(t,e){var r=this._out[t];if(r){var a=y.A(r);return e?n.A(a,function(t){return t.w===e}):a}}nodeEdges(t,e){var r=this.inEdges(t,e);if(r)return r.concat(this.outEdges(t,e))}}function m(t,e){t[e]?t[e]++:t[e]=1}function w(t,e){--t[e]||delete t[e]}function _(t,e,r,a){var s=""+e,i=""+r;if(!t&&s>i){var n=s;s=i,i=n}return s+"\x01"+i+"\x01"+(c.A(a)?"\0":a)}function L(t,e){return _(t,e.v,e.w,e.name)}f.prototype._nodeCount=0,f.prototype._edgeCount=0},50053:(t,e,r)=>{r.d(e,{A:()=>s});var a=r(68675);const s=function(t){return(0,a.A)(t,4)}},52501:(t,e,r)=>{r.d(e,{o:()=>a});var a=(0,r(40797).K2)(()=>"\n /* Font Awesome icon styling - consolidated */\n .label-icon {\n display: inline-block;\n height: 1em;\n overflow: visible;\n vertical-align: -0.125em;\n }\n \n .node .label-icon path {\n fill: currentColor;\n stroke: revert;\n stroke-width: revert;\n }\n","getIconStyles")},65996:(t,e,r)=>{r.d(e,{diagram:()=>we});var a=r(52501),s=r(28698),i=r(63245),n=r(30092),o=r(13226),l=r(67633),c=r(40797),d=r(50053),h=r(25582),g=r(75937),u=r(70451),p=r(697),y=function(){var t=(0,c.K2)(function(t,e,r,a){for(r=r||{},a=t.length;a--;r[t[a]]=e);return r},"o"),e=[1,15],r=[1,7],a=[1,13],s=[1,14],i=[1,19],n=[1,16],o=[1,17],l=[1,18],d=[8,30],h=[8,10,21,28,29,30,31,39,43,46],g=[1,23],u=[1,24],p=[8,10,15,16,21,28,29,30,31,39,43,46],y=[8,10,15,16,21,27,28,29,30,31,39,43,46],b=[1,49],x={trace:(0,c.K2)(function(){},"trace"),yy:{},symbols_:{error:2,spaceLines:3,SPACELINE:4,NL:5,separator:6,SPACE:7,EOF:8,start:9,BLOCK_DIAGRAM_KEY:10,document:11,stop:12,statement:13,link:14,LINK:15,START_LINK:16,LINK_LABEL:17,STR:18,nodeStatement:19,columnsStatement:20,SPACE_BLOCK:21,blockStatement:22,classDefStatement:23,cssClassStatement:24,styleStatement:25,node:26,SIZE:27,COLUMNS:28,"id-block":29,end:30,NODE_ID:31,nodeShapeNLabel:32,dirList:33,DIR:34,NODE_DSTART:35,NODE_DEND:36,BLOCK_ARROW_START:37,BLOCK_ARROW_END:38,classDef:39,CLASSDEF_ID:40,CLASSDEF_STYLEOPTS:41,DEFAULT:42,class:43,CLASSENTITY_IDS:44,STYLECLASS:45,style:46,STYLE_ENTITY_IDS:47,STYLE_DEFINITION_DATA:48,$accept:0,$end:1},terminals_:{2:"error",4:"SPACELINE",5:"NL",7:"SPACE",8:"EOF",10:"BLOCK_DIAGRAM_KEY",15:"LINK",16:"START_LINK",17:"LINK_LABEL",18:"STR",21:"SPACE_BLOCK",27:"SIZE",28:"COLUMNS",29:"id-block",30:"end",31:"NODE_ID",34:"DIR",35:"NODE_DSTART",36:"NODE_DEND",37:"BLOCK_ARROW_START",38:"BLOCK_ARROW_END",39:"classDef",40:"CLASSDEF_ID",41:"CLASSDEF_STYLEOPTS",42:"DEFAULT",43:"class",44:"CLASSENTITY_IDS",45:"STYLECLASS",46:"style",47:"STYLE_ENTITY_IDS",48:"STYLE_DEFINITION_DATA"},productions_:[0,[3,1],[3,2],[3,2],[6,1],[6,1],[6,1],[9,3],[12,1],[12,1],[12,2],[12,2],[11,1],[11,2],[14,1],[14,4],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[19,3],[19,2],[19,1],[20,1],[22,4],[22,3],[26,1],[26,2],[33,1],[33,2],[32,3],[32,4],[23,3],[23,3],[24,3],[25,3]],performAction:(0,c.K2)(function(t,e,r,a,s,i,n){var o=i.length-1;switch(s){case 4:a.getLogger().debug("Rule: separator (NL) ");break;case 5:a.getLogger().debug("Rule: separator (Space) ");break;case 6:a.getLogger().debug("Rule: separator (EOF) ");break;case 7:a.getLogger().debug("Rule: hierarchy: ",i[o-1]),a.setHierarchy(i[o-1]);break;case 8:a.getLogger().debug("Stop NL ");break;case 9:a.getLogger().debug("Stop EOF ");break;case 10:a.getLogger().debug("Stop NL2 ");break;case 11:a.getLogger().debug("Stop EOF2 ");break;case 12:a.getLogger().debug("Rule: statement: ",i[o]),"number"==typeof i[o].length?this.$=i[o]:this.$=[i[o]];break;case 13:a.getLogger().debug("Rule: statement #2: ",i[o-1]),this.$=[i[o-1]].concat(i[o]);break;case 14:a.getLogger().debug("Rule: link: ",i[o],t),this.$={edgeTypeStr:i[o],label:""};break;case 15:a.getLogger().debug("Rule: LABEL link: ",i[o-3],i[o-1],i[o]),this.$={edgeTypeStr:i[o],label:i[o-1]};break;case 18:const e=parseInt(i[o]),r=a.generateId();this.$={id:r,type:"space",label:"",width:e,children:[]};break;case 23:a.getLogger().debug("Rule: (nodeStatement link node) ",i[o-2],i[o-1],i[o]," typestr: ",i[o-1].edgeTypeStr);const s=a.edgeStrToEdgeData(i[o-1].edgeTypeStr);this.$=[{id:i[o-2].id,label:i[o-2].label,type:i[o-2].type,directions:i[o-2].directions},{id:i[o-2].id+"-"+i[o].id,start:i[o-2].id,end:i[o].id,label:i[o-1].label,type:"edge",directions:i[o].directions,arrowTypeEnd:s,arrowTypeStart:"arrow_open"},{id:i[o].id,label:i[o].label,type:a.typeStr2Type(i[o].typeStr),directions:i[o].directions}];break;case 24:a.getLogger().debug("Rule: nodeStatement (abc88 node size) ",i[o-1],i[o]),this.$={id:i[o-1].id,label:i[o-1].label,type:a.typeStr2Type(i[o-1].typeStr),directions:i[o-1].directions,widthInColumns:parseInt(i[o],10)};break;case 25:a.getLogger().debug("Rule: nodeStatement (node) ",i[o]),this.$={id:i[o].id,label:i[o].label,type:a.typeStr2Type(i[o].typeStr),directions:i[o].directions,widthInColumns:1};break;case 26:a.getLogger().debug("APA123",this?this:"na"),a.getLogger().debug("COLUMNS: ",i[o]),this.$={type:"column-setting",columns:"auto"===i[o]?-1:parseInt(i[o])};break;case 27:a.getLogger().debug("Rule: id-block statement : ",i[o-2],i[o-1]);a.generateId();this.$={...i[o-2],type:"composite",children:i[o-1]};break;case 28:a.getLogger().debug("Rule: blockStatement : ",i[o-2],i[o-1],i[o]);const n=a.generateId();this.$={id:n,type:"composite",label:"",children:i[o-1]};break;case 29:a.getLogger().debug("Rule: node (NODE_ID separator): ",i[o]),this.$={id:i[o]};break;case 30:a.getLogger().debug("Rule: node (NODE_ID nodeShapeNLabel separator): ",i[o-1],i[o]),this.$={id:i[o-1],label:i[o].label,typeStr:i[o].typeStr,directions:i[o].directions};break;case 31:a.getLogger().debug("Rule: dirList: ",i[o]),this.$=[i[o]];break;case 32:a.getLogger().debug("Rule: dirList: ",i[o-1],i[o]),this.$=[i[o-1]].concat(i[o]);break;case 33:a.getLogger().debug("Rule: nodeShapeNLabel: ",i[o-2],i[o-1],i[o]),this.$={typeStr:i[o-2]+i[o],label:i[o-1]};break;case 34:a.getLogger().debug("Rule: BLOCK_ARROW nodeShapeNLabel: ",i[o-3],i[o-2]," #3:",i[o-1],i[o]),this.$={typeStr:i[o-3]+i[o],label:i[o-2],directions:i[o-1]};break;case 35:case 36:this.$={type:"classDef",id:i[o-1].trim(),css:i[o].trim()};break;case 37:this.$={type:"applyClass",id:i[o-1].trim(),styleClass:i[o].trim()};break;case 38:this.$={type:"applyStyles",id:i[o-1].trim(),stylesStr:i[o].trim()}}},"anonymous"),table:[{9:1,10:[1,2]},{1:[3]},{10:e,11:3,13:4,19:5,20:6,21:r,22:8,23:9,24:10,25:11,26:12,28:a,29:s,31:i,39:n,43:o,46:l},{8:[1,20]},t(d,[2,12],{13:4,19:5,20:6,22:8,23:9,24:10,25:11,26:12,11:21,10:e,21:r,28:a,29:s,31:i,39:n,43:o,46:l}),t(h,[2,16],{14:22,15:g,16:u}),t(h,[2,17]),t(h,[2,18]),t(h,[2,19]),t(h,[2,20]),t(h,[2,21]),t(h,[2,22]),t(p,[2,25],{27:[1,25]}),t(h,[2,26]),{19:26,26:12,31:i},{10:e,11:27,13:4,19:5,20:6,21:r,22:8,23:9,24:10,25:11,26:12,28:a,29:s,31:i,39:n,43:o,46:l},{40:[1,28],42:[1,29]},{44:[1,30]},{47:[1,31]},t(y,[2,29],{32:32,35:[1,33],37:[1,34]}),{1:[2,7]},t(d,[2,13]),{26:35,31:i},{31:[2,14]},{17:[1,36]},t(p,[2,24]),{10:e,11:37,13:4,14:22,15:g,16:u,19:5,20:6,21:r,22:8,23:9,24:10,25:11,26:12,28:a,29:s,31:i,39:n,43:o,46:l},{30:[1,38]},{41:[1,39]},{41:[1,40]},{45:[1,41]},{48:[1,42]},t(y,[2,30]),{18:[1,43]},{18:[1,44]},t(p,[2,23]),{18:[1,45]},{30:[1,46]},t(h,[2,28]),t(h,[2,35]),t(h,[2,36]),t(h,[2,37]),t(h,[2,38]),{36:[1,47]},{33:48,34:b},{15:[1,50]},t(h,[2,27]),t(y,[2,33]),{38:[1,51]},{33:52,34:b,38:[2,31]},{31:[2,15]},t(y,[2,34]),{38:[2,32]}],defaultActions:{20:[2,7],23:[2,14],50:[2,15],52:[2,32]},parseError:(0,c.K2)(function(t,e){if(!e.recoverable){var r=new Error(t);throw r.hash=e,r}this.trace(t)},"parseError"),parse:(0,c.K2)(function(t){var e=this,r=[0],a=[],s=[null],i=[],n=this.table,o="",l=0,d=0,h=0,g=i.slice.call(arguments,1),u=Object.create(this.lexer),p={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(p.yy[y]=this.yy[y]);u.setInput(t,p.yy),p.yy.lexer=u,p.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var b=u.yylloc;i.push(b);var x=u.options&&u.options.ranges;function f(){var t;return"number"!=typeof(t=a.pop()||u.lex()||1)&&(t instanceof Array&&(t=(a=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,c.K2)(function(t){r.length=r.length-2*t,s.length=s.length-t,i.length=i.length-t},"popStack"),(0,c.K2)(f,"lex");for(var m,w,_,L,k,S,v,E,D,C={};;){if(_=r[r.length-1],this.defaultActions[_]?L=this.defaultActions[_]:(null==m&&(m=f()),L=n[_]&&n[_][m]),void 0===L||!L.length||!L[0]){var R="";for(S in D=[],n[_])this.terminals_[S]&&S>2&&D.push("'"+this.terminals_[S]+"'");R=u.showPosition?"Parse error on line "+(l+1)+":\n"+u.showPosition()+"\nExpecting "+D.join(", ")+", got '"+(this.terminals_[m]||m)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==m?"end of input":"'"+(this.terminals_[m]||m)+"'"),this.parseError(R,{text:u.match,token:this.terminals_[m]||m,line:u.yylineno,loc:b,expected:D})}if(L[0]instanceof Array&&L.length>1)throw new Error("Parse Error: multiple actions possible at state: "+_+", token: "+m);switch(L[0]){case 1:r.push(m),s.push(u.yytext),i.push(u.yylloc),r.push(L[1]),m=null,w?(m=w,w=null):(d=u.yyleng,o=u.yytext,l=u.yylineno,b=u.yylloc,h>0&&h--);break;case 2:if(v=this.productions_[L[1]][1],C.$=s[s.length-v],C._$={first_line:i[i.length-(v||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(v||1)].first_column,last_column:i[i.length-1].last_column},x&&(C._$.range=[i[i.length-(v||1)].range[0],i[i.length-1].range[1]]),void 0!==(k=this.performAction.apply(C,[o,d,l,p.yy,L[1],s,i].concat(g))))return k;v&&(r=r.slice(0,-1*v*2),s=s.slice(0,-1*v),i=i.slice(0,-1*v)),r.push(this.productions_[L[1]][0]),s.push(C.$),i.push(C._$),E=n[r[r.length-2]][r[r.length-1]],r.push(E);break;case 3:return!0}}return!0},"parse")},f=function(){return{EOF:1,parseError:(0,c.K2)(function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},"parseError"),setInput:(0,c.K2)(function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:(0,c.K2)(function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},"input"),unput:(0,c.K2)(function(t){var e=t.length,r=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var a=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),r.length-1&&(this.yylineno-=r.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:r?(r.length===a.length?this.yylloc.first_column:0)+a[a.length-r.length].length-r[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},"unput"),more:(0,c.K2)(function(){return this._more=!0,this},"more"),reject:(0,c.K2)(function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"reject"),less:(0,c.K2)(function(t){this.unput(this.match.slice(t))},"less"),pastInput:(0,c.K2)(function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:(0,c.K2)(function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:(0,c.K2)(function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},"showPosition"),test_match:(0,c.K2)(function(t,e){var r,a,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(a=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=a.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:a?a[a.length-1].length-a[a.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],r=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),r)return r;if(this._backtrack){for(var i in s)this[i]=s[i];return!1}return!1},"test_match"),next:(0,c.K2)(function(){if(this.done)return this.EOF;var t,e,r,a;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),i=0;i<s.length;i++)if((r=this._input.match(this.rules[s[i]]))&&(!e||r[0].length>e[0].length)){if(e=r,a=i,this.options.backtrack_lexer){if(!1!==(t=this.test_match(r,s[i])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[a]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:(0,c.K2)(function(){var t=this.next();return t||this.lex()},"lex"),begin:(0,c.K2)(function(t){this.conditionStack.push(t)},"begin"),popState:(0,c.K2)(function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:(0,c.K2)(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:(0,c.K2)(function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},"topState"),pushState:(0,c.K2)(function(t){this.begin(t)},"pushState"),stateStackSize:(0,c.K2)(function(){return this.conditionStack.length},"stateStackSize"),options:{},performAction:(0,c.K2)(function(t,e,r,a){switch(r){case 0:return t.getLogger().debug("Found block-beta"),10;case 1:return t.getLogger().debug("Found id-block"),29;case 2:return t.getLogger().debug("Found block"),10;case 3:t.getLogger().debug(".",e.yytext);break;case 4:t.getLogger().debug("_",e.yytext);break;case 5:return 5;case 6:return e.yytext=-1,28;case 7:return e.yytext=e.yytext.replace(/columns\s+/,""),t.getLogger().debug("COLUMNS (LEX)",e.yytext),28;case 8:case 76:case 77:case 99:this.pushState("md_string");break;case 9:return"MD_STR";case 10:case 34:case 79:this.popState();break;case 11:this.pushState("string");break;case 12:t.getLogger().debug("LEX: POPPING STR:",e.yytext),this.popState();break;case 13:return t.getLogger().debug("LEX: STR end:",e.yytext),"STR";case 14:return e.yytext=e.yytext.replace(/space\:/,""),t.getLogger().debug("SPACE NUM (LEX)",e.yytext),21;case 15:return e.yytext="1",t.getLogger().debug("COLUMNS (LEX)",e.yytext),21;case 16:return 42;case 17:return"LINKSTYLE";case 18:return"INTERPOLATE";case 19:return this.pushState("CLASSDEF"),39;case 20:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";case 21:return this.popState(),this.pushState("CLASSDEFID"),40;case 22:return this.popState(),41;case 23:return this.pushState("CLASS"),43;case 24:return this.popState(),this.pushState("CLASS_STYLE"),44;case 25:return this.popState(),45;case 26:return this.pushState("STYLE_STMNT"),46;case 27:return this.popState(),this.pushState("STYLE_DEFINITION"),47;case 28:return this.popState(),48;case 29:return this.pushState("acc_title"),"acc_title";case 30:return this.popState(),"acc_title_value";case 31:return this.pushState("acc_descr"),"acc_descr";case 32:return this.popState(),"acc_descr_value";case 33:this.pushState("acc_descr_multiline");break;case 35:return"acc_descr_multiline_value";case 36:return 30;case 37:case 38:case 40:case 41:case 44:return this.popState(),t.getLogger().debug("Lex: (("),"NODE_DEND";case 39:return this.popState(),t.getLogger().debug("Lex: ))"),"NODE_DEND";case 42:return this.popState(),t.getLogger().debug("Lex: (-"),"NODE_DEND";case 43:return this.popState(),t.getLogger().debug("Lex: -)"),"NODE_DEND";case 45:return this.popState(),t.getLogger().debug("Lex: ]]"),"NODE_DEND";case 46:return this.popState(),t.getLogger().debug("Lex: ("),"NODE_DEND";case 47:return this.popState(),t.getLogger().debug("Lex: ])"),"NODE_DEND";case 48:case 49:return this.popState(),t.getLogger().debug("Lex: /]"),"NODE_DEND";case 50:return this.popState(),t.getLogger().debug("Lex: )]"),"NODE_DEND";case 51:return this.popState(),t.getLogger().debug("Lex: )"),"NODE_DEND";case 52:return this.popState(),t.getLogger().debug("Lex: ]>"),"NODE_DEND";case 53:return this.popState(),t.getLogger().debug("Lex: ]"),"NODE_DEND";case 54:return t.getLogger().debug("Lexa: -)"),this.pushState("NODE"),35;case 55:return t.getLogger().debug("Lexa: (-"),this.pushState("NODE"),35;case 56:return t.getLogger().debug("Lexa: ))"),this.pushState("NODE"),35;case 57:case 59:case 60:case 61:case 64:return t.getLogger().debug("Lexa: )"),this.pushState("NODE"),35;case 58:return t.getLogger().debug("Lex: ((("),this.pushState("NODE"),35;case 62:return t.getLogger().debug("Lexc: >"),this.pushState("NODE"),35;case 63:return t.getLogger().debug("Lexa: (["),this.pushState("NODE"),35;case 65:case 66:case 67:case 68:case 69:case 70:case 71:return this.pushState("NODE"),35;case 72:return t.getLogger().debug("Lexa: ["),this.pushState("NODE"),35;case 73:return this.pushState("BLOCK_ARROW"),t.getLogger().debug("LEX ARR START"),37;case 74:return t.getLogger().debug("Lex: NODE_ID",e.yytext),31;case 75:return t.getLogger().debug("Lex: EOF",e.yytext),8;case 78:return"NODE_DESCR";case 80:t.getLogger().debug("Lex: Starting string"),this.pushState("string");break;case 81:t.getLogger().debug("LEX ARR: Starting string"),this.pushState("string");break;case 82:return t.getLogger().debug("LEX: NODE_DESCR:",e.yytext),"NODE_DESCR";case 83:t.getLogger().debug("LEX POPPING"),this.popState();break;case 84:t.getLogger().debug("Lex: =>BAE"),this.pushState("ARROW_DIR");break;case 85:return e.yytext=e.yytext.replace(/^,\s*/,""),t.getLogger().debug("Lex (right): dir:",e.yytext),"DIR";case 86:return e.yytext=e.yytext.replace(/^,\s*/,""),t.getLogger().debug("Lex (left):",e.yytext),"DIR";case 87:return e.yytext=e.yytext.replace(/^,\s*/,""),t.getLogger().debug("Lex (x):",e.yytext),"DIR";case 88:return e.yytext=e.yytext.replace(/^,\s*/,""),t.getLogger().debug("Lex (y):",e.yytext),"DIR";case 89:return e.yytext=e.yytext.replace(/^,\s*/,""),t.getLogger().debug("Lex (up):",e.yytext),"DIR";case 90:return e.yytext=e.yytext.replace(/^,\s*/,""),t.getLogger().debug("Lex (down):",e.yytext),"DIR";case 91:return e.yytext="]>",t.getLogger().debug("Lex (ARROW_DIR end):",e.yytext),this.popState(),this.popState(),"BLOCK_ARROW_END";case 92:return t.getLogger().debug("Lex: LINK","#"+e.yytext+"#"),15;case 93:case 94:case 95:return t.getLogger().debug("Lex: LINK",e.yytext),15;case 96:case 97:case 98:return t.getLogger().debug("Lex: START_LINK",e.yytext),this.pushState("LLABEL"),16;case 100:return t.getLogger().debug("Lex: Starting string"),this.pushState("string"),"LINK_LABEL";case 101:return this.popState(),t.getLogger().debug("Lex: LINK","#"+e.yytext+"#"),15;case 102:case 103:return this.popState(),t.getLogger().debug("Lex: LINK",e.yytext),15;case 104:return t.getLogger().debug("Lex: COLON",e.yytext),e.yytext=e.yytext.slice(1),27}},"anonymous"),rules:[/^(?:block-beta\b)/,/^(?:block:)/,/^(?:block\b)/,/^(?:[\s]+)/,/^(?:[\n]+)/,/^(?:((\u000D\u000A)|(\u000A)))/,/^(?:columns\s+auto\b)/,/^(?:columns\s+[\d]+)/,/^(?:["][`])/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:space[:]\d+)/,/^(?:space\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\s+)/,/^(?:DEFAULT\s+)/,/^(?:\w+\s+)/,/^(?:[^\n]*)/,/^(?:class\s+)/,/^(?:(\w+)+((,\s*\w+)*))/,/^(?:[^\n]*)/,/^(?:style\s+)/,/^(?:(\w+)+((,\s*\w+)*))/,/^(?:[^\n]*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:end\b\s*)/,/^(?:\(\(\()/,/^(?:\)\)\))/,/^(?:[\)]\))/,/^(?:\}\})/,/^(?:\})/,/^(?:\(-)/,/^(?:-\))/,/^(?:\(\()/,/^(?:\]\])/,/^(?:\()/,/^(?:\]\))/,/^(?:\\\])/,/^(?:\/\])/,/^(?:\)\])/,/^(?:[\)])/,/^(?:\]>)/,/^(?:[\]])/,/^(?:-\))/,/^(?:\(-)/,/^(?:\)\))/,/^(?:\))/,/^(?:\(\(\()/,/^(?:\(\()/,/^(?:\{\{)/,/^(?:\{)/,/^(?:>)/,/^(?:\(\[)/,/^(?:\()/,/^(?:\[\[)/,/^(?:\[\|)/,/^(?:\[\()/,/^(?:\)\)\))/,/^(?:\[\\)/,/^(?:\[\/)/,/^(?:\[\\)/,/^(?:\[)/,/^(?:<\[)/,/^(?:[^\(\[\n\-\)\{\}\s\<\>:]+)/,/^(?:$)/,/^(?:["][`])/,/^(?:["][`])/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["])/,/^(?:["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:\]>\s*\()/,/^(?:,?\s*right\s*)/,/^(?:,?\s*left\s*)/,/^(?:,?\s*x\s*)/,/^(?:,?\s*y\s*)/,/^(?:,?\s*up\s*)/,/^(?:,?\s*down\s*)/,/^(?:\)\s*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*~~[\~]+\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:["][`])/,/^(?:["])/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?::\d+)/],conditions:{STYLE_DEFINITION:{rules:[28],inclusive:!1},STYLE_STMNT:{rules:[27],inclusive:!1},CLASSDEFID:{rules:[22],inclusive:!1},CLASSDEF:{rules:[20,21],inclusive:!1},CLASS_STYLE:{rules:[25],inclusive:!1},CLASS:{rules:[24],inclusive:!1},LLABEL:{rules:[99,100,101,102,103],inclusive:!1},ARROW_DIR:{rules:[85,86,87,88,89,90,91],inclusive:!1},BLOCK_ARROW:{rules:[76,81,84],inclusive:!1},NODE:{rules:[37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,77,80],inclusive:!1},md_string:{rules:[9,10,78,79],inclusive:!1},space:{rules:[],inclusive:!1},string:{rules:[12,13,82,83],inclusive:!1},acc_descr_multiline:{rules:[34,35],inclusive:!1},acc_descr:{rules:[32],inclusive:!1},acc_title:{rules:[30],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,11,14,15,16,17,18,19,23,26,29,31,33,36,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,92,93,94,95,96,97,98,104],inclusive:!0}}}}();function m(){this.yy={}}return x.lexer=f,(0,c.K2)(m,"Parser"),m.prototype=x,x.Parser=m,new m}();y.parser=y;var b=y,x=new Map,f=[],m=new Map,w="color",_="fill",L=(0,l.D7)(),k=new Map,S=(0,c.K2)(t=>l.Y2.sanitizeText(t,L),"sanitizeText"),v=(0,c.K2)(function(t,e=""){let r=k.get(t);r||(r={id:t,styles:[],textStyles:[]},k.set(t,r)),null!=e&&e.split(",").forEach(t=>{const e=t.replace(/([^;]*);/,"$1").trim();if(RegExp(w).exec(t)){const t=e.replace(_,"bgFill").replace(w,_);r.textStyles.push(t)}r.styles.push(e)})},"addStyleClass"),E=(0,c.K2)(function(t,e=""){const r=x.get(t);null!=e&&(r.styles=e.split(","))},"addStyle2Node"),D=(0,c.K2)(function(t,e){t.split(",").forEach(function(t){let r=x.get(t);if(void 0===r){const e=t.trim();r={id:e,type:"na",children:[]},x.set(e,r)}r.classes||(r.classes=[]),r.classes.push(e)})},"setCssClass"),C=(0,c.K2)((t,e)=>{const r=t.flat(),a=[],s=r.find(t=>"column-setting"===t?.type),i=s?.columns??-1;for(const n of r)if("number"==typeof i&&i>0&&"column-setting"!==n.type&&"number"==typeof n.widthInColumns&&n.widthInColumns>i&&c.Rm.warn(`Block ${n.id} width ${n.widthInColumns} exceeds configured column width ${i}`),n.label&&(n.label=S(n.label)),"classDef"!==n.type)if("applyClass"!==n.type)if("applyStyles"!==n.type)if("column-setting"===n.type)e.columns=n.columns??-1;else if("edge"===n.type){const t=(m.get(n.id)??0)+1;m.set(n.id,t),n.id=t+"-"+n.id,f.push(n)}else{n.label||("composite"===n.type?n.label="":n.label=n.id);const t=x.get(n.id);if(void 0===t?x.set(n.id,n):("na"!==n.type&&(t.type=n.type),n.label!==n.id&&(t.label=n.label)),n.children&&C(n.children,n),"space"===n.type){const t=n.width??1;for(let e=0;e<t;e++){const t=(0,d.A)(n);t.id=t.id+"-"+e,x.set(t.id,t),a.push(t)}}else void 0===t&&a.push(n)}else n?.stylesStr&&E(n.id,n?.stylesStr);else D(n.id,n?.styleClass??"");else v(n.id,n.css);e.children=a},"populateBlockDatabase"),R=[],K={id:"root",type:"composite",children:[],columns:-1},$=(0,c.K2)(()=>{c.Rm.debug("Clear called"),(0,l.IU)(),K={id:"root",type:"composite",children:[],columns:-1},x=new Map([["root",K]]),R=[],k=new Map,f=[],m=new Map},"clear");function N(t){switch(c.Rm.debug("typeStr2Type",t),t){case"[]":return"square";case"()":return c.Rm.debug("we have a round"),"round";case"(())":return"circle";case">]":return"rect_left_inv_arrow";case"{}":return"diamond";case"{{}}":return"hexagon";case"([])":return"stadium";case"[[]]":return"subroutine";case"[()]":return"cylinder";case"((()))":return"doublecircle";case"[//]":return"lean_right";case"[\\\\]":return"lean_left";case"[/\\]":return"trapezoid";case"[\\/]":return"inv_trapezoid";case"<[]>":return"block_arrow";default:return"na"}}function T(t){return c.Rm.debug("typeStr2Type",t),"=="===t?"thick":"normal"}function A(t){switch(t.replace(/^[\s-]+|[\s-]+$/g,"")){case"x":return"arrow_cross";case"o":return"arrow_circle";case">":return"arrow_point";default:return""}}(0,c.K2)(N,"typeStr2Type"),(0,c.K2)(T,"edgeTypeStr2Type"),(0,c.K2)(A,"edgeStrToEdgeData");var I=0,O=(0,c.K2)(()=>(I++,"id-"+Math.random().toString(36).substr(2,12)+"-"+I),"generateId"),B=(0,c.K2)(t=>{K.children=t,C(t,K),R=K.children},"setHierarchy"),z=(0,c.K2)(t=>{const e=x.get(t);return e?e.columns?e.columns:e.children?e.children.length:-1:-1},"getColumns"),M=(0,c.K2)(()=>[...x.values()],"getBlocksFlat"),P=(0,c.K2)(()=>R||[],"getBlocks"),Y=(0,c.K2)(()=>f,"getEdges"),F=(0,c.K2)(t=>x.get(t),"getBlock"),j=(0,c.K2)(t=>{x.set(t.id,t)},"setBlock"),W=(0,c.K2)(()=>c.Rm,"getLogger"),X=(0,c.K2)(function(){return k},"getClasses"),H={getConfig:(0,c.K2)(()=>(0,l.zj)().block,"getConfig"),typeStr2Type:N,edgeTypeStr2Type:T,edgeStrToEdgeData:A,getLogger:W,getBlocksFlat:M,getBlocks:P,getEdges:Y,setHierarchy:B,getBlock:F,setBlock:j,getColumns:z,getClasses:X,clear:$,generateId:O},U=(0,c.K2)((t,e)=>{const r=g.A,a=r(t,"r"),s=r(t,"g"),i=r(t,"b");return h.A(a,s,i,e)},"fade"),Z=(0,c.K2)(t=>`.label {\n font-family: ${t.fontFamily};\n color: ${t.nodeTextColor||t.textColor};\n }\n .cluster-label text {\n fill: ${t.titleColor};\n }\n .cluster-label span,p {\n color: ${t.titleColor};\n }\n\n\n\n .label text,span,p {\n fill: ${t.nodeTextColor||t.textColor};\n color: ${t.nodeTextColor||t.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n .flowchart-label text {\n text-anchor: middle;\n }\n // .flowchart-label .text-outer-tspan {\n // text-anchor: middle;\n // }\n // .flowchart-label .text-inner-tspan {\n // text-anchor: start;\n // }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${t.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${t.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${t.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${t.edgeLabelBackground};\n rect {\n opacity: 0.5;\n background-color: ${t.edgeLabelBackground};\n fill: ${t.edgeLabelBackground};\n }\n text-align: center;\n }\n\n /* For html labels only */\n .labelBkg {\n background-color: ${U(t.edgeLabelBackground,.5)};\n // background-color:\n }\n\n .node .cluster {\n // fill: ${U(t.mainBkg,.5)};\n fill: ${U(t.clusterBkg,.5)};\n stroke: ${U(t.clusterBorder,.2)};\n box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${t.titleColor};\n }\n\n .cluster span,p {\n color: ${t.titleColor};\n }\n /* .cluster div {\n color: ${t.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${t.fontFamily};\n font-size: 12px;\n background: ${t.tertiaryColor};\n border: 1px solid ${t.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n }\n ${(0,a.o)()}\n`,"getStyles"),q=(0,c.K2)((t,e,r,a)=>{e.forEach(e=>{G[e](t,r,a)})},"insertMarkers"),G={extension:(0,c.K2)((t,e,r)=>{c.Rm.trace("Making markers for ",r),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionStart").attr("class","marker extension "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionEnd").attr("class","marker extension "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")},"extension"),composition:(0,c.K2)((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionStart").attr("class","marker composition "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionEnd").attr("class","marker composition "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},"composition"),aggregation:(0,c.K2)((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationStart").attr("class","marker aggregation "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationEnd").attr("class","marker aggregation "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},"aggregation"),dependency:(0,c.K2)((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyStart").attr("class","marker dependency "+e).attr("refX",6).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyEnd").attr("class","marker dependency "+e).attr("refX",13).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},"dependency"),lollipop:(0,c.K2)((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopStart").attr("class","marker lollipop "+e).attr("refX",13).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6),t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopEnd").attr("class","marker lollipop "+e).attr("refX",1).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6)},"lollipop"),point:(0,c.K2)((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-pointEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",6).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-pointStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",4.5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},"point"),circle:(0,c.K2)((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-circleEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-circleStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},"circle"),cross:(0,c.K2)((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-crossEnd").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-crossStart").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")},"cross"),barb:(0,c.K2)((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","strokeWidth").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},"barb")},J=q,V=(0,l.D7)()?.block?.padding??8;function Q(t,e){if(0===t||!Number.isInteger(t))throw new Error("Columns must be an integer !== 0.");if(e<0||!Number.isInteger(e))throw new Error("Position must be a non-negative integer."+e);if(t<0)return{px:e,py:0};if(1===t)return{px:0,py:e};return{px:e%t,py:Math.floor(e/t)}}(0,c.K2)(Q,"calculateBlockPosition");var tt=(0,c.K2)(t=>{let e=0,r=0;for(const a of t.children){const{width:s,height:i,x:n,y:o}=a.size??{width:0,height:0,x:0,y:0};c.Rm.debug("getMaxChildSize abc95 child:",a.id,"width:",s,"height:",i,"x:",n,"y:",o,a.type),"space"!==a.type&&(s>e&&(e=s/(t.widthInColumns??1)),i>r&&(r=i))}return{width:e,height:r}},"getMaxChildSize");function et(t,e,r=0,a=0){c.Rm.debug("setBlockSizes abc95 (start)",t.id,t?.size?.x,"block width =",t?.size,"siblingWidth",r),t?.size?.width||(t.size={width:r,height:a,x:0,y:0});let s=0,i=0;if(t.children?.length>0){for(const r of t.children)et(r,e);const n=tt(t);s=n.width,i=n.height,c.Rm.debug("setBlockSizes abc95 maxWidth of",t.id,":s children is ",s,i);for(const e of t.children)e.size&&(c.Rm.debug(`abc95 Setting size of children of ${t.id} id=${e.id} ${s} ${i} ${JSON.stringify(e.size)}`),e.size.width=s*(e.widthInColumns??1)+V*((e.widthInColumns??1)-1),e.size.height=i,e.size.x=0,e.size.y=0,c.Rm.debug(`abc95 updating size of ${t.id} children child:${e.id} maxWidth:${s} maxHeight:${i}`));for(const r of t.children)et(r,e,s,i);const o=t.columns??-1;let l=0;for(const e of t.children)l+=e.widthInColumns??1;let d=t.children.length;o>0&&o<l&&(d=o);const h=Math.ceil(l/d);let g=d*(s+V)+V,u=h*(i+V)+V;if(g<r){c.Rm.debug(`Detected to small sibling: abc95 ${t.id} siblingWidth ${r} siblingHeight ${a} width ${g}`),g=r,u=a;const e=(r-d*V-V)/d,n=(a-h*V-V)/h;c.Rm.debug("Size indata abc88",t.id,"childWidth",e,"maxWidth",s),c.Rm.debug("Size indata abc88",t.id,"childHeight",n,"maxHeight",i),c.Rm.debug("Size indata abc88 xSize",d,"padding",V);for(const r of t.children)r.size&&(r.size.width=e,r.size.height=n,r.size.x=0,r.size.y=0)}if(c.Rm.debug(`abc95 (finale calc) ${t.id} xSize ${d} ySize ${h} columns ${o}${t.children.length} width=${Math.max(g,t.size?.width||0)}`),g<(t?.size?.width||0)){g=t?.size?.width||0;const e=o>0?Math.min(t.children.length,o):t.children.length;if(e>0){const r=(g-e*V-V)/e;c.Rm.debug("abc95 (growing to fit) width",t.id,g,t.size?.width,r);for(const e of t.children)e.size&&(e.size.width=r)}}t.size={width:g,height:u,x:0,y:0}}c.Rm.debug("setBlockSizes abc94 (done)",t.id,t?.size?.x,t?.size?.width,t?.size?.y,t?.size?.height)}function rt(t,e){c.Rm.debug(`abc85 layout blocks (=>layoutBlocks) ${t.id} x: ${t?.size?.x} y: ${t?.size?.y} width: ${t?.size?.width}`);const r=t.columns??-1;if(c.Rm.debug("layoutBlocks columns abc95",t.id,"=>",r,t),t.children&&t.children.length>0){const a=t?.children[0]?.size?.width??0,s=t.children.length*a+(t.children.length-1)*V;c.Rm.debug("widthOfChildren 88",s,"posX");let i=0;c.Rm.debug("abc91 block?.size?.x",t.id,t?.size?.x);let n=t?.size?.x?t?.size?.x+(-t?.size?.width/2||0):-V,o=0;for(const l of t.children){const a=t;if(!l.size)continue;const{width:s,height:d}=l.size,{px:h,py:g}=Q(r,i);if(g!=o&&(o=g,n=t?.size?.x?t?.size?.x+(-t?.size?.width/2||0):-V,c.Rm.debug("New row in layout for block",t.id," and child ",l.id,o)),c.Rm.debug(`abc89 layout blocks (child) id: ${l.id} Pos: ${i} (px, py) ${h},${g} (${a?.size?.x},${a?.size?.y}) parent: ${a.id} width: ${s}${V}`),a.size){const t=s/2;l.size.x=n+V+t,c.Rm.debug(`abc91 layout blocks (calc) px, pyid:${l.id} startingPos=X${n} new startingPosX${l.size.x} ${t} padding=${V} width=${s} halfWidth=${t} => x:${l.size.x} y:${l.size.y} ${l.widthInColumns} (width * (child?.w || 1)) / 2 ${s*(l?.widthInColumns??1)/2}`),n=l.size.x+t,l.size.y=a.size.y-a.size.height/2+g*(d+V)+d/2+V,c.Rm.debug(`abc88 layout blocks (calc) px, pyid:${l.id}startingPosX${n}${V}${t}=>x:${l.size.x}y:${l.size.y}${l.widthInColumns}(width * (child?.w || 1)) / 2${s*(l?.widthInColumns??1)/2}`)}l.children&&rt(l,e);let u=l?.widthInColumns??1;r>0&&(u=Math.min(u,r-i%r)),i+=u,c.Rm.debug("abc88 columnsPos",l,i)}}c.Rm.debug(`layout blocks (<==layoutBlocks) ${t.id} x: ${t?.size?.x} y: ${t?.size?.y} width: ${t?.size?.width}`)}function at(t,{minX:e,minY:r,maxX:a,maxY:s}={minX:0,minY:0,maxX:0,maxY:0}){if(t.size&&"root"!==t.id){const{x:i,y:n,width:o,height:l}=t.size;i-o/2<e&&(e=i-o/2),n-l/2<r&&(r=n-l/2),i+o/2>a&&(a=i+o/2),n+l/2>s&&(s=n+l/2)}if(t.children)for(const i of t.children)({minX:e,minY:r,maxX:a,maxY:s}=at(i,{minX:e,minY:r,maxX:a,maxY:s}));return{minX:e,minY:r,maxX:a,maxY:s}}function st(t){const e=t.getBlock("root");if(!e)return;et(e,t,0,0),rt(e,t),c.Rm.debug("getBlocks",JSON.stringify(e,null,2));const{minX:r,minY:a,maxX:s,maxY:i}=at(e);return{x:r,y:a,width:s-r,height:i-a}}function it(t,e){e&&t.attr("style",e)}function nt(t,e){const r=(0,u.Ltv)(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),a=r.append("xhtml:div"),s=t.label,i=t.isNode?"nodeLabel":"edgeLabel",n=a.append("span");return n.html((0,l.jZ)(s,e)),it(n,t.labelStyle),n.attr("class",i),it(a,t.labelStyle),a.style("display","inline-block"),a.style("white-space","nowrap"),a.attr("xmlns","http://www.w3.org/1999/xhtml"),r.node()}(0,c.K2)(et,"setBlockSizes"),(0,c.K2)(rt,"layoutBlocks"),(0,c.K2)(at,"findBounds"),(0,c.K2)(st,"layout"),(0,c.K2)(it,"applyStyle"),(0,c.K2)(nt,"addHtmlLabel");var ot=(0,c.K2)(async(t,e,r,a)=>{let s=t||"";"object"==typeof s&&(s=s[0]);const i=(0,l.D7)();if((0,l._3)(i.flowchart.htmlLabels)){s=s.replace(/\\n|\n/g,"<br />"),c.Rm.debug("vertexText"+s);return nt({isNode:a,label:await(0,n.hE)((0,o.Sm)(s)),labelStyle:e.replace("fill:","color:")},i)}{const t=document.createElementNS("http://www.w3.org/2000/svg","text");t.setAttribute("style",e.replace("color:","fill:"));let a=[];a="string"==typeof s?s.split(/\\n|\n|<br\s*\/?>/gi):Array.isArray(s)?s:[];for(const e of a){const a=document.createElementNS("http://www.w3.org/2000/svg","tspan");a.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),a.setAttribute("dy","1em"),a.setAttribute("x","0"),r?a.setAttribute("class","title-row"):a.setAttribute("class","row"),a.textContent=e.trim(),t.appendChild(a)}return t}},"createLabel"),lt=(0,c.K2)((t,e,r,a,s)=>{e.arrowTypeStart&&dt(t,"start",e.arrowTypeStart,r,a,s),e.arrowTypeEnd&&dt(t,"end",e.arrowTypeEnd,r,a,s)},"addEdgeMarkers"),ct={arrow_cross:"cross",arrow_point:"point",arrow_barb:"barb",arrow_circle:"circle",aggregation:"aggregation",extension:"extension",composition:"composition",dependency:"dependency",lollipop:"lollipop"},dt=(0,c.K2)((t,e,r,a,s,i)=>{const n=ct[r];if(!n)return void c.Rm.warn(`Unknown arrow type: ${r}`);const o="start"===e?"Start":"End";t.attr(`marker-${e}`,`url(${a}#${s}_${i}-${n}${o})`)},"addEdgeMarker"),ht={},gt={},ut=(0,c.K2)(async(t,e)=>{const r=(0,l.D7)(),a=(0,l._3)(r.flowchart.htmlLabels),s="markdown"===e.labelType?(0,n.GZ)(t,e.label,{style:e.labelStyle,useHtmlLabels:a,addSvgBackground:!0},r):await ot(e.label,e.labelStyle),i=t.insert("g").attr("class","edgeLabel"),o=i.insert("g").attr("class","label");o.node().appendChild(s);let c,d=s.getBBox();if(a){const t=s.children[0],e=(0,u.Ltv)(s);d=t.getBoundingClientRect(),e.attr("width",d.width),e.attr("height",d.height)}if(o.attr("transform","translate("+-d.width/2+", "+-d.height/2+")"),ht[e.id]=i,e.width=d.width,e.height=d.height,e.startLabelLeft){const r=await ot(e.startLabelLeft,e.labelStyle),a=t.insert("g").attr("class","edgeTerminals"),s=a.insert("g").attr("class","inner");c=s.node().appendChild(r);const i=r.getBBox();s.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),gt[e.id]||(gt[e.id]={}),gt[e.id].startLeft=a,pt(c,e.startLabelLeft)}if(e.startLabelRight){const r=await ot(e.startLabelRight,e.labelStyle),a=t.insert("g").attr("class","edgeTerminals"),s=a.insert("g").attr("class","inner");c=a.node().appendChild(r),s.node().appendChild(r);const i=r.getBBox();s.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),gt[e.id]||(gt[e.id]={}),gt[e.id].startRight=a,pt(c,e.startLabelRight)}if(e.endLabelLeft){const r=await ot(e.endLabelLeft,e.labelStyle),a=t.insert("g").attr("class","edgeTerminals"),s=a.insert("g").attr("class","inner");c=s.node().appendChild(r);const i=r.getBBox();s.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),a.node().appendChild(r),gt[e.id]||(gt[e.id]={}),gt[e.id].endLeft=a,pt(c,e.endLabelLeft)}if(e.endLabelRight){const r=await ot(e.endLabelRight,e.labelStyle),a=t.insert("g").attr("class","edgeTerminals"),s=a.insert("g").attr("class","inner");c=s.node().appendChild(r);const i=r.getBBox();s.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),a.node().appendChild(r),gt[e.id]||(gt[e.id]={}),gt[e.id].endRight=a,pt(c,e.endLabelRight)}return s},"insertEdgeLabel");function pt(t,e){(0,l.D7)().flowchart.htmlLabels&&t&&(t.style.width=9*e.length+"px",t.style.height="12px")}(0,c.K2)(pt,"setTerminalWidth");var yt=(0,c.K2)((t,e)=>{c.Rm.debug("Moving label abc88 ",t.id,t.label,ht[t.id],e);let r=e.updatedPath?e.updatedPath:e.originalPath;const a=(0,l.D7)(),{subGraphTitleTotalMargin:s}=(0,i.O)(a);if(t.label){const a=ht[t.id];let i=t.x,n=t.y;if(r){const a=o._K.calcLabelPosition(r);c.Rm.debug("Moving label "+t.label+" from (",i,",",n,") to (",a.x,",",a.y,") abc88"),e.updatedPath&&(i=a.x,n=a.y)}a.attr("transform",`translate(${i}, ${n+s/2})`)}if(t.startLabelLeft){const e=gt[t.id].startLeft;let a=t.x,s=t.y;if(r){const e=o._K.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",r);a=e.x,s=e.y}e.attr("transform",`translate(${a}, ${s})`)}if(t.startLabelRight){const e=gt[t.id].startRight;let a=t.x,s=t.y;if(r){const e=o._K.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",r);a=e.x,s=e.y}e.attr("transform",`translate(${a}, ${s})`)}if(t.endLabelLeft){const e=gt[t.id].endLeft;let a=t.x,s=t.y;if(r){const e=o._K.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",r);a=e.x,s=e.y}e.attr("transform",`translate(${a}, ${s})`)}if(t.endLabelRight){const e=gt[t.id].endRight;let a=t.x,s=t.y;if(r){const e=o._K.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",r);a=e.x,s=e.y}e.attr("transform",`translate(${a}, ${s})`)}},"positionEdgeLabel"),bt=(0,c.K2)((t,e)=>{const r=t.x,a=t.y,s=Math.abs(e.x-r),i=Math.abs(e.y-a),n=t.width/2,o=t.height/2;return s>=n||i>=o},"outsideNode"),xt=(0,c.K2)((t,e,r)=>{c.Rm.debug(`intersection calc abc89:\n outsidePoint: ${JSON.stringify(e)}\n insidePoint : ${JSON.stringify(r)}\n node : x:${t.x} y:${t.y} w:${t.width} h:${t.height}`);const a=t.x,s=t.y,i=Math.abs(a-r.x),n=t.width/2;let o=r.x<e.x?n-i:n+i;const l=t.height/2,d=Math.abs(e.y-r.y),h=Math.abs(e.x-r.x);if(Math.abs(s-e.y)*n>Math.abs(a-e.x)*l){let t=r.y<e.y?e.y-l-s:s-l-e.y;o=h*t/d;const a={x:r.x<e.x?r.x+o:r.x-h+o,y:r.y<e.y?r.y+d-t:r.y-d+t};return 0===o&&(a.x=e.x,a.y=e.y),0===h&&(a.x=e.x),0===d&&(a.y=e.y),c.Rm.debug(`abc89 topp/bott calc, Q ${d}, q ${t}, R ${h}, r ${o}`,a),a}{o=r.x<e.x?e.x-n-a:a-n-e.x;let t=d*o/h,s=r.x<e.x?r.x+h-o:r.x-h+o,i=r.y<e.y?r.y+t:r.y-t;return c.Rm.debug(`sides calc abc89, Q ${d}, q ${t}, R ${h}, r ${o}`,{_x:s,_y:i}),0===o&&(s=e.x,i=e.y),0===h&&(s=e.x),0===d&&(i=e.y),{x:s,y:i}}},"intersection"),ft=(0,c.K2)((t,e)=>{c.Rm.debug("abc88 cutPathAtIntersect",t,e);let r=[],a=t[0],s=!1;return t.forEach(t=>{if(bt(e,t)||s)a=t,s||r.push(t);else{const i=xt(e,a,t);let n=!1;r.forEach(t=>{n=n||t.x===i.x&&t.y===i.y}),r.some(t=>t.x===i.x&&t.y===i.y)||r.push(i),s=!0}}),r},"cutPathAtIntersect"),mt=(0,c.K2)(function(t,e,r,a,i,n,o){let d=r.points;c.Rm.debug("abc88 InsertEdge: edge=",r,"e=",e);let h=!1;const g=n.node(e.v);var p=n.node(e.w);p?.intersect&&g?.intersect&&(d=d.slice(1,r.points.length-1),d.unshift(g.intersect(d[0])),d.push(p.intersect(d[d.length-1]))),r.toCluster&&(c.Rm.debug("to cluster abc88",a[r.toCluster]),d=ft(r.points,a[r.toCluster].node),h=!0),r.fromCluster&&(c.Rm.debug("from cluster abc88",a[r.fromCluster]),d=ft(d.reverse(),a[r.fromCluster].node).reverse(),h=!0);const y=d.filter(t=>!Number.isNaN(t.y));let b=u.qrM;!r.curve||"graph"!==i&&"flowchart"!==i||(b=r.curve);const{x:x,y:f}=(0,s.RI)(r),m=(0,u.n8j)().x(x).y(f).curve(b);let w;switch(r.thickness){case"normal":w="edge-thickness-normal";break;case"thick":case"invisible":w="edge-thickness-thick";break;default:w=""}switch(r.pattern){case"solid":w+=" edge-pattern-solid";break;case"dotted":w+=" edge-pattern-dotted";break;case"dashed":w+=" edge-pattern-dashed"}const _=t.append("path").attr("d",m(y)).attr("id",r.id).attr("class"," "+w+(r.classes?" "+r.classes:"")).attr("style",r.style);let L="";((0,l.D7)().flowchart.arrowMarkerAbsolute||(0,l.D7)().state.arrowMarkerAbsolute)&&(L=(0,l.ID)(!0)),lt(_,r,L,o,i);let k={};return h&&(k.updatedPath=d),k.originalPath=r.points,k},"insertEdge"),wt=(0,c.K2)(t=>{const e=new Set;for(const r of t)switch(r){case"x":e.add("right"),e.add("left");break;case"y":e.add("up"),e.add("down");break;default:e.add(r)}return e},"expandAndDeduplicateDirections"),_t=(0,c.K2)((t,e,r)=>{const a=wt(t),s=e.height+2*r.padding,i=s/2,n=e.width+2*i+r.padding,o=r.padding/2;return a.has("right")&&a.has("left")&&a.has("up")&&a.has("down")?[{x:0,y:0},{x:i,y:0},{x:n/2,y:2*o},{x:n-i,y:0},{x:n,y:0},{x:n,y:-s/3},{x:n+2*o,y:-s/2},{x:n,y:-2*s/3},{x:n,y:-s},{x:n-i,y:-s},{x:n/2,y:-s-2*o},{x:i,y:-s},{x:0,y:-s},{x:0,y:-2*s/3},{x:-2*o,y:-s/2},{x:0,y:-s/3}]:a.has("right")&&a.has("left")&&a.has("up")?[{x:i,y:0},{x:n-i,y:0},{x:n,y:-s/2},{x:n-i,y:-s},{x:i,y:-s},{x:0,y:-s/2}]:a.has("right")&&a.has("left")&&a.has("down")?[{x:0,y:0},{x:i,y:-s},{x:n-i,y:-s},{x:n,y:0}]:a.has("right")&&a.has("up")&&a.has("down")?[{x:0,y:0},{x:n,y:-i},{x:n,y:-s+i},{x:0,y:-s}]:a.has("left")&&a.has("up")&&a.has("down")?[{x:n,y:0},{x:0,y:-i},{x:0,y:-s+i},{x:n,y:-s}]:a.has("right")&&a.has("left")?[{x:i,y:0},{x:i,y:-o},{x:n-i,y:-o},{x:n-i,y:0},{x:n,y:-s/2},{x:n-i,y:-s},{x:n-i,y:-s+o},{x:i,y:-s+o},{x:i,y:-s},{x:0,y:-s/2}]:a.has("up")&&a.has("down")?[{x:n/2,y:0},{x:0,y:-o},{x:i,y:-o},{x:i,y:-s+o},{x:0,y:-s+o},{x:n/2,y:-s},{x:n,y:-s+o},{x:n-i,y:-s+o},{x:n-i,y:-o},{x:n,y:-o}]:a.has("right")&&a.has("up")?[{x:0,y:0},{x:n,y:-i},{x:0,y:-s}]:a.has("right")&&a.has("down")?[{x:0,y:0},{x:n,y:0},{x:0,y:-s}]:a.has("left")&&a.has("up")?[{x:n,y:0},{x:0,y:-i},{x:n,y:-s}]:a.has("left")&&a.has("down")?[{x:n,y:0},{x:0,y:0},{x:n,y:-s}]:a.has("right")?[{x:i,y:-o},{x:i,y:-o},{x:n-i,y:-o},{x:n-i,y:0},{x:n,y:-s/2},{x:n-i,y:-s},{x:n-i,y:-s+o},{x:i,y:-s+o},{x:i,y:-s+o}]:a.has("left")?[{x:i,y:0},{x:i,y:-o},{x:n-i,y:-o},{x:n-i,y:-s+o},{x:i,y:-s+o},{x:i,y:-s},{x:0,y:-s/2}]:a.has("up")?[{x:i,y:-o},{x:i,y:-s+o},{x:0,y:-s+o},{x:n/2,y:-s},{x:n,y:-s+o},{x:n-i,y:-s+o},{x:n-i,y:-o}]:a.has("down")?[{x:n/2,y:0},{x:0,y:-o},{x:i,y:-o},{x:i,y:-s+o},{x:n-i,y:-s+o},{x:n-i,y:-o},{x:n,y:-o}]:[{x:0,y:0}]},"getArrowPoints");function Lt(t,e){return t.intersect(e)}(0,c.K2)(Lt,"intersectNode");var kt=Lt;function St(t,e,r,a){var s=t.x,i=t.y,n=s-a.x,o=i-a.y,l=Math.sqrt(e*e*o*o+r*r*n*n),c=Math.abs(e*r*n/l);a.x<s&&(c=-c);var d=Math.abs(e*r*o/l);return a.y<i&&(d=-d),{x:s+c,y:i+d}}(0,c.K2)(St,"intersectEllipse");var vt=St;function Et(t,e,r){return vt(t,e,e,r)}(0,c.K2)(Et,"intersectCircle");var Dt=Et;function Ct(t,e,r,a){var s,i,n,o,l,c,d,h,g,u,p,y,b;if(s=e.y-t.y,n=t.x-e.x,l=e.x*t.y-t.x*e.y,g=s*r.x+n*r.y+l,u=s*a.x+n*a.y+l,!(0!==g&&0!==u&&Rt(g,u)||(i=a.y-r.y,o=r.x-a.x,c=a.x*r.y-r.x*a.y,d=i*t.x+o*t.y+c,h=i*e.x+o*e.y+c,0!==d&&0!==h&&Rt(d,h)||0===(p=s*o-i*n))))return y=Math.abs(p/2),{x:(b=n*c-o*l)<0?(b-y)/p:(b+y)/p,y:(b=i*l-s*c)<0?(b-y)/p:(b+y)/p}}function Rt(t,e){return t*e>0}(0,c.K2)(Ct,"intersectLine"),(0,c.K2)(Rt,"sameSign");var Kt=Ct,$t=Nt;function Nt(t,e,r){var a=t.x,s=t.y,i=[],n=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY;"function"==typeof e.forEach?e.forEach(function(t){n=Math.min(n,t.x),o=Math.min(o,t.y)}):(n=Math.min(n,e.x),o=Math.min(o,e.y));for(var l=a-t.width/2-n,c=s-t.height/2-o,d=0;d<e.length;d++){var h=e[d],g=e[d<e.length-1?d+1:0],u=Kt(t,r,{x:l+h.x,y:c+h.y},{x:l+g.x,y:c+g.y});u&&i.push(u)}return i.length?(i.length>1&&i.sort(function(t,e){var a=t.x-r.x,s=t.y-r.y,i=Math.sqrt(a*a+s*s),n=e.x-r.x,o=e.y-r.y,l=Math.sqrt(n*n+o*o);return i<l?-1:i===l?0:1}),i[0]):t}(0,c.K2)(Nt,"intersectPolygon");var Tt={node:kt,circle:Dt,ellipse:vt,polygon:$t,rect:(0,c.K2)((t,e)=>{var r,a,s=t.x,i=t.y,n=e.x-s,o=e.y-i,l=t.width/2,c=t.height/2;return Math.abs(o)*l>Math.abs(n)*c?(o<0&&(c=-c),r=0===o?0:c*n/o,a=c):(n<0&&(l=-l),r=l,a=0===n?0:l*o/n),{x:s+r,y:i+a}},"intersectRect")},At=(0,c.K2)(async(t,e,r,a)=>{const s=(0,l.D7)();let i;const d=e.useHtmlLabels||(0,l._3)(s.flowchart.htmlLabels);i=r||"node default";const h=t.insert("g").attr("class",i).attr("id",e.domId||e.id),g=h.insert("g").attr("class","label").attr("style",e.labelStyle);let p;p=void 0===e.labelText?"":"string"==typeof e.labelText?e.labelText:e.labelText[0];const y=g.node();let b;b="markdown"===e.labelType?(0,n.GZ)(g,(0,l.jZ)((0,o.Sm)(p),s),{useHtmlLabels:d,width:e.width||s.flowchart.wrappingWidth,classes:"markdown-node-label"},s):y.appendChild(await ot((0,l.jZ)((0,o.Sm)(p),s),e.labelStyle,!1,a));let x=b.getBBox();const f=e.padding/2;if((0,l._3)(s.flowchart.htmlLabels)){const t=b.children[0],e=(0,u.Ltv)(b),r=t.getElementsByTagName("img");if(r){const t=""===p.replace(/<img[^>]*>/g,"").trim();await Promise.all([...r].map(e=>new Promise(r=>{function a(){if(e.style.display="flex",e.style.flexDirection="column",t){const t=s.fontSize?s.fontSize:window.getComputedStyle(document.body).fontSize,r=5,a=parseInt(t,10)*r+"px";e.style.minWidth=a,e.style.maxWidth=a}else e.style.width="100%";r(e)}(0,c.K2)(a,"setupImage"),setTimeout(()=>{e.complete&&a()}),e.addEventListener("error",a),e.addEventListener("load",a)})))}x=t.getBoundingClientRect(),e.attr("width",x.width),e.attr("height",x.height)}return d?g.attr("transform","translate("+-x.width/2+", "+-x.height/2+")"):g.attr("transform","translate(0, "+-x.height/2+")"),e.centerLabel&&g.attr("transform","translate("+-x.width/2+", "+-x.height/2+")"),g.insert("rect",":first-child"),{shapeSvg:h,bbox:x,halfPadding:f,label:g}},"labelHelper"),It=(0,c.K2)((t,e)=>{const r=e.node().getBBox();t.width=r.width,t.height=r.height},"updateNodeBounds");function Ot(t,e,r,a){return t.insert("polygon",":first-child").attr("points",a.map(function(t){return t.x+","+t.y}).join(" ")).attr("class","label-container").attr("transform","translate("+-e/2+","+r/2+")")}(0,c.K2)(Ot,"insertPolygonShape");var Bt=(0,c.K2)(async(t,e)=>{e.useHtmlLabels||(0,l.D7)().flowchart.htmlLabels||(e.centerLabel=!0);const{shapeSvg:r,bbox:a,halfPadding:s}=await At(t,e,"node "+e.classes,!0);c.Rm.info("Classes = ",e.classes);const i=r.insert("rect",":first-child");return i.attr("rx",e.rx).attr("ry",e.ry).attr("x",-a.width/2-s).attr("y",-a.height/2-s).attr("width",a.width+e.padding).attr("height",a.height+e.padding),It(e,i),e.intersect=function(t){return Tt.rect(e,t)},r},"note"),zt=(0,c.K2)(t=>t?" "+t:"","formatClass"),Mt=(0,c.K2)((t,e)=>`${e||"node default"}${zt(t.classes)} ${zt(t.class)}`,"getClassesFromNode"),Pt=(0,c.K2)(async(t,e)=>{const{shapeSvg:r,bbox:a}=await At(t,e,Mt(e,void 0),!0),s=a.width+e.padding+(a.height+e.padding),i=[{x:s/2,y:0},{x:s,y:-s/2},{x:s/2,y:-s},{x:0,y:-s/2}];c.Rm.info("Question main (Circle)");const n=Ot(r,s,s,i);return n.attr("style",e.style),It(e,n),e.intersect=function(t){return c.Rm.warn("Intersect called"),Tt.polygon(e,i,t)},r},"question"),Yt=(0,c.K2)((t,e)=>{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),a=[{x:0,y:14},{x:14,y:0},{x:0,y:-14},{x:-14,y:0}];return r.insert("polygon",":first-child").attr("points",a.map(function(t){return t.x+","+t.y}).join(" ")).attr("class","state-start").attr("r",7).attr("width",28).attr("height",28),e.width=28,e.height=28,e.intersect=function(t){return Tt.circle(e,14,t)},r},"choice"),Ft=(0,c.K2)(async(t,e)=>{const{shapeSvg:r,bbox:a}=await At(t,e,Mt(e,void 0),!0),s=a.height+e.padding,i=s/4,n=a.width+2*i+e.padding,o=[{x:i,y:0},{x:n-i,y:0},{x:n,y:-s/2},{x:n-i,y:-s},{x:i,y:-s},{x:0,y:-s/2}],l=Ot(r,n,s,o);return l.attr("style",e.style),It(e,l),e.intersect=function(t){return Tt.polygon(e,o,t)},r},"hexagon"),jt=(0,c.K2)(async(t,e)=>{const{shapeSvg:r,bbox:a}=await At(t,e,void 0,!0),s=a.height+2*e.padding,i=s/2,n=a.width+2*i+e.padding,o=_t(e.directions,a,e),l=Ot(r,n,s,o);return l.attr("style",e.style),It(e,l),e.intersect=function(t){return Tt.polygon(e,o,t)},r},"block_arrow"),Wt=(0,c.K2)(async(t,e)=>{const{shapeSvg:r,bbox:a}=await At(t,e,Mt(e,void 0),!0),s=a.width+e.padding,i=a.height+e.padding,n=[{x:-i/2,y:0},{x:s,y:0},{x:s,y:-i},{x:-i/2,y:-i},{x:0,y:-i/2}];return Ot(r,s,i,n).attr("style",e.style),e.width=s+i,e.height=i,e.intersect=function(t){return Tt.polygon(e,n,t)},r},"rect_left_inv_arrow"),Xt=(0,c.K2)(async(t,e)=>{const{shapeSvg:r,bbox:a}=await At(t,e,Mt(e),!0),s=a.width+e.padding,i=a.height+e.padding,n=[{x:-2*i/6,y:0},{x:s-i/6,y:0},{x:s+2*i/6,y:-i},{x:i/6,y:-i}],o=Ot(r,s,i,n);return o.attr("style",e.style),It(e,o),e.intersect=function(t){return Tt.polygon(e,n,t)},r},"lean_right"),Ht=(0,c.K2)(async(t,e)=>{const{shapeSvg:r,bbox:a}=await At(t,e,Mt(e,void 0),!0),s=a.width+e.padding,i=a.height+e.padding,n=[{x:2*i/6,y:0},{x:s+i/6,y:0},{x:s-2*i/6,y:-i},{x:-i/6,y:-i}],o=Ot(r,s,i,n);return o.attr("style",e.style),It(e,o),e.intersect=function(t){return Tt.polygon(e,n,t)},r},"lean_left"),Ut=(0,c.K2)(async(t,e)=>{const{shapeSvg:r,bbox:a}=await At(t,e,Mt(e,void 0),!0),s=a.width+e.padding,i=a.height+e.padding,n=[{x:-2*i/6,y:0},{x:s+2*i/6,y:0},{x:s-i/6,y:-i},{x:i/6,y:-i}],o=Ot(r,s,i,n);return o.attr("style",e.style),It(e,o),e.intersect=function(t){return Tt.polygon(e,n,t)},r},"trapezoid"),Zt=(0,c.K2)(async(t,e)=>{const{shapeSvg:r,bbox:a}=await At(t,e,Mt(e,void 0),!0),s=a.width+e.padding,i=a.height+e.padding,n=[{x:i/6,y:0},{x:s-i/6,y:0},{x:s+2*i/6,y:-i},{x:-2*i/6,y:-i}],o=Ot(r,s,i,n);return o.attr("style",e.style),It(e,o),e.intersect=function(t){return Tt.polygon(e,n,t)},r},"inv_trapezoid"),qt=(0,c.K2)(async(t,e)=>{const{shapeSvg:r,bbox:a}=await At(t,e,Mt(e,void 0),!0),s=a.width+e.padding,i=a.height+e.padding,n=[{x:0,y:0},{x:s+i/2,y:0},{x:s,y:-i/2},{x:s+i/2,y:-i},{x:0,y:-i}],o=Ot(r,s,i,n);return o.attr("style",e.style),It(e,o),e.intersect=function(t){return Tt.polygon(e,n,t)},r},"rect_right_inv_arrow"),Gt=(0,c.K2)(async(t,e)=>{const{shapeSvg:r,bbox:a}=await At(t,e,Mt(e,void 0),!0),s=a.width+e.padding,i=s/2,n=i/(2.5+s/50),o=a.height+n+e.padding,l="M 0,"+n+" a "+i+","+n+" 0,0,0 "+s+" 0 a "+i+","+n+" 0,0,0 "+-s+" 0 l 0,"+o+" a "+i+","+n+" 0,0,0 "+s+" 0 l 0,"+-o,c=r.attr("label-offset-y",n).insert("path",":first-child").attr("style",e.style).attr("d",l).attr("transform","translate("+-s/2+","+-(o/2+n)+")");return It(e,c),e.intersect=function(t){const r=Tt.rect(e,t),a=r.x-e.x;if(0!=i&&(Math.abs(a)<e.width/2||Math.abs(a)==e.width/2&&Math.abs(r.y-e.y)>e.height/2-n)){let s=n*n*(1-a*a/(i*i));0!=s&&(s=Math.sqrt(s)),s=n-s,t.y-e.y>0&&(s=-s),r.y+=s}return r},r},"cylinder"),Jt=(0,c.K2)(async(t,e)=>{const{shapeSvg:r,bbox:a,halfPadding:s}=await At(t,e,"node "+e.classes+" "+e.class,!0),i=r.insert("rect",":first-child"),n=e.positioned?e.width:a.width+e.padding,o=e.positioned?e.height:a.height+e.padding,l=e.positioned?-n/2:-a.width/2-s,d=e.positioned?-o/2:-a.height/2-s;if(i.attr("class","basic label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",l).attr("y",d).attr("width",n).attr("height",o),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(te(i,e.props.borders,n,o),t.delete("borders")),t.forEach(t=>{c.Rm.warn(`Unknown node property ${t}`)})}return It(e,i),e.intersect=function(t){return Tt.rect(e,t)},r},"rect"),Vt=(0,c.K2)(async(t,e)=>{const{shapeSvg:r,bbox:a,halfPadding:s}=await At(t,e,"node "+e.classes,!0),i=r.insert("rect",":first-child"),n=e.positioned?e.width:a.width+e.padding,o=e.positioned?e.height:a.height+e.padding,l=e.positioned?-n/2:-a.width/2-s,d=e.positioned?-o/2:-a.height/2-s;if(i.attr("class","basic cluster composite label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",l).attr("y",d).attr("width",n).attr("height",o),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(te(i,e.props.borders,n,o),t.delete("borders")),t.forEach(t=>{c.Rm.warn(`Unknown node property ${t}`)})}return It(e,i),e.intersect=function(t){return Tt.rect(e,t)},r},"composite"),Qt=(0,c.K2)(async(t,e)=>{const{shapeSvg:r}=await At(t,e,"label",!0);c.Rm.trace("Classes = ",e.class);const a=r.insert("rect",":first-child");if(a.attr("width",0).attr("height",0),r.attr("class","label edgeLabel"),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(te(a,e.props.borders,0,0),t.delete("borders")),t.forEach(t=>{c.Rm.warn(`Unknown node property ${t}`)})}return It(e,a),e.intersect=function(t){return Tt.rect(e,t)},r},"labelRect");function te(t,e,r,a){const s=[],i=(0,c.K2)(t=>{s.push(t,0)},"addBorder"),n=(0,c.K2)(t=>{s.push(0,t)},"skipBorder");e.includes("t")?(c.Rm.debug("add top border"),i(r)):n(r),e.includes("r")?(c.Rm.debug("add right border"),i(a)):n(a),e.includes("b")?(c.Rm.debug("add bottom border"),i(r)):n(r),e.includes("l")?(c.Rm.debug("add left border"),i(a)):n(a),t.attr("stroke-dasharray",s.join(" "))}(0,c.K2)(te,"applyNodePropertyBorders");var ee=(0,c.K2)(async(t,e)=>{let r;r=e.classes?"node "+e.classes:"node default";const a=t.insert("g").attr("class",r).attr("id",e.domId||e.id),s=a.insert("rect",":first-child"),i=a.insert("line"),n=a.insert("g").attr("class","label"),o=e.labelText.flat?e.labelText.flat():e.labelText;let d="";d="object"==typeof o?o[0]:o,c.Rm.info("Label text abc79",d,o,"object"==typeof o);const h=n.node().appendChild(await ot(d,e.labelStyle,!0,!0));let g={width:0,height:0};if((0,l._3)((0,l.D7)().flowchart.htmlLabels)){const t=h.children[0],e=(0,u.Ltv)(h);g=t.getBoundingClientRect(),e.attr("width",g.width),e.attr("height",g.height)}c.Rm.info("Text 2",o);const p=o.slice(1,o.length);let y=h.getBBox();const b=n.node().appendChild(await ot(p.join?p.join("<br/>"):p,e.labelStyle,!0,!0));if((0,l._3)((0,l.D7)().flowchart.htmlLabels)){const t=b.children[0],e=(0,u.Ltv)(b);g=t.getBoundingClientRect(),e.attr("width",g.width),e.attr("height",g.height)}const x=e.padding/2;return(0,u.Ltv)(b).attr("transform","translate( "+(g.width>y.width?0:(y.width-g.width)/2)+", "+(y.height+x+5)+")"),(0,u.Ltv)(h).attr("transform","translate( "+(g.width<y.width?0:-(y.width-g.width)/2)+", 0)"),g=n.node().getBBox(),n.attr("transform","translate("+-g.width/2+", "+(-g.height/2-x+3)+")"),s.attr("class","outer title-state").attr("x",-g.width/2-x).attr("y",-g.height/2-x).attr("width",g.width+e.padding).attr("height",g.height+e.padding),i.attr("class","divider").attr("x1",-g.width/2-x).attr("x2",g.width/2+x).attr("y1",-g.height/2-x+y.height+x).attr("y2",-g.height/2-x+y.height+x),It(e,s),e.intersect=function(t){return Tt.rect(e,t)},a},"rectWithTitle"),re=(0,c.K2)(async(t,e)=>{const{shapeSvg:r,bbox:a}=await At(t,e,Mt(e,void 0),!0),s=a.height+e.padding,i=a.width+s/4+e.padding,n=r.insert("rect",":first-child").attr("style",e.style).attr("rx",s/2).attr("ry",s/2).attr("x",-i/2).attr("y",-s/2).attr("width",i).attr("height",s);return It(e,n),e.intersect=function(t){return Tt.rect(e,t)},r},"stadium"),ae=(0,c.K2)(async(t,e)=>{const{shapeSvg:r,bbox:a,halfPadding:s}=await At(t,e,Mt(e,void 0),!0),i=r.insert("circle",":first-child");return i.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",a.width/2+s).attr("width",a.width+e.padding).attr("height",a.height+e.padding),c.Rm.info("Circle main"),It(e,i),e.intersect=function(t){return c.Rm.info("Circle intersect",e,a.width/2+s,t),Tt.circle(e,a.width/2+s,t)},r},"circle"),se=(0,c.K2)(async(t,e)=>{const{shapeSvg:r,bbox:a,halfPadding:s}=await At(t,e,Mt(e,void 0),!0),i=r.insert("g",":first-child"),n=i.insert("circle"),o=i.insert("circle");return i.attr("class",e.class),n.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",a.width/2+s+5).attr("width",a.width+e.padding+10).attr("height",a.height+e.padding+10),o.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",a.width/2+s).attr("width",a.width+e.padding).attr("height",a.height+e.padding),c.Rm.info("DoubleCircle main"),It(e,n),e.intersect=function(t){return c.Rm.info("DoubleCircle intersect",e,a.width/2+s+5,t),Tt.circle(e,a.width/2+s+5,t)},r},"doublecircle"),ie=(0,c.K2)(async(t,e)=>{const{shapeSvg:r,bbox:a}=await At(t,e,Mt(e,void 0),!0),s=a.width+e.padding,i=a.height+e.padding,n=[{x:0,y:0},{x:s,y:0},{x:s,y:-i},{x:0,y:-i},{x:0,y:0},{x:-8,y:0},{x:s+8,y:0},{x:s+8,y:-i},{x:-8,y:-i},{x:-8,y:0}],o=Ot(r,s,i,n);return o.attr("style",e.style),It(e,o),e.intersect=function(t){return Tt.polygon(e,n,t)},r},"subroutine"),ne=(0,c.K2)((t,e)=>{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),a=r.insert("circle",":first-child");return a.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),It(e,a),e.intersect=function(t){return Tt.circle(e,7,t)},r},"start"),oe=(0,c.K2)((t,e,r)=>{const a=t.insert("g").attr("class","node default").attr("id",e.domId||e.id);let s=70,i=10;"LR"===r&&(s=10,i=70);const n=a.append("rect").attr("x",-1*s/2).attr("y",-1*i/2).attr("width",s).attr("height",i).attr("class","fork-join");return It(e,n),e.height=e.height+e.padding/2,e.width=e.width+e.padding/2,e.intersect=function(t){return Tt.rect(e,t)},a},"forkJoin"),le={rhombus:Pt,composite:Vt,question:Pt,rect:Jt,labelRect:Qt,rectWithTitle:ee,choice:Yt,circle:ae,doublecircle:se,stadium:re,hexagon:Ft,block_arrow:jt,rect_left_inv_arrow:Wt,lean_right:Xt,lean_left:Ht,trapezoid:Ut,inv_trapezoid:Zt,rect_right_inv_arrow:qt,cylinder:Gt,start:ne,end:(0,c.K2)((t,e)=>{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),a=r.insert("circle",":first-child"),s=r.insert("circle",":first-child");return s.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),a.attr("class","state-end").attr("r",5).attr("width",10).attr("height",10),It(e,s),e.intersect=function(t){return Tt.circle(e,7,t)},r},"end"),note:Bt,subroutine:ie,fork:oe,join:oe,class_box:(0,c.K2)(async(t,e)=>{const r=e.padding/2;let a;a=e.classes?"node "+e.classes:"node default";const s=t.insert("g").attr("class",a).attr("id",e.domId||e.id),i=s.insert("rect",":first-child"),n=s.insert("line"),o=s.insert("line");let c=0,d=4;const h=s.insert("g").attr("class","label");let g=0;const p=e.classData.annotations?.[0],y=e.classData.annotations[0]?"\xab"+e.classData.annotations[0]+"\xbb":"",b=h.node().appendChild(await ot(y,e.labelStyle,!0,!0));let x=b.getBBox();if((0,l._3)((0,l.D7)().flowchart.htmlLabels)){const t=b.children[0],e=(0,u.Ltv)(b);x=t.getBoundingClientRect(),e.attr("width",x.width),e.attr("height",x.height)}e.classData.annotations[0]&&(d+=x.height+4,c+=x.width);let f=e.classData.label;void 0!==e.classData.type&&""!==e.classData.type&&((0,l.D7)().flowchart.htmlLabels?f+="<"+e.classData.type+">":f+="<"+e.classData.type+">");const m=h.node().appendChild(await ot(f,e.labelStyle,!0,!0));(0,u.Ltv)(m).attr("class","classTitle");let w=m.getBBox();if((0,l._3)((0,l.D7)().flowchart.htmlLabels)){const t=m.children[0],e=(0,u.Ltv)(m);w=t.getBoundingClientRect(),e.attr("width",w.width),e.attr("height",w.height)}d+=w.height+4,w.width>c&&(c=w.width);const _=[];e.classData.members.forEach(async t=>{const r=t.getDisplayDetails();let a=r.displayText;(0,l.D7)().flowchart.htmlLabels&&(a=a.replace(/</g,"<").replace(/>/g,">"));const s=h.node().appendChild(await ot(a,r.cssStyle?r.cssStyle:e.labelStyle,!0,!0));let i=s.getBBox();if((0,l._3)((0,l.D7)().flowchart.htmlLabels)){const t=s.children[0],e=(0,u.Ltv)(s);i=t.getBoundingClientRect(),e.attr("width",i.width),e.attr("height",i.height)}i.width>c&&(c=i.width),d+=i.height+4,_.push(s)}),d+=8;const L=[];if(e.classData.methods.forEach(async t=>{const r=t.getDisplayDetails();let a=r.displayText;(0,l.D7)().flowchart.htmlLabels&&(a=a.replace(/</g,"<").replace(/>/g,">"));const s=h.node().appendChild(await ot(a,r.cssStyle?r.cssStyle:e.labelStyle,!0,!0));let i=s.getBBox();if((0,l._3)((0,l.D7)().flowchart.htmlLabels)){const t=s.children[0],e=(0,u.Ltv)(s);i=t.getBoundingClientRect(),e.attr("width",i.width),e.attr("height",i.height)}i.width>c&&(c=i.width),d+=i.height+4,L.push(s)}),d+=8,p){let t=(c-x.width)/2;(0,u.Ltv)(b).attr("transform","translate( "+(-1*c/2+t)+", "+-1*d/2+")"),g=x.height+4}let k=(c-w.width)/2;return(0,u.Ltv)(m).attr("transform","translate( "+(-1*c/2+k)+", "+(-1*d/2+g)+")"),g+=w.height+4,n.attr("class","divider").attr("x1",-c/2-r).attr("x2",c/2+r).attr("y1",-d/2-r+8+g).attr("y2",-d/2-r+8+g),g+=8,_.forEach(t=>{(0,u.Ltv)(t).attr("transform","translate( "+-c/2+", "+(-1*d/2+g+4)+")");const e=t?.getBBox();g+=(e?.height??0)+4}),g+=8,o.attr("class","divider").attr("x1",-c/2-r).attr("x2",c/2+r).attr("y1",-d/2-r+8+g).attr("y2",-d/2-r+8+g),g+=8,L.forEach(t=>{(0,u.Ltv)(t).attr("transform","translate( "+-c/2+", "+(-1*d/2+g)+")");const e=t?.getBBox();g+=(e?.height??0)+4}),i.attr("style",e.style).attr("class","outer title-state").attr("x",-c/2-r).attr("y",-d/2-r).attr("width",c+e.padding).attr("height",d+e.padding),It(e,i),e.intersect=function(t){return Tt.rect(e,t)},s},"class_box")},ce={},de=(0,c.K2)(async(t,e,r)=>{let a,s;if(e.link){let i;"sandbox"===(0,l.D7)().securityLevel?i="_top":e.linkTarget&&(i=e.linkTarget||"_blank"),a=t.insert("svg:a").attr("xlink:href",e.link).attr("target",i),s=await le[e.shape](a,e,r)}else s=await le[e.shape](t,e,r),a=s;return e.tooltip&&s.attr("title",e.tooltip),e.class&&s.attr("class","node default "+e.class),ce[e.id]=a,e.haveCallback&&ce[e.id].attr("class",ce[e.id].attr("class")+" clickable"),a},"insertNode"),he=(0,c.K2)(t=>{const e=ce[t.id];c.Rm.trace("Transforming node",t.diff,t,"translate("+(t.x-t.width/2-5)+", "+t.width/2+")");const r=t.diff||0;return t.clusterNode?e.attr("transform","translate("+(t.x+r-t.width/2)+", "+(t.y-t.height/2-8)+")"):e.attr("transform","translate("+t.x+", "+t.y+")"),r},"positionNode");function ge(t,e,r=!1){const a=t;let s="default";(a?.classes?.length||0)>0&&(s=(a?.classes??[]).join(" ")),s+=" flowchart-label";let i,n=0,c="";switch(a.type){case"round":n=5,c="rect";break;case"composite":n=0,c="composite",i=0;break;case"square":case"group":default:c="rect";break;case"diamond":c="question";break;case"hexagon":c="hexagon";break;case"block_arrow":c="block_arrow";break;case"odd":case"rect_left_inv_arrow":c="rect_left_inv_arrow";break;case"lean_right":c="lean_right";break;case"lean_left":c="lean_left";break;case"trapezoid":c="trapezoid";break;case"inv_trapezoid":c="inv_trapezoid";break;case"circle":c="circle";break;case"ellipse":c="ellipse";break;case"stadium":c="stadium";break;case"subroutine":c="subroutine";break;case"cylinder":c="cylinder";break;case"doublecircle":c="doublecircle"}const d=(0,o.sM)(a?.styles??[]),h=a.label,g=a.size??{width:0,height:0,x:0,y:0};return{labelStyle:d.labelStyle,shape:c,labelText:h,rx:n,ry:n,class:s,style:d.style,id:a.id,directions:a.directions,width:g.width,height:g.height,x:g.x,y:g.y,positioned:r,intersect:void 0,type:a.type,padding:i??(0,l.zj)()?.block?.padding??0}}async function ue(t,e,r){const a=ge(e,0,!1);if("group"===a.type)return;const s=(0,l.zj)(),i=await de(t,a,{config:s}),n=i.node().getBBox(),o=r.getBlock(a.id);o.size={width:n.width,height:n.height,x:0,y:0,node:i},r.setBlock(o),i.remove()}async function pe(t,e,r){const a=ge(e,0,!0);if("space"!==r.getBlock(a.id).type){const r=(0,l.zj)();await de(t,a,{config:r}),e.intersect=a?.intersect,he(a)}}async function ye(t,e,r,a){for(const s of e)await a(t,s,r),s.children&&await ye(t,s.children,r,a)}async function be(t,e,r){await ye(t,e,r,ue)}async function xe(t,e,r){await ye(t,e,r,pe)}async function fe(t,e,r,a,s){const i=new p.T({multigraph:!0,compound:!0});i.setGraph({rankdir:"TB",nodesep:10,ranksep:10,marginx:8,marginy:8});for(const n of r)n.size&&i.setNode(n.id,{width:n.size.width,height:n.size.height,intersect:n.intersect});for(const n of e)if(n.start&&n.end){const e=a.getBlock(n.start),r=a.getBlock(n.end);if(e?.size&&r?.size){const a=e.size,o=r.size,l=[{x:a.x,y:a.y},{x:a.x+(o.x-a.x)/2,y:a.y+(o.y-a.y)/2},{x:o.x,y:o.y}];mt(t,{v:n.start,w:n.end,name:n.id},{...n,arrowTypeEnd:n.arrowTypeEnd,arrowTypeStart:n.arrowTypeStart,points:l,classes:"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1"},void 0,"block",i,s),n.label&&(await ut(t,{...n,label:n.label,labelStyle:"stroke: #333; stroke-width: 1.5px;fill:none;",arrowTypeEnd:n.arrowTypeEnd,arrowTypeStart:n.arrowTypeStart,points:l,classes:"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1"}),yt({...n,x:l[1].x,y:l[1].y},{originalPath:l}))}}}(0,c.K2)(ge,"getNodeFromBlock"),(0,c.K2)(ue,"calculateBlockSize"),(0,c.K2)(pe,"insertBlockPositioned"),(0,c.K2)(ye,"performOperations"),(0,c.K2)(be,"calculateBlockSizes"),(0,c.K2)(xe,"insertBlocks"),(0,c.K2)(fe,"insertEdges");var me=(0,c.K2)(function(t,e){return e.db.getClasses()},"getClasses"),we={parser:b,db:H,renderer:{draw:(0,c.K2)(async function(t,e,r,a){const{securityLevel:s,block:i}=(0,l.zj)(),n=a.db;let o;"sandbox"===s&&(o=(0,u.Ltv)("#i"+e));const d="sandbox"===s?(0,u.Ltv)(o.nodes()[0].contentDocument.body):(0,u.Ltv)("body"),h="sandbox"===s?d.select(`[id="${e}"]`):(0,u.Ltv)(`[id="${e}"]`);J(h,["point","circle","cross"],a.type,e);const g=n.getBlocks(),p=n.getBlocksFlat(),y=n.getEdges(),b=h.insert("g").attr("class","block");await be(b,g,n);const x=st(n);if(await xe(b,g,n),await fe(b,y,p,n,e),x){const t=x,e=Math.max(1,Math.round(t.width/t.height*.125)),r=t.height+e+10,a=t.width+10,{useMaxWidth:s}=i;(0,l.a$)(h,r,a,!!s),c.Rm.debug("Here Bounds",x,t),h.attr("viewBox",`${t.x-5} ${t.y-5} ${t.width+10} ${t.height+10}`)}},"draw"),getClasses:me},styles:Z}},75937:(t,e,r)=>{r.d(e,{A:()=>i});var a=r(72453),s=r(74886);const i=(t,e)=>a.A.lang.round(s.A.parse(t)[e])}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/5a6332a4.55cef70a.js b/pr-preview/pr-4027/assets/js/5a6332a4.55cef70a.js deleted file mode 100644 index d1378cb02..000000000 --- a/pr-preview/pr-4027/assets/js/5a6332a4.55cef70a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5096],{28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>l});var o=i(96540);const s={},t=o.createContext(s);function r(e){const n=o.useContext(t);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(t.Provider,{value:n},e.children)}},43053:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>p,frontMatter:()=>r,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"reference/cli","title":"CLI reference","description":"Use the Constellation CLI to create and manage your clusters.","source":"@site/versioned_docs/version-2.22/reference/cli.md","sourceDirName":"reference","slug":"/reference/cli","permalink":"/constellation/pr-preview/pr-4027/2.22/reference/cli","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/reference/cli.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Reference","permalink":"/constellation/pr-preview/pr-4027/2.22/category/reference"},"next":{"title":"Configuration migrations","permalink":"/constellation/pr-preview/pr-4027/2.22/reference/migration"}}');var s=i(74848),t=i(28453);const r={},l="CLI reference",a={},c=[{value:"constellation config",id:"constellation-config",level:2},{value:"Synopsis",id:"synopsis",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"constellation config generate",id:"constellation-config-generate",level:2},{value:"Synopsis",id:"synopsis-1",level:3},{value:"Options",id:"options-1",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-1",level:3},{value:"constellation config fetch-measurements",id:"constellation-config-fetch-measurements",level:2},{value:"Synopsis",id:"synopsis-2",level:3},{value:"Options",id:"options-2",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-2",level:3},{value:"constellation config instance-types",id:"constellation-config-instance-types",level:2},{value:"Synopsis",id:"synopsis-3",level:3},{value:"Options",id:"options-3",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-3",level:3},{value:"constellation config kubernetes-versions",id:"constellation-config-kubernetes-versions",level:2},{value:"Synopsis",id:"synopsis-4",level:3},{value:"Options",id:"options-4",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-4",level:3},{value:"constellation config migrate",id:"constellation-config-migrate",level:2},{value:"Synopsis",id:"synopsis-5",level:3},{value:"Options",id:"options-5",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-5",level:3},{value:"constellation create",id:"constellation-create",level:2},{value:"Synopsis",id:"synopsis-6",level:3},{value:"Options",id:"options-6",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-6",level:3},{value:"constellation apply",id:"constellation-apply",level:2},{value:"Synopsis",id:"synopsis-7",level:3},{value:"Options",id:"options-7",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-7",level:3},{value:"constellation mini",id:"constellation-mini",level:2},{value:"Synopsis",id:"synopsis-8",level:3},{value:"Options",id:"options-8",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-8",level:3},{value:"constellation mini up",id:"constellation-mini-up",level:2},{value:"Synopsis",id:"synopsis-9",level:3},{value:"Options",id:"options-9",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-9",level:3},{value:"constellation mini down",id:"constellation-mini-down",level:2},{value:"Synopsis",id:"synopsis-10",level:3},{value:"Options",id:"options-10",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-10",level:3},{value:"constellation status",id:"constellation-status",level:2},{value:"Synopsis",id:"synopsis-11",level:3},{value:"Options",id:"options-11",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-11",level:3},{value:"constellation verify",id:"constellation-verify",level:2},{value:"Synopsis",id:"synopsis-12",level:3},{value:"Options",id:"options-12",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-12",level:3},{value:"constellation upgrade",id:"constellation-upgrade",level:2},{value:"Synopsis",id:"synopsis-13",level:3},{value:"Options",id:"options-13",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-13",level:3},{value:"constellation upgrade check",id:"constellation-upgrade-check",level:2},{value:"Synopsis",id:"synopsis-14",level:3},{value:"Options",id:"options-14",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-14",level:3},{value:"constellation upgrade apply",id:"constellation-upgrade-apply",level:2},{value:"Synopsis",id:"synopsis-15",level:3},{value:"Options",id:"options-15",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-15",level:3},{value:"constellation recover",id:"constellation-recover",level:2},{value:"Synopsis",id:"synopsis-16",level:3},{value:"Options",id:"options-16",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-16",level:3},{value:"constellation terminate",id:"constellation-terminate",level:2},{value:"Synopsis",id:"synopsis-17",level:3},{value:"Options",id:"options-17",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-17",level:3},{value:"constellation iam",id:"constellation-iam",level:2},{value:"Synopsis",id:"synopsis-18",level:3},{value:"Options",id:"options-18",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-18",level:3},{value:"constellation iam create",id:"constellation-iam-create",level:2},{value:"Synopsis",id:"synopsis-19",level:3},{value:"Options",id:"options-19",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-19",level:3},{value:"constellation iam create aws",id:"constellation-iam-create-aws",level:2},{value:"Synopsis",id:"synopsis-20",level:3},{value:"Options",id:"options-20",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-20",level:3},{value:"constellation iam create azure",id:"constellation-iam-create-azure",level:2},{value:"Synopsis",id:"synopsis-21",level:3},{value:"Options",id:"options-21",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-21",level:3},{value:"constellation iam create gcp",id:"constellation-iam-create-gcp",level:2},{value:"Synopsis",id:"synopsis-22",level:3},{value:"Options",id:"options-22",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-22",level:3},{value:"constellation iam destroy",id:"constellation-iam-destroy",level:2},{value:"Synopsis",id:"synopsis-23",level:3},{value:"Options",id:"options-23",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-23",level:3},{value:"constellation iam upgrade",id:"constellation-iam-upgrade",level:2},{value:"Synopsis",id:"synopsis-24",level:3},{value:"Options",id:"options-24",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-24",level:3},{value:"constellation iam upgrade apply",id:"constellation-iam-upgrade-apply",level:2},{value:"Synopsis",id:"synopsis-25",level:3},{value:"Options",id:"options-25",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-25",level:3},{value:"constellation version",id:"constellation-version",level:2},{value:"Synopsis",id:"synopsis-26",level:3},{value:"Options",id:"options-26",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-26",level:3},{value:"constellation init",id:"constellation-init",level:2},{value:"Synopsis",id:"synopsis-27",level:3},{value:"Options",id:"options-27",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-27",level:3},{value:"constellation ssh",id:"constellation-ssh",level:2},{value:"Synopsis",id:"synopsis-28",level:3},{value:"Options",id:"options-28",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-28",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"cli-reference",children:"CLI reference"})}),"\n",(0,s.jsx)(n.p,{children:"Use the Constellation CLI to create and manage your clusters."}),"\n",(0,s.jsx)(n.p,{children:"Usage:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation [command]\n"})}),"\n",(0,s.jsx)(n.p,{children:"Commands:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config",children:"config"}),": Work with the Constellation configuration file","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-generate",children:"generate"}),": Generate a default configuration and state file"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-fetch-measurements",children:"fetch-measurements"}),": Fetch measurements for configured cloud provider and image"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-instance-types",children:"instance-types"}),": Print the supported instance types for all cloud providers"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-kubernetes-versions",children:"kubernetes-versions"}),": Print the Kubernetes versions supported by this CLI"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-migrate",children:"migrate"}),": Migrate a configuration file to a new version"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-create",children:"create"}),": Create instances on a cloud platform for your Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-apply",children:"apply"}),": Apply a configuration to a Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-mini",children:"mini"}),": Manage MiniConstellation clusters","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-mini-up",children:"up"}),": Create and initialize a new MiniConstellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-mini-down",children:"down"}),": Destroy a MiniConstellation cluster"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-status",children:"status"}),": Show status of a Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-verify",children:"verify"}),": Verify the confidential properties of a Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-upgrade",children:"upgrade"}),": Find and apply upgrades to your Constellation cluster","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-upgrade-check",children:"check"}),": Check for possible upgrades"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-upgrade-apply",children:"apply"}),": Apply an upgrade to a Constellation cluster"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-recover",children:"recover"}),": Recover a completely stopped Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-terminate",children:"terminate"}),": Terminate a Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam",children:"iam"}),": Work with the IAM configuration on your cloud provider","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-create",children:"create"}),": Create IAM configuration on a cloud platform for your Constellation cluster","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-create-aws",children:"aws"}),": Create IAM configuration on AWS for your Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-create-azure",children:"azure"}),": Create IAM configuration on Microsoft Azure for your Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-create-gcp",children:"gcp"}),": Create IAM configuration on GCP for your Constellation cluster"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-destroy",children:"destroy"}),": Destroy an IAM configuration and delete local Terraform files"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-upgrade",children:"upgrade"}),": Find and apply upgrades to your IAM profile","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-upgrade-apply",children:"apply"}),": Apply an upgrade to an IAM profile"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-version",children:"version"}),": Display version of this CLI"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-init",children:"init"}),": Initialize the Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-ssh",children:"ssh"}),": Generate a certificate for emergency SSH access"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config",children:"constellation config"}),"\n",(0,s.jsx)(n.p,{children:"Work with the Constellation configuration file"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Work with the Constellation configuration file."}),"\n",(0,s.jsx)(n.h3,{id:"options",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for config\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-generate",children:"constellation config generate"}),"\n",(0,s.jsx)(n.p,{children:"Generate a default configuration and state file"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-1",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Generate a default configuration and state file for your selected cloud provider."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config generate {aws|azure|gcp|openstack|qemu|stackit} [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-1",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' -a, --attestation string attestation variant to use {aws-sev-snp|aws-nitro-tpm|azure-sev-snp|azure-tdx|azure-trustedlaunch|gcp-sev-snp|gcp-sev-es|qemu-vtpm}. If not specified, the default for the cloud provider is used\n -h, --help help for generate\n -k, --kubernetes string Kubernetes version to use in format MAJOR.MINOR (default "v1.30")\n -t, --tags strings additional tags for created resources given a list of key=value\n'})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-1",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-fetch-measurements",children:"constellation config fetch-measurements"}),"\n",(0,s.jsx)(n.p,{children:"Fetch measurements for configured cloud provider and image"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-2",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Fetch measurements for configured cloud provider and image."}),"\n",(0,s.jsx)(n.p,{children:"A config needs to be generated first."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config fetch-measurements [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-2",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for fetch-measurements\n -s, --signature-url string alternative URL to fetch measurements' signature from\n -u, --url string alternative URL to fetch measurements from\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-2",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-instance-types",children:"constellation config instance-types"}),"\n",(0,s.jsx)(n.p,{children:"Print the supported instance types for all cloud providers"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-3",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Print the supported instance types for all cloud providers."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config instance-types [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-3",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for instance-types\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-3",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-kubernetes-versions",children:"constellation config kubernetes-versions"}),"\n",(0,s.jsx)(n.p,{children:"Print the Kubernetes versions supported by this CLI"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-4",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Print the Kubernetes versions supported by this CLI."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config kubernetes-versions [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-4",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for kubernetes-versions\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-4",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-migrate",children:"constellation config migrate"}),"\n",(0,s.jsx)(n.p,{children:"Migrate a configuration file to a new version"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-5",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Migrate a configuration file to a new version."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config migrate [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-5",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for migrate\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-5",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-create",children:"constellation create"}),"\n",(0,s.jsx)(n.p,{children:"Create instances on a cloud platform for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-6",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create instances on a cloud platform for your Constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation create [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-6",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for create\n -y, --yes create the cluster without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-6",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-apply",children:"constellation apply"}),"\n",(0,s.jsx)(n.p,{children:"Apply a configuration to a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-7",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Apply a configuration to a Constellation cluster to initialize or upgrade the cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation apply [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-7",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" --conformance enable conformance mode\n -h, --help help for apply\n --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config\n --skip-helm-wait install helm charts without waiting for deployments to be ready\n --skip-phases strings comma-separated list of upgrade phases to skip\n one or multiple of { infrastructure | init | attestationconfig | certsans | helm | image | k8s }\n -y, --yes run command without further confirmation\n WARNING: the command might delete or update existing resources without additional checks. Please read the docs.\n \n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-7",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-mini",children:"constellation mini"}),"\n",(0,s.jsx)(n.p,{children:"Manage MiniConstellation clusters"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-8",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Manage MiniConstellation clusters."}),"\n",(0,s.jsx)(n.h3,{id:"options-8",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for mini\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-8",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-mini-up",children:"constellation mini up"}),"\n",(0,s.jsx)(n.p,{children:"Create and initialize a new MiniConstellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-9",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create and initialize a new MiniConstellation cluster."}),"\n",(0,s.jsx)(n.p,{children:"A mini cluster consists of a single control-plane and worker node, hosted using QEMU/KVM."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation mini up [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-9",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for up\n --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config (default true)\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-9",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-mini-down",children:"constellation mini down"}),"\n",(0,s.jsx)(n.p,{children:"Destroy a MiniConstellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-10",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Destroy a MiniConstellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation mini down [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-10",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for down\n -y, --yes terminate the cluster without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-10",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-status",children:"constellation status"}),"\n",(0,s.jsx)(n.p,{children:"Show status of a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-11",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Show the status of a constellation cluster."}),"\n",(0,s.jsx)(n.p,{children:"Shows microservice, image, and Kubernetes versions installed in the cluster. Also shows status of current version upgrades."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation status [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-11",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for status\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-11",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-verify",children:"constellation verify"}),"\n",(0,s.jsx)(n.p,{children:"Verify the confidential properties of a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-12",children:"Synopsis"}),"\n",(0,s.jsxs)(n.p,{children:["Verify the confidential properties of a Constellation cluster.\nIf arguments aren't specified, values are read from ",(0,s.jsx)(n.code,{children:"constellation-state.yaml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation verify [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-12",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" --cluster-id string expected cluster identifier\n -h, --help help for verify\n -e, --node-endpoint string endpoint of the node to verify, passed as HOST[:PORT]\n -o, --output string print the attestation document in the output format {json|raw}\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-12",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-upgrade",children:"constellation upgrade"}),"\n",(0,s.jsx)(n.p,{children:"Find and apply upgrades to your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-13",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Find and apply upgrades to your Constellation cluster."}),"\n",(0,s.jsx)(n.h3,{id:"options-13",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for upgrade\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-13",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-upgrade-check",children:"constellation upgrade check"}),"\n",(0,s.jsx)(n.p,{children:"Check for possible upgrades"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-14",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Check which upgrades can be applied to your Constellation Cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation upgrade check [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-14",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' -h, --help help for check\n --ref string the reference to use for querying new versions (default "-")\n --stream string the stream to use for querying new versions (default "stable")\n -u, --update-config update the specified config file with the suggested versions\n'})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-14",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-upgrade-apply",children:"constellation upgrade apply"}),"\n",(0,s.jsx)(n.p,{children:"Apply an upgrade to a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-15",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Apply an upgrade to a Constellation cluster by applying the chosen configuration."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation upgrade apply [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-15",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" --conformance enable conformance mode\n -h, --help help for apply\n --skip-helm-wait install helm charts without waiting for deployments to be ready\n --skip-phases strings comma-separated list of upgrade phases to skip\n one or multiple of { infrastructure | helm | image | k8s }\n -y, --yes run upgrades without further confirmation\n WARNING: might delete your resources in case you are using cert-manager in your cluster. Please read the docs.\n WARNING: might unintentionally overwrite measurements in the running cluster.\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-15",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-recover",children:"constellation recover"}),"\n",(0,s.jsx)(n.p,{children:"Recover a completely stopped Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-16",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Recover a Constellation cluster by sending a recovery key to an instance in the boot stage."}),"\n",(0,s.jsx)(n.p,{children:"This is only required if instances restart without other instances available for bootstrapping."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation recover [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-16",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -e, --endpoint string endpoint of the instance, passed as HOST[:PORT]\n -h, --help help for recover\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-16",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-terminate",children:"constellation terminate"}),"\n",(0,s.jsx)(n.p,{children:"Terminate a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-17",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Terminate a Constellation cluster."}),"\n",(0,s.jsx)(n.p,{children:"The cluster can't be started again, and all persistent storage will be lost."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation terminate [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-17",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for terminate\n -y, --yes terminate the cluster without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-17",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam",children:"constellation iam"}),"\n",(0,s.jsx)(n.p,{children:"Work with the IAM configuration on your cloud provider"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-18",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Work with the IAM configuration on your cloud provider."}),"\n",(0,s.jsx)(n.h3,{id:"options-18",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for iam\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-18",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-create",children:"constellation iam create"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on a cloud platform for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-19",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on a cloud platform for your Constellation cluster."}),"\n",(0,s.jsx)(n.h3,{id:"options-19",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for create\n --update-config update the config file with the specific IAM information\n -y, --yes create the IAM configuration without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-19",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-create-aws",children:"constellation iam create aws"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on AWS for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-20",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on AWS for your Constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam create aws [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-20",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for aws\n --prefix string name prefix for all resources (required)\n --zone string AWS availability zone the resources will be created in, e.g., us-east-2a (required)\n See the Constellation docs for a list of currently supported regions.\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-20",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n --update-config update the config file with the specific IAM information\n -C, --workspace string path to the Constellation workspace\n -y, --yes create the IAM configuration without further confirmation\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-create-azure",children:"constellation iam create azure"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on Microsoft Azure for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-21",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on Microsoft Azure for your Constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam create azure [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-21",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for azure\n --region string region the resources will be created in, e.g., westus (required)\n --resourceGroup string name prefix of the two resource groups your cluster / IAM resources will be created in (required)\n --servicePrincipal string name of the service principal that will be created (required)\n --subscriptionID string subscription ID of the Azure account. Required if the 'ARM_SUBSCRIPTION_ID' environment variable is not set\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-21",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n --update-config update the config file with the specific IAM information\n -C, --workspace string path to the Constellation workspace\n -y, --yes create the IAM configuration without further confirmation\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-create-gcp",children:"constellation iam create gcp"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on GCP for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-22",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on GCP for your Constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam create gcp [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-22",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for gcp\n --prefix string Prefix for the service account ID and VM ID that will be created (required)\n Must be letters, digits, or hyphens.\n --projectID string ID of the GCP project the configuration will be created in (required)\n Find it on the welcome screen of your project: https://console.cloud.google.com/welcome\n --zone string GCP zone the cluster will be deployed in (required)\n Find a list of available zones here: https://cloud.google.com/compute/docs/regions-zones#available\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-22",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n --update-config update the config file with the specific IAM information\n -C, --workspace string path to the Constellation workspace\n -y, --yes create the IAM configuration without further confirmation\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-destroy",children:"constellation iam destroy"}),"\n",(0,s.jsx)(n.p,{children:"Destroy an IAM configuration and delete local Terraform files"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-23",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Destroy an IAM configuration and delete local Terraform files."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam destroy [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-23",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for destroy\n -y, --yes destroy the IAM configuration without asking for confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-23",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-upgrade",children:"constellation iam upgrade"}),"\n",(0,s.jsx)(n.p,{children:"Find and apply upgrades to your IAM profile"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-24",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Find and apply upgrades to your IAM profile."}),"\n",(0,s.jsx)(n.h3,{id:"options-24",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for upgrade\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-24",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-upgrade-apply",children:"constellation iam upgrade apply"}),"\n",(0,s.jsx)(n.p,{children:"Apply an upgrade to an IAM profile"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-25",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Apply an upgrade to an IAM profile."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam upgrade apply [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-25",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for apply\n -y, --yes run upgrades without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-25",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-version",children:"constellation version"}),"\n",(0,s.jsx)(n.p,{children:"Display version of this CLI"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-26",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Display version of this CLI."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation version [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-26",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for version\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-26",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-init",children:"constellation init"}),"\n",(0,s.jsx)(n.p,{children:"Initialize the Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-27",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Initialize the Constellation cluster."}),"\n",(0,s.jsx)(n.p,{children:"Start your confidential Kubernetes."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation init [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-27",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" --conformance enable conformance mode\n -h, --help help for init\n --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config\n --skip-helm-wait install helm charts without waiting for deployments to be ready\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-27",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-ssh",children:"constellation ssh"}),"\n",(0,s.jsx)(n.p,{children:"Generate a certificate for emergency SSH access"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-28",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Generate a certificate for emergency SSH access to your SSH-enabled constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation ssh [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-28",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for ssh\n --key string the path to an existing SSH public key\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-28",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/5aae01e0.4eb12944.js b/pr-preview/pr-4027/assets/js/5aae01e0.4eb12944.js deleted file mode 100644 index 3907d1cbf..000000000 --- a/pr-preview/pr-4027/assets/js/5aae01e0.4eb12944.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[249],{11480:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"workflows/terminate","title":"Terminate your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","source":"@site/versioned_docs/version-2.22/workflows/terminate.md","sourceDirName":"workflows","slug":"/workflows/terminate","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/terminate","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/workflows/terminate.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Install s3proxy","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/s3proxy"},"next":{"title":"Recover your cluster","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/recovery"}}');var o=n(74848),s=n(28453);const a={},i="Terminate your cluster",l={},c=[];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",header:"header",hr:"hr",p:"p",pre:"pre",...(0,s.R)(),...e.components},{AsciinemaWidget:n,TabItem:r,Tabs:a}=t;return n||u("AsciinemaWidget",!0),r||u("TabItem",!0),a||u("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"terminate-your-cluster",children:"Terminate your cluster"})}),"\n",(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsx)(t.p,{children:"This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details."})}),"\n",(0,o.jsx)(n,{src:"/constellation/assets/terminate-cluster.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,o.jsx)(t.hr,{}),"\n",(0,o.jsxs)(t.p,{children:["You can terminate your cluster using the CLI. For this, you need the Terraform state directory named ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/reference/terraform",children:(0,o.jsx)(t.code,{children:"constellation-terraform"})})," in the current directory."]}),"\n",(0,o.jsx)(t.admonition,{type:"danger",children:(0,o.jsx)(t.p,{children:"All ephemeral storage and state of your cluster will be lost. Make sure any data is safely stored in persistent storage. Constellation can recreate your cluster and the associated encryption keys, but won't backup your application data automatically."})}),"\n",(0,o.jsxs)(a,{groupId:"provider",children:[(0,o.jsxs)(r,{value:"cli",label:"CLI",children:[(0,o.jsx)(t.p,{children:"Terminate the cluster by running:"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation terminate\n"})}),(0,o.jsx)(t.p,{children:"Or without confirmation (e.g., for automation purposes):"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation terminate --yes\n"})}),(0,o.jsxs)(t.p,{children:["This deletes all resources created by Constellation in your cloud environment.\nAll local files created by the ",(0,o.jsx)(t.code,{children:"apply"})," command are deleted as well, except for ",(0,o.jsx)(t.code,{children:"constellation-mastersecret.json"})," and the configuration file."]}),(0,o.jsx)(t.admonition,{type:"caution",children:(0,o.jsxs)(t.p,{children:["Termination can fail if additional resources have been created that depend on the ones managed by Constellation. In this case, you need to delete these additional\nresources manually. Just run the ",(0,o.jsx)(t.code,{children:"terminate"})," command again afterward to continue the termination process of the cluster."]})})]}),(0,o.jsxs)(r,{value:"terraform",label:"Terraform",children:[(0,o.jsx)(t.p,{children:"Terminate the cluster by running:"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"terraform destroy\n"})}),(0,o.jsx)(t.p,{children:"Delete all files that are no longer needed:"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"rm constellation-state.yaml constellation-admin.conf\n"})}),(0,o.jsxs)(t.p,{children:["Only the ",(0,o.jsx)(t.code,{children:"constellation-mastersecret.json"})," and the configuration file remain."]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}function u(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var r=n(96540);const o={},s=r.createContext(o);function a(e){const t=r.useContext(s);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/5bf0e48f.1b0be145.js b/pr-preview/pr-4027/assets/js/5bf0e48f.1b0be145.js deleted file mode 100644 index 5f3161eac..000000000 --- a/pr-preview/pr-4027/assets/js/5bf0e48f.1b0be145.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8917],{28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>o});var r=n(96540);const a={},i=r.createContext(a);function s(e){const t=r.useContext(i);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),r.createElement(i.Provider,{value:t},e.children)}},60602:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"architecture/keys","title":"Key management and cryptographic primitives","description":"Constellation protects and isolates your cluster and workloads.","source":"@site/docs/architecture/keys.md","sourceDirName":"architecture","slug":"/architecture/keys","permalink":"/constellation/pr-preview/pr-4027/next/architecture/keys","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/architecture/keys.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Images","permalink":"/constellation/pr-preview/pr-4027/next/architecture/images"},"next":{"title":"Encrypted persistent storage","permalink":"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage"}}');var a=n(74848),i=n(28453);const s={},o="Key management and cryptographic primitives",l={},c=[{value:"Confidential VMs",id:"confidential-vms",level:2},{value:"Master secret",id:"master-secret",level:2},{value:"Cluster identity",id:"cluster-identity",level:2},{value:"Network encryption",id:"network-encryption",level:2},{value:"Storage encryption",id:"storage-encryption",level:2},{value:"Constellation-managed key management",id:"constellation-managed-key-management",level:3},{value:"Key material and key derivation",id:"key-material-and-key-derivation",level:4},{value:"State and storage",id:"state-and-storage",level:4},{value:"Availability",id:"availability",level:4},{value:"Recovery",id:"recovery",level:4},{value:"User-managed key management",id:"user-managed-key-management",level:3},{value:"Recovery and migration",id:"recovery-and-migration",level:4}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"key-management-and-cryptographic-primitives",children:"Key management and cryptographic primitives"})}),"\n",(0,a.jsx)(t.p,{children:"Constellation protects and isolates your cluster and workloads.\nTo that end, cryptography is the foundation that ensures the confidentiality and integrity of all components.\nEvaluating the security and compliance of Constellation requires a precise understanding of the cryptographic primitives and keys used.\nThe following gives an overview of the architecture and explains the technical details."}),"\n",(0,a.jsx)(t.h2,{id:"confidential-vms",children:"Confidential VMs"}),"\n",(0,a.jsx)(t.p,{children:"Confidential VM (CVM) technology comes with hardware and software components for memory encryption, isolation, and remote attestation.\nFor details on the implementations and cryptographic soundness, refer to the hardware vendors' documentation and advisories."}),"\n",(0,a.jsx)(t.h2,{id:"master-secret",children:"Master secret"}),"\n",(0,a.jsxs)(t.p,{children:["The master secret is the cryptographic material used for deriving the ",(0,a.jsx)(t.a,{href:"#cluster-identity",children:(0,a.jsx)(t.em,{children:"clusterID"})})," and the ",(0,a.jsx)(t.em,{children:"key encryption key (KEK)"})," for ",(0,a.jsx)(t.a,{href:"#storage-encryption",children:"storage encryption"}),".\nIt's generated during the bootstrapping of a Constellation cluster.\nIt can either be managed by ",(0,a.jsx)(t.a,{href:"#constellation-managed-key-management",children:"Constellation"})," or an ",(0,a.jsx)(t.a,{href:"#user-managed-key-management",children:"external key management system"}),".\nIn case of ",(0,a.jsx)(t.a,{href:"#recovery-and-migration",children:"recovery"}),", the master secret allows to decrypt the state and recover a Constellation cluster."]}),"\n",(0,a.jsx)(t.h2,{id:"cluster-identity",children:"Cluster identity"}),"\n",(0,a.jsxs)(t.p,{children:["The identity of a Constellation cluster is represented by cryptographic ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/attestation#runtime-measurements",children:"measurements"}),":"]}),"\n",(0,a.jsxs)(t.p,{children:["The ",(0,a.jsx)(t.strong,{children:"base measurements"})," represent the identity of a valid, uninitialized Constellation node.\nThey depend on the node image, but are otherwise the same for every Constellation cluster.\nOn node boot, they're determined using the CVM's attestation mechanism and ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/images",children:"measured boot up to the read-only root filesystem"}),"."]}),"\n",(0,a.jsxs)(t.p,{children:["The ",(0,a.jsx)(t.strong,{children:"clusterID"})," represents the identity of a single initialized Constellation cluster.\nIt's derived from the master secret and a cryptographically random salt and unique for every Constellation cluster.\nThe ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#bootstrapper",children:"Bootstrapper"})," measures the ",(0,a.jsx)(t.em,{children:"clusterID"})," into its own PCR before executing any code not measured as part of the ",(0,a.jsx)(t.em,{children:"base measurements"}),".\nSee ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/attestation#node-attestation",children:"Node attestation"})," for details."]}),"\n",(0,a.jsxs)(t.p,{children:["The remote attestation statement of a Constellation cluster combines the ",(0,a.jsx)(t.em,{children:"base measurements"})," and the ",(0,a.jsx)(t.em,{children:"clusterID"})," for a verifiable, unspoofable, unique identity."]}),"\n",(0,a.jsx)(t.h2,{id:"network-encryption",children:"Network encryption"}),"\n",(0,a.jsxs)(t.p,{children:["Constellation encrypts all cluster network communication using the ",(0,a.jsx)(t.a,{href:"https://github.com/containernetworking/cni",children:"container network interface (CNI)"}),".\nSee ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/networking",children:"network encryption"})," for more details."]}),"\n",(0,a.jsxs)(t.p,{children:["The Cilium agent running on each node establishes a secure ",(0,a.jsx)(t.a,{href:"https://www.wireguard.com/",children:"WireGuard"})," tunnel between it and all other known nodes in the cluster.\nEach node creates its own ",(0,a.jsx)(t.a,{href:"http://cr.yp.to/ecdh.html",children:"Curve25519"})," encryption key pair and distributes its public key via Kubernetes.\nA node uses another node's public key to decrypt and encrypt traffic from and to Cilium-managed endpoints running on that node.\nConnections are always encrypted peer-to-peer using ",(0,a.jsx)(t.a,{href:"http://cr.yp.to/chacha.html",children:"ChaCha20"})," with ",(0,a.jsx)(t.a,{href:"http://cr.yp.to/mac.html",children:"Poly1305"}),".\nWireGuard implements ",(0,a.jsx)(t.a,{href:"https://lists.zx2c4.com/pipermail/wireguard/2017-December/002141.html",children:"forward secrecy with key rotation every 2 minutes"}),"."]}),"\n",(0,a.jsx)(t.h2,{id:"storage-encryption",children:"Storage encryption"}),"\n",(0,a.jsx)(t.p,{children:"Constellation supports transparent encryption of persistent storage.\nThe Linux kernel's device mapper-based encryption features are used to encrypt the data on the block storage level.\nCurrently, the following primitives are used for block storage encryption:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-crypt.html",children:"dm-crypt"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-integrity.html",children:"dm-integrity"})}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["Adding primitives for integrity protection in the CVM attacker model are under active development and will be available in a future version of Constellation.\nSee ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage",children:"encrypted storage"})," for more details."]}),"\n",(0,a.jsxs)(t.p,{children:["As a cluster administrator, when creating a cluster, you can use the Constellation ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/orchestration",children:"installation program"})," to select one of the following methods for key management:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Constellation-managed key management"}),"\n",(0,a.jsx)(t.li,{children:"User-managed key management"}),"\n"]}),"\n",(0,a.jsx)(t.h3,{id:"constellation-managed-key-management",children:"Constellation-managed key management"}),"\n",(0,a.jsx)(t.h4,{id:"key-material-and-key-derivation",children:"Key material and key derivation"}),"\n",(0,a.jsxs)(t.p,{children:["During the creation of a Constellation cluster, the cluster's master secret is used to derive a KEK.\nThis means creating two clusters with the same master secret will yield the same KEK.\nAny data encryption key (DEK) is derived from the KEK via HKDF.\nNote that the master secret is recommended to be unique for every cluster and shouldn't be reused (except in case of ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/recovery",children:"recovering"})," a cluster)."]}),"\n",(0,a.jsx)(t.h4,{id:"state-and-storage",children:"State and storage"}),"\n",(0,a.jsx)(t.p,{children:"The KEK is derived from the master secret during the initialization.\nSubsequently, all other key material is derived from the KEK.\nGiven the same KEK, any DEK can be derived deterministically from a given identifier.\nHence, there is no need to store DEKs. They can be derived on demand.\nAfter the KEK was derived, it's stored in memory only and never leaves the CVM context."}),"\n",(0,a.jsx)(t.h4,{id:"availability",children:"Availability"}),"\n",(0,a.jsxs)(t.p,{children:["Constellation-managed key management has the same availability as the underlying Kubernetes cluster.\nTherefore, the KEK is stored in the ",(0,a.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/",children:"distributed Kubernetes etcd storage"})," to allow for unexpected but non-fatal (control-plane) node failure.\nThe etcd storage is backed by the encrypted and integrity protected ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/images#state-disk",children:"state disk"})," of the nodes."]}),"\n",(0,a.jsx)(t.h4,{id:"recovery",children:"Recovery"}),"\n",(0,a.jsxs)(t.p,{children:["Constellation clusters can be recovered in the event of a disaster, even when all node machines have been stopped and need to be rebooted.\nFor details on the process see the ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/recovery",children:"recovery workflow"}),"."]}),"\n",(0,a.jsx)(t.h3,{id:"user-managed-key-management",children:"User-managed key management"}),"\n",(0,a.jsx)(t.p,{children:"User-managed key management is under active development and will be available soon.\nIn scenarios where constellation-managed key management isn't an option, this mode allows you to keep full control of your keys.\nFor example, compliance requirements may force you to keep your KEKs in an on-prem key management system (KMS)."}),"\n",(0,a.jsx)(t.p,{children:'During the creation of a Constellation cluster, you specify a KEK present in a remote KMS.\nThis follows the common scheme of "bring your own key" (BYOK).\nConstellation will support several KMSs for managing the storage and access of your KEK.\nInitially, it will support the following KMSs:'}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://aws.amazon.com/kms/",children:"AWS KMS"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://cloud.google.com/security-key-management",children:"GCP KMS"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://azure.microsoft.com/en-us/services/key-vault/#product-overview",children:"Azure Key Vault"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=kmip",children:"KMIP-compatible KMS"})}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Storing the keys in Cloud KMS of AWS, Azure, or GCP binds the key usage to the particular cloud identity access management (IAM).\nIn the future, Constellation will support remote attestation-based access policies for Cloud KMS once available.\nNote that using a Cloud KMS limits the isolation and protection to the guarantees of the particular offering."}),"\n",(0,a.jsx)(t.p,{children:'KMIP support allows you to use your KMIP-compatible on-prem KMS and keep full control over your keys.\nThis follows the common scheme of "hold your own key" (HYOK).'}),"\n",(0,a.jsx)(t.p,{children:'The KEK is used to encrypt per-data "data encryption keys" (DEKs).\nDEKs are generated to encrypt your data before storing it on persistent storage.\nAfter being encrypted by the KEK, the DEKs are stored on dedicated cloud storage for persistence.\nCurrently, Constellation supports the following cloud storage options:'}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://aws.amazon.com/s3/",children:"AWS S3"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://cloud.google.com/storage",children:"GCP Cloud Storage"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://azure.microsoft.com/en-us/services/storage/blobs/#overview",children:"Azure Blob Storage"})}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"The DEKs are only present in plaintext form in the encrypted main memory of the CVMs.\nSimilarly, the cryptographic operations for encrypting data before writing it to persistent storage are performed in the context of the CVMs."}),"\n",(0,a.jsx)(t.h4,{id:"recovery-and-migration",children:"Recovery and migration"}),"\n",(0,a.jsx)(t.p,{children:"In the case of a disaster, the KEK can be used to decrypt the DEKs locally and subsequently use them to decrypt and retrieve the data.\nIn case of migration, configuring the same KEK will provide seamless migration of data.\nThus, only the DEK storage needs to be transferred to the new cluster alongside the encrypted data for seamless migration."})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/5d6cdc31.4cfde06b.js b/pr-preview/pr-4027/assets/js/5d6cdc31.4cfde06b.js deleted file mode 100644 index c0caceef5..000000000 --- a/pr-preview/pr-4027/assets/js/5d6cdc31.4cfde06b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2662],{28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>a});var n=s(96540);const o={},i=n.createContext(o);function r(e){const t=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(i.Provider,{value:t},e.children)}},43995:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"workflows/s3proxy","title":"Install s3proxy","description":"Constellation includes a transparent client-side encryption proxy for AWS S3 and compatible stores.","source":"@site/versioned_docs/version-2.22/workflows/s3proxy.md","sourceDirName":"workflows","slug":"/workflows/s3proxy","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/s3proxy","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/workflows/s3proxy.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Install cert-manager","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/cert-manager"},"next":{"title":"Terminate your cluster","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/terminate"}}');var o=s(74848),i=s(28453);const r={},a="Install s3proxy",l={},c=[{value:"Limitations",id:"limitations",level:2},{value:"Deployment",id:"deployment",level:2},{value:"Technical details",id:"technical-details",level:2},{value:"Encryption",id:"encryption",level:3},{value:"Traffic interception",id:"traffic-interception",level:3}];function p(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"install-s3proxy",children:"Install s3proxy"})}),"\n",(0,o.jsxs)(t.p,{children:["Constellation includes a transparent client-side encryption proxy for ",(0,o.jsx)(t.a,{href:"https://aws.amazon.com/de/s3/",children:"AWS S3"})," and compatible stores.\ns3proxy encrypts objects before sending them to S3 and automatically decrypts them on retrieval, without requiring changes to your application.\nWith s3proxy, you can use S3 for storage in a confidential way without having to trust the storage provider."]}),"\n",(0,o.jsx)(t.h2,{id:"limitations",children:"Limitations"}),"\n",(0,o.jsx)(t.p,{children:"Currently, s3proxy has the following limitations:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["Only ",(0,o.jsx)(t.code,{children:"PutObject"})," and ",(0,o.jsx)(t.code,{children:"GetObject"})," requests are encrypted/decrypted by s3proxy.\nBy default, s3proxy will block requests that may expose unencrypted data to S3 (e.g. UploadPart).\nThe ",(0,o.jsx)(t.code,{children:"allow-multipart"})," flag disables request blocking for evaluation purposes."]}),"\n",(0,o.jsxs)(t.li,{children:["Using the ",(0,o.jsx)(t.a,{href:"https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html#API_GetObject_RequestSyntax",children:"Range"})," header on ",(0,o.jsx)(t.code,{children:"GetObject"})," is currently not supported and will result in an error."]}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:["These limitations will be removed with future iterations of s3proxy.\nIf you want to use s3proxy but these limitations stop you from doing so, consider ",(0,o.jsx)(t.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&projects=&template=feature_request.yml",children:"opening an issue"}),"."]}),"\n",(0,o.jsx)(t.h2,{id:"deployment",children:"Deployment"}),"\n",(0,o.jsx)(t.p,{children:"You can add the s3proxy to your Constellation cluster as follows:"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsxs)(t.li,{children:["Add the Edgeless Systems chart repository:","\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"helm repo add edgeless https://helm.edgeless.systems/stable\nhelm repo update\n"})}),"\n"]}),"\n",(0,o.jsx)(t.li,{children:"Set ACCESS_KEY and ACCESS_SECRET to valid credentials you want s3proxy to use to interact with S3."}),"\n",(0,o.jsxs)(t.li,{children:["Deploy s3proxy:","\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:'helm install s3proxy edgeless/s3proxy --set awsAccessKeyID="$ACCESS_KEY" --set awsSecretAccessKey="$ACCESS_SECRET"\n'})}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:["If you want to run a demo application, check out the ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/filestash-s3proxy",children:"Filestash with s3proxy"})," example."]}),"\n",(0,o.jsx)(t.h2,{id:"technical-details",children:"Technical details"}),"\n",(0,o.jsx)(t.h3,{id:"encryption",children:"Encryption"}),"\n",(0,o.jsxs)(t.p,{children:["s3proxy relies on Google's ",(0,o.jsx)(t.a,{href:"https://developers.google.com/tink",children:"Tink Cryptographic Library"})," to implement cryptographic operations securely.\nThe used cryptographic primitives are ",(0,o.jsx)(t.a,{href:"https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf",children:"NIST SP 800 38f"})," for key wrapping and ",(0,o.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Advanced_Encryption_Standard",children:"AES"}),"-",(0,o.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Galois/counter_(GCM)",children:"GCM"})," with 256 bit keys for data encryption."]}),"\n",(0,o.jsxs)(t.p,{children:["s3proxy uses ",(0,o.jsx)(t.a,{href:"https://cloud.google.com/kms/docs/envelope-encryption",children:"envelope encryption"})," to encrypt objects.\nThis means s3proxy uses a key encryption key (KEK) issued by the ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#keyservice",children:"KeyService"})," to encrypt data encryption keys (DEKs).\nEach S3 object is encrypted with its own DEK.\nThe encrypted DEK is then saved as metadata of the encrypted object.\nThis enables key rotation of the KEK without re-encrypting the data in S3.\nThe approach also allows access to objects from different locations, as long as each location has access to the KEK."]}),"\n",(0,o.jsx)(t.h3,{id:"traffic-interception",children:"Traffic interception"}),"\n",(0,o.jsx)(t.p,{children:"To use s3proxy, you have to redirect your outbound S3 traffic to s3proxy.\nThis can either be done by modifying your client application or by changing the deployment of your application."}),"\n",(0,o.jsxs)(t.p,{children:["The necessary deployment modifications are to add DNS redirection and a trusted TLS certificate to the client's trust store.\nDNS redirection can be defined for each pod, allowing you to use s3proxy for one application without changing other applications in the same cluster.\nAdding a trusted TLS certificate is necessary as clients communicate with s3proxy via HTTPS.\nTo have your client application trust s3proxy's TLS certificate, the certificate has to be added to the client's certificate trust store.\nThe ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/filestash-s3proxy",children:"Filestash with s3proxy"})," example shows how to do this."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/5dc5a687.7b3d863e.js b/pr-preview/pr-4027/assets/js/5dc5a687.7b3d863e.js deleted file mode 100644 index c79faeb7a..000000000 --- a/pr-preview/pr-4027/assets/js/5dc5a687.7b3d863e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2762],{28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>i});var o=s(96540);const t={},r=o.createContext(t);function a(e){const n=o.useContext(r);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),o.createElement(r.Provider,{value:n},e.children)}},35385:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"workflows/lb","title":"Expose a service","description":"Constellation integrates the native load balancers of each CSP. Therefore, to expose a service simply create a service of type LoadBalancer.","source":"@site/versioned_docs/version-2.22/workflows/lb.md","sourceDirName":"workflows","slug":"/workflows/lb","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/lb","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/workflows/lb.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Upgrade your cluster","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade"},"next":{"title":"Install cert-manager","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/cert-manager"}}');var t=s(74848),r=s(28453);const a={},i="Expose a service",c={},l=[{value:"Internet-facing LB service on AWS",id:"internet-facing-lb-service-on-aws",level:2},{value:"Ingress on AWS",id:"ingress-on-aws",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"expose-a-service",children:"Expose a service"})}),"\n",(0,t.jsxs)(n.p,{children:["Constellation integrates the native load balancers of each CSP. Therefore, to expose a service simply ",(0,t.jsxs)(n.a,{href:"https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer",children:["create a service of type ",(0,t.jsx)(n.code,{children:"LoadBalancer"})]}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"internet-facing-lb-service-on-aws",children:"Internet-facing LB service on AWS"}),"\n",(0,t.jsxs)(n.p,{children:["To expose your application service externally you might want to use a Kubernetes Service of type ",(0,t.jsx)(n.code,{children:"LoadBalancer"}),". On AWS, load-balancing is achieved through the ",(0,t.jsx)(n.a,{href:"https://kubernetes-sigs.github.io/aws-load-balancer-controller",children:"AWS Load Balancer Controller"})," as in the managed EKS."]}),"\n",(0,t.jsxs)(n.p,{children:["Since recent versions, the controller deploy an internal LB by default requiring to set an annotation ",(0,t.jsx)(n.code,{children:"service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing"})," to have an internet-facing LB. For more details, see the ",(0,t.jsx)(n.a,{href:"https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.7/guide/service/nlb/",children:"official docs"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["For general information on LB with AWS see ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/eks/latest/userguide/network-load-balancing.html",children:"Network load balancing on Amazon EKS"}),"."]}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsx)(n.p,{children:"Before terminating the cluster, all LB backed services should be deleted, so that the controller can cleanup the related resources."})}),"\n",(0,t.jsx)(n.h2,{id:"ingress-on-aws",children:"Ingress on AWS"}),"\n",(0,t.jsxs)(n.p,{children:["The AWS Load Balancer Controller also provisions ",(0,t.jsx)(n.code,{children:"Ingress"})," resources of class ",(0,t.jsx)(n.code,{children:"alb"}),".\nAWS Application Load Balancers (ALBs) can be configured with a ",(0,t.jsx)(n.a,{href:"https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.7/guide/ingress/annotations/#target-type",children:(0,t.jsx)(n.code,{children:"target-type"})}),".\nThe target type ",(0,t.jsx)(n.code,{children:"ip"})," requires using the EKS container network solution, which makes it incompatible with Constellation.\nIf a service can be exposed on a ",(0,t.jsx)(n.code,{children:"NodePort"}),", the target type ",(0,t.jsx)(n.code,{children:"instance"})," can be used."]}),"\n",(0,t.jsxs)(n.p,{children:["See ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html",children:"Application load balancing on Amazon EKS"})," for more information."]}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsx)(n.p,{children:"Ingress handlers backed by AWS ALBs reside outside the Constellation cluster, so they shouldn't be handling sensitive traffic!"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/5e23635c.096a5bd0.js b/pr-preview/pr-4027/assets/js/5e23635c.096a5bd0.js deleted file mode 100644 index 6af0f8b18..000000000 --- a/pr-preview/pr-4027/assets/js/5e23635c.096a5bd0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1901],{28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>l});var i=s(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}},68074:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>a});const i=JSON.parse('{"id":"workflows/config","title":"Configure your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","source":"@site/versioned_docs/version-2.24/workflows/config.md","sourceDirName":"workflows","slug":"/workflows/config","permalink":"/constellation/pr-preview/pr-4027/workflows/config","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/workflows/config.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Verify the CLI","permalink":"/constellation/pr-preview/pr-4027/workflows/verify-cli"},"next":{"title":"Create your cluster","permalink":"/constellation/pr-preview/pr-4027/workflows/create"}}');var t=s(74848),r=s(28453);const o={},l="Configure your cluster",c={},a=[{value:"Creating the configuration file",id:"creating-the-configuration-file",level:2},{value:"Choosing a VM type",id:"choosing-a-vm-type",level:2},{value:"Creating additional node groups",id:"creating-additional-node-groups",level:2},{value:"Choosing a Kubernetes version",id:"choosing-a-kubernetes-version",level:2},{value:"Creating an IAM configuration",id:"creating-an-iam-configuration",level:2},{value:"Deleting an IAM configuration",id:"deleting-an-iam-configuration",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components},{AsciinemaWidget:s,Details:i,TabItem:o,Tabs:l}=n;return s||u("AsciinemaWidget",!0),i||u("Details",!0),o||u("TabItem",!0),l||u("Tabs",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"configure-your-cluster",children:"Configure your cluster"})}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsx)(n.p,{children:"This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details."})}),"\n",(0,t.jsx)(s,{src:"/constellation/assets/configure-cluster.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.p,{children:"Before you can create your cluster, you need to configure the identity and access management (IAM) for your cloud service provider (CSP) and choose machine types for the nodes."}),"\n",(0,t.jsx)(n.h2,{id:"creating-the-configuration-file",children:"Creating the configuration file"}),"\n",(0,t.jsx)(n.p,{children:"You can generate a configuration file for your CSP by using the following CLI command:"}),"\n",(0,t.jsxs)(l,{groupId:"csp",children:[(0,t.jsx)(o,{value:"aws",label:"AWS",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation config generate aws\n"})})}),(0,t.jsx)(o,{value:"azure",label:"Azure",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation config generate azure\n"})})}),(0,t.jsx)(o,{value:"gcp",label:"GCP",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation config generate gcp\n"})})}),(0,t.jsx)(o,{value:"stackit",label:"STACKIT",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation config generate stackit\n"})})})]}),"\n",(0,t.jsxs)(n.p,{children:["This creates the file ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," in the current directory."]}),"\n",(0,t.jsx)(n.h2,{id:"choosing-a-vm-type",children:"Choosing a VM type"}),"\n",(0,t.jsx)(n.p,{children:"Constellation supports the following VM types:"}),"\n",(0,t.jsxs)(l,{groupId:"csp",children:[(0,t.jsxs)(o,{value:"aws",label:"AWS",children:[(0,t.jsxs)(n.p,{children:["By default, Constellation uses ",(0,t.jsx)(n.code,{children:"m6a.xlarge"})," VMs (4 vCPUs, 16 GB RAM) to create your cluster.\nOptionally, you can switch to a different VM type by modifying ",(0,t.jsx)(n.code,{children:"instanceType"})," in the configuration file.\nIf you are using the default attestation variant ",(0,t.jsx)(n.code,{children:"awsSEVSNP"}),", you can use the instance types described in ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/snp-requirements.html",children:"AWS's AMD SEV-SNP docs"}),".\nPlease mind the region restrictions mentioned in the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/getting-started/first-steps#create-a-cluster",children:"Getting started"})," section."]}),(0,t.jsxs)(n.p,{children:["If you are using the attestation variant ",(0,t.jsx)(n.code,{children:"awsNitroTPM"}),", you can choose any of the ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enable-nitrotpm-prerequisites.html",children:"nitroTPM-enabled instance types"}),"."]}),(0,t.jsxs)(n.p,{children:["The Constellation CLI can also print the supported instance types with: ",(0,t.jsx)(n.code,{children:"constellation config instance-types"}),"."]})]}),(0,t.jsxs)(o,{value:"azure",label:"Azure",children:[(0,t.jsxs)(n.p,{children:["By default, Constellation uses ",(0,t.jsx)(n.code,{children:"Standard_DC4as_v5"})," CVMs (4 vCPUs, 16 GB RAM) to create your cluster. Optionally, you can switch to a different VM type by modifying ",(0,t.jsx)(n.code,{children:"instanceType"})," in the configuration file. For CVMs, any VM type with a minimum of 4 vCPUs from the ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/dcasv5-dcadsv5-series",children:"DCasv5 & DCadsv5"})," or ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/ecasv5-ecadsv5-series",children:"ECasv5 & ECadsv5"})," families is supported."]}),(0,t.jsxs)(n.p,{children:["You can also run ",(0,t.jsx)(n.code,{children:"constellation config instance-types"})," to get the list of all supported options."]})]}),(0,t.jsx)(o,{value:"gcp",label:"GCP",children:(0,t.jsxs)(n.p,{children:["By default, Constellation uses ",(0,t.jsx)(n.code,{children:"n2d-standard-4"})," VMs (4 vCPUs, 16 GB RAM) to create your cluster. Optionally, you can switch to a different VM type by modifying ",(0,t.jsx)(n.code,{children:"instanceType"})," in the configuration file. Supported are all machines with a minimum of 4 vCPUs from the ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/compute-optimized-machines#c2d_machine_types",children:"C2D"})," or ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/general-purpose-machines#n2d_machines",children:"N2D"})," family. You can run ",(0,t.jsx)(n.code,{children:"constellation config instance-types"})," to get the list of all supported options."]})}),(0,t.jsxs)(o,{value:"stackit",label:"STACKIT",children:[(0,t.jsxs)(n.p,{children:["By default, Constellation uses ",(0,t.jsx)(n.code,{children:"m1a.4cd"})," VMs (4 vCPUs, 30 GB RAM) to create your cluster.\nOptionally, you can switch to a different VM type by modifying ",(0,t.jsx)(n.code,{children:"instanceType"})," in the configuration file."]}),(0,t.jsx)(n.p,{children:"The following instance types are known to be supported:"}),(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"name"}),(0,t.jsx)(n.th,{children:"vCPUs"}),(0,t.jsx)(n.th,{children:"GB RAM"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"m1a.4cd"}),(0,t.jsx)(n.td,{children:"4"}),(0,t.jsx)(n.td,{children:"30"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"m1a.8cd"}),(0,t.jsx)(n.td,{children:"8"}),(0,t.jsx)(n.td,{children:"60"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"m1a.16cd"}),(0,t.jsx)(n.td,{children:"16"}),(0,t.jsx)(n.td,{children:"120"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"m1a.30cd"}),(0,t.jsx)(n.td,{children:"30"}),(0,t.jsx)(n.td,{children:"230"})]})]})]}),(0,t.jsxs)(n.p,{children:["You can choose any of the SEV-enabled instance types. You can find a list of all supported instance types in the ",(0,t.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/virtual-machine-flavors-75137231.html",children:"STACKIT documentation"}),"."]}),(0,t.jsxs)(n.p,{children:["The Constellation CLI can also print the supported instance types with: ",(0,t.jsx)(n.code,{children:"constellation config instance-types"}),"."]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Fill the desired VM type into the ",(0,t.jsx)(n.code,{children:"instanceType"})," fields in the ",(0,t.jsx)(n.code,{children:"constellation-conf.yml"})," file."]}),"\n",(0,t.jsx)(n.h2,{id:"creating-additional-node-groups",children:"Creating additional node groups"}),"\n",(0,t.jsxs)(n.p,{children:["By default, Constellation creates the node groups ",(0,t.jsx)(n.code,{children:"control_plane_default"})," and ",(0,t.jsx)(n.code,{children:"worker_default"})," for control-plane nodes and workers, respectively.\nIf you require additional control-plane or worker groups with different instance types, zone placements, or disk sizes, you can add additional node groups to the ",(0,t.jsx)(n.code,{children:"constellation-conf.yml"})," file.\nEach node group can be scaled individually."]}),"\n",(0,t.jsx)(n.p,{children:"Consider the following example for AWS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"nodeGroups:\n control_plane_default:\n role: control-plane\n instanceType: c6a.xlarge\n stateDiskSizeGB: 30\n stateDiskType: gp3\n zone: eu-west-1c\n initialCount: 3\n worker_default:\n role: worker\n instanceType: c6a.xlarge\n stateDiskSizeGB: 30\n stateDiskType: gp3\n zone: eu-west-1c\n initialCount: 2\n high_cpu:\n role: worker\n instanceType: c6a.24xlarge\n stateDiskSizeGB: 128\n stateDiskType: gp3\n zone: eu-west-1c\n initialCount: 1\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This configuration creates an additional node group ",(0,t.jsx)(n.code,{children:"high_cpu"})," with a larger instance type and disk."]}),"\n",(0,t.jsxs)(n.p,{children:["You can use the field ",(0,t.jsx)(n.code,{children:"zone"})," to specify what availability zone nodes of the group are placed in.\nOn Azure, this field is empty by default and nodes are automatically spread across availability zones.\nSTACKIT currently offers SEV-enabled CPUs in the ",(0,t.jsx)(n.code,{children:"eu01-1"}),", ",(0,t.jsx)(n.code,{children:"eu01-2"}),", and ",(0,t.jsx)(n.code,{children:"eu01-3"})," zones.\nConsult the documentation of your cloud provider for more information:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://aws.amazon.com/about-aws/global-infrastructure/regions_az/",children:"AWS"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/explore/global-infrastructure/availability-zones",children:"Azure"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones",children:"GCP"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/regions-and-availability-zones-75137212.html",children:"STACKIT"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"choosing-a-kubernetes-version",children:"Choosing a Kubernetes version"}),"\n",(0,t.jsxs)(n.p,{children:["To learn which Kubernetes versions can be installed with your current CLI, you can run ",(0,t.jsx)(n.code,{children:"constellation config kubernetes-versions"}),".\nSee also Constellation's ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/versions#kubernetes-support-policy",children:"Kubernetes support policy"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"creating-an-iam-configuration",children:"Creating an IAM configuration"}),"\n",(0,t.jsxs)(n.p,{children:["You can create an IAM configuration for your cluster automatically using the ",(0,t.jsx)(n.code,{children:"constellation iam create"})," command.\nIf you already have a Constellation configuration file, you can add the ",(0,t.jsx)(n.code,{children:"--update-config"})," flag to the command. This writes the needed IAM fields into your configuration. Furthermore, the flag updates the zone/region of the configuration if it hasn't been set yet."]}),"\n",(0,t.jsxs)(l,{groupId:"csp",children:[(0,t.jsxs)(o,{value:"aws",label:"AWS",children:[(0,t.jsxs)(n.p,{children:["You must be authenticated with the ",(0,t.jsx)(n.a,{href:"https://aws.amazon.com/en/cli/",children:"AWS CLI"})," in the shell session with a user that has the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/getting-started/install#set-up-cloud-credentials",children:"required permissions for IAM creation"}),"."]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation iam create aws --zone=us-east-2a --prefix=constellTest\n"})}),(0,t.jsxs)(n.p,{children:["This command creates IAM configuration for the AWS zone ",(0,t.jsx)(n.code,{children:"us-east-2a"})," using the prefix ",(0,t.jsx)(n.code,{children:"constellTest"})," for all named resources being created."]}),(0,t.jsx)(n.p,{children:"Constellation OS images are currently replicated to the following regions:"}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-central-1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-west-1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-west-3"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"us-east-2"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"ap-south-1"})}),"\n"]}),(0,t.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+AWS+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),(0,t.jsxs)(n.p,{children:["You can find a list of all ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions",children:"regions in AWS's documentation"}),"."]}),(0,t.jsxs)(n.p,{children:["Paste the output into the corresponding fields of the ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," file."]})]}),(0,t.jsxs)(o,{value:"azure",label:"Azure",children:[(0,t.jsxs)(n.p,{children:["You must be authenticated with the ",(0,t.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/cli/azure/install-azure-cli",children:"Azure CLI"})," in the shell session with a user that has the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/getting-started/install#set-up-cloud-credentials",children:"required permissions for IAM creation"}),"."]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation iam create azure --subscriptionID 00000000-0000-0000-0000-000000000000 --region=westus --resourceGroup=constellTest --servicePrincipal=spTest\n"})}),(0,t.jsxs)(n.p,{children:["This command creates IAM configuration on the Azure region ",(0,t.jsx)(n.code,{children:"westus"})," creating a new resource group ",(0,t.jsx)(n.code,{children:"constellTest"})," and a new service principal ",(0,t.jsx)(n.code,{children:"spTest"}),"."]}),(0,t.jsx)(n.p,{children:"CVMs are available in several Azure regions. Constellation OS images are currently replicated to the following:"}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"germanywestcentral"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"westus"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eastus"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"northeurope"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"westeurope"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"southeastasia"})}),"\n"]}),(0,t.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+Azure+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),(0,t.jsxs)(n.p,{children:["You can find a list of all ",(0,t.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/global-infrastructure/services/?products=virtual-machines®ions=all",children:"regions in Azure's documentation"}),"."]}),(0,t.jsxs)(n.p,{children:["Paste the output into the corresponding fields of the ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," file."]})]}),(0,t.jsxs)(o,{value:"gcp",label:"GCP",children:[(0,t.jsxs)(n.p,{children:["You must be authenticated with the ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/sdk/gcloud",children:"GCP CLI"})," in the shell session with a user that has the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/getting-started/install#set-up-cloud-credentials",children:"required permissions for IAM creation"}),"."]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation iam create gcp --projectID=yourproject-12345 --zone=europe-west3-a --prefix=constell-test\n"})}),(0,t.jsxs)(n.p,{children:["This command creates IAM configuration in the GCP project ",(0,t.jsx)(n.code,{children:"yourproject-12345"})," on the GCP zone ",(0,t.jsx)(n.code,{children:"europe-west3-a"})," creating a new service account ",(0,t.jsx)(n.code,{children:"constell-test"}),"."]}),(0,t.jsxs)(n.p,{children:["Note that only regions offering CVMs of the ",(0,t.jsx)(n.code,{children:"C2D"})," or ",(0,t.jsx)(n.code,{children:"N2D"})," series are supported. You can find a ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones#available",children:"list of all regions in Google's documentation"}),", which you can filter by machine type ",(0,t.jsx)(n.code,{children:"N2D"}),"."]}),(0,t.jsxs)(n.p,{children:["Paste the output into the corresponding fields of the ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," file."]})]}),(0,t.jsx)(o,{value:"stackit",label:"STACKIT",children:(0,t.jsxs)(n.p,{children:["STACKIT requires manual creation and configuration of service accounts. Look at the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/getting-started/first-steps",children:"first steps"})," for more information."]})})]}),"\n",(0,t.jsxs)(i,{children:[(0,t.jsx)("summary",{children:"Alternatively, you can manually create the IAM configuration on your CSP."}),(0,t.jsx)(n.p,{children:"The following describes the configuration fields and how you obtain the required information or create the required resources."}),(0,t.jsxs)(l,{groupId:"csp",children:[(0,t.jsx)(o,{value:"aws",label:"AWS",children:(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"region"}),": The name of your chosen AWS data center region, e.g., ",(0,t.jsx)(n.code,{children:"us-east-2"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Constellation OS images are currently replicated to the following regions:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-central-1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-west-1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-west-3"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"us-east-2"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"ap-south-1"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+AWS+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find a list of all ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions",children:"regions in AWS's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"zone"}),": The name of your chosen AWS data center availability zone, e.g., ",(0,t.jsx)(n.code,{children:"us-east-2a"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Learn more about ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-availability-zones",children:"availability zones in AWS's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"iamProfileControlPlane"}),": The name of an IAM instance profile attached to all control-plane nodes."]}),"\n",(0,t.jsxs)(n.p,{children:["You can create the resource with ",(0,t.jsx)(n.a,{href:"https://www.terraform.io/",children:"Terraform"}),". For that, use the ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/tree/release/v2.2/hack/terraform/aws/iam",children:"provided Terraform script"})," to generate the necessary profile. The profile name will be provided as Terraform output value: ",(0,t.jsx)(n.code,{children:"control_plane_instance_profile_name"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Alternatively, you can create the AWS profile with a tool of your choice. Use the JSON policy in ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/tree/release/v2.2/hack/terraform/aws/iam/main.tf",children:"main.tf"})," in the resource ",(0,t.jsx)(n.code,{children:"aws_iam_policy.control_plane_policy"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"iamProfileWorkerNodes"}),": The name of an IAM instance profile attached to all worker nodes."]}),"\n",(0,t.jsxs)(n.p,{children:["You can create the resource with ",(0,t.jsx)(n.a,{href:"https://www.terraform.io/",children:"Terraform"}),". For that, use the ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/tree/release/v2.2/hack/terraform/aws/iam",children:"provided Terraform script"})," to generate the necessary profile. The profile name will be provided as Terraform output value: ",(0,t.jsx)(n.code,{children:"worker_nodes_instance_profile_name"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Alternatively, you can create the AWS profile with a tool of your choice. Use the JSON policy in ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/tree/release/v2.2/hack/terraform/aws/iam/main.tf",children:"main.tf"})," in the resource ",(0,t.jsx)(n.code,{children:"aws_iam_policy.worker_node_policy"}),"."]}),"\n"]}),"\n"]})}),(0,t.jsx)(o,{value:"azure",label:"Azure",children:(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"subscription"}),": The UUID of your Azure subscription, e.g., ",(0,t.jsx)(n.code,{children:"8b8bd01f-efd9-4113-9bd1-c82137c32da7"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can view your subscription UUID via ",(0,t.jsx)(n.code,{children:"az account show"})," and read the ",(0,t.jsx)(n.code,{children:"id"})," field. For more information refer to ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id#find-your-azure-subscription",children:"Azure's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"tenant"}),": The UUID of your Azure tenant, e.g., ",(0,t.jsx)(n.code,{children:"3400e5a2-8fe2-492a-886c-38cb66170f25"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can view your tenant UUID via ",(0,t.jsx)(n.code,{children:"az account show"})," and read the ",(0,t.jsx)(n.code,{children:"tenant"})," field. For more information refer to ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id#find-your-azure-ad-tenant",children:"Azure's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"location"}),": The Azure datacenter location you want to deploy your cluster in, e.g., ",(0,t.jsx)(n.code,{children:"westus"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"CVMs are available in several Azure regions. Constellation OS images are currently replicated to the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"germanywestcentral"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"westus"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eastus"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"northeurope"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"westeurope"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"southeastasia"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+Azure+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find a list of all ",(0,t.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/global-infrastructure/services/?products=virtual-machines®ions=all",children:"regions in Azure's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"resourceGroup"}),": ",(0,t.jsx)(n.a,{href:"https://learn.microsoft.com/azure/azure-resource-manager/management/manage-resource-groups-portal",children:"Create a new resource group in Azure"})," for your Constellation cluster. Set this configuration field to the name of the created resource group."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"userAssignedIdentity"}),": ",(0,t.jsx)(n.a,{href:"https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/how-manage-user-assigned-managed-identities",children:"Create a new managed identity in Azure"}),". You should create the identity in a different resource group as all resources within the cluster resource group will be deleted on cluster termination."]}),"\n",(0,t.jsxs)(n.p,{children:["Add three role assignments to the identity: ",(0,t.jsx)(n.code,{children:"Owner"}),", ",(0,t.jsx)(n.code,{children:"Virtual Machine Contributor"}),", and ",(0,t.jsx)(n.code,{children:"Application Insights Component Contributor"}),". The ",(0,t.jsx)(n.code,{children:"scope"})," of all three should refer to the previously created cluster resource group."]}),"\n",(0,t.jsxs)(n.p,{children:["Set the configuration value to the full ID of the created identity, e.g., ",(0,t.jsx)(n.code,{children:"/subscriptions/8b8bd01f-efd9-4113-9bd1-c82137c32da7/resourcegroups/constellation-identity/providers/Microsoft.ManagedIdentity/userAssignedIdentities/constellation-identity"}),". You can get it by opening the ",(0,t.jsx)(n.code,{children:"JSON View"})," from the ",(0,t.jsx)(n.code,{children:"Overview"})," section of the identity."]}),"\n",(0,t.jsxs)(n.p,{children:["The user-assigned identity is used by instances of the cluster to access other cloud resources.\nFor more information about managed identities refer to ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-manage-user-assigned-managed-identities",children:"Azure's documentation"}),"."]}),"\n"]}),"\n"]})}),(0,t.jsx)(o,{value:"gcp",label:"GCP",children:(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"project"}),": The ID of your GCP project, e.g., ",(0,t.jsx)(n.code,{children:"constellation-129857"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find it on the ",(0,t.jsx)(n.a,{href:"https://console.cloud.google.com/welcome",children:"welcome screen of your GCP project"}),". For more information refer to ",(0,t.jsx)(n.a,{href:"https://support.google.com/googleapi/answer/7014113",children:"Google's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"region"}),": The GCP region you want to deploy your cluster in, e.g., ",(0,t.jsx)(n.code,{children:"us-central1"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find a ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones#available",children:"list of all regions in Google's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"zone"}),": The GCP zone you want to deploy your cluster in, e.g., ",(0,t.jsx)(n.code,{children:"us-central1-a"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find a ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones#available",children:"list of all zones in Google's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"serviceAccountKeyPath"}),": To configure this, you need to create a GCP ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/iam/docs/service-accounts",children:"service account"})," with the following permissions:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Compute Instance Admin (v1) (roles/compute.instanceAdmin.v1)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Compute Network Admin (roles/compute.networkAdmin)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Compute Security Admin (roles/compute.securityAdmin)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Compute Storage Admin (roles/compute.storageAdmin)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Service Account User (roles/iam.serviceAccountUser)"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Afterward, create and download a new JSON key for this service account. Place the downloaded file in your Constellation workspace, and set the config parameter to the filename, e.g., ",(0,t.jsx)(n.code,{children:"constellation-129857-15343dba46cb.json"}),"."]}),"\n"]}),"\n"]})}),(0,t.jsx)(o,{value:"stackit",label:"STACKIT",children:(0,t.jsxs)(n.p,{children:["STACKIT requires manual creation and configuration of service accounts. Look at the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/getting-started/first-steps",children:"first steps"})," for more information."]})})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Now that you've configured your CSP, you can ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/create",children:"create your cluster"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"deleting-an-iam-configuration",children:"Deleting an IAM configuration"}),"\n",(0,t.jsx)(n.p,{children:"You can keep a created IAM configuration and reuse it for new clusters. Alternatively, you can also delete it if you don't want to use it anymore."}),"\n",(0,t.jsxs)(n.p,{children:["Delete the IAM configuration by executing the following command in the same directory where you executed ",(0,t.jsx)(n.code,{children:"constellation iam create"})," (the directory that contains ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/reference/terraform",children:(0,t.jsx)(n.code,{children:"constellation-iam-terraform"})})," as a subdirectory):"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation iam destroy\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsxs)(n.p,{children:["For Azure, deleting the IAM configuration by executing ",(0,t.jsx)(n.code,{children:"constellation iam destroy"})," will delete the whole resource group created by ",(0,t.jsx)(n.code,{children:"constellation iam create"}),".\nThis also includes any additional resources in the resource group that weren't created by Constellation."]})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}function u(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/5e92d76a.c9131055.js b/pr-preview/pr-4027/assets/js/5e92d76a.c9131055.js deleted file mode 100644 index 2d917368d..000000000 --- a/pr-preview/pr-4027/assets/js/5e92d76a.c9131055.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[292],{2201:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"getting-started/first-steps","title":"First steps with Constellation","description":"The following steps guide you through the process of creating a cluster and deploying a sample app. This example assumes that you have successfully installed and set up Constellation,","source":"@site/versioned_docs/version-2.22/getting-started/first-steps.md","sourceDirName":"getting-started","slug":"/getting-started/first-steps","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/getting-started/first-steps.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Installation","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/install"},"next":{"title":"First steps (local)","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local"}}');var i=s(74848),l=s(28453);const o={},r="First steps with Constellation",a={},c=[{value:"Create a cluster",id:"create-a-cluster",level:2},{value:"Deploy a sample application",id:"deploy-a-sample-application",level:2},{value:"Terminate your cluster",id:"terminate-your-cluster",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,l.R)(),...e.components},{TabItem:s,Tabs:t}=n;return s||u("TabItem",!0),t||u("Tabs",!0),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"first-steps-with-constellation",children:"First steps with Constellation"})}),"\n",(0,i.jsxs)(n.p,{children:["The following steps guide you through the process of creating a cluster and deploying a sample app. This example assumes that you have successfully ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/install",children:"installed and set up Constellation"}),",\nand have access to a cloud subscription."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["If you don't have a cloud subscription, you can also set up a ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local",children:"local Constellation cluster using virtualization"})," for testing."]})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["If you encounter any problem with the following steps, make sure to use the ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/releases/latest",children:"latest release"})," and check out the ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"known issues"}),"."]})}),"\n",(0,i.jsx)(n.h2,{id:"create-a-cluster",children:"Create a cluster"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Create the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/config",children:"configuration file"})," and state file for your cloud provider. If you are following the steps of this guide, there is no need to edit the file."]}),"\n",(0,i.jsxs)(t,{groupId:"csp",children:[(0,i.jsx)(s,{value:"aws",label:"AWS",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation config generate aws\n"})})}),(0,i.jsx)(s,{value:"azure",label:"Azure",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation config generate azure\n"})})}),(0,i.jsx)(s,{value:"gcp",label:"GCP",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation config generate gcp\n"})})}),(0,i.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation config generate stackit\n"})})})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Create your ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/config#creating-an-iam-configuration",children:"IAM configuration"}),"."]}),"\n",(0,i.jsxs)(t,{groupId:"csp",children:[(0,i.jsxs)(s,{value:"aws",label:"AWS",children:[(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation iam create aws --zone=us-east-2a --prefix=constellTest --update-config\n"})}),(0,i.jsxs)(n.p,{children:["This command creates IAM configuration for the AWS zone ",(0,i.jsx)(n.code,{children:"us-east-2a"})," using the prefix ",(0,i.jsx)(n.code,{children:"constellTest"})," for all named resources being created. It also updates the configuration file ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"})," in your current directory with the IAM values filled in."]}),(0,i.jsxs)(n.p,{children:["Depending on the attestation variant selected on config generation, different regions are available.\nAMD SEV-SNP machines (requires the default attestation variant ",(0,i.jsx)(n.code,{children:"awsSEVSNP"}),") are currently available in the following regions:"]}),(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"eu-west-1"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"us-east-2"})}),"\n"]}),(0,i.jsxs)(n.p,{children:["You can find a list of regions that support AMD SEV-SNP in ",(0,i.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/snp-requirements.html",children:"AWS's documentation"}),"."]}),(0,i.jsxs)(n.p,{children:["NitroTPM machines (requires the attestation variant ",(0,i.jsx)(n.code,{children:"awsNitroTPM"}),") are available in all regions.\nConstellation OS images are currently replicated to the following regions:"]}),(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"eu-central-1"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"eu-west-1"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"eu-west-3"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"us-east-2"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"ap-south-1"})}),"\n"]}),(0,i.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+AWS+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),(0,i.jsxs)(n.p,{children:["You can find a list of all ",(0,i.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions",children:"regions in AWS's documentation"}),"."]})]}),(0,i.jsxs)(s,{value:"azure",label:"Azure",children:[(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation iam create azure --subscriptionID 00000000-0000-0000-0000-000000000000 --region=westus --resourceGroup=constellTest --servicePrincipal=spTest --update-config\n"})}),(0,i.jsxs)(n.p,{children:["This command creates IAM configuration on the Azure region ",(0,i.jsx)(n.code,{children:"westus"})," creating a new resource group ",(0,i.jsx)(n.code,{children:"constellTest"})," and a new service principal ",(0,i.jsx)(n.code,{children:"spTest"}),". It also updates the configuration file ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"})," in your current directory with the IAM values filled in."]}),(0,i.jsx)(n.p,{children:"CVMs are available in several Azure regions. Constellation OS images are currently replicated to the following:"}),(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"germanywestcentral"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"westus"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"eastus"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"northeurope"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"westeurope"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"southeastasia"})}),"\n"]}),(0,i.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+Azure+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),(0,i.jsxs)(n.p,{children:["You can find a list of all ",(0,i.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/global-infrastructure/services/?products=virtual-machines®ions=all",children:"regions in Azure's documentation"}),"."]})]}),(0,i.jsxs)(s,{value:"gcp",label:"GCP",children:[(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation iam create gcp --projectID=yourproject-12345 --zone=europe-west3-a --prefix=constell-test --update-config\n"})}),(0,i.jsxs)(n.p,{children:["This command creates IAM configuration in the GCP project ",(0,i.jsx)(n.code,{children:"yourproject-12345"})," on the GCP zone ",(0,i.jsx)(n.code,{children:"europe-west3-a"})," creating a new service account ",(0,i.jsx)(n.code,{children:"constell-test"}),". It also updates the configuration file ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"})," in your current directory with the IAM values filled in."]}),(0,i.jsxs)(n.p,{children:["Note that only regions offering CVMs of the ",(0,i.jsx)(n.code,{children:"C2D"})," or ",(0,i.jsx)(n.code,{children:"N2D"})," series are supported. You can find a ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones#available",children:"list of all regions in Google's documentation"}),", which you can filter by machine type ",(0,i.jsx)(n.code,{children:"C2D"})," or ",(0,i.jsx)(n.code,{children:"N2D"}),"."]})]}),(0,i.jsxs)(s,{value:"stackit",label:"STACKIT",children:[(0,i.jsxs)(n.p,{children:["To use Constellation on STACKIT, the cluster will use the User Access Token (UAT) that's generated ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/install",children:"during the install step"}),".\nAfter creating the accounts, fill in the STACKIT details in ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"})," under ",(0,i.jsx)(n.code,{children:"provider.openstack"}),":"]}),(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"stackitProjectID"}),": STACKIT project id (can be found after login on the ",(0,i.jsx)(n.a,{href:"https://portal.stackit.cloud",children:"STACKIT portal"}),")"]}),"\n"]}),(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"stackitProjectID"})," refers to the ID of your STACKIT project. The STACKIT portal also shows the OpenStack ID that's associated with your project in some places. Make sure you insert the STACKIT project ID in the ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"})," file. It's of the format ",(0,i.jsx)(n.code,{children:"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"}),"."]})})]})]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["To learn about all options you have for managing IAM resources and Constellation configuration, see the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/config",children:"Configuration workflow"}),"."]})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"3",children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Create the cluster. ",(0,i.jsx)(n.code,{children:"constellation apply"})," uses options set in ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"}),".\nIf you want to manually manage your cloud resources, for example by using ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/reference/terraform",children:"Terraform"}),", follow the corresponding instructions in the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/create",children:"Create workflow"}),"."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsx)(n.p,{children:"On Azure, you may need to wait 15+ minutes at this point for role assignments to propagate."})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation apply -y\n"})}),"\n",(0,i.jsx)(n.p,{children:"This should look similar to the following:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell-session",children:'$ constellation apply -y\nChecking for infrastructure changes\nThe following Constellation cluster will be created:\n 3 control-plane nodes of type n2d-standard-4 will be created.\n 1 worker node of type n2d-standard-4 will be created.\nCreating\nCloud infrastructure created successfully\nYour Constellation master secret was successfully written to ./constellation-mastersecret.json\nConnecting\nInitializing cluster\nInstalling Kubernetes components\nYour Constellation cluster was successfully initialized.\n\nConstellation cluster identifier g6iMP5wRU1b7mpOz2WEISlIYSfdAhB0oNaOg6XEwKFY=\nKubernetes configuration constellation-admin.conf\n\nYou can now connect to your cluster by executing:\n export KUBECONFIG="$PWD/constellation-admin.conf"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The cluster's identifier will be different in your output.\nKeep ",(0,i.jsx)(n.code,{children:"constellation-mastersecret.json"})," somewhere safe.\nThis will allow you to ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/recovery",children:"recover your cluster"})," in case of a disaster."]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["Depending on your CSP and region, ",(0,i.jsx)(n.code,{children:"constellation apply"})," may take 10+ minutes to complete."]})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Configure kubectl."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'export KUBECONFIG="$PWD/constellation-admin.conf"\n'})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"deploy-a-sample-application",children:"Deploy a sample application"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Deploy the ",(0,i.jsx)(n.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"emojivoto app"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Expose the frontend service locally"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments\nkubectl -n emojivoto port-forward svc/web-svc 8080:80 &\ncurl http://localhost:8080\nkill %1\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"terminate-your-cluster",children:"Terminate your cluster"}),"\n",(0,i.jsxs)(n.p,{children:["Use the CLI to terminate your cluster. If you manually used ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/reference/terraform",children:"Terraform"})," to manage your cloud resources, follow the corresponding instructions in the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/terminate",children:"Terminate workflow"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation terminate\n"})}),"\n",(0,i.jsx)(n.p,{children:"This should give the following output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell-session",children:"$ constellation terminate\nYou are about to terminate a Constellation cluster.\nAll of its associated resources will be DESTROYED.\nThis action is irreversible and ALL DATA WILL BE LOST.\nDo you want to continue? [y/n]:\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Confirm with ",(0,i.jsx)(n.code,{children:"y"})," to terminate the cluster:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell-session",children:"Terminating ...\nYour Constellation cluster was terminated successfully.\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Optionally, you can also ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/config#deleting-an-iam-configuration",children:"delete your IAM resources"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}function u(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>r});var t=s(96540);const i={},l=t.createContext(i);function o(e){const n=t.useContext(l);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/5e95c892.8e057c80.js b/pr-preview/pr-4027/assets/js/5e95c892.8e057c80.js deleted file mode 100644 index aba223861..000000000 --- a/pr-preview/pr-4027/assets/js/5e95c892.8e057c80.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9647],{83124:(s,e,a)=>{a.r(e),a.d(e,{default:()=>u});a(96540);var c=a(34164),l=a(18630),o=a(17153),n=a(22831),r=a(86185),t=a(74848);function u(s){return(0,t.jsx)(o.e3,{className:(0,c.A)(l.G.wrapper.docsPages),children:(0,t.jsx)(r.A,{children:(0,n.v)(s.route.routes)})})}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/60d3a1b7.20628eac.js b/pr-preview/pr-4027/assets/js/60d3a1b7.20628eac.js deleted file mode 100644 index bdbb0b3c5..000000000 --- a/pr-preview/pr-4027/assets/js/60d3a1b7.20628eac.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6665],{28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>l});var i=s(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}},97536:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>a});const i=JSON.parse('{"id":"workflows/config","title":"Configure your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","source":"@site/versioned_docs/version-2.23/workflows/config.md","sourceDirName":"workflows","slug":"/workflows/config","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/config","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/workflows/config.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Verify the CLI","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cli"},"next":{"title":"Create your cluster","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/create"}}');var t=s(74848),r=s(28453);const o={},l="Configure your cluster",c={},a=[{value:"Creating the configuration file",id:"creating-the-configuration-file",level:2},{value:"Choosing a VM type",id:"choosing-a-vm-type",level:2},{value:"Creating additional node groups",id:"creating-additional-node-groups",level:2},{value:"Choosing a Kubernetes version",id:"choosing-a-kubernetes-version",level:2},{value:"Creating an IAM configuration",id:"creating-an-iam-configuration",level:2},{value:"Deleting an IAM configuration",id:"deleting-an-iam-configuration",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components},{AsciinemaWidget:s,Details:i,TabItem:o,Tabs:l}=n;return s||u("AsciinemaWidget",!0),i||u("Details",!0),o||u("TabItem",!0),l||u("Tabs",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"configure-your-cluster",children:"Configure your cluster"})}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsx)(n.p,{children:"This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details."})}),"\n",(0,t.jsx)(s,{src:"/constellation/assets/configure-cluster.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.p,{children:"Before you can create your cluster, you need to configure the identity and access management (IAM) for your cloud service provider (CSP) and choose machine types for the nodes."}),"\n",(0,t.jsx)(n.h2,{id:"creating-the-configuration-file",children:"Creating the configuration file"}),"\n",(0,t.jsx)(n.p,{children:"You can generate a configuration file for your CSP by using the following CLI command:"}),"\n",(0,t.jsxs)(l,{groupId:"csp",children:[(0,t.jsx)(o,{value:"aws",label:"AWS",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation config generate aws\n"})})}),(0,t.jsx)(o,{value:"azure",label:"Azure",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation config generate azure\n"})})}),(0,t.jsx)(o,{value:"gcp",label:"GCP",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation config generate gcp\n"})})}),(0,t.jsx)(o,{value:"stackit",label:"STACKIT",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation config generate stackit\n"})})})]}),"\n",(0,t.jsxs)(n.p,{children:["This creates the file ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," in the current directory."]}),"\n",(0,t.jsx)(n.h2,{id:"choosing-a-vm-type",children:"Choosing a VM type"}),"\n",(0,t.jsx)(n.p,{children:"Constellation supports the following VM types:"}),"\n",(0,t.jsxs)(l,{groupId:"csp",children:[(0,t.jsxs)(o,{value:"aws",label:"AWS",children:[(0,t.jsxs)(n.p,{children:["By default, Constellation uses ",(0,t.jsx)(n.code,{children:"m6a.xlarge"})," VMs (4 vCPUs, 16 GB RAM) to create your cluster.\nOptionally, you can switch to a different VM type by modifying ",(0,t.jsx)(n.code,{children:"instanceType"})," in the configuration file.\nIf you are using the default attestation variant ",(0,t.jsx)(n.code,{children:"awsSEVSNP"}),", you can use the instance types described in ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/snp-requirements.html",children:"AWS's AMD SEV-SNP docs"}),".\nPlease mind the region restrictions mentioned in the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps#create-a-cluster",children:"Getting started"})," section."]}),(0,t.jsxs)(n.p,{children:["If you are using the attestation variant ",(0,t.jsx)(n.code,{children:"awsNitroTPM"}),", you can choose any of the ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enable-nitrotpm-prerequisites.html",children:"nitroTPM-enabled instance types"}),"."]}),(0,t.jsxs)(n.p,{children:["The Constellation CLI can also print the supported instance types with: ",(0,t.jsx)(n.code,{children:"constellation config instance-types"}),"."]})]}),(0,t.jsxs)(o,{value:"azure",label:"Azure",children:[(0,t.jsxs)(n.p,{children:["By default, Constellation uses ",(0,t.jsx)(n.code,{children:"Standard_DC4as_v5"})," CVMs (4 vCPUs, 16 GB RAM) to create your cluster. Optionally, you can switch to a different VM type by modifying ",(0,t.jsx)(n.code,{children:"instanceType"})," in the configuration file. For CVMs, any VM type with a minimum of 4 vCPUs from the ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/dcasv5-dcadsv5-series",children:"DCasv5 & DCadsv5"})," or ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/ecasv5-ecadsv5-series",children:"ECasv5 & ECadsv5"})," families is supported."]}),(0,t.jsxs)(n.p,{children:["You can also run ",(0,t.jsx)(n.code,{children:"constellation config instance-types"})," to get the list of all supported options."]})]}),(0,t.jsx)(o,{value:"gcp",label:"GCP",children:(0,t.jsxs)(n.p,{children:["By default, Constellation uses ",(0,t.jsx)(n.code,{children:"n2d-standard-4"})," VMs (4 vCPUs, 16 GB RAM) to create your cluster. Optionally, you can switch to a different VM type by modifying ",(0,t.jsx)(n.code,{children:"instanceType"})," in the configuration file. Supported are all machines with a minimum of 4 vCPUs from the ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/compute-optimized-machines#c2d_machine_types",children:"C2D"})," or ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/general-purpose-machines#n2d_machines",children:"N2D"})," family. You can run ",(0,t.jsx)(n.code,{children:"constellation config instance-types"})," to get the list of all supported options."]})}),(0,t.jsxs)(o,{value:"stackit",label:"STACKIT",children:[(0,t.jsxs)(n.p,{children:["By default, Constellation uses ",(0,t.jsx)(n.code,{children:"m1a.4cd"})," VMs (4 vCPUs, 30 GB RAM) to create your cluster.\nOptionally, you can switch to a different VM type by modifying ",(0,t.jsx)(n.code,{children:"instanceType"})," in the configuration file."]}),(0,t.jsx)(n.p,{children:"The following instance types are known to be supported:"}),(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"name"}),(0,t.jsx)(n.th,{children:"vCPUs"}),(0,t.jsx)(n.th,{children:"GB RAM"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"m1a.4cd"}),(0,t.jsx)(n.td,{children:"4"}),(0,t.jsx)(n.td,{children:"30"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"m1a.8cd"}),(0,t.jsx)(n.td,{children:"8"}),(0,t.jsx)(n.td,{children:"60"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"m1a.16cd"}),(0,t.jsx)(n.td,{children:"16"}),(0,t.jsx)(n.td,{children:"120"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"m1a.30cd"}),(0,t.jsx)(n.td,{children:"30"}),(0,t.jsx)(n.td,{children:"230"})]})]})]}),(0,t.jsxs)(n.p,{children:["You can choose any of the SEV-enabled instance types. You can find a list of all supported instance types in the ",(0,t.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/virtual-machine-flavors-75137231.html",children:"STACKIT documentation"}),"."]}),(0,t.jsxs)(n.p,{children:["The Constellation CLI can also print the supported instance types with: ",(0,t.jsx)(n.code,{children:"constellation config instance-types"}),"."]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Fill the desired VM type into the ",(0,t.jsx)(n.code,{children:"instanceType"})," fields in the ",(0,t.jsx)(n.code,{children:"constellation-conf.yml"})," file."]}),"\n",(0,t.jsx)(n.h2,{id:"creating-additional-node-groups",children:"Creating additional node groups"}),"\n",(0,t.jsxs)(n.p,{children:["By default, Constellation creates the node groups ",(0,t.jsx)(n.code,{children:"control_plane_default"})," and ",(0,t.jsx)(n.code,{children:"worker_default"})," for control-plane nodes and workers, respectively.\nIf you require additional control-plane or worker groups with different instance types, zone placements, or disk sizes, you can add additional node groups to the ",(0,t.jsx)(n.code,{children:"constellation-conf.yml"})," file.\nEach node group can be scaled individually."]}),"\n",(0,t.jsx)(n.p,{children:"Consider the following example for AWS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"nodeGroups:\n control_plane_default:\n role: control-plane\n instanceType: c6a.xlarge\n stateDiskSizeGB: 30\n stateDiskType: gp3\n zone: eu-west-1c\n initialCount: 3\n worker_default:\n role: worker\n instanceType: c6a.xlarge\n stateDiskSizeGB: 30\n stateDiskType: gp3\n zone: eu-west-1c\n initialCount: 2\n high_cpu:\n role: worker\n instanceType: c6a.24xlarge\n stateDiskSizeGB: 128\n stateDiskType: gp3\n zone: eu-west-1c\n initialCount: 1\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This configuration creates an additional node group ",(0,t.jsx)(n.code,{children:"high_cpu"})," with a larger instance type and disk."]}),"\n",(0,t.jsxs)(n.p,{children:["You can use the field ",(0,t.jsx)(n.code,{children:"zone"})," to specify what availability zone nodes of the group are placed in.\nOn Azure, this field is empty by default and nodes are automatically spread across availability zones.\nSTACKIT currently offers SEV-enabled CPUs in the ",(0,t.jsx)(n.code,{children:"eu01-1"}),", ",(0,t.jsx)(n.code,{children:"eu01-2"}),", and ",(0,t.jsx)(n.code,{children:"eu01-3"})," zones.\nConsult the documentation of your cloud provider for more information:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://aws.amazon.com/about-aws/global-infrastructure/regions_az/",children:"AWS"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/explore/global-infrastructure/availability-zones",children:"Azure"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones",children:"GCP"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/regions-and-availability-zones-75137212.html",children:"STACKIT"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"choosing-a-kubernetes-version",children:"Choosing a Kubernetes version"}),"\n",(0,t.jsxs)(n.p,{children:["To learn which Kubernetes versions can be installed with your current CLI, you can run ",(0,t.jsx)(n.code,{children:"constellation config kubernetes-versions"}),".\nSee also Constellation's ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/versions#kubernetes-support-policy",children:"Kubernetes support policy"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"creating-an-iam-configuration",children:"Creating an IAM configuration"}),"\n",(0,t.jsxs)(n.p,{children:["You can create an IAM configuration for your cluster automatically using the ",(0,t.jsx)(n.code,{children:"constellation iam create"})," command.\nIf you already have a Constellation configuration file, you can add the ",(0,t.jsx)(n.code,{children:"--update-config"})," flag to the command. This writes the needed IAM fields into your configuration. Furthermore, the flag updates the zone/region of the configuration if it hasn't been set yet."]}),"\n",(0,t.jsxs)(l,{groupId:"csp",children:[(0,t.jsxs)(o,{value:"aws",label:"AWS",children:[(0,t.jsxs)(n.p,{children:["You must be authenticated with the ",(0,t.jsx)(n.a,{href:"https://aws.amazon.com/en/cli/",children:"AWS CLI"})," in the shell session with a user that has the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/install#set-up-cloud-credentials",children:"required permissions for IAM creation"}),"."]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation iam create aws --zone=us-east-2a --prefix=constellTest\n"})}),(0,t.jsxs)(n.p,{children:["This command creates IAM configuration for the AWS zone ",(0,t.jsx)(n.code,{children:"us-east-2a"})," using the prefix ",(0,t.jsx)(n.code,{children:"constellTest"})," for all named resources being created."]}),(0,t.jsx)(n.p,{children:"Constellation OS images are currently replicated to the following regions:"}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-central-1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-west-1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-west-3"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"us-east-2"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"ap-south-1"})}),"\n"]}),(0,t.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+AWS+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),(0,t.jsxs)(n.p,{children:["You can find a list of all ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions",children:"regions in AWS's documentation"}),"."]}),(0,t.jsxs)(n.p,{children:["Paste the output into the corresponding fields of the ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," file."]})]}),(0,t.jsxs)(o,{value:"azure",label:"Azure",children:[(0,t.jsxs)(n.p,{children:["You must be authenticated with the ",(0,t.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/cli/azure/install-azure-cli",children:"Azure CLI"})," in the shell session with a user that has the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/install#set-up-cloud-credentials",children:"required permissions for IAM creation"}),"."]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation iam create azure --subscriptionID 00000000-0000-0000-0000-000000000000 --region=westus --resourceGroup=constellTest --servicePrincipal=spTest\n"})}),(0,t.jsxs)(n.p,{children:["This command creates IAM configuration on the Azure region ",(0,t.jsx)(n.code,{children:"westus"})," creating a new resource group ",(0,t.jsx)(n.code,{children:"constellTest"})," and a new service principal ",(0,t.jsx)(n.code,{children:"spTest"}),"."]}),(0,t.jsx)(n.p,{children:"CVMs are available in several Azure regions. Constellation OS images are currently replicated to the following:"}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"germanywestcentral"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"westus"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eastus"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"northeurope"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"westeurope"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"southeastasia"})}),"\n"]}),(0,t.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+Azure+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),(0,t.jsxs)(n.p,{children:["You can find a list of all ",(0,t.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/global-infrastructure/services/?products=virtual-machines®ions=all",children:"regions in Azure's documentation"}),"."]}),(0,t.jsxs)(n.p,{children:["Paste the output into the corresponding fields of the ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," file."]})]}),(0,t.jsxs)(o,{value:"gcp",label:"GCP",children:[(0,t.jsxs)(n.p,{children:["You must be authenticated with the ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/sdk/gcloud",children:"GCP CLI"})," in the shell session with a user that has the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/install#set-up-cloud-credentials",children:"required permissions for IAM creation"}),"."]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation iam create gcp --projectID=yourproject-12345 --zone=europe-west3-a --prefix=constell-test\n"})}),(0,t.jsxs)(n.p,{children:["This command creates IAM configuration in the GCP project ",(0,t.jsx)(n.code,{children:"yourproject-12345"})," on the GCP zone ",(0,t.jsx)(n.code,{children:"europe-west3-a"})," creating a new service account ",(0,t.jsx)(n.code,{children:"constell-test"}),"."]}),(0,t.jsxs)(n.p,{children:["Note that only regions offering CVMs of the ",(0,t.jsx)(n.code,{children:"C2D"})," or ",(0,t.jsx)(n.code,{children:"N2D"})," series are supported. You can find a ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones#available",children:"list of all regions in Google's documentation"}),", which you can filter by machine type ",(0,t.jsx)(n.code,{children:"N2D"}),"."]}),(0,t.jsxs)(n.p,{children:["Paste the output into the corresponding fields of the ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," file."]})]}),(0,t.jsx)(o,{value:"stackit",label:"STACKIT",children:(0,t.jsxs)(n.p,{children:["STACKIT requires manual creation and configuration of service accounts. Look at the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps",children:"first steps"})," for more information."]})})]}),"\n",(0,t.jsxs)(i,{children:[(0,t.jsx)("summary",{children:"Alternatively, you can manually create the IAM configuration on your CSP."}),(0,t.jsx)(n.p,{children:"The following describes the configuration fields and how you obtain the required information or create the required resources."}),(0,t.jsxs)(l,{groupId:"csp",children:[(0,t.jsx)(o,{value:"aws",label:"AWS",children:(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"region"}),": The name of your chosen AWS data center region, e.g., ",(0,t.jsx)(n.code,{children:"us-east-2"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Constellation OS images are currently replicated to the following regions:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-central-1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-west-1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-west-3"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"us-east-2"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"ap-south-1"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+AWS+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find a list of all ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions",children:"regions in AWS's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"zone"}),": The name of your chosen AWS data center availability zone, e.g., ",(0,t.jsx)(n.code,{children:"us-east-2a"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Learn more about ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-availability-zones",children:"availability zones in AWS's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"iamProfileControlPlane"}),": The name of an IAM instance profile attached to all control-plane nodes."]}),"\n",(0,t.jsxs)(n.p,{children:["You can create the resource with ",(0,t.jsx)(n.a,{href:"https://www.terraform.io/",children:"Terraform"}),". For that, use the ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/tree/release/v2.2/hack/terraform/aws/iam",children:"provided Terraform script"})," to generate the necessary profile. The profile name will be provided as Terraform output value: ",(0,t.jsx)(n.code,{children:"control_plane_instance_profile_name"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Alternatively, you can create the AWS profile with a tool of your choice. Use the JSON policy in ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/tree/release/v2.2/hack/terraform/aws/iam/main.tf",children:"main.tf"})," in the resource ",(0,t.jsx)(n.code,{children:"aws_iam_policy.control_plane_policy"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"iamProfileWorkerNodes"}),": The name of an IAM instance profile attached to all worker nodes."]}),"\n",(0,t.jsxs)(n.p,{children:["You can create the resource with ",(0,t.jsx)(n.a,{href:"https://www.terraform.io/",children:"Terraform"}),". For that, use the ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/tree/release/v2.2/hack/terraform/aws/iam",children:"provided Terraform script"})," to generate the necessary profile. The profile name will be provided as Terraform output value: ",(0,t.jsx)(n.code,{children:"worker_nodes_instance_profile_name"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Alternatively, you can create the AWS profile with a tool of your choice. Use the JSON policy in ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/tree/release/v2.2/hack/terraform/aws/iam/main.tf",children:"main.tf"})," in the resource ",(0,t.jsx)(n.code,{children:"aws_iam_policy.worker_node_policy"}),"."]}),"\n"]}),"\n"]})}),(0,t.jsx)(o,{value:"azure",label:"Azure",children:(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"subscription"}),": The UUID of your Azure subscription, e.g., ",(0,t.jsx)(n.code,{children:"8b8bd01f-efd9-4113-9bd1-c82137c32da7"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can view your subscription UUID via ",(0,t.jsx)(n.code,{children:"az account show"})," and read the ",(0,t.jsx)(n.code,{children:"id"})," field. For more information refer to ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id#find-your-azure-subscription",children:"Azure's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"tenant"}),": The UUID of your Azure tenant, e.g., ",(0,t.jsx)(n.code,{children:"3400e5a2-8fe2-492a-886c-38cb66170f25"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can view your tenant UUID via ",(0,t.jsx)(n.code,{children:"az account show"})," and read the ",(0,t.jsx)(n.code,{children:"tenant"})," field. For more information refer to ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id#find-your-azure-ad-tenant",children:"Azure's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"location"}),": The Azure datacenter location you want to deploy your cluster in, e.g., ",(0,t.jsx)(n.code,{children:"westus"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"CVMs are available in several Azure regions. Constellation OS images are currently replicated to the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"germanywestcentral"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"westus"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eastus"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"northeurope"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"westeurope"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"southeastasia"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+Azure+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find a list of all ",(0,t.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/global-infrastructure/services/?products=virtual-machines®ions=all",children:"regions in Azure's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"resourceGroup"}),": ",(0,t.jsx)(n.a,{href:"https://learn.microsoft.com/azure/azure-resource-manager/management/manage-resource-groups-portal",children:"Create a new resource group in Azure"})," for your Constellation cluster. Set this configuration field to the name of the created resource group."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"userAssignedIdentity"}),": ",(0,t.jsx)(n.a,{href:"https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/how-manage-user-assigned-managed-identities",children:"Create a new managed identity in Azure"}),". You should create the identity in a different resource group as all resources within the cluster resource group will be deleted on cluster termination."]}),"\n",(0,t.jsxs)(n.p,{children:["Add three role assignments to the identity: ",(0,t.jsx)(n.code,{children:"Owner"}),", ",(0,t.jsx)(n.code,{children:"Virtual Machine Contributor"}),", and ",(0,t.jsx)(n.code,{children:"Application Insights Component Contributor"}),". The ",(0,t.jsx)(n.code,{children:"scope"})," of all three should refer to the previously created cluster resource group."]}),"\n",(0,t.jsxs)(n.p,{children:["Set the configuration value to the full ID of the created identity, e.g., ",(0,t.jsx)(n.code,{children:"/subscriptions/8b8bd01f-efd9-4113-9bd1-c82137c32da7/resourcegroups/constellation-identity/providers/Microsoft.ManagedIdentity/userAssignedIdentities/constellation-identity"}),". You can get it by opening the ",(0,t.jsx)(n.code,{children:"JSON View"})," from the ",(0,t.jsx)(n.code,{children:"Overview"})," section of the identity."]}),"\n",(0,t.jsxs)(n.p,{children:["The user-assigned identity is used by instances of the cluster to access other cloud resources.\nFor more information about managed identities refer to ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-manage-user-assigned-managed-identities",children:"Azure's documentation"}),"."]}),"\n"]}),"\n"]})}),(0,t.jsx)(o,{value:"gcp",label:"GCP",children:(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"project"}),": The ID of your GCP project, e.g., ",(0,t.jsx)(n.code,{children:"constellation-129857"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find it on the ",(0,t.jsx)(n.a,{href:"https://console.cloud.google.com/welcome",children:"welcome screen of your GCP project"}),". For more information refer to ",(0,t.jsx)(n.a,{href:"https://support.google.com/googleapi/answer/7014113",children:"Google's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"region"}),": The GCP region you want to deploy your cluster in, e.g., ",(0,t.jsx)(n.code,{children:"us-central1"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find a ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones#available",children:"list of all regions in Google's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"zone"}),": The GCP zone you want to deploy your cluster in, e.g., ",(0,t.jsx)(n.code,{children:"us-central1-a"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find a ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones#available",children:"list of all zones in Google's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"serviceAccountKeyPath"}),": To configure this, you need to create a GCP ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/iam/docs/service-accounts",children:"service account"})," with the following permissions:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Compute Instance Admin (v1) (roles/compute.instanceAdmin.v1)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Compute Network Admin (roles/compute.networkAdmin)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Compute Security Admin (roles/compute.securityAdmin)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Compute Storage Admin (roles/compute.storageAdmin)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Service Account User (roles/iam.serviceAccountUser)"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Afterward, create and download a new JSON key for this service account. Place the downloaded file in your Constellation workspace, and set the config parameter to the filename, e.g., ",(0,t.jsx)(n.code,{children:"constellation-129857-15343dba46cb.json"}),"."]}),"\n"]}),"\n"]})}),(0,t.jsx)(o,{value:"stackit",label:"STACKIT",children:(0,t.jsxs)(n.p,{children:["STACKIT requires manual creation and configuration of service accounts. Look at the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps",children:"first steps"})," for more information."]})})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Now that you've configured your CSP, you can ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/create",children:"create your cluster"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"deleting-an-iam-configuration",children:"Deleting an IAM configuration"}),"\n",(0,t.jsx)(n.p,{children:"You can keep a created IAM configuration and reuse it for new clusters. Alternatively, you can also delete it if you don't want to use it anymore."}),"\n",(0,t.jsxs)(n.p,{children:["Delete the IAM configuration by executing the following command in the same directory where you executed ",(0,t.jsx)(n.code,{children:"constellation iam create"})," (the directory that contains ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/reference/terraform",children:(0,t.jsx)(n.code,{children:"constellation-iam-terraform"})})," as a subdirectory):"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation iam destroy\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsxs)(n.p,{children:["For Azure, deleting the IAM configuration by executing ",(0,t.jsx)(n.code,{children:"constellation iam destroy"})," will delete the whole resource group created by ",(0,t.jsx)(n.code,{children:"constellation iam create"}),".\nThis also includes any additional resources in the resource group that weren't created by Constellation."]})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}function u(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/617.55c4d8c0.js b/pr-preview/pr-4027/assets/js/617.55c4d8c0.js deleted file mode 100644 index 1b43dd76f..000000000 --- a/pr-preview/pr-4027/assets/js/617.55c4d8c0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[617],{50617:(e,s,c)=>{c.d(s,{createPieServices:()=>a.f});var a=c(69150);c(87960)}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/619bb71e.87871acc.js b/pr-preview/pr-4027/assets/js/619bb71e.87871acc.js deleted file mode 100644 index 61475843f..000000000 --- a/pr-preview/pr-4027/assets/js/619bb71e.87871acc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9698],{28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>c});var t=n(96540);const i={},r=t.createContext(i);function o(e){const s=t.useContext(r);return t.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(r.Provider,{value:s},e.children)}},86942:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"overview/license","title":"License","description":"Constellation is available under the Business Source License 1.1.","source":"@site/versioned_docs/version-2.24/overview/license.md","sourceDirName":"overview","slug":"/overview/license","permalink":"/constellation/pr-preview/pr-4027/overview/license","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/overview/license.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Application benchmarks","permalink":"/constellation/pr-preview/pr-4027/overview/performance/application"},"next":{"title":"Getting started","permalink":"/constellation/pr-preview/pr-4027/category/getting-started"}}');var i=n(74848),r=n(28453);const o={},c="License",a={},l=[{value:"Enterprise License",id:"enterprise-license",level:2},{value:"CSP Marketplaces",id:"csp-marketplaces",level:2}];function p(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.header,{children:(0,i.jsx)(s.h1,{id:"license",children:"License"})}),"\n",(0,i.jsxs)(s.p,{children:["Constellation is available under the ",(0,i.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/blob/main/LICENSE",children:"Business Source License 1.1"}),"."]}),"\n",(0,i.jsx)(s.p,{children:'You may use it free of charge for non-production use ("Community License").'}),"\n",(0,i.jsx)(s.h2,{id:"enterprise-license",children:"Enterprise License"}),"\n",(0,i.jsxs)(s.p,{children:["Enterprise Licenses permit production use and come with support and additional features. Find out more at the ",(0,i.jsx)(s.a,{href:"https://www.edgeless.systems/products/constellation/",children:"product website"}),"."]}),"\n",(0,i.jsxs)(s.p,{children:["Once you have received your Enterprise License file, place it in your ",(0,i.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/architecture/orchestration#workspaces",children:"Constellation workspace"})," in a file named ",(0,i.jsx)(s.code,{children:"constellation.license"}),"."]}),"\n",(0,i.jsx)(s.h2,{id:"csp-marketplaces",children:"CSP Marketplaces"}),"\n",(0,i.jsxs)(s.p,{children:["Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please ",(0,i.jsx)(s.a,{href:"https://www.edgeless.systems/enterprise-support/",children:"contact us"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(p,{...e})}):p(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/6241.826bee80.js b/pr-preview/pr-4027/assets/js/6241.826bee80.js deleted file mode 100644 index 2c40d61b7..000000000 --- a/pr-preview/pr-4027/assets/js/6241.826bee80.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6241],{16241:(t,e,n)=>{n.d(e,{diagram:()=>I});var i=n(73590),s=n(52501),r=n(73981),o=n(5894),a=(n(63245),n(32387),n(30092),n(13226),n(67633)),c=n(40797),l=n(3219),h=n(78041),g=n(75263),u=function(){var t=(0,c.K2)(function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},"o"),e=[1,4],n=[1,13],i=[1,12],s=[1,15],r=[1,16],o=[1,20],a=[1,19],l=[6,7,8],h=[1,26],g=[1,24],u=[1,25],d=[6,7,11],p=[1,31],y=[6,7,11,24],f=[1,6,13,16,17,20,23],m=[1,35],b=[1,36],_=[1,6,7,11,13,16,17,20,23],k=[1,38],E={trace:(0,c.K2)(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,KANBAN:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,shapeData:15,ICON:16,CLASS:17,nodeWithId:18,nodeWithoutId:19,NODE_DSTART:20,NODE_DESCR:21,NODE_DEND:22,NODE_ID:23,SHAPE_DATA:24,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"KANBAN",11:"EOF",13:"SPACELIST",16:"ICON",17:"CLASS",20:"NODE_DSTART",21:"NODE_DESCR",22:"NODE_DEND",23:"NODE_ID",24:"SHAPE_DATA"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,3],[12,2],[12,2],[12,2],[12,1],[12,2],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[19,3],[18,1],[18,4],[15,2],[15,1]],performAction:(0,c.K2)(function(t,e,n,i,s,r,o){var a=r.length-1;switch(s){case 6:case 7:return i;case 8:i.getLogger().trace("Stop NL ");break;case 9:i.getLogger().trace("Stop EOF ");break;case 11:i.getLogger().trace("Stop NL2 ");break;case 12:i.getLogger().trace("Stop EOF2 ");break;case 15:i.getLogger().info("Node: ",r[a-1].id),i.addNode(r[a-2].length,r[a-1].id,r[a-1].descr,r[a-1].type,r[a]);break;case 16:i.getLogger().info("Node: ",r[a].id),i.addNode(r[a-1].length,r[a].id,r[a].descr,r[a].type);break;case 17:i.getLogger().trace("Icon: ",r[a]),i.decorateNode({icon:r[a]});break;case 18:case 23:i.decorateNode({class:r[a]});break;case 19:i.getLogger().trace("SPACELIST");break;case 20:i.getLogger().trace("Node: ",r[a-1].id),i.addNode(0,r[a-1].id,r[a-1].descr,r[a-1].type,r[a]);break;case 21:i.getLogger().trace("Node: ",r[a].id),i.addNode(0,r[a].id,r[a].descr,r[a].type);break;case 22:i.decorateNode({icon:r[a]});break;case 27:i.getLogger().trace("node found ..",r[a-2]),this.$={id:r[a-1],descr:r[a-1],type:i.getType(r[a-2],r[a])};break;case 28:this.$={id:r[a],descr:r[a],type:0};break;case 29:i.getLogger().trace("node found ..",r[a-3]),this.$={id:r[a-3],descr:r[a-1],type:i.getType(r[a-2],r[a])};break;case 30:this.$=r[a-1]+r[a];break;case 31:this.$=r[a]}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:e},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:e},{6:n,7:[1,10],9:9,12:11,13:i,14:14,16:s,17:r,18:17,19:18,20:o,23:a},t(l,[2,3]),{1:[2,2]},t(l,[2,4]),t(l,[2,5]),{1:[2,6],6:n,12:21,13:i,14:14,16:s,17:r,18:17,19:18,20:o,23:a},{6:n,9:22,12:11,13:i,14:14,16:s,17:r,18:17,19:18,20:o,23:a},{6:h,7:g,10:23,11:u},t(d,[2,24],{18:17,19:18,14:27,16:[1,28],17:[1,29],20:o,23:a}),t(d,[2,19]),t(d,[2,21],{15:30,24:p}),t(d,[2,22]),t(d,[2,23]),t(y,[2,25]),t(y,[2,26]),t(y,[2,28],{20:[1,32]}),{21:[1,33]},{6:h,7:g,10:34,11:u},{1:[2,7],6:n,12:21,13:i,14:14,16:s,17:r,18:17,19:18,20:o,23:a},t(f,[2,14],{7:m,11:b}),t(_,[2,8]),t(_,[2,9]),t(_,[2,10]),t(d,[2,16],{15:37,24:p}),t(d,[2,17]),t(d,[2,18]),t(d,[2,20],{24:k}),t(y,[2,31]),{21:[1,39]},{22:[1,40]},t(f,[2,13],{7:m,11:b}),t(_,[2,11]),t(_,[2,12]),t(d,[2,15],{24:k}),t(y,[2,30]),{22:[1,41]},t(y,[2,27]),t(y,[2,29])],defaultActions:{2:[2,1],6:[2,2]},parseError:(0,c.K2)(function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},"parseError"),parse:(0,c.K2)(function(t){var e=this,n=[0],i=[],s=[null],r=[],o=this.table,a="",l=0,h=0,g=0,u=r.slice.call(arguments,1),d=Object.create(this.lexer),p={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(p.yy[y]=this.yy[y]);d.setInput(t,p.yy),p.yy.lexer=d,p.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var f=d.yylloc;r.push(f);var m=d.options&&d.options.ranges;function b(){var t;return"number"!=typeof(t=i.pop()||d.lex()||1)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,c.K2)(function(t){n.length=n.length-2*t,s.length=s.length-t,r.length=r.length-t},"popStack"),(0,c.K2)(b,"lex");for(var _,k,E,S,N,x,D,L,I,v={};;){if(E=n[n.length-1],this.defaultActions[E]?S=this.defaultActions[E]:(null==_&&(_=b()),S=o[E]&&o[E][_]),void 0===S||!S.length||!S[0]){var C="";for(x in I=[],o[E])this.terminals_[x]&&x>2&&I.push("'"+this.terminals_[x]+"'");C=d.showPosition?"Parse error on line "+(l+1)+":\n"+d.showPosition()+"\nExpecting "+I.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==_?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(C,{text:d.match,token:this.terminals_[_]||_,line:d.yylineno,loc:f,expected:I})}if(S[0]instanceof Array&&S.length>1)throw new Error("Parse Error: multiple actions possible at state: "+E+", token: "+_);switch(S[0]){case 1:n.push(_),s.push(d.yytext),r.push(d.yylloc),n.push(S[1]),_=null,k?(_=k,k=null):(h=d.yyleng,a=d.yytext,l=d.yylineno,f=d.yylloc,g>0&&g--);break;case 2:if(D=this.productions_[S[1]][1],v.$=s[s.length-D],v._$={first_line:r[r.length-(D||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(D||1)].first_column,last_column:r[r.length-1].last_column},m&&(v._$.range=[r[r.length-(D||1)].range[0],r[r.length-1].range[1]]),void 0!==(N=this.performAction.apply(v,[a,h,l,p.yy,S[1],s,r].concat(u))))return N;D&&(n=n.slice(0,-1*D*2),s=s.slice(0,-1*D),r=r.slice(0,-1*D)),n.push(this.productions_[S[1]][0]),s.push(v.$),r.push(v._$),L=o[n[n.length-2]][n[n.length-1]],n.push(L);break;case 3:return!0}}return!0},"parse")},S=function(){return{EOF:1,parseError:(0,c.K2)(function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},"parseError"),setInput:(0,c.K2)(function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:(0,c.K2)(function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},"input"),unput:(0,c.K2)(function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},"unput"),more:(0,c.K2)(function(){return this._more=!0,this},"more"),reject:(0,c.K2)(function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"reject"),less:(0,c.K2)(function(t){this.unput(this.match.slice(t))},"less"),pastInput:(0,c.K2)(function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:(0,c.K2)(function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:(0,c.K2)(function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},"showPosition"),test_match:(0,c.K2)(function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},"test_match"),next:(0,c.K2)(function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((n=this._input.match(this.rules[s[r]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:(0,c.K2)(function(){var t=this.next();return t||this.lex()},"lex"),begin:(0,c.K2)(function(t){this.conditionStack.push(t)},"begin"),popState:(0,c.K2)(function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:(0,c.K2)(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:(0,c.K2)(function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},"topState"),pushState:(0,c.K2)(function(t){this.begin(t)},"pushState"),stateStackSize:(0,c.K2)(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,c.K2)(function(t,e,n,i){switch(n){case 0:return this.pushState("shapeData"),e.yytext="",24;case 1:return this.pushState("shapeDataStr"),24;case 2:return this.popState(),24;case 3:const n=/\n\s*/g;return e.yytext=e.yytext.replace(n,"<br/>"),24;case 4:return 24;case 5:case 10:case 29:case 32:this.popState();break;case 6:return t.getLogger().trace("Found comment",e.yytext),6;case 7:return 8;case 8:this.begin("CLASS");break;case 9:return this.popState(),17;case 11:t.getLogger().trace("Begin icon"),this.begin("ICON");break;case 12:return t.getLogger().trace("SPACELINE"),6;case 13:return 7;case 14:return 16;case 15:t.getLogger().trace("end icon"),this.popState();break;case 16:return t.getLogger().trace("Exploding node"),this.begin("NODE"),20;case 17:return t.getLogger().trace("Cloud"),this.begin("NODE"),20;case 18:return t.getLogger().trace("Explosion Bang"),this.begin("NODE"),20;case 19:return t.getLogger().trace("Cloud Bang"),this.begin("NODE"),20;case 20:case 21:case 22:case 23:return this.begin("NODE"),20;case 24:return 13;case 25:return 23;case 26:return 11;case 27:this.begin("NSTR2");break;case 28:return"NODE_DESCR";case 30:t.getLogger().trace("Starting NSTR"),this.begin("NSTR");break;case 31:return t.getLogger().trace("description:",e.yytext),"NODE_DESCR";case 33:return this.popState(),t.getLogger().trace("node end ))"),"NODE_DEND";case 34:return this.popState(),t.getLogger().trace("node end )"),"NODE_DEND";case 35:return this.popState(),t.getLogger().trace("node end ...",e.yytext),"NODE_DEND";case 36:case 39:case 40:return this.popState(),t.getLogger().trace("node end (("),"NODE_DEND";case 37:case 38:return this.popState(),t.getLogger().trace("node end (-"),"NODE_DEND";case 41:case 42:return t.getLogger().trace("Long description:",e.yytext),21}},"anonymous"),rules:[/^(?:@\{)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^\"]+)/i,/^(?:[^}^"]+)/i,/^(?:\})/i,/^(?:\s*%%.*)/i,/^(?:kanban\b)/i,/^(?::::)/i,/^(?:.+)/i,/^(?:\n)/i,/^(?:::icon\()/i,/^(?:[\s]+[\n])/i,/^(?:[\n]+)/i,/^(?:[^\)]+)/i,/^(?:\))/i,/^(?:-\))/i,/^(?:\(-)/i,/^(?:\)\))/i,/^(?:\))/i,/^(?:\(\()/i,/^(?:\{\{)/i,/^(?:\()/i,/^(?:\[)/i,/^(?:[\s]+)/i,/^(?:[^\(\[\n\)\{\}@]+)/i,/^(?:$)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:[^"]+)/i,/^(?:["])/i,/^(?:[\)]\))/i,/^(?:[\)])/i,/^(?:[\]])/i,/^(?:\}\})/i,/^(?:\(-)/i,/^(?:-\))/i,/^(?:\(\()/i,/^(?:\()/i,/^(?:[^\)\]\(\}]+)/i,/^(?:.+(?!\(\())/i],conditions:{shapeDataEndBracket:{rules:[],inclusive:!1},shapeDataStr:{rules:[2,3],inclusive:!1},shapeData:{rules:[1,4,5],inclusive:!1},CLASS:{rules:[9,10],inclusive:!1},ICON:{rules:[14,15],inclusive:!1},NSTR2:{rules:[28,29],inclusive:!1},NSTR:{rules:[31,32],inclusive:!1},NODE:{rules:[27,30,33,34,35,36,37,38,39,40,41,42],inclusive:!1},INITIAL:{rules:[0,6,7,8,11,12,13,16,17,18,19,20,21,22,23,24,25,26],inclusive:!0}}}}();function N(){this.yy={}}return E.lexer=S,(0,c.K2)(N,"Parser"),N.prototype=E,E.Parser=N,new N}();u.parser=u;var d=u,p=[],y=[],f=0,m={},b=(0,c.K2)(()=>{p=[],y=[],f=0,m={}},"clear"),_=(0,c.K2)(t=>{if(0===p.length)return null;const e=p[0].level;let n=null;for(let i=p.length-1;i>=0;i--)if(p[i].level!==e||n||(n=p[i]),p[i].level<e)throw new Error('Items without section detected, found section ("'+p[i].label+'")');return t===n?.level?null:n},"getSection"),k=(0,c.K2)(function(){return y},"getSections"),E=(0,c.K2)(function(){const t=[],e=k(),n=(0,a.D7)();for(const i of e){const e={id:i.id,label:(0,a.jZ)(i.label??"",n),isGroup:!0,ticket:i.ticket,shape:"kanbanSection",level:i.level,look:n.look};t.push(e);const s=p.filter(t=>t.parentId===i.id);for(const r of s){const e={id:r.id,parentId:i.id,label:(0,a.jZ)(r.label??"",n),isGroup:!1,ticket:r?.ticket,priority:r?.priority,assigned:r?.assigned,icon:r?.icon,shape:"kanbanItem",level:r.level,rx:5,ry:5,cssStyles:["text-align: left"]};t.push(e)}}return{nodes:t,edges:[],other:{},config:(0,a.D7)()}},"getData"),S=(0,c.K2)((t,e,n,i,s)=>{const o=(0,a.D7)();let c=o.mindmap?.padding??a.UI.mindmap.padding;switch(i){case N.ROUNDED_RECT:case N.RECT:case N.HEXAGON:c*=2}const l={id:(0,a.jZ)(e,o)||"kbn"+f++,level:t,label:(0,a.jZ)(n,o),width:o.mindmap?.maxNodeWidth??a.UI.mindmap.maxNodeWidth,padding:c,isGroup:!1};if(void 0!==s){let t;t=s.includes("\n")?s+"\n":"{\n"+s+"\n}";const e=(0,r.H)(t,{schema:r.r});if(e.shape&&(e.shape!==e.shape.toLowerCase()||e.shape.includes("_")))throw new Error(`No such shape: ${e.shape}. Shape names should be lowercase.`);e?.shape&&"kanbanItem"===e.shape&&(l.shape=e?.shape),e?.label&&(l.label=e?.label),e?.icon&&(l.icon=e?.icon.toString()),e?.assigned&&(l.assigned=e?.assigned.toString()),e?.ticket&&(l.ticket=e?.ticket.toString()),e?.priority&&(l.priority=e?.priority)}const h=_(t);h?l.parentId=h.id||"kbn"+f++:y.push(l),p.push(l)},"addNode"),N={DEFAULT:0,NO_BORDER:0,ROUNDED_RECT:1,RECT:2,CIRCLE:3,CLOUD:4,BANG:5,HEXAGON:6},x={clear:b,addNode:S,getSections:k,getData:E,nodeType:N,getType:(0,c.K2)((t,e)=>{switch(c.Rm.debug("In get type",t,e),t){case"[":return N.RECT;case"(":return")"===e?N.ROUNDED_RECT:N.CLOUD;case"((":return N.CIRCLE;case")":return N.CLOUD;case"))":return N.BANG;case"{{":return N.HEXAGON;default:return N.DEFAULT}},"getType"),setElementForId:(0,c.K2)((t,e)=>{m[t]=e},"setElementForId"),decorateNode:(0,c.K2)(t=>{if(!t)return;const e=(0,a.D7)(),n=p[p.length-1];t.icon&&(n.icon=(0,a.jZ)(t.icon,e)),t.class&&(n.cssClasses=(0,a.jZ)(t.class,e))},"decorateNode"),type2Str:(0,c.K2)(t=>{switch(t){case N.DEFAULT:return"no-border";case N.RECT:return"rect";case N.ROUNDED_RECT:return"rounded-rect";case N.CIRCLE:return"circle";case N.CLOUD:return"cloud";case N.BANG:return"bang";case N.HEXAGON:return"hexgon";default:return"no-border"}},"type2Str"),getLogger:(0,c.K2)(()=>c.Rm,"getLogger"),getElementById:(0,c.K2)(t=>m[t],"getElementById")},D={draw:(0,c.K2)(async(t,e,n,s)=>{c.Rm.debug("Rendering kanban diagram\n"+t);const r=s.db.getData(),l=(0,a.D7)();l.htmlLabels=!1;const h=(0,i.D)(e),g=h.append("g");g.attr("class","sections");const u=h.append("g");u.attr("class","items");const d=r.nodes.filter(t=>t.isGroup);let p=0;const y=[];let f=25;for(const i of d){const t=l?.kanban?.sectionWidth||200;p+=1,i.x=t*p+10*(p-1)/2,i.width=t,i.y=0,i.height=3*t,i.rx=5,i.ry=5,i.cssClasses=i.cssClasses+" section-"+p;const e=await(0,o.U)(g,i);f=Math.max(f,e?.labelBBox?.height),y.push(e)}let m=0;for(const i of d){const t=y[m];m+=1;const e=l?.kanban?.sectionWidth||200,n=3*-e/2+f;let s=n;const a=r.nodes.filter(t=>t.parentId===i.id);for(const r of a){if(r.isGroup)throw new Error("Groups within groups are not allowed in Kanban diagrams");r.x=i.x,r.width=e-15;const t=(await(0,o.on)(u,r,{config:l})).node().getBBox();r.y=s+t.height/2,await(0,o.U_)(r),s=r.y+t.height/2+5}const c=t.cluster.select("rect"),h=Math.max(s-n+30,50)+(f-25);c.attr("height",h)}(0,a.ot)(void 0,h,l.mindmap?.padding??a.UI.kanban.padding,l.mindmap?.useMaxWidth??a.UI.kanban.useMaxWidth)},"draw")},L=(0,c.K2)(t=>{let e="";for(let i=0;i<t.THEME_COLOR_LIMIT;i++)t["lineColor"+i]=t["lineColor"+i]||t["cScaleInv"+i],(0,l.A)(t["lineColor"+i])?t["lineColor"+i]=(0,h.A)(t["lineColor"+i],20):t["lineColor"+i]=(0,g.A)(t["lineColor"+i],20);const n=(0,c.K2)((e,n)=>t.darkMode?(0,g.A)(e,n):(0,h.A)(e,n),"adjuster");for(let i=0;i<t.THEME_COLOR_LIMIT;i++){const s=""+(17-3*i);e+=`\n .section-${i-1} rect, .section-${i-1} path, .section-${i-1} circle, .section-${i-1} polygon, .section-${i-1} path {\n fill: ${n(t["cScale"+i],10)};\n stroke: ${n(t["cScale"+i],10)};\n\n }\n .section-${i-1} text {\n fill: ${t["cScaleLabel"+i]};\n }\n .node-icon-${i-1} {\n font-size: 40px;\n color: ${t["cScaleLabel"+i]};\n }\n .section-edge-${i-1}{\n stroke: ${t["cScale"+i]};\n }\n .edge-depth-${i-1}{\n stroke-width: ${s};\n }\n .section-${i-1} line {\n stroke: ${t["cScaleInv"+i]} ;\n stroke-width: 3;\n }\n\n .disabled, .disabled circle, .disabled text {\n fill: lightgray;\n }\n .disabled text {\n fill: #efefef;\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.background};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n .kanban-ticket-link {\n fill: ${t.background};\n stroke: ${t.nodeBorder};\n text-decoration: underline;\n }\n `}return e},"genSections"),I={db:x,renderer:D,parser:d,styles:(0,c.K2)(t=>`\n .edge {\n stroke-width: 3;\n }\n ${L(t)}\n .section-root rect, .section-root path, .section-root circle, .section-root polygon {\n fill: ${t.git0};\n }\n .section-root text {\n fill: ${t.gitBranchLabel0};\n }\n .icon-container {\n height:100%;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .edge {\n fill: none;\n }\n .cluster-label, .label {\n color: ${t.textColor};\n fill: ${t.textColor};\n }\n .kanban-label {\n dy: 1em;\n alignment-baseline: middle;\n text-anchor: middle;\n dominant-baseline: middle;\n text-align: center;\n }\n ${(0,s.o)()}\n`,"getStyles")}},52501:(t,e,n)=>{n.d(e,{o:()=>i});var i=(0,n(40797).K2)(()=>"\n /* Font Awesome icon styling - consolidated */\n .label-icon {\n display: inline-block;\n height: 1em;\n overflow: visible;\n vertical-align: -0.125em;\n }\n \n .node .label-icon path {\n fill: currentColor;\n stroke: revert;\n stroke-width: revert;\n }\n","getIconStyles")}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/6319.ec99954f.js b/pr-preview/pr-4027/assets/js/6319.ec99954f.js deleted file mode 100644 index 51137a2cd..000000000 --- a/pr-preview/pr-4027/assets/js/6319.ec99954f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6319],{25871:(t,r,e)=>{function n(t,r){t.accDescr&&r.setAccDescription?.(t.accDescr),t.accTitle&&r.setAccTitle?.(t.accTitle),t.title&&r.setDiagramTitle?.(t.title)}e.d(r,{S:()=>n}),(0,e(40797).K2)(n,"populateCommonDb")},66319:(t,r,e)=>{e.d(r,{diagram:()=>ut});var n=e(25871),o=e(72938),a=e(13226),c=e(67633),s=e(40797),i=e(78731),h=e(70451),d={NORMAL:0,REVERSE:1,HIGHLIGHT:2,MERGE:3,CHERRY_PICK:4},m=c.UI.gitGraph,$=(0,s.K2)(()=>(0,a.$t)({...m,...(0,c.zj)().gitGraph}),"getConfig"),l=new o.m(()=>{const t=$(),r=t.mainBranchName,e=t.mainBranchOrder;return{mainBranchName:r,commits:new Map,head:null,branchConfig:new Map([[r,{name:r,order:e}]]),branches:new Map([[r,null]]),currBranch:r,direction:"LR",seq:0,options:{}}});function g(){return(0,a.yT)({length:7})}function y(t,r){const e=Object.create(null);return t.reduce((t,n)=>{const o=r(n);return e[o]||(e[o]=!0,t.push(n)),t},[])}(0,s.K2)(g,"getID"),(0,s.K2)(y,"uniqBy");var p=(0,s.K2)(function(t){l.records.direction=t},"setDirection"),x=(0,s.K2)(function(t){s.Rm.debug("options str",t),t=t?.trim(),t=t||"{}";try{l.records.options=JSON.parse(t)}catch(r){s.Rm.error("error while parsing gitGraph options",r.message)}},"setOptions"),f=(0,s.K2)(function(){return l.records.options},"getOptions"),u=(0,s.K2)(function(t){let r=t.msg,e=t.id;const n=t.type;let o=t.tags;s.Rm.info("commit",r,e,n,o),s.Rm.debug("Entering commit:",r,e,n,o);const a=$();e=c.Y2.sanitizeText(e,a),r=c.Y2.sanitizeText(r,a),o=o?.map(t=>c.Y2.sanitizeText(t,a));const i={id:e||l.records.seq+"-"+g(),message:r,seq:l.records.seq++,type:n??d.NORMAL,tags:o??[],parents:null==l.records.head?[]:[l.records.head.id],branch:l.records.currBranch};l.records.head=i,s.Rm.info("main branch",a.mainBranchName),l.records.commits.has(i.id)&&s.Rm.warn(`Commit ID ${i.id} already exists`),l.records.commits.set(i.id,i),l.records.branches.set(l.records.currBranch,i.id),s.Rm.debug("in pushCommit "+i.id)},"commit"),b=(0,s.K2)(function(t){let r=t.name;const e=t.order;if(r=c.Y2.sanitizeText(r,$()),l.records.branches.has(r))throw new Error(`Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout ${r}")`);l.records.branches.set(r,null!=l.records.head?l.records.head.id:null),l.records.branchConfig.set(r,{name:r,order:e}),E(r),s.Rm.debug("in createBranch")},"branch"),w=(0,s.K2)(t=>{let r=t.branch,e=t.id;const n=t.type,o=t.tags,a=$();r=c.Y2.sanitizeText(r,a),e&&(e=c.Y2.sanitizeText(e,a));const i=l.records.branches.get(l.records.currBranch),h=l.records.branches.get(r),m=i?l.records.commits.get(i):void 0,y=h?l.records.commits.get(h):void 0;if(m&&y&&m.branch===r)throw new Error(`Cannot merge branch '${r}' into itself.`);if(l.records.currBranch===r){const t=new Error('Incorrect usage of "merge". Cannot merge a branch to itself');throw t.hash={text:`merge ${r}`,token:`merge ${r}`,expected:["branch abc"]},t}if(void 0===m||!m){const t=new Error(`Incorrect usage of "merge". Current branch (${l.records.currBranch})has no commits`);throw t.hash={text:`merge ${r}`,token:`merge ${r}`,expected:["commit"]},t}if(!l.records.branches.has(r)){const t=new Error('Incorrect usage of "merge". Branch to be merged ('+r+") does not exist");throw t.hash={text:`merge ${r}`,token:`merge ${r}`,expected:[`branch ${r}`]},t}if(void 0===y||!y){const t=new Error('Incorrect usage of "merge". Branch to be merged ('+r+") has no commits");throw t.hash={text:`merge ${r}`,token:`merge ${r}`,expected:['"commit"']},t}if(m===y){const t=new Error('Incorrect usage of "merge". Both branches have same head');throw t.hash={text:`merge ${r}`,token:`merge ${r}`,expected:["branch abc"]},t}if(e&&l.records.commits.has(e)){const t=new Error('Incorrect usage of "merge". Commit with id:'+e+" already exists, use different custom id");throw t.hash={text:`merge ${r} ${e} ${n} ${o?.join(" ")}`,token:`merge ${r} ${e} ${n} ${o?.join(" ")}`,expected:[`merge ${r} ${e}_UNIQUE ${n} ${o?.join(" ")}`]},t}const p=h||"",x={id:e||`${l.records.seq}-${g()}`,message:`merged branch ${r} into ${l.records.currBranch}`,seq:l.records.seq++,parents:null==l.records.head?[]:[l.records.head.id,p],branch:l.records.currBranch,type:d.MERGE,customType:n,customId:!!e,tags:o??[]};l.records.head=x,l.records.commits.set(x.id,x),l.records.branches.set(l.records.currBranch,x.id),s.Rm.debug(l.records.branches),s.Rm.debug("in mergeBranch")},"merge"),B=(0,s.K2)(function(t){let r=t.id,e=t.targetId,n=t.tags,o=t.parent;s.Rm.debug("Entering cherryPick:",r,e,n);const a=$();if(r=c.Y2.sanitizeText(r,a),e=c.Y2.sanitizeText(e,a),n=n?.map(t=>c.Y2.sanitizeText(t,a)),o=c.Y2.sanitizeText(o,a),!r||!l.records.commits.has(r)){const t=new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');throw t.hash={text:`cherryPick ${r} ${e}`,token:`cherryPick ${r} ${e}`,expected:["cherry-pick abc"]},t}const i=l.records.commits.get(r);if(void 0===i||!i)throw new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');if(o&&(!Array.isArray(i.parents)||!i.parents.includes(o))){throw new Error("Invalid operation: The specified parent commit is not an immediate parent of the cherry-picked commit.")}const h=i.branch;if(i.type===d.MERGE&&!o){throw new Error("Incorrect usage of cherry-pick: If the source commit is a merge commit, an immediate parent commit must be specified.")}if(!e||!l.records.commits.has(e)){if(h===l.records.currBranch){const t=new Error('Incorrect usage of "cherryPick". Source commit is already on current branch');throw t.hash={text:`cherryPick ${r} ${e}`,token:`cherryPick ${r} ${e}`,expected:["cherry-pick abc"]},t}const t=l.records.branches.get(l.records.currBranch);if(void 0===t||!t){const t=new Error(`Incorrect usage of "cherry-pick". Current branch (${l.records.currBranch})has no commits`);throw t.hash={text:`cherryPick ${r} ${e}`,token:`cherryPick ${r} ${e}`,expected:["cherry-pick abc"]},t}const a=l.records.commits.get(t);if(void 0===a||!a){const t=new Error(`Incorrect usage of "cherry-pick". Current branch (${l.records.currBranch})has no commits`);throw t.hash={text:`cherryPick ${r} ${e}`,token:`cherryPick ${r} ${e}`,expected:["cherry-pick abc"]},t}const c={id:l.records.seq+"-"+g(),message:`cherry-picked ${i?.message} into ${l.records.currBranch}`,seq:l.records.seq++,parents:null==l.records.head?[]:[l.records.head.id,i.id],branch:l.records.currBranch,type:d.CHERRY_PICK,tags:n?n.filter(Boolean):[`cherry-pick:${i.id}${i.type===d.MERGE?`|parent:${o}`:""}`]};l.records.head=c,l.records.commits.set(c.id,c),l.records.branches.set(l.records.currBranch,c.id),s.Rm.debug(l.records.branches),s.Rm.debug("in cherryPick")}},"cherryPick"),E=(0,s.K2)(function(t){if(t=c.Y2.sanitizeText(t,$()),!l.records.branches.has(t)){const r=new Error(`Trying to checkout branch which is not yet created. (Help try using "branch ${t}")`);throw r.hash={text:`checkout ${t}`,token:`checkout ${t}`,expected:[`branch ${t}`]},r}{l.records.currBranch=t;const r=l.records.branches.get(l.records.currBranch);l.records.head=void 0!==r&&r?l.records.commits.get(r)??null:null}},"checkout");function k(t,r,e){const n=t.indexOf(r);-1===n?t.push(e):t.splice(n,1,e)}function C(t){const r=t.reduce((t,r)=>t.seq>r.seq?t:r,t[0]);let e="";t.forEach(function(t){e+=t===r?"\t*":"\t|"});const n=[e,r.id,r.seq];for(const o in l.records.branches)l.records.branches.get(o)===r.id&&n.push(o);if(s.Rm.debug(n.join(" ")),r.parents&&2==r.parents.length&&r.parents[0]&&r.parents[1]){const e=l.records.commits.get(r.parents[0]);k(t,r,e),r.parents[1]&&t.push(l.records.commits.get(r.parents[1]))}else{if(0==r.parents.length)return;if(r.parents[0]){const e=l.records.commits.get(r.parents[0]);k(t,r,e)}}C(t=y(t,t=>t.id))}(0,s.K2)(k,"upsert"),(0,s.K2)(C,"prettyPrintCommitHistory");var T=(0,s.K2)(function(){s.Rm.debug(l.records.commits);C([v()[0]])},"prettyPrint"),L=(0,s.K2)(function(){l.reset(),(0,c.IU)()},"clear"),K=(0,s.K2)(function(){return[...l.records.branchConfig.values()].map((t,r)=>null!==t.order&&void 0!==t.order?t:{...t,order:parseFloat(`0.${r}`)}).sort((t,r)=>(t.order??0)-(r.order??0)).map(({name:t})=>({name:t}))},"getBranchesAsObjArray"),M=(0,s.K2)(function(){return l.records.branches},"getBranches"),R=(0,s.K2)(function(){return l.records.commits},"getCommits"),v=(0,s.K2)(function(){const t=[...l.records.commits.values()];return t.forEach(function(t){s.Rm.debug(t.id)}),t.sort((t,r)=>t.seq-r.seq),t},"getCommitsArray"),P={commitType:d,getConfig:$,setDirection:p,setOptions:x,getOptions:f,commit:u,branch:b,merge:w,cherryPick:B,checkout:E,prettyPrint:T,clear:L,getBranchesAsObjArray:K,getBranches:M,getCommits:R,getCommitsArray:v,getCurrentBranch:(0,s.K2)(function(){return l.records.currBranch},"getCurrentBranch"),getDirection:(0,s.K2)(function(){return l.records.direction},"getDirection"),getHead:(0,s.K2)(function(){return l.records.head},"getHead"),setAccTitle:c.SV,getAccTitle:c.iN,getAccDescription:c.m7,setAccDescription:c.EI,setDiagramTitle:c.ke,getDiagramTitle:c.ab},I=(0,s.K2)((t,r)=>{(0,n.S)(t,r),t.dir&&r.setDirection(t.dir);for(const e of t.statements)A(e,r)},"populate"),A=(0,s.K2)((t,r)=>{const e={Commit:(0,s.K2)(t=>r.commit(G(t)),"Commit"),Branch:(0,s.K2)(t=>r.branch(O(t)),"Branch"),Merge:(0,s.K2)(t=>r.merge(q(t)),"Merge"),Checkout:(0,s.K2)(t=>r.checkout(z(t)),"Checkout"),CherryPicking:(0,s.K2)(t=>r.cherryPick(D(t)),"CherryPicking")}[t.$type];e?e(t):s.Rm.error(`Unknown statement type: ${t.$type}`)},"parseStatement"),G=(0,s.K2)(t=>({id:t.id,msg:t.message??"",type:void 0!==t.type?d[t.type]:d.NORMAL,tags:t.tags??void 0}),"parseCommit"),O=(0,s.K2)(t=>({name:t.name,order:t.order??0}),"parseBranch"),q=(0,s.K2)(t=>({branch:t.branch,id:t.id??"",type:void 0!==t.type?d[t.type]:void 0,tags:t.tags??void 0}),"parseMerge"),z=(0,s.K2)(t=>t.branch,"parseCheckout"),D=(0,s.K2)(t=>({id:t.id,targetId:"",tags:0===t.tags?.length?void 0:t.tags,parent:t.parent}),"parseCherryPicking"),H={parse:(0,s.K2)(async t=>{const r=await(0,i.qg)("gitGraph",t);s.Rm.debug(r),I(r,P)},"parse")};var S=(0,c.D7)(),Y=S?.gitGraph,N=10,j=40,W=new Map,_=new Map,F=new Map,U=[],V=0,J="LR",Q=(0,s.K2)(()=>{W.clear(),_.clear(),F.clear(),V=0,U=[],J="LR"},"clear"),X=(0,s.K2)(t=>{const r=document.createElementNS("http://www.w3.org/2000/svg","text");return("string"==typeof t?t.split(/\\n|\n|<br\s*\/?>/gi):t).forEach(t=>{const e=document.createElementNS("http://www.w3.org/2000/svg","tspan");e.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),e.setAttribute("dy","1em"),e.setAttribute("x","0"),e.setAttribute("class","row"),e.textContent=t.trim(),r.appendChild(e)}),r},"drawText"),Z=(0,s.K2)(t=>{let r,e,n;return"BT"===J?(e=(0,s.K2)((t,r)=>t<=r,"comparisonFunc"),n=1/0):(e=(0,s.K2)((t,r)=>t>=r,"comparisonFunc"),n=0),t.forEach(t=>{const o="TB"===J||"BT"==J?_.get(t)?.y:_.get(t)?.x;void 0!==o&&e(o,n)&&(r=t,n=o)}),r},"findClosestParent"),tt=(0,s.K2)(t=>{let r="",e=1/0;return t.forEach(t=>{const n=_.get(t).y;n<=e&&(r=t,e=n)}),r||void 0},"findClosestParentBT"),rt=(0,s.K2)((t,r,e)=>{let n=e,o=e;const a=[];t.forEach(t=>{const e=r.get(t);if(!e)throw new Error(`Commit not found for key ${t}`);e.parents.length?(n=nt(e),o=Math.max(n,o)):a.push(e),ot(e,n)}),n=o,a.forEach(t=>{at(t,n,e)}),t.forEach(t=>{const e=r.get(t);if(e?.parents.length){const t=tt(e.parents);n=_.get(t).y-j,n<=o&&(o=n);const r=W.get(e.branch).pos,a=n-N;_.set(e.id,{x:r,y:a})}})},"setParallelBTPos"),et=(0,s.K2)(t=>{const r=Z(t.parents.filter(t=>null!==t));if(!r)throw new Error(`Closest parent not found for commit ${t.id}`);const e=_.get(r)?.y;if(void 0===e)throw new Error(`Closest parent position not found for commit ${t.id}`);return e},"findClosestParentPos"),nt=(0,s.K2)(t=>et(t)+j,"calculateCommitPosition"),ot=(0,s.K2)((t,r)=>{const e=W.get(t.branch);if(!e)throw new Error(`Branch not found for commit ${t.id}`);const n=e.pos,o=r+N;return _.set(t.id,{x:n,y:o}),{x:n,y:o}},"setCommitPosition"),at=(0,s.K2)((t,r,e)=>{const n=W.get(t.branch);if(!n)throw new Error(`Branch not found for commit ${t.id}`);const o=r+e,a=n.pos;_.set(t.id,{x:a,y:o})},"setRootPosition"),ct=(0,s.K2)((t,r,e,n,o,a)=>{if(a===d.HIGHLIGHT)t.append("rect").attr("x",e.x-10).attr("y",e.y-10).attr("width",20).attr("height",20).attr("class",`commit ${r.id} commit-highlight${o%8} ${n}-outer`),t.append("rect").attr("x",e.x-6).attr("y",e.y-6).attr("width",12).attr("height",12).attr("class",`commit ${r.id} commit${o%8} ${n}-inner`);else if(a===d.CHERRY_PICK)t.append("circle").attr("cx",e.x).attr("cy",e.y).attr("r",10).attr("class",`commit ${r.id} ${n}`),t.append("circle").attr("cx",e.x-3).attr("cy",e.y+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${r.id} ${n}`),t.append("circle").attr("cx",e.x+3).attr("cy",e.y+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${r.id} ${n}`),t.append("line").attr("x1",e.x+3).attr("y1",e.y+1).attr("x2",e.x).attr("y2",e.y-5).attr("stroke","#fff").attr("class",`commit ${r.id} ${n}`),t.append("line").attr("x1",e.x-3).attr("y1",e.y+1).attr("x2",e.x).attr("y2",e.y-5).attr("stroke","#fff").attr("class",`commit ${r.id} ${n}`);else{const c=t.append("circle");if(c.attr("cx",e.x),c.attr("cy",e.y),c.attr("r",r.type===d.MERGE?9:10),c.attr("class",`commit ${r.id} commit${o%8}`),a===d.MERGE){const a=t.append("circle");a.attr("cx",e.x),a.attr("cy",e.y),a.attr("r",6),a.attr("class",`commit ${n} ${r.id} commit${o%8}`)}if(a===d.REVERSE){t.append("path").attr("d",`M ${e.x-5},${e.y-5}L${e.x+5},${e.y+5}M${e.x-5},${e.y+5}L${e.x+5},${e.y-5}`).attr("class",`commit ${n} ${r.id} commit${o%8}`)}}},"drawCommitBullet"),st=(0,s.K2)((t,r,e,n)=>{if(r.type!==d.CHERRY_PICK&&(r.customId&&r.type===d.MERGE||r.type!==d.MERGE)&&Y?.showCommitLabel){const o=t.append("g"),a=o.insert("rect").attr("class","commit-label-bkg"),c=o.append("text").attr("x",n).attr("y",e.y+25).attr("class","commit-label").text(r.id),s=c.node()?.getBBox();if(s&&(a.attr("x",e.posWithOffset-s.width/2-2).attr("y",e.y+13.5).attr("width",s.width+4).attr("height",s.height+4),"TB"===J||"BT"===J?(a.attr("x",e.x-(s.width+16+5)).attr("y",e.y-12),c.attr("x",e.x-(s.width+16)).attr("y",e.y+s.height-12)):c.attr("x",e.posWithOffset-s.width/2),Y.rotateCommitLabel))if("TB"===J||"BT"===J)c.attr("transform","rotate(-45, "+e.x+", "+e.y+")"),a.attr("transform","rotate(-45, "+e.x+", "+e.y+")");else{const t=-7.5-(s.width+10)/25*9.5,r=10+s.width/25*8.5;o.attr("transform","translate("+t+", "+r+") rotate(-45, "+n+", "+e.y+")")}}},"drawCommitLabel"),it=(0,s.K2)((t,r,e,n)=>{if(r.tags.length>0){let o=0,a=0,c=0;const s=[];for(const n of r.tags.reverse()){const r=t.insert("polygon"),i=t.append("circle"),h=t.append("text").attr("y",e.y-16-o).attr("class","tag-label").text(n),d=h.node()?.getBBox();if(!d)throw new Error("Tag bbox not found");a=Math.max(a,d.width),c=Math.max(c,d.height),h.attr("x",e.posWithOffset-d.width/2),s.push({tag:h,hole:i,rect:r,yOffset:o}),o+=20}for(const{tag:t,hole:r,rect:i,yOffset:h}of s){const o=c/2,s=e.y-19.2-h;if(i.attr("class","tag-label-bkg").attr("points",`\n ${n-a/2-2},${s+2} \n ${n-a/2-2},${s-2}\n ${e.posWithOffset-a/2-4},${s-o-2}\n ${e.posWithOffset+a/2+4},${s-o-2}\n ${e.posWithOffset+a/2+4},${s+o+2}\n ${e.posWithOffset-a/2-4},${s+o+2}`),r.attr("cy",s).attr("cx",n-a/2+2).attr("r",1.5).attr("class","tag-hole"),"TB"===J||"BT"===J){const c=n+h;i.attr("class","tag-label-bkg").attr("points",`\n ${e.x},${c+2}\n ${e.x},${c-2}\n ${e.x+N},${c-o-2}\n ${e.x+N+a+4},${c-o-2}\n ${e.x+N+a+4},${c+o+2}\n ${e.x+N},${c+o+2}`).attr("transform","translate(12,12) rotate(45, "+e.x+","+n+")"),r.attr("cx",e.x+2).attr("cy",c).attr("transform","translate(12,12) rotate(45, "+e.x+","+n+")"),t.attr("x",e.x+5).attr("y",c+3).attr("transform","translate(14,14) rotate(45, "+e.x+","+n+")")}}}},"drawCommitTags"),ht=(0,s.K2)(t=>{switch(t.customType??t.type){case d.NORMAL:return"commit-normal";case d.REVERSE:return"commit-reverse";case d.HIGHLIGHT:return"commit-highlight";case d.MERGE:return"commit-merge";case d.CHERRY_PICK:return"commit-cherry-pick";default:return"commit-normal"}},"getCommitClassType"),dt=(0,s.K2)((t,r,e,n)=>{const o={x:0,y:0};if(!(t.parents.length>0)){if("TB"===r)return 30;if("BT"===r){return(n.get(t.id)??o).y-j}return 0}{const e=Z(t.parents);if(e){const a=n.get(e)??o;if("TB"===r)return a.y+j;if("BT"===r){return(n.get(t.id)??o).y-j}return a.x+j}}return 0},"calculatePosition"),mt=(0,s.K2)((t,r,e)=>{const n="BT"===J&&e?r:r+N,o="TB"===J||"BT"===J?n:W.get(t.branch)?.pos,a="TB"===J||"BT"===J?W.get(t.branch)?.pos:n;if(void 0===a||void 0===o)throw new Error(`Position were undefined for commit ${t.id}`);return{x:a,y:o,posWithOffset:n}},"getCommitPosition"),$t=(0,s.K2)((t,r,e)=>{if(!Y)throw new Error("GitGraph config not found");const n=t.append("g").attr("class","commit-bullets"),o=t.append("g").attr("class","commit-labels");let a="TB"===J||"BT"===J?30:0;const c=[...r.keys()],i=Y?.parallelCommits??!1,h=(0,s.K2)((t,e)=>{const n=r.get(t)?.seq,o=r.get(e)?.seq;return void 0!==n&&void 0!==o?n-o:0},"sortKeys");let d=c.sort(h);"BT"===J&&(i&&rt(d,r,a),d=d.reverse()),d.forEach(t=>{const c=r.get(t);if(!c)throw new Error(`Commit not found for key ${t}`);i&&(a=dt(c,J,a,_));const s=mt(c,a,i);if(e){const t=ht(c),r=c.customType??c.type,e=W.get(c.branch)?.index??0;ct(n,c,s,t,e,r),st(o,c,s,a),it(o,c,s,a)}"TB"===J||"BT"===J?_.set(c.id,{x:s.x,y:s.posWithOffset}):_.set(c.id,{x:s.posWithOffset,y:s.y}),a="BT"===J&&i?a+j:a+j+N,a>V&&(V=a)})},"drawCommits"),lt=(0,s.K2)((t,r,e,n,o)=>{const a=("TB"===J||"BT"===J?e.x<n.x:e.y<n.y)?r.branch:t.branch,c=(0,s.K2)(t=>t.branch===a,"isOnBranchToGetCurve"),i=(0,s.K2)(e=>e.seq>t.seq&&e.seq<r.seq,"isBetweenCommits");return[...o.values()].some(t=>i(t)&&c(t))},"shouldRerouteArrow"),gt=(0,s.K2)((t,r,e=0)=>{const n=t+Math.abs(t-r)/2;if(e>5)return n;if(U.every(t=>Math.abs(t-n)>=10))return U.push(n),n;const o=Math.abs(t-r);return gt(t,r-o/5,e+1)},"findLane"),yt=(0,s.K2)((t,r,e,n)=>{const o=_.get(r.id),a=_.get(e.id);if(void 0===o||void 0===a)throw new Error(`Commit positions not found for commits ${r.id} and ${e.id}`);const c=lt(r,e,o,a,n);let s,i="",h="",m=0,$=0,l=W.get(e.branch)?.index;if(e.type===d.MERGE&&r.id!==e.parents[0]&&(l=W.get(r.branch)?.index),c){i="A 10 10, 0, 0, 0,",h="A 10 10, 0, 0, 1,",m=10,$=10;const t=o.y<a.y?gt(o.y,a.y):gt(a.y,o.y),e=o.x<a.x?gt(o.x,a.x):gt(a.x,o.x);"TB"===J?o.x<a.x?s=`M ${o.x} ${o.y} L ${e-m} ${o.y} ${h} ${e} ${o.y+$} L ${e} ${a.y-m} ${i} ${e+$} ${a.y} L ${a.x} ${a.y}`:(l=W.get(r.branch)?.index,s=`M ${o.x} ${o.y} L ${e+m} ${o.y} ${i} ${e} ${o.y+$} L ${e} ${a.y-m} ${h} ${e-$} ${a.y} L ${a.x} ${a.y}`):"BT"===J?o.x<a.x?s=`M ${o.x} ${o.y} L ${e-m} ${o.y} ${i} ${e} ${o.y-$} L ${e} ${a.y+m} ${h} ${e+$} ${a.y} L ${a.x} ${a.y}`:(l=W.get(r.branch)?.index,s=`M ${o.x} ${o.y} L ${e+m} ${o.y} ${h} ${e} ${o.y-$} L ${e} ${a.y+m} ${i} ${e-$} ${a.y} L ${a.x} ${a.y}`):o.y<a.y?s=`M ${o.x} ${o.y} L ${o.x} ${t-m} ${i} ${o.x+$} ${t} L ${a.x-m} ${t} ${h} ${a.x} ${t+$} L ${a.x} ${a.y}`:(l=W.get(r.branch)?.index,s=`M ${o.x} ${o.y} L ${o.x} ${t+m} ${h} ${o.x+$} ${t} L ${a.x-m} ${t} ${i} ${a.x} ${t-$} L ${a.x} ${a.y}`)}else i="A 20 20, 0, 0, 0,",h="A 20 20, 0, 0, 1,",m=20,$=20,"TB"===J?(o.x<a.x&&(s=e.type===d.MERGE&&r.id!==e.parents[0]?`M ${o.x} ${o.y} L ${o.x} ${a.y-m} ${i} ${o.x+$} ${a.y} L ${a.x} ${a.y}`:`M ${o.x} ${o.y} L ${a.x-m} ${o.y} ${h} ${a.x} ${o.y+$} L ${a.x} ${a.y}`),o.x>a.x&&(i="A 20 20, 0, 0, 0,",h="A 20 20, 0, 0, 1,",m=20,$=20,s=e.type===d.MERGE&&r.id!==e.parents[0]?`M ${o.x} ${o.y} L ${o.x} ${a.y-m} ${h} ${o.x-$} ${a.y} L ${a.x} ${a.y}`:`M ${o.x} ${o.y} L ${a.x+m} ${o.y} ${i} ${a.x} ${o.y+$} L ${a.x} ${a.y}`),o.x===a.x&&(s=`M ${o.x} ${o.y} L ${a.x} ${a.y}`)):"BT"===J?(o.x<a.x&&(s=e.type===d.MERGE&&r.id!==e.parents[0]?`M ${o.x} ${o.y} L ${o.x} ${a.y+m} ${h} ${o.x+$} ${a.y} L ${a.x} ${a.y}`:`M ${o.x} ${o.y} L ${a.x-m} ${o.y} ${i} ${a.x} ${o.y-$} L ${a.x} ${a.y}`),o.x>a.x&&(i="A 20 20, 0, 0, 0,",h="A 20 20, 0, 0, 1,",m=20,$=20,s=e.type===d.MERGE&&r.id!==e.parents[0]?`M ${o.x} ${o.y} L ${o.x} ${a.y+m} ${i} ${o.x-$} ${a.y} L ${a.x} ${a.y}`:`M ${o.x} ${o.y} L ${a.x-m} ${o.y} ${i} ${a.x} ${o.y-$} L ${a.x} ${a.y}`),o.x===a.x&&(s=`M ${o.x} ${o.y} L ${a.x} ${a.y}`)):(o.y<a.y&&(s=e.type===d.MERGE&&r.id!==e.parents[0]?`M ${o.x} ${o.y} L ${a.x-m} ${o.y} ${h} ${a.x} ${o.y+$} L ${a.x} ${a.y}`:`M ${o.x} ${o.y} L ${o.x} ${a.y-m} ${i} ${o.x+$} ${a.y} L ${a.x} ${a.y}`),o.y>a.y&&(s=e.type===d.MERGE&&r.id!==e.parents[0]?`M ${o.x} ${o.y} L ${a.x-m} ${o.y} ${i} ${a.x} ${o.y-$} L ${a.x} ${a.y}`:`M ${o.x} ${o.y} L ${o.x} ${a.y+m} ${h} ${o.x+$} ${a.y} L ${a.x} ${a.y}`),o.y===a.y&&(s=`M ${o.x} ${o.y} L ${a.x} ${a.y}`));if(void 0===s)throw new Error("Line definition not found");t.append("path").attr("d",s).attr("class","arrow arrow"+l%8)},"drawArrow"),pt=(0,s.K2)((t,r)=>{const e=t.append("g").attr("class","commit-arrows");[...r.keys()].forEach(t=>{const n=r.get(t);n.parents&&n.parents.length>0&&n.parents.forEach(t=>{yt(e,r.get(t),n,r)})})},"drawArrows"),xt=(0,s.K2)((t,r)=>{const e=t.append("g");r.forEach((t,r)=>{const n=r%8,o=W.get(t.name)?.pos;if(void 0===o)throw new Error(`Position not found for branch ${t.name}`);const a=e.append("line");a.attr("x1",0),a.attr("y1",o),a.attr("x2",V),a.attr("y2",o),a.attr("class","branch branch"+n),"TB"===J?(a.attr("y1",30),a.attr("x1",o),a.attr("y2",V),a.attr("x2",o)):"BT"===J&&(a.attr("y1",V),a.attr("x1",o),a.attr("y2",30),a.attr("x2",o)),U.push(o);const c=t.name,s=X(c),i=e.insert("rect"),h=e.insert("g").attr("class","branchLabel").insert("g").attr("class","label branch-label"+n);h.node().appendChild(s);const d=s.getBBox();i.attr("class","branchLabelBkg label"+n).attr("rx",4).attr("ry",4).attr("x",-d.width-4-(!0===Y?.rotateCommitLabel?30:0)).attr("y",-d.height/2+8).attr("width",d.width+18).attr("height",d.height+4),h.attr("transform","translate("+(-d.width-14-(!0===Y?.rotateCommitLabel?30:0))+", "+(o-d.height/2-1)+")"),"TB"===J?(i.attr("x",o-d.width/2-10).attr("y",0),h.attr("transform","translate("+(o-d.width/2-5)+", 0)")):"BT"===J?(i.attr("x",o-d.width/2-10).attr("y",V),h.attr("transform","translate("+(o-d.width/2-5)+", "+V+")")):i.attr("transform","translate(-19, "+(o-d.height/2)+")")})},"drawBranches"),ft=(0,s.K2)(function(t,r,e,n,o){return W.set(t,{pos:r,index:e}),r+=50+(o?40:0)+("TB"===J||"BT"===J?n.width/2:0)},"setBranchPosition");var ut={parser:H,db:P,renderer:{draw:(0,s.K2)(function(t,r,e,n){if(Q(),s.Rm.debug("in gitgraph renderer",t+"\n","id:",r,e),!Y)throw new Error("GitGraph config not found");const o=Y.rotateCommitLabel??!1,i=n.db;F=i.getCommits();const d=i.getBranchesAsObjArray();J=i.getDirection();const m=(0,h.Ltv)(`[id="${r}"]`);let $=0;d.forEach((t,r)=>{const e=X(t.name),n=m.append("g"),a=n.insert("g").attr("class","branchLabel"),c=a.insert("g").attr("class","label branch-label");c.node()?.appendChild(e);const s=e.getBBox();$=ft(t.name,$,r,s,o),c.remove(),a.remove(),n.remove()}),$t(m,F,!1),Y.showBranches&&xt(m,d),pt(m,F),$t(m,F,!0),a._K.insertTitle(m,"gitTitleText",Y.titleTopMargin??0,i.getDiagramTitle()),(0,c.mj)(void 0,m,Y.diagramPadding,Y.useMaxWidth)},"draw")},styles:(0,s.K2)(t=>`\n .commit-id,\n .commit-msg,\n .branch-label {\n fill: lightgrey;\n color: lightgrey;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n ${[0,1,2,3,4,5,6,7].map(r=>`\n .branch-label${r} { fill: ${t["gitBranchLabel"+r]}; }\n .commit${r} { stroke: ${t["git"+r]}; fill: ${t["git"+r]}; }\n .commit-highlight${r} { stroke: ${t["gitInv"+r]}; fill: ${t["gitInv"+r]}; }\n .label${r} { fill: ${t["git"+r]}; }\n .arrow${r} { stroke: ${t["git"+r]}; }\n `).join("\n")}\n\n .branch {\n stroke-width: 1;\n stroke: ${t.lineColor};\n stroke-dasharray: 2;\n }\n .commit-label { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelColor};}\n .commit-label-bkg { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelBackground}; opacity: 0.5; }\n .tag-label { font-size: ${t.tagLabelFontSize}; fill: ${t.tagLabelColor};}\n .tag-label-bkg { fill: ${t.tagLabelBackground}; stroke: ${t.tagLabelBorder}; }\n .tag-hole { fill: ${t.textColor}; }\n\n .commit-merge {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n .commit-reverse {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n stroke-width: 3;\n }\n .commit-highlight-outer {\n }\n .commit-highlight-inner {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n\n .arrow { stroke-width: 8; stroke-linecap: round; fill: none}\n .gitTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n }\n`,"getStyles")}},72938:(t,r,e)=>{e.d(r,{m:()=>o});var n=e(40797),o=class{constructor(t){this.init=t,this.records=this.init()}static{(0,n.K2)(this,"ImperativeState")}reset(){this.records=this.init()}}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/633fbb2f.fefad383.js b/pr-preview/pr-4027/assets/js/633fbb2f.fefad383.js deleted file mode 100644 index 79e8e3eff..000000000 --- a/pr-preview/pr-4027/assets/js/633fbb2f.fefad383.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3325],{28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>a});var n=s(96540);const o={},i=n.createContext(o);function r(e){const t=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(i.Provider,{value:t},e.children)}},67532:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"workflows/s3proxy","title":"Install s3proxy","description":"Constellation includes a transparent client-side encryption proxy for AWS S3 and compatible stores.","source":"@site/versioned_docs/version-2.23/workflows/s3proxy.md","sourceDirName":"workflows","slug":"/workflows/s3proxy","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/s3proxy","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/workflows/s3proxy.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Install cert-manager","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/cert-manager"},"next":{"title":"Terminate your cluster","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/terminate"}}');var o=s(74848),i=s(28453);const r={},a="Install s3proxy",l={},c=[{value:"Limitations",id:"limitations",level:2},{value:"Deployment",id:"deployment",level:2},{value:"Technical details",id:"technical-details",level:2},{value:"Encryption",id:"encryption",level:3},{value:"Traffic interception",id:"traffic-interception",level:3}];function p(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"install-s3proxy",children:"Install s3proxy"})}),"\n",(0,o.jsxs)(t.p,{children:["Constellation includes a transparent client-side encryption proxy for ",(0,o.jsx)(t.a,{href:"https://aws.amazon.com/de/s3/",children:"AWS S3"})," and compatible stores.\ns3proxy encrypts objects before sending them to S3 and automatically decrypts them on retrieval, without requiring changes to your application.\nWith s3proxy, you can use S3 for storage in a confidential way without having to trust the storage provider."]}),"\n",(0,o.jsx)(t.h2,{id:"limitations",children:"Limitations"}),"\n",(0,o.jsx)(t.p,{children:"Currently, s3proxy has the following limitations:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["Only ",(0,o.jsx)(t.code,{children:"PutObject"})," and ",(0,o.jsx)(t.code,{children:"GetObject"})," requests are encrypted/decrypted by s3proxy.\nBy default, s3proxy will block requests that may expose unencrypted data to S3 (e.g. UploadPart).\nThe ",(0,o.jsx)(t.code,{children:"allow-multipart"})," flag disables request blocking for evaluation purposes."]}),"\n",(0,o.jsxs)(t.li,{children:["Using the ",(0,o.jsx)(t.a,{href:"https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html#API_GetObject_RequestSyntax",children:"Range"})," header on ",(0,o.jsx)(t.code,{children:"GetObject"})," is currently not supported and will result in an error."]}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:["These limitations will be removed with future iterations of s3proxy.\nIf you want to use s3proxy but these limitations stop you from doing so, consider ",(0,o.jsx)(t.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&projects=&template=feature_request.yml",children:"opening an issue"}),"."]}),"\n",(0,o.jsx)(t.h2,{id:"deployment",children:"Deployment"}),"\n",(0,o.jsx)(t.p,{children:"You can add the s3proxy to your Constellation cluster as follows:"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsxs)(t.li,{children:["Add the Edgeless Systems chart repository:","\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"helm repo add edgeless https://helm.edgeless.systems/stable\nhelm repo update\n"})}),"\n"]}),"\n",(0,o.jsx)(t.li,{children:"Set ACCESS_KEY and ACCESS_SECRET to valid credentials you want s3proxy to use to interact with S3."}),"\n",(0,o.jsxs)(t.li,{children:["Deploy s3proxy:","\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:'helm install s3proxy edgeless/s3proxy --set awsAccessKeyID="$ACCESS_KEY" --set awsSecretAccessKey="$ACCESS_SECRET"\n'})}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:["If you want to run a demo application, check out the ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/filestash-s3proxy",children:"Filestash with s3proxy"})," example."]}),"\n",(0,o.jsx)(t.h2,{id:"technical-details",children:"Technical details"}),"\n",(0,o.jsx)(t.h3,{id:"encryption",children:"Encryption"}),"\n",(0,o.jsxs)(t.p,{children:["s3proxy relies on Google's ",(0,o.jsx)(t.a,{href:"https://developers.google.com/tink",children:"Tink Cryptographic Library"})," to implement cryptographic operations securely.\nThe used cryptographic primitives are ",(0,o.jsx)(t.a,{href:"https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf",children:"NIST SP 800 38f"})," for key wrapping and ",(0,o.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Advanced_Encryption_Standard",children:"AES"}),"-",(0,o.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Galois/counter_(GCM)",children:"GCM"})," with 256 bit keys for data encryption."]}),"\n",(0,o.jsxs)(t.p,{children:["s3proxy uses ",(0,o.jsx)(t.a,{href:"https://cloud.google.com/kms/docs/envelope-encryption",children:"envelope encryption"})," to encrypt objects.\nThis means s3proxy uses a key encryption key (KEK) issued by the ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#keyservice",children:"KeyService"})," to encrypt data encryption keys (DEKs).\nEach S3 object is encrypted with its own DEK.\nThe encrypted DEK is then saved as metadata of the encrypted object.\nThis enables key rotation of the KEK without re-encrypting the data in S3.\nThe approach also allows access to objects from different locations, as long as each location has access to the KEK."]}),"\n",(0,o.jsx)(t.h3,{id:"traffic-interception",children:"Traffic interception"}),"\n",(0,o.jsx)(t.p,{children:"To use s3proxy, you have to redirect your outbound S3 traffic to s3proxy.\nThis can either be done by modifying your client application or by changing the deployment of your application."}),"\n",(0,o.jsxs)(t.p,{children:["The necessary deployment modifications are to add DNS redirection and a trusted TLS certificate to the client's trust store.\nDNS redirection can be defined for each pod, allowing you to use s3proxy for one application without changing other applications in the same cluster.\nAdding a trusted TLS certificate is necessary as clients communicate with s3proxy via HTTPS.\nTo have your client application trust s3proxy's TLS certificate, the certificate has to be added to the client's certificate trust store.\nThe ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/filestash-s3proxy",children:"Filestash with s3proxy"})," example shows how to do this."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/6366.060304b1.js b/pr-preview/pr-4027/assets/js/6366.060304b1.js deleted file mode 100644 index efeff8827..000000000 --- a/pr-preview/pr-4027/assets/js/6366.060304b1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6366],{86366:(c,e,s)=>{s.d(e,{createArchitectureServices:()=>t.S});var t=s(38980);s(87960)}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/642ed902.5ef7e201.js b/pr-preview/pr-4027/assets/js/642ed902.5ef7e201.js deleted file mode 100644 index 9696885b3..000000000 --- a/pr-preview/pr-4027/assets/js/642ed902.5ef7e201.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5541],{28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const i={},r=s.createContext(i);function o(e){const t=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:t},e.children)}},48162:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"architecture/attestation","title":"Attestation","description":"This page explains Constellation\'s attestation process and highlights the cornerstones of its trust model.","source":"@site/docs/architecture/attestation.md","sourceDirName":"architecture","slug":"/architecture/attestation","permalink":"/constellation/pr-preview/pr-4027/next/architecture/attestation","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/architecture/attestation.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Microservices","permalink":"/constellation/pr-preview/pr-4027/next/architecture/microservices"},"next":{"title":"Images","permalink":"/constellation/pr-preview/pr-4027/next/architecture/images"}}');var i=n(74848),r=n(28453);const o={},a="Attestation",d={},l=[{value:"Terms",id:"terms",level:2},{value:"Trusted Platform Module (TPM)",id:"trusted-platform-module-tpm",level:3},{value:"Runtime measurement",id:"runtime-measurement",level:3},{value:"Platform Configuration Register (PCR)",id:"platform-configuration-register-pcr",level:3},{value:"Measured boot",id:"measured-boot",level:3},{value:"Remote attestation (RA)",id:"remote-attestation-ra",level:3},{value:"Confidential virtual machine (CVM)",id:"confidential-virtual-machine-cvm",level:3},{value:"Attested TLS (aTLS)",id:"attested-tls-atls",level:3},{value:"Overview",id:"overview",level:2},{value:"Node attestation",id:"node-attestation",level:2},{value:"Runtime measurements",id:"runtime-measurements",level:3},{value:"CVM verification",id:"cvm-verification",level:3},{value:"Cluster attestation",id:"cluster-attestation",level:2},{value:"Cluster-facing attestation",id:"cluster-facing-attestation",level:3},{value:"User-facing attestation",id:"user-facing-attestation",level:3},{value:"Putting it all together",id:"putting-it-all-together",level:2},{value:"CLI and node images",id:"cli-and-node-images",level:3},{value:"Cluster creation",id:"cluster-creation",level:3},{value:"Chain of trust",id:"chain-of-trust",level:3},{value:"Upgrades",id:"upgrades",level:3},{value:"References",id:"references",level:2}];function c(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",mermaid:"mermaid",ol:"ol",p:"p",pre:"pre",section:"section",strong:"strong",sup:"sup",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components},{TabItem:n,Tabs:s}=t;return n||u("TabItem",!0),s||u("Tabs",!0),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"attestation",children:"Attestation"})}),"\n",(0,i.jsx)(t.p,{children:"This page explains Constellation's attestation process and highlights the cornerstones of its trust model."}),"\n",(0,i.jsx)(t.h2,{id:"terms",children:"Terms"}),"\n",(0,i.jsx)(t.p,{children:"The following lists terms and concepts that help to understand the attestation concept of Constellation."}),"\n",(0,i.jsx)(t.h3,{id:"trusted-platform-module-tpm",children:"Trusted Platform Module (TPM)"}),"\n",(0,i.jsxs)(t.p,{children:["A TPM chip is a dedicated tamper-resistant crypto-processor.\nIt can securely store artifacts such as passwords, certificates, encryption keys, or ",(0,i.jsx)(t.em,{children:"runtime measurements"})," (more on this below).\nWhen a TPM is implemented in software, it's typically called a ",(0,i.jsx)(t.em,{children:"virtual"})," TPM (vTPM)."]}),"\n",(0,i.jsx)(t.h3,{id:"runtime-measurement",children:"Runtime measurement"}),"\n",(0,i.jsxs)(t.p,{children:["A runtime measurement is a cryptographic hash of the memory pages of a so called ",(0,i.jsx)(t.em,{children:"runtime component"}),". Runtime components of interest typically include a system's bootloader or OS kernel."]}),"\n",(0,i.jsx)(t.h3,{id:"platform-configuration-register-pcr",children:"Platform Configuration Register (PCR)"}),"\n",(0,i.jsx)(t.p,{children:"A Platform Configuration Register (PCR) is a memory location in the TPM that has some unique properties.\nTo store a new value in a PCR, the existing value is extended with a new value as follows:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"PCR[N] = HASHalg( PCR[N] || ArgumentOfExtend )\n"})}),"\n",(0,i.jsx)(t.p,{children:"The PCRs are typically used to store runtime measurements.\nThe new value of a PCR is always an extension of the existing value.\nThus, storing the measurements of multiple components into the same PCR irreversibly links them together."}),"\n",(0,i.jsx)(t.h3,{id:"measured-boot",children:"Measured boot"}),"\n",(0,i.jsx)(t.p,{children:"Measured boot builds on the concept of chained runtime measurements.\nEach component in the boot chain loads and measures the next component into the PCR before executing it.\nBy comparing the resulting PCR values against trusted reference values, the integrity of the entire boot chain and thereby the running system can be ensured."}),"\n",(0,i.jsx)(t.h3,{id:"remote-attestation-ra",children:"Remote attestation (RA)"}),"\n",(0,i.jsx)(t.p,{children:"Remote attestation is the process of verifying certain properties of an application or platform, such as integrity and confidentiality, from a remote location.\nIn the case of a measured boot, the goal is to obtain a signed attestation statement on the PCR values of the boot measurements.\nThe statement can then be verified and compared to a set of trusted reference values.\nThis way, the integrity of the platform can be ensured before sharing secrets with it."}),"\n",(0,i.jsx)(t.h3,{id:"confidential-virtual-machine-cvm",children:"Confidential virtual machine (CVM)"}),"\n",(0,i.jsx)(t.p,{children:"Confidential computing (CC) is the protection of data in-use with hardware-based trusted execution environments (TEEs).\nWith CVMs, TEEs encapsulate entire virtual machines and isolate them against the hypervisor, other VMs, and direct memory access.\nAfter loading the initial VM image into encrypted memory, the hypervisor calls for a secure processor to measure these initial memory pages.\nThe secure processor locks these pages and generates an attestation report on the initial page measurements.\nCVM memory pages are encrypted with a key that resides inside the secure processor, which makes sure only the guest VM can access them.\nThe attestation report is signed by the secure processor and can be verified using remote attestation via the certificate authority of the hardware vendor.\nSuch an attestation statement guarantees the confidentiality and integrity of a CVM."}),"\n",(0,i.jsx)(t.h3,{id:"attested-tls-atls",children:"Attested TLS (aTLS)"}),"\n",(0,i.jsx)(t.p,{children:"In a CC environment, attested TLS (aTLS) can be used to establish secure connections between two parties using the remote attestation features of the CC components."}),"\n",(0,i.jsx)(t.p,{children:"aTLS modifies the TLS handshake by embedding an attestation statement into the TLS certificate.\nInstead of relying on a certificate authority, aTLS uses this attestation statement to establish trust in the certificate."}),"\n",(0,i.jsx)(t.p,{children:"The protocol can be used by clients to verify a server certificate, by a server to verify a client certificate, or for mutual verification (mutual aTLS)."}),"\n",(0,i.jsx)(t.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsx)(t.p,{children:"The challenge for Constellation is to lift a CVM's attestation statement to the Kubernetes software layer and make it end-to-end verifiable.\nFrom there, Constellation needs to expand the attestation from a single CVM to the entire cluster."}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#joinservice",children:(0,i.jsx)(t.em,{children:"JoinService"})})," and ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#verificationservice",children:(0,i.jsx)(t.em,{children:"VerificationService"})})," are where all runs together.\nInternally, the ",(0,i.jsx)(t.em,{children:"JoinService"})," uses remote attestation to securely join CVM nodes to the cluster.\nExternally, the ",(0,i.jsx)(t.em,{children:"VerificationService"})," provides an attestation statement for the cluster's CVMs and configuration."]}),"\n",(0,i.jsx)(t.p,{children:"The following explains the details of both steps."}),"\n",(0,i.jsx)(t.h2,{id:"node-attestation",children:"Node attestation"}),"\n",(0,i.jsx)(t.p,{children:"The idea is that Constellation nodes should have verifiable integrity from the CVM hardware measurement up to the Kubernetes software layer.\nThe solution is a verifiable boot chain and an integrity-protected runtime environment."}),"\n",(0,i.jsxs)(t.p,{children:["Constellation uses measured boot within CVMs, measuring each component in the boot process before executing it.\nOutside of CC, this is usually implemented via TPMs.\nCVM technologies differ in how they implement runtime measurements, but the general concepts are similar to those of a TPM.\nFor simplicity, TPM terminology like ",(0,i.jsx)(t.em,{children:"PCR"})," is used in the following."]}),"\n",(0,i.jsxs)(t.p,{children:["When a Constellation node image boots inside a CVM, measured boot is used for all stages and components of the boot chain.\nThis process goes up to the root filesystem.\nThe root filesystem is mounted read-only with integrity protection.\nFor the details on the image and boot stages see the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/images",children:"image architecture"})," documentation.\nAny changes to the image will inevitably also change the corresponding PCR values.\nTo create a node attestation statement, the Constellation image obtains a CVM attestation statement from the hardware.\nThis includes the runtime measurements and thereby binds the measured boot results to the CVM hardware measurement."]}),"\n",(0,i.jsxs)(t.p,{children:["In addition to the image measurements, Constellation extends a PCR during the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/create",children:"initialization phase"})," that irrevocably marks the node as initialized.\nThe measurement is created using the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys#cluster-identity",children:(0,i.jsx)(t.em,{children:"clusterID"})}),", tying all future attestation statements to this ID.\nThereby, an attestation statement is unique for every cluster and a node can be identified unambiguously as being initialized."]}),"\n",(0,i.jsxs)(t.p,{children:["To verify an attestation, the hardware's signature and a statement are verified first to establish trust in the contained runtime measurements.\nIf successful, the measurements are verified against the trusted values of the particular Constellation release version.\nFinally, the measurement of the ",(0,i.jsx)(t.em,{children:"clusterID"})," can be compared by calculating it with the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys#master-secret",children:"master secret"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"runtime-measurements",children:"Runtime measurements"}),"\n",(0,i.jsx)(t.p,{children:"Constellation uses runtime measurements to implement the measured boot approach.\nAs stated above, the underlying hardware technology and guest firmware differ in their implementations of runtime measurements.\nThe following gives a detailed description of the available measurements in the different cloud environments."}),"\n",(0,i.jsx)(t.p,{children:"The runtime measurements consist of two types of values:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Measurements produced by the cloud infrastructure and firmware of the CVM"}),":\nThese are measurements of closed-source firmware and other values controlled by the cloud provider.\nWhile not being reproducible for the user, some of them can be compared against previously observed values.\nOthers may change frequently and aren't suitable for verification.\nThe ",(0,i.jsx)(t.a,{href:"#chain-of-trust",children:"signed image measurements"})," include measurements that are known, previously observed values."]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Measurements produced by the Constellation bootloader and boot chain"}),":\nThe Constellation Bootloader takes over from the CVM firmware and ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/images",children:"measures the rest of the boot chain"}),".\nThe Constellation ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#bootstrapper",children:"Bootstrapper"})," is the first user mode component that runs in a Constellation image.\nIt extends PCR registers with the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys#cluster-identity",children:"IDs"})," of the cluster marking a node as initialized."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Constellation allows to specify in the config which measurements should be enforced during the attestation process.\nEnforcing non-reproducible measurements controlled by the cloud provider means that changes in these values require manual updates to the cluster's config.\nBy default, Constellation only enforces measurements that are stable values produced by the infrastructure or by Constellation directly."}),"\n",(0,i.jsxs)(s,{groupId:"csp",children:[(0,i.jsxs)(n,{value:"aws",label:"AWS",children:[(0,i.jsxs)(t.p,{children:["Constellation uses the ",(0,i.jsx)(t.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nitrotpm.html",children:"vTPM"})," (NitroTPM) feature of the ",(0,i.jsx)(t.a,{href:"http://aws.amazon.com/ec2/nitro/",children:"AWS Nitro System"})," on AWS for runtime measurements."]}),(0,i.jsxs)(t.p,{children:["The vTPM adheres to the ",(0,i.jsx)(t.a,{href:"https://trustedcomputinggroup.org/resource/tpm-library-specification/",children:"TPM 2.0"})," specification.\nThe VMs are attested by obtaining signed PCR values over the VM's boot configuration from the TPM and comparing them to a known, good state (measured boot)."]}),(0,i.jsx)(t.p,{children:"The following table lists all PCR values of the vTPM and the measured components.\nIt also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable.\nThe latter means that the value can be generated offline and compared to the one in the vTPM."}),(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"PCR"}),(0,i.jsx)(t.th,{children:"Components"}),(0,i.jsx)(t.th,{children:"Measured by"}),(0,i.jsx)(t.th,{children:"Reproducible and verifiable"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"0"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"2"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"3"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"4"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader, Kernel, initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"AWS, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"5"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"6"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"AWS"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"7"}),(0,i.jsx)(t.td,{children:"Secure Boot Policy"}),(0,i.jsx)(t.td,{children:"AWS, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"8"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"9"}),(0,i.jsx)(t.td,{children:"initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Linux Kernel"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10"}),(0,i.jsx)(t.td,{children:"User space"}),(0,i.jsx)(t.td,{children:"Linux IMA"}),(0,i.jsxs)(t.td,{children:["No",(0,i.jsx)(t.sup,{children:(0,i.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"11"}),(0,i.jsx)(t.td,{children:"Unified Kernel Image components"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"12"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(User space, Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"13"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"14"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"15"}),(0,i.jsx)(t.td,{children:"ClusterID"}),(0,i.jsx)(t.td,{children:"Constellation Bootstrapper"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"16\u201323"}),(0,i.jsx)(t.td,{children:"Unused"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]})]})]})]}),(0,i.jsxs)(n,{value:"azure",label:"Azure",children:[(0,i.jsxs)(t.p,{children:["Constellation uses the ",(0,i.jsx)(t.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/trusted-launch#vtpm",children:"vTPM"})," feature of Azure CVMs for runtime measurements.\nThis vTPM adheres to the ",(0,i.jsx)(t.a,{href:"https://trustedcomputinggroup.org/resource/tpm-library-specification/",children:"TPM 2.0"})," specification.\nIt provides a ",(0,i.jsx)(t.a,{href:"https://docs.microsoft.com/en-us/azure/security/fundamentals/measured-boot-host-attestation#measured-boot",children:"measured boot"})," verification that's based on the trusted launch feature of ",(0,i.jsx)(t.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/trusted-launch",children:"Trusted Launch VMs"}),"."]}),(0,i.jsx)(t.p,{children:"The following table lists all PCR values of the vTPM and the measured components.\nIt also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable.\nThe latter means that the value can be generated offline and compared to the one in the vTPM."}),(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"PCR"}),(0,i.jsx)(t.th,{children:"Components"}),(0,i.jsx)(t.th,{children:"Measured by"}),(0,i.jsx)(t.th,{children:"Reproducible and verifiable"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"0"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"2"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"3"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"4"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader, Kernel, initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Azure, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"5"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"6"}),(0,i.jsx)(t.td,{children:"VM Unique ID"}),(0,i.jsx)(t.td,{children:"Azure"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"7"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Azure, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"8"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"9"}),(0,i.jsx)(t.td,{children:"initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Linux Kernel"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10"}),(0,i.jsx)(t.td,{children:"User space"}),(0,i.jsx)(t.td,{children:"Linux IMA"}),(0,i.jsxs)(t.td,{children:["No",(0,i.jsx)(t.sup,{children:(0,i.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"11"}),(0,i.jsx)(t.td,{children:"Unified Kernel Image components"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"12"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(User space, Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"13"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"14"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"15"}),(0,i.jsx)(t.td,{children:"ClusterID"}),(0,i.jsx)(t.td,{children:"Constellation Bootstrapper"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"16\u201323"}),(0,i.jsx)(t.td,{children:"Unused"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]})]})]})]}),(0,i.jsxs)(n,{value:"gcp",label:"GCP",children:[(0,i.jsxs)(t.p,{children:["Constellation uses the ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/compute/confidential-vm/docs/about-cvm",children:"vTPM"})," feature of CVMs on GCP for runtime measurements.\nNote that this vTPM doesn't run inside the hardware-protected CVM context, but is emulated by the hypervisor."]}),(0,i.jsxs)(t.p,{children:["The vTPM adheres to the ",(0,i.jsx)(t.a,{href:"https://trustedcomputinggroup.org/resource/tpm-library-specification/",children:"TPM 2.0"})," specification.\nIt provides a ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/compute/confidential-vm/docs/monitoring#about_launch_attestation_report_events",children:"launch attestation report"})," that's based on the measured boot feature of ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/compute/shielded-vm/docs/shielded-vm#measured-boot",children:"Shielded VMs"}),"."]}),(0,i.jsx)(t.p,{children:"The following table lists all PCR values of the vTPM and the measured components.\nIt also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable.\nThe latter means that the value can be generated offline and compared to the one in the vTPM."}),(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"PCR"}),(0,i.jsx)(t.th,{children:"Components"}),(0,i.jsx)(t.th,{children:"Measured by"}),(0,i.jsx)(t.th,{children:"Reproducible and verifiable"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"0"}),(0,i.jsx)(t.td,{children:"CVM version and technology"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"2"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"3"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"4"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader, Kernel, initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"GCP, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"5"}),(0,i.jsx)(t.td,{children:"Disk GUID partition table"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"6"}),(0,i.jsx)(t.td,{children:"Disk GUID partition table"}),(0,i.jsx)(t.td,{children:"GCP"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"7"}),(0,i.jsx)(t.td,{children:"GCP Secure Boot Policy"}),(0,i.jsx)(t.td,{children:"GCP, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"8"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"9"}),(0,i.jsx)(t.td,{children:"initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Linux Kernel"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10"}),(0,i.jsx)(t.td,{children:"User space"}),(0,i.jsx)(t.td,{children:"Linux IMA"}),(0,i.jsxs)(t.td,{children:["No",(0,i.jsx)(t.sup,{children:(0,i.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"11"}),(0,i.jsx)(t.td,{children:"Unified Kernel Image components"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"12"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(User space, Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"13"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"14"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"15"}),(0,i.jsx)(t.td,{children:"ClusterID"}),(0,i.jsx)(t.td,{children:"Constellation Bootstrapper"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"16\u201323"}),(0,i.jsx)(t.td,{children:"Unused"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]})]})]})]}),(0,i.jsxs)(n,{value:"stackit",label:"STACKIT",children:[(0,i.jsx)(t.p,{children:"Constellation uses a hypervisor-based vTPM for runtime measurements."}),(0,i.jsxs)(t.p,{children:["The vTPM adheres to the ",(0,i.jsx)(t.a,{href:"https://trustedcomputinggroup.org/resource/tpm-library-specification/",children:"TPM 2.0"})," specification.\nThe VMs are attested by obtaining signed PCR values over the VM's boot configuration from the TPM and comparing them to a known, good state (measured boot)."]}),(0,i.jsx)(t.p,{children:"The following table lists all PCR values of the vTPM and the measured components.\nIt also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable.\nThe latter means that the value can be generated offline and compared to the one in the vTPM."}),(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"PCR"}),(0,i.jsx)(t.th,{children:"Components"}),(0,i.jsx)(t.th,{children:"Measured by"}),(0,i.jsx)(t.th,{children:"Reproducible and verifiable"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"0"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"1"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"2"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"3"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"4"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader, Kernel, initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"STACKIT, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"5"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"6"}),(0,i.jsx)(t.td,{children:"Firmware"}),(0,i.jsx)(t.td,{children:"STACKIT"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"7"}),(0,i.jsx)(t.td,{children:"Secure Boot Policy"}),(0,i.jsx)(t.td,{children:"STACKIT, Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"8"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"9"}),(0,i.jsx)(t.td,{children:"initramfs, Kernel command line"}),(0,i.jsx)(t.td,{children:"Linux Kernel"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10"}),(0,i.jsx)(t.td,{children:"User space"}),(0,i.jsx)(t.td,{children:"Linux IMA"}),(0,i.jsxs)(t.td,{children:["No",(0,i.jsx)(t.sup,{children:(0,i.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"11"}),(0,i.jsx)(t.td,{children:"Unified Kernel Image components"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"12"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(User space, Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"13"}),(0,i.jsx)(t.td,{children:"Reserved"}),(0,i.jsx)(t.td,{children:"(Constellation Bootloader)"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"14"}),(0,i.jsx)(t.td,{children:"Secure Boot State"}),(0,i.jsx)(t.td,{children:"Constellation Bootloader"}),(0,i.jsx)(t.td,{children:"No"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"15"}),(0,i.jsx)(t.td,{children:"ClusterID"}),(0,i.jsx)(t.td,{children:"Constellation Bootstrapper"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"16\u201323"}),(0,i.jsx)(t.td,{children:"Unused"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]})]})]})]})]}),"\n",(0,i.jsx)(t.h3,{id:"cvm-verification",children:"CVM verification"}),"\n",(0,i.jsx)(t.p,{children:"To verify the integrity of the received attestation statement, a chain of trust from the CVM technology to the interface providing the statement has to be established.\nFor verification of the CVM technology, Constellation may expose additional options in its config file."}),"\n",(0,i.jsxs)(s,{groupId:"csp",children:[(0,i.jsxs)(n,{value:"aws",label:"AWS",children:[(0,i.jsx)(t.p,{children:"On AWS, AMD SEV-SNP is used to provide runtime encryption to the VMs.\nAn SEV-SNP attestation report is used to establish trust in the VM.\nYou may customize certain parameters for verification of the attestation statement using the Constellation config file."}),(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"TCB versions"}),"\n",(0,i.jsx)(t.p,{children:"You can set the minimum version numbers of components in the SEV-SNP TCB.\nUse the latest versions to enforce that only machines with the most recent firmware updates are allowed to join the cluster.\nAlternatively, you can set a lower minimum version to allow slightly out-of-date machines to still be able to join the cluster."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Root Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This certificate is the root of trust for verifying the SEV-SNP certificate chain."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Signing Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This is the intermediate certificate for verifying the SEV-SNP report's signature.\nIf it's not specified, the CLI fetches it from the AMD key distribution server."}),"\n"]}),"\n"]})]}),(0,i.jsxs)(n,{value:"azure",label:"Azure SEV-SNP",children:[(0,i.jsx)(t.p,{children:"On Azure, AMD SEV-SNP is used to provide runtime encryption to the VMs.\nAn SEV-SNP attestation report is used to establish trust in the vTPM running inside the VM.\nYou may customize certain parameters for verification of the attestation statement using the Constellation config file."}),(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"TCB versions"}),"\n",(0,i.jsx)(t.p,{children:"You can set the minimum version numbers of components in the SEV-SNP TCB.\nUse the latest versions to enforce that only machines with the most recent firmware updates are allowed to join the cluster.\nAlternatively, you can set a lower minimum version to allow slightly out-of-date machines to still be able to join the cluster."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Root Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This certificate is the root of trust for verifying the SEV-SNP certificate chain."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"Firmware Signer"}),"\n",(0,i.jsxs)(t.p,{children:["This config option allows you to specify how the firmware signer should be verified.\nMore explicitly, it controls the verification of the ",(0,i.jsx)(t.code,{children:"IDKeyDigest"})," value in the SEV-SNP attestation report.\nYou can provide a list of accepted key digests and specify a policy on how this list is compared against the reported ",(0,i.jsx)(t.code,{children:"IDKeyDigest"}),"."]}),"\n"]}),"\n"]})]}),(0,i.jsxs)(n,{value:"gcp",label:"GCP",children:[(0,i.jsx)(t.p,{children:"On GCP, AMD SEV-SNP is used to provide runtime encryption to the VMs.\nAn SEV-SNP attestation report is used to establish trust in the VM.\nYou may customize certain parameters for verification of the attestation statement using the Constellation config file."}),(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"TCB versions"}),"\n",(0,i.jsx)(t.p,{children:"You can set the minimum version numbers of components in the SEV-SNP TCB.\nUse the latest versions to enforce that only machines with the most recent firmware updates are allowed to join the cluster.\nAlternatively, you can set a lower minimum version to allow slightly out-of-date machines to still be able to join the cluster."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Root Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This certificate is the root of trust for verifying the SEV-SNP certificate chain."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"AMD Signing Key Certificate"}),"\n",(0,i.jsx)(t.p,{children:"This is the intermediate certificate for verifying the SEV-SNP report's signature.\nIf it's not specified, the CLI fetches it from the AMD key distribution server."}),"\n"]}),"\n"]})]}),(0,i.jsx)(n,{value:"stackit",label:"STACKIT",children:(0,i.jsxs)(t.p,{children:["On STACKIT, AMD SEV-ES is used to provide runtime encryption to the VMs.\nThe hypervisor-based vTPM is used to establish trust in the VM via ",(0,i.jsx)(t.a,{href:"#runtime-measurements",children:"runtime measurements"}),".\nThere is no additional configuration available for STACKIT."]})})]}),"\n",(0,i.jsx)(t.h2,{id:"cluster-attestation",children:"Cluster attestation"}),"\n",(0,i.jsxs)(t.p,{children:["Cluster-facing, Constellation's ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#joinservice",children:(0,i.jsx)(t.em,{children:"JoinService"})})," verifies each node joining the cluster given the configured ground truth runtime measurements.\nUser-facing, the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#verificationservice",children:(0,i.jsx)(t.em,{children:"VerificationService"})})," provides an interface to verify a node using remote attestation.\nBy verifying the first node during the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#bootstrapper",children:"initialization"})," and configuring the ground truth measurements that are subsequently enforced by the ",(0,i.jsx)(t.em,{children:"JoinService"}),", the whole cluster is verified in a transitive way."]}),"\n",(0,i.jsx)(t.h3,{id:"cluster-facing-attestation",children:"Cluster-facing attestation"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"JoinService"})," is provided with the runtime measurements of the whitelisted Constellation image version as the ground truth.\nDuring the initialization and the cluster bootstrapping, each node connects to the ",(0,i.jsx)(t.em,{children:"JoinService"})," using ",(0,i.jsx)(t.a,{href:"#attested-tls-atls",children:"aTLS"}),".\nDuring the handshake, the node transmits an attestation statement including its runtime measurements.\nThe ",(0,i.jsx)(t.em,{children:"JoinService"})," verifies that statement and compares the measurements against the ground truth.\nFor details of the initialization process check the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices",children:"microservice descriptions"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["After the initialization, every node updates its runtime measurements with the ",(0,i.jsx)(t.em,{children:"clusterID"})," value, marking it irreversibly as initialized.\nWhen an initialized node tries to join another cluster, its measurements inevitably mismatch the measurements of an uninitialized node and it will be declined."]}),"\n",(0,i.jsx)(t.h3,{id:"user-facing-attestation",children:"User-facing attestation"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#verificationservice",children:(0,i.jsx)(t.em,{children:"VerificationService"})})," provides an endpoint for obtaining its hardware-based remote attestation statement, which includes the runtime measurements.\nA user can ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/verify-cluster",children:"verify"})," this statement and compare the measurements against the configured ground truth and, thus, verify the identity and integrity of all Constellation components and the cluster configuration. Subsequently, the user knows that the entire cluster is in the expected state and is trustworthy."]}),"\n",(0,i.jsx)(t.h2,{id:"putting-it-all-together",children:"Putting it all together"}),"\n",(0,i.jsx)(t.p,{children:"This section puts the aforementioned concepts together and illustrate how trust into a Constellation cluster is established and maintained."}),"\n",(0,i.jsx)(t.h3,{id:"cli-and-node-images",children:"CLI and node images"}),"\n",(0,i.jsxs)(t.p,{children:["It all starts with the CLI executable. The CLI is signed by Edgeless Systems. To ensure non-repudiability for CLI releases, Edgeless Systems publishes corresponding signatures to the public ledger of the ",(0,i.jsx)(t.a,{href:"https://www.sigstore.dev/",children:"sigstore project"}),". There's a ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/verify-cli",children:"step-by-step guide"})," on how to verify CLI signatures based on sigstore."]}),"\n",(0,i.jsxs)(t.p,{children:["The CLI contains the latest runtime measurements of the Constellation node image for all supported cloud platforms. In case a different version of the node image is to be used, the corresponding runtime measurements can be fetched using the CLI's ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/reference/cli#constellation-config-fetch-measurements",children:"fetch-measurements command"}),". This command downloads the runtime measurements and the corresponding signature from cdn.confidential.cloud. See for example the following files corresponding to node image v2.16.3:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://cdn.confidential.cloud/constellation/v2/ref/-/stream/stable/v2.16.3/image/measurements.json",children:"Measurements"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://cdn.confidential.cloud/constellation/v2/ref/-/stream/stable/v2.16.3/image/measurements.json.sig",children:"Signature"})}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"The CLI contains the long-term public key of Edgeless Systems to verify the signature of downloaded runtime measurements."}),"\n",(0,i.jsx)(t.h3,{id:"cluster-creation",children:"Cluster creation"}),"\n",(0,i.jsxs)(t.p,{children:["When a cluster is ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/create",children:"created"}),", the CLI automatically verifies the runtime measurements of the ",(0,i.jsx)(t.em,{children:"first node"})," using remote attestation. Based on this, the CLI and the first node set up a temporary TLS connection. This ",(0,i.jsx)(t.a,{href:"#attested-tls-atls",children:"aTLS"})," connection is used for two things:"]}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["The CLI sends the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys#master-secret",children:"master secret"})," of the to-be-created cluster to the CLI. The master secret is generated by the first node."]}),"\n",(0,i.jsxs)(t.li,{children:["The first node sends a ",(0,i.jsx)(t.a,{href:"https://www.redhat.com/sysadmin/kubeconfig",children:"kubeconfig file"})," with Kubernetes credentials to the CLI."]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["After this, the aTLS connection is closed and the first node bootstraps the Kubernetes cluster. All subsequent interactions between the CLI and the cluster go via the ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/overview/kubernetes-api/",children:"Kubernetes API"})," server running inside the cluster. The CLI (and other tools like kubectl) use the credentials referenced by the kubeconfig file to authenticate themselves towards the Kubernetes API server and to establish a mTLS connection."]}),"\n",(0,i.jsx)(t.p,{children:"The CLI connects to the Kubernetes API to write the runtime measurements for the applicable node image to etcd. The JoinService uses these runtime measurements to verify all nodes that join the cluster subsequently."}),"\n",(0,i.jsx)(t.h3,{id:"chain-of-trust",children:"Chain of trust"}),"\n",(0,i.jsx)(t.p,{children:"In summary, there's a chain of trust based on cryptographic signatures that goes from the user to the cluster via the CLI. This is illustrated in the following diagram."}),"\n",(0,i.jsx)(t.mermaid,{value:'flowchart LR\n A[User]-- "verifies" --\x3eB[CLI]\n B[CLI]-- "verifies" --\x3eC([Runtime measurements])\n D[Edgeless Systems]-- "signs" --\x3eB[CLI]\n D[Edgeless Systems]-- "signs" --\x3eC([Runtime measurements])\n B[CLI]-- "verifies (remote attestation)" --\x3eE[First node]\n E[First node]-- "verifies (remote attestation)" --\x3eF[Other nodes]\n C([Runtime measurements]) -.-> E[First node]\n C([Runtime measurements]) -.-> F[Other nodes]'}),"\n",(0,i.jsx)(t.h3,{id:"upgrades",children:"Upgrades"}),"\n",(0,i.jsxs)(t.p,{children:["Whenever a cluster is ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/upgrade",children:"upgraded"})," to a new version of the node image, the CLI sends the corresponding runtime measurements via the Kubernetes API server. The new runtime measurements are stored in etcd within the cluster and replace any previous runtime measurements. The new runtime measurements are then used automatically by the JoinService for the verification of new nodes."]}),"\n",(0,i.jsx)(t.h2,{id:"references",children:"References"}),"\n","\n",(0,i.jsxs)(t.section,{"data-footnotes":!0,className:"footnotes",children:[(0,i.jsx)(t.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{id:"user-content-fn-1",children:["\n",(0,i.jsxs)(t.p,{children:["Linux IMA produces runtime measurements of user-space binaries.\nHowever, these measurements aren't deterministic and thus, PCR[10] can't be compared to a constant value.\nInstead, a policy engine must be used to verify the TPM event log against a policy. ",(0,i.jsx)(t.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})," ",(0,i.jsxs)(t.a,{href:"#user-content-fnref-1-2","data-footnote-backref":"","aria-label":"Back to reference 1-2",className:"data-footnote-backref",children:["\u21a9",(0,i.jsx)(t.sup,{children:"2"})]})," ",(0,i.jsxs)(t.a,{href:"#user-content-fnref-1-3","data-footnote-backref":"","aria-label":"Back to reference 1-3",className:"data-footnote-backref",children:["\u21a9",(0,i.jsx)(t.sup,{children:"3"})]})," ",(0,i.jsxs)(t.a,{href:"#user-content-fnref-1-4","data-footnote-backref":"","aria-label":"Back to reference 1-4",className:"data-footnote-backref",children:["\u21a9",(0,i.jsx)(t.sup,{children:"4"})]})]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}function u(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/64c81f13.d0a432fb.js b/pr-preview/pr-4027/assets/js/64c81f13.d0a432fb.js deleted file mode 100644 index a85b86947..000000000 --- a/pr-preview/pr-4027/assets/js/64c81f13.d0a432fb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2733],{3048:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"workflows/trusted-launch","title":"Use Azure trusted launch VMs","description":"Constellation also supports trusted launch VMs on Microsoft Azure. Trusted launch VMs don\'t offer the same level of security as Confidential VMs, but are available in more regions and in larger quantities. The main difference between trusted launch VMs and normal VMs is that the former offer vTPM-based remote attestation. When used with trusted launch VMs, Constellation relies on vTPM-based remote attestation to verify nodes.","source":"@site/versioned_docs/version-2.23/workflows/trusted-launch.md","sourceDirName":"workflows","slug":"/workflows/trusted-launch","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/trusted-launch","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/workflows/trusted-launch.md","tags":[],"version":"2.23","frontMatter":{}}');var o=s(74848),i=s(28453);const r={},a="Use Azure trusted launch VMs",l={},c=[{value:"VM images",id:"vm-images",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"use-azure-trusted-launch-vms",children:"Use Azure trusted launch VMs"})}),"\n",(0,o.jsxs)(n.p,{children:["Constellation also supports ",(0,o.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/trusted-launch",children:"trusted launch VMs"})," on Microsoft Azure. Trusted launch VMs don't offer the same level of security as Confidential VMs, but are available in more regions and in larger quantities. The main difference between trusted launch VMs and normal VMs is that the former offer vTPM-based remote attestation. When used with trusted launch VMs, Constellation relies on vTPM-based remote attestation to verify nodes."]}),"\n",(0,o.jsx)(n.admonition,{type:"caution",children:(0,o.jsx)(n.p,{children:"Trusted launch VMs don't provide runtime encryption and don't keep the cloud service provider (CSP) out of your trusted computing base."})}),"\n",(0,o.jsxs)(n.p,{children:["Constellation supports trusted launch VMs with instance types ",(0,o.jsx)(n.code,{children:"Standard_D*_v4"})," and ",(0,o.jsx)(n.code,{children:"Standard_E*_v4"}),". Run ",(0,o.jsx)(n.code,{children:"constellation config instance-types"})," for a list of all supported instance types."]}),"\n",(0,o.jsx)(n.h2,{id:"vm-images",children:"VM images"}),"\n",(0,o.jsxs)(n.p,{children:["Azure currently doesn't support ",(0,o.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/share-gallery-community",children:"community galleries for trusted launch VMs"}),". Thus, you need to manually import the Constellation node image into your cloud subscription."]}),"\n",(0,o.jsxs)(n.p,{children:["The latest image is available at ",(0,o.jsx)(n.code,{children:"https://cdn.confidential.cloud/constellation/images/azure/trusted-launch/v2.2.0/constellation.img"}),". Simply adjust the version number to download a newer version."]}),"\n",(0,o.jsxs)(n.p,{children:["After you've downloaded the image, create a resource group ",(0,o.jsx)(n.code,{children:"constellation-images"})," in your Azure subscription and import the image.\nYou can use a script to do this:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"wget https://raw.githubusercontent.com/edgelesssys/constellation/main/hack/importAzure.sh\nchmod +x importAzure.sh\nAZURE_IMAGE_VERSION=2.2.0 AZURE_RESOURCE_GROUP_NAME=constellation-images AZURE_IMAGE_FILE=./constellation.img ./importAzure.sh\n"})}),"\n",(0,o.jsx)(n.p,{children:"The script creates the following resources:"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["A new image gallery with the default name ",(0,o.jsx)(n.code,{children:"constellation-import"})]}),"\n",(0,o.jsxs)(n.li,{children:["A new image definition with the default name ",(0,o.jsx)(n.code,{children:"constellation"})]}),"\n",(0,o.jsxs)(n.li,{children:["The actual image with the provided version. In this case ",(0,o.jsx)(n.code,{children:"2.2.0"})]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Once the import is completed, use the ",(0,o.jsx)(n.code,{children:"ID"})," of the image version in your ",(0,o.jsx)(n.code,{children:"constellation-conf.yaml"})," for the ",(0,o.jsx)(n.code,{children:"image"})," field. Set ",(0,o.jsx)(n.code,{children:"confidentialVM"})," to ",(0,o.jsx)(n.code,{children:"false"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"Fetch the image measurements:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"IMAGE_VERSION=2.2.0\nURL=https://public-edgeless-constellation.s3.us-east-2.amazonaws.com//communitygalleries/constellationcvm-b3782fa0-0df7-4f2f-963e-fc7fc42663df/images/constellation/versions/$IMAGE_VERSION/measurements.yaml\nconstellation config fetch-measurements -u$URL -s$URL.sig\n"})}),"\n",(0,o.jsxs)(n.admonition,{type:"info",children:[(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/create",children:(0,o.jsx)(n.code,{children:"constellation apply"})})," command will issue a warning because manually imported images aren't recognized as production grade images:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-shell-session",children:"Configured image doesn't look like a released production image. Double check image before deploying to production.\n"})}),(0,o.jsx)(n.p,{children:"Please ignore this warning."})]})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>a});var t=s(96540);const o={},i=t.createContext(o);function r(e){const n=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/66852f4d.0306c16e.js b/pr-preview/pr-4027/assets/js/66852f4d.0306c16e.js deleted file mode 100644 index 6a282705e..000000000 --- a/pr-preview/pr-4027/assets/js/66852f4d.0306c16e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6850],{28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var s=t(96540);const i={},o=s.createContext(i);function r(e){const n=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:n},e.children)}},60420:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/concept-d3a09a16a8e7ca14a7bdf274ea7bce40.svg"},62129:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"intro","title":"Introduction","description":"Constellation is no longer actively maintained by Edgeless Systems.","source":"@site/versioned_docs/version-2.24/intro.md","sourceDirName":".","slug":"/","permalink":"/constellation/pr-preview/pr-4027/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/intro.md","tags":[],"version":"2.24","frontMatter":{"slug":"/","id":"intro"},"sidebar":"docs","next":{"title":"Basics","permalink":"/constellation/pr-preview/pr-4027/category/basics"}}');var i=t(74848),o=t(28453);const r={slug:"/",id:"intro"},a="Introduction",l={},c=[{value:"Goals",id:"goals",level:2},{value:"Use cases",id:"use-cases",level:2},{value:"Next steps",id:"next-steps",level:2}];function d(e){const n={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"introduction",children:"Introduction"})}),"\n",(0,i.jsxs)(n.admonition,{title:"Maintenance Notice",type:"caution",children:[(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Constellation is no longer actively maintained by Edgeless Systems."})}),(0,i.jsx)(n.p,{children:"This project is no longer receiving updates or support from Edgeless Systems. The repository and documentation remain available for archival purposes and community use."})]}),"\n",(0,i.jsx)(n.p,{children:"Welcome to the documentation of Constellation! Constellation is a Kubernetes engine that aims to provide the best possible data security."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Constellation concept",src:t(60420).A+"",width:"1776",height:"746"})}),"\n",(0,i.jsxs)(n.p,{children:["Constellation shields your entire Kubernetes cluster from the underlying cloud infrastructure. Everything inside is always encrypted, including at runtime in memory. For this, Constellation leverages a technology called ",(0,i.jsx)(n.em,{children:"confidential computing"})," and more specifically Confidential VMs."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["See the \ud83d\udcc4",(0,i.jsx)(n.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"})," for more information on confidential computing."]})}),"\n",(0,i.jsx)(n.h2,{id:"goals",children:"Goals"}),"\n",(0,i.jsx)(n.p,{children:"From a security perspective, Constellation is designed to keep all data always encrypted and to prevent any access from the underlying (cloud) infrastructure. This includes access from datacenter employees, privileged cloud admins, and attackers coming through the infrastructure. Such attackers could be malicious co-tenants escalating their privileges or hackers who managed to compromise a cloud server."}),"\n",(0,i.jsx)(n.p,{children:"From a DevOps perspective, Constellation is designed to work just like what you would expect from a modern Kubernetes engine."}),"\n",(0,i.jsx)(n.h2,{id:"use-cases",children:"Use cases"}),"\n",(0,i.jsxs)(n.p,{children:["Constellation provides unique security ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/overview/confidential-kubernetes",children:"features"})," and ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/overview/security-benefits",children:"benefits"}),". The core use cases are:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Increasing the overall security of your clusters"}),"\n",(0,i.jsx)(n.li,{children:"Increasing the trustworthiness of your SaaS offerings"}),"\n",(0,i.jsx)(n.li,{children:"Moving sensitive workloads from on-prem to the cloud"}),"\n",(0,i.jsx)(n.li,{children:"Meeting regulatory requirements"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,i.jsxs)(n.p,{children:["You can learn more about the concept of Confidential Kubernetes, features, security benefits, and performance of Constellation in the ",(0,i.jsx)(n.em,{children:"Basics"})," section. To jump right into the action head to ",(0,i.jsx)(n.em,{children:"Getting started"}),"."]})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/66e2533d.3c4f9e07.js b/pr-preview/pr-4027/assets/js/66e2533d.3c4f9e07.js deleted file mode 100644 index 3d244af03..000000000 --- a/pr-preview/pr-4027/assets/js/66e2533d.3c4f9e07.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1523],{28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>c});var s=n(96540);const i={},r=s.createContext(i);function o(e){const t=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:t},e.children)}},89786:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"overview/license","title":"License","description":"Constellation is available under the Business Source License 1.1.","source":"@site/docs/overview/license.md","sourceDirName":"overview","slug":"/overview/license","permalink":"/constellation/pr-preview/pr-4027/next/overview/license","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/overview/license.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Application benchmarks","permalink":"/constellation/pr-preview/pr-4027/next/overview/performance/application"},"next":{"title":"Getting started","permalink":"/constellation/pr-preview/pr-4027/next/category/getting-started"}}');var i=n(74848),r=n(28453);const o={},c="License",a={},l=[{value:"Enterprise License",id:"enterprise-license",level:2},{value:"CSP Marketplaces",id:"csp-marketplaces",level:2}];function p(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"license",children:"License"})}),"\n",(0,i.jsxs)(t.p,{children:["Constellation is available under the ",(0,i.jsx)(t.a,{href:"https://github.com/edgelesssys/constellation/blob/main/LICENSE",children:"Business Source License 1.1"}),"."]}),"\n",(0,i.jsx)(t.p,{children:'You may use it free of charge for non-production use ("Community License").'}),"\n",(0,i.jsx)(t.h2,{id:"enterprise-license",children:"Enterprise License"}),"\n",(0,i.jsxs)(t.p,{children:["Enterprise Licenses permit production use and come with support and additional features. Find out more at the ",(0,i.jsx)(t.a,{href:"https://www.edgeless.systems/products/constellation/",children:"product website"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["Once you have received your Enterprise License file, place it in your ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/orchestration#workspaces",children:"Constellation workspace"})," in a file named ",(0,i.jsx)(t.code,{children:"constellation.license"}),"."]}),"\n",(0,i.jsx)(t.h2,{id:"csp-marketplaces",children:"CSP Marketplaces"}),"\n",(0,i.jsxs)(t.p,{children:["Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please ",(0,i.jsx)(t.a,{href:"https://www.edgeless.systems/enterprise-support/",children:"contact us"}),"."]})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(p,{...e})}):p(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/6776993e.3d373e8f.js b/pr-preview/pr-4027/assets/js/6776993e.3d373e8f.js deleted file mode 100644 index 609a1d38c..000000000 --- a/pr-preview/pr-4027/assets/js/6776993e.3d373e8f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9023],{28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var r=n(96540);const o={},s=r.createContext(o);function a(e){const t=r.useContext(s);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),r.createElement(s.Provider,{value:t},e.children)}},62708:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"workflows/terminate","title":"Terminate your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","source":"@site/docs/workflows/terminate.md","sourceDirName":"workflows","slug":"/workflows/terminate","permalink":"/constellation/pr-preview/pr-4027/next/workflows/terminate","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/workflows/terminate.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Install s3proxy","permalink":"/constellation/pr-preview/pr-4027/next/workflows/s3proxy"},"next":{"title":"Recover your cluster","permalink":"/constellation/pr-preview/pr-4027/next/workflows/recovery"}}');var o=n(74848),s=n(28453);const a={},i="Terminate your cluster",l={},c=[];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",header:"header",hr:"hr",p:"p",pre:"pre",...(0,s.R)(),...e.components},{AsciinemaWidget:n,TabItem:r,Tabs:a}=t;return n||u("AsciinemaWidget",!0),r||u("TabItem",!0),a||u("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"terminate-your-cluster",children:"Terminate your cluster"})}),"\n",(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsx)(t.p,{children:"This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details."})}),"\n",(0,o.jsx)(n,{src:"/constellation/assets/terminate-cluster.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,o.jsx)(t.hr,{}),"\n",(0,o.jsxs)(t.p,{children:["You can terminate your cluster using the CLI. For this, you need the Terraform state directory named ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/reference/terraform",children:(0,o.jsx)(t.code,{children:"constellation-terraform"})})," in the current directory."]}),"\n",(0,o.jsx)(t.admonition,{type:"danger",children:(0,o.jsx)(t.p,{children:"All ephemeral storage and state of your cluster will be lost. Make sure any data is safely stored in persistent storage. Constellation can recreate your cluster and the associated encryption keys, but won't backup your application data automatically."})}),"\n",(0,o.jsxs)(a,{groupId:"provider",children:[(0,o.jsxs)(r,{value:"cli",label:"CLI",children:[(0,o.jsx)(t.p,{children:"Terminate the cluster by running:"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation terminate\n"})}),(0,o.jsx)(t.p,{children:"Or without confirmation (e.g., for automation purposes):"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation terminate --yes\n"})}),(0,o.jsxs)(t.p,{children:["This deletes all resources created by Constellation in your cloud environment.\nAll local files created by the ",(0,o.jsx)(t.code,{children:"apply"})," command are deleted as well, except for ",(0,o.jsx)(t.code,{children:"constellation-mastersecret.json"})," and the configuration file."]}),(0,o.jsx)(t.admonition,{type:"caution",children:(0,o.jsxs)(t.p,{children:["Termination can fail if additional resources have been created that depend on the ones managed by Constellation. In this case, you need to delete these additional\nresources manually. Just run the ",(0,o.jsx)(t.code,{children:"terminate"})," command again afterward to continue the termination process of the cluster."]})})]}),(0,o.jsxs)(r,{value:"terraform",label:"Terraform",children:[(0,o.jsx)(t.p,{children:"Terminate the cluster by running:"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"terraform destroy\n"})}),(0,o.jsx)(t.p,{children:"Delete all files that are no longer needed:"}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"rm constellation-state.yaml constellation-admin.conf\n"})}),(0,o.jsxs)(t.p,{children:["Only the ",(0,o.jsx)(t.code,{children:"constellation-mastersecret.json"})," and the configuration file remain."]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}function u(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/68f29d4c.2d54c93a.js b/pr-preview/pr-4027/assets/js/68f29d4c.2d54c93a.js deleted file mode 100644 index dadb420ee..000000000 --- a/pr-preview/pr-4027/assets/js/68f29d4c.2d54c93a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8865],{11355:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"workflows/terraform-provider","title":"Use the Terraform provider","description":"The Constellation Terraform provider allows to manage the full lifecycle of a Constellation cluster (namely creation, upgrades, and deletion) via Terraform.","source":"@site/versioned_docs/version-2.24/workflows/terraform-provider.md","sourceDirName":"workflows","slug":"/workflows/terraform-provider","permalink":"/constellation/pr-preview/pr-4027/workflows/terraform-provider","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/workflows/terraform-provider.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Use persistent storage","permalink":"/constellation/pr-preview/pr-4027/workflows/storage"},"next":{"title":"Consume SBOMs","permalink":"/constellation/pr-preview/pr-4027/workflows/sbom"}}');var t=n(74848),s=n(28453);const i={},a="Use the Terraform provider",l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Quick setup",id:"quick-setup",level:2},{value:"Bringing your own infrastructure",id:"bringing-your-own-infrastructure",level:2},{value:"Cluster upgrades",id:"cluster-upgrades",level:2}];function d(e){const r={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components},{TabItem:n,Tabs:o}=r;return n||h("TabItem",!0),o||h("Tabs",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.header,{children:(0,t.jsx)(r.h1,{id:"use-the-terraform-provider",children:"Use the Terraform provider"})}),"\n",(0,t.jsxs)(r.p,{children:["The Constellation Terraform provider allows to manage the full lifecycle of a Constellation cluster (namely creation, upgrades, and deletion) via Terraform.\nThe provider is available through the ",(0,t.jsx)(r.a,{href:"https://registry.terraform.io/providers/edgelesssys/constellation/latest",children:"Terraform registry"})," and is released in lock-step with Constellation releases."]}),"\n",(0,t.jsx)(r.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsx)(r.li,{children:"a Linux / Mac operating system (ARM64/AMD64)"}),"\n",(0,t.jsxs)(r.li,{children:["a Terraform installation of version ",(0,t.jsx)(r.code,{children:"v1.4.4"})," or above"]}),"\n"]}),"\n",(0,t.jsx)(r.h2,{id:"quick-setup",children:"Quick setup"}),"\n",(0,t.jsxs)(r.p,{children:["This example shows how to set up a Constellation cluster with the reference IAM and infrastructure setup. This setup is also used when creating a Constellation cluster through the Constellation CLI. You can either consume the IAM / infrastructure modules through a remote source (recommended) or local files. The latter requires downloading the infrastructure and IAM modules for the corresponding CSP from ",(0,t.jsx)(r.code,{children:"terraform-modules.zip"})," on the ",(0,t.jsx)(r.a,{href:"https://github.com/edgelesssys/constellation/releases/latest",children:"Constellation release page"})," and placing them in the Terraform workspace directory."]}),"\n",(0,t.jsxs)(r.ol,{children:["\n",(0,t.jsx)(r.li,{children:"Create a directory (workspace) for your Constellation cluster."}),"\n"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"mkdir constellation-workspace\ncd constellation-workspace\n"})}),"\n",(0,t.jsxs)(r.ol,{start:"2",children:["\n",(0,t.jsxs)(r.li,{children:["Use one of the ",(0,t.jsx)(r.a,{href:"https://github.com/edgelesssys/constellation/tree/main/terraform-provider-constellation/examples/full",children:"example configurations for using the Constellation Terraform provider"})," or create a ",(0,t.jsx)(r.code,{children:"main.tf"})," file and fill it with the resources you want to create. The ",(0,t.jsx)(r.a,{href:"https://registry.terraform.io/providers/edgelesssys/constellation/latest",children:"Constellation Terraform provider documentation"})," offers thorough documentation on the resources and their attributes."]}),"\n",(0,t.jsx)(r.li,{children:"Initialize and apply the Terraform configuration."}),"\n"]}),"\n",(0,t.jsxs)(o,{groupId:"csp",children:[(0,t.jsxs)(n,{value:"aws",label:"AWS",children:[(0,t.jsx)(r.p,{children:"Initialize the providers and apply the configuration."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply\n"})}),(0,t.jsxs)(r.p,{children:["Optionally, you can prefix the ",(0,t.jsx)(r.code,{children:"terraform apply"})," command with ",(0,t.jsx)(r.code,{children:"TF_LOG=INFO"})," to collect ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform logs"})," while applying the configuration. This may provide helpful output in debugging scenarios."]})]}),(0,t.jsxs)(n,{value:"azure",label:"Azure",children:[(0,t.jsxs)(r.admonition,{type:"info",children:[(0,t.jsx)(r.p,{children:"On SEV-SNP, you need to manually patch the policy of the MAA provider before creating the Constellation cluster, as this feature isn't available in Azure's Terraform provider yet. The Constellation CLI provides a utility for patching, but you can also do it manually."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply -target module.azure_iam # adjust resource path if not using the example configuration\nterraform apply -target module.azure_infrastructure # adjust resource path if not using the example configuration\nconstellation maa-patch $(terraform output -raw maa_url) # adjust output path / input if not using the example configuration or manually patch the resource\nterraform apply -target constellation_cluster.azure_example # adjust resource path if not using the example configuration\n"})}),(0,t.jsx)(r.p,{children:"Use the following policy if manually performing the patch."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{children:'version= 1.0;\nauthorizationrules\n{\n [type=="x-ms-azurevm-default-securebootkeysvalidated", value==false] => deny();\n [type=="x-ms-azurevm-debuggersdisabled", value==false] => deny();\n // The line below was edited to use the MAA provider within Constellation. Do not edit manually.\n //[type=="secureboot", value==false] => deny();\n [type=="x-ms-azurevm-signingdisabled", value==false] => deny();\n [type=="x-ms-azurevm-dbvalidated", value==false] => deny();\n [type=="x-ms-azurevm-dbxvalidated", value==false] => deny();\n => permit();\n};\nissuancerules\n{\n};\n'})})]}),(0,t.jsx)(r.p,{children:"Initialize the providers and apply the configuration."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply\n"})}),(0,t.jsxs)(r.p,{children:["Optionally, you can prefix the ",(0,t.jsx)(r.code,{children:"terraform apply"})," command with ",(0,t.jsx)(r.code,{children:"TF_LOG=INFO"})," to collect ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform logs"})," while applying the configuration. This may provide helpful output in debugging scenarios."]})]}),(0,t.jsxs)(n,{value:"gcp",label:"GCP",children:[(0,t.jsx)(r.p,{children:"Initialize the providers and apply the configuration."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply\n"})}),(0,t.jsxs)(r.p,{children:["Optionally, you can prefix the ",(0,t.jsx)(r.code,{children:"terraform apply"})," command with ",(0,t.jsx)(r.code,{children:"TF_LOG=INFO"})," to collect ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform logs"})," while applying the configuration. This may provide helpful output in debugging scenarios."]})]}),(0,t.jsxs)(n,{value:"stackit",label:"STACKIT",children:[(0,t.jsx)(r.p,{children:"Initialize the providers and apply the configuration."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply\n"})}),(0,t.jsxs)(r.p,{children:["Optionally, you can prefix the ",(0,t.jsx)(r.code,{children:"terraform apply"})," command with ",(0,t.jsx)(r.code,{children:"TF_LOG=INFO"})," to collect ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform logs"})," while applying the configuration. This may provide helpful output in debugging scenarios."]})]})]}),"\n",(0,t.jsxs)(r.ol,{start:"4",children:["\n",(0,t.jsx)(r.li,{children:"Connect to the cluster."}),"\n"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform output -raw kubeconfig > constellation-admin.conf\nexport KUBECONFIG=$(realpath constellation-admin.conf)\n"})}),"\n",(0,t.jsx)(r.h2,{id:"bringing-your-own-infrastructure",children:"Bringing your own infrastructure"}),"\n",(0,t.jsxs)(r.p,{children:["Instead of using the example infrastructure used in the ",(0,t.jsx)(r.a,{href:"#quick-setup",children:"quick setup"}),", you can also provide your own infrastructure.\nIf you need a starting point for a custom infrastructure setup, you can download the infrastructure / IAM Terraform modules for the respective CSP from the Constellation ",(0,t.jsx)(r.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub releases"}),". You can modify and extend the modules per your requirements, while keeping the basic functionality intact.\nThe module contains:"]}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsxs)(r.li,{children:[(0,t.jsx)(r.code,{children:"{csp}"}),": cloud resources the cluster runs on"]}),"\n",(0,t.jsxs)(r.li,{children:[(0,t.jsx)(r.code,{children:"iam/{csp}"}),": IAM resources used within the cluster"]}),"\n"]}),"\n",(0,t.jsx)(r.p,{children:"When upgrading your cluster, make sure to check the Constellation release notes for potential breaking changes in the reference infrastructure / IAM modules that need to be considered."}),"\n",(0,t.jsx)(r.h2,{id:"cluster-upgrades",children:"Cluster upgrades"}),"\n",(0,t.jsx)(r.admonition,{type:"tip",children:(0,t.jsxs)(r.p,{children:["Also see the ",(0,t.jsx)(r.a,{href:"/constellation/pr-preview/pr-4027/workflows/upgrade",children:"general documentation on cluster upgrades"}),"."]})}),"\n",(0,t.jsx)(r.p,{children:"The steps for applying the upgrade are as follows:"}),"\n",(0,t.jsxs)(r.ol,{children:["\n",(0,t.jsxs)(r.li,{children:["Update the version constraint of the Constellation Terraform provider in the ",(0,t.jsx)(r.code,{children:"required_providers"})," block in your Terraform configuration."]}),"\n",(0,t.jsxs)(r.li,{children:["If you explicitly set any of the version attributes of the provider's resources and data sources (e.g. ",(0,t.jsx)(r.code,{children:"image_version"})," or ",(0,t.jsx)(r.code,{children:"constellation_microservice_version"}),"), make sure to update them too. Refer to Constellation's ",(0,t.jsx)(r.a,{href:"https://github.com/edgelesssys/constellation/blob/main/dev-docs/workflows/versions-support.md",children:"version support policy"})," for more information on how each Constellation version and its dependencies are supported."]}),"\n",(0,t.jsxs)(r.li,{children:["Update the IAM / infrastructure configuration.","\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsxs)(r.li,{children:["For ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/language/modules/sources#fetching-archives-over-http",children:"remote addresses as module sources"}),", update the version number inside the address of the ",(0,t.jsx)(r.code,{children:"source"})," field of the infrastructure / IAM module to the target version."]}),"\n",(0,t.jsxs)(r.li,{children:["For ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/language/modules/sources#local-paths",children:"local paths as module sources"})," or when ",(0,t.jsx)(r.a,{href:"#bringing-your-own-infrastructure",children:"providing your own infrastructure"}),", see the changes made in the reference modules since the upgrade's origin version and adjust your infrastructure / IAM configuration accordingly."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(r.li,{children:"Upgrade the Terraform module and provider dependencies and apply the targeted configuration."}),"\n"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:" terraform init -upgrade\n terraform apply\n"})})]})}function u(e={}){const{wrapper:r}={...(0,s.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}function h(e,r){throw new Error("Expected "+(r?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,r,n)=>{n.d(r,{R:()=>i,x:()=>a});var o=n(96540);const t={},s=o.createContext(t);function i(e){const r=o.useContext(s);return o.useMemo(function(){return"function"==typeof e?e(r):{...r,...e}},[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),o.createElement(s.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/6992.6bbbbe26.js b/pr-preview/pr-4027/assets/js/6992.6bbbbe26.js deleted file mode 100644 index 10208e0d7..000000000 --- a/pr-preview/pr-4027/assets/js/6992.6bbbbe26.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6992],{16992:(t,e,a)=>{a.d(e,{diagram:()=>z});var r=a(73590),n=a(25871),i=a(13226),s=a(67633),o=a(40797),l=a(78731),c={showLegend:!0,ticks:5,max:null,min:0,graticule:"circle"},d={axes:[],curves:[],options:c},g=structuredClone(d),h=s.UI.radar,u=(0,o.K2)(()=>(0,i.$t)({...h,...(0,s.zj)().radar}),"getConfig"),p=(0,o.K2)(()=>g.axes,"getAxes"),x=(0,o.K2)(()=>g.curves,"getCurves"),m=(0,o.K2)(()=>g.options,"getOptions"),$=(0,o.K2)(t=>{g.axes=t.map(t=>({name:t.name,label:t.label??t.name}))},"setAxes"),f=(0,o.K2)(t=>{g.curves=t.map(t=>({name:t.name,label:t.label??t.name,entries:y(t.entries)}))},"setCurves"),y=(0,o.K2)(t=>{if(null==t[0].axis)return t.map(t=>t.value);const e=p();if(0===e.length)throw new Error("Axes must be populated before curves for reference entries");return e.map(e=>{const a=t.find(t=>t.axis?.$refText===e.name);if(void 0===a)throw new Error("Missing entry for axis "+e.label);return a.value})},"computeCurveEntries"),v={getAxes:p,getCurves:x,getOptions:m,setAxes:$,setCurves:f,setOptions:(0,o.K2)(t=>{const e=t.reduce((t,e)=>(t[e.name]=e,t),{});g.options={showLegend:e.showLegend?.value??c.showLegend,ticks:e.ticks?.value??c.ticks,max:e.max?.value??c.max,min:e.min?.value??c.min,graticule:e.graticule?.value??c.graticule}},"setOptions"),getConfig:u,clear:(0,o.K2)(()=>{(0,s.IU)(),g=structuredClone(d)},"clear"),setAccTitle:s.SV,getAccTitle:s.iN,setDiagramTitle:s.ke,getDiagramTitle:s.ab,getAccDescription:s.m7,setAccDescription:s.EI},b=(0,o.K2)(t=>{(0,n.S)(t,v);const{axes:e,curves:a,options:r}=t;v.setAxes(e),v.setCurves(a),v.setOptions(r)},"populate"),w={parse:(0,o.K2)(async t=>{const e=await(0,l.qg)("radar",t);o.Rm.debug(e),b(e)},"parse")},C=(0,o.K2)((t,e,a,n)=>{const i=n.db,s=i.getAxes(),o=i.getCurves(),l=i.getOptions(),c=i.getConfig(),d=i.getDiagramTitle(),g=(0,r.D)(e),h=M(g,c),u=l.max??Math.max(...o.map(t=>Math.max(...t.entries))),p=l.min,x=Math.min(c.width,c.height)/2;K(h,s,x,l.ticks,l.graticule),T(h,s,x,c),L(h,s,o,p,u,l.graticule,c),O(h,o,l.showLegend,c),h.append("text").attr("class","radarTitle").text(d).attr("x",0).attr("y",-c.height/2-c.marginTop)},"draw"),M=(0,o.K2)((t,e)=>{const a=e.width+e.marginLeft+e.marginRight,r=e.height+e.marginTop+e.marginBottom,n=e.marginLeft+e.width/2,i=e.marginTop+e.height/2;return t.attr("viewbox",`0 0 ${a} ${r}`).attr("width",a).attr("height",r),t.append("g").attr("transform",`translate(${n}, ${i})`)},"drawFrame"),K=(0,o.K2)((t,e,a,r,n)=>{if("circle"===n)for(let i=0;i<r;i++){const e=a*(i+1)/r;t.append("circle").attr("r",e).attr("class","radarGraticule")}else if("polygon"===n){const n=e.length;for(let i=0;i<r;i++){const s=a*(i+1)/r,o=e.map((t,e)=>{const a=2*e*Math.PI/n-Math.PI/2;return`${s*Math.cos(a)},${s*Math.sin(a)}`}).join(" ");t.append("polygon").attr("points",o).attr("class","radarGraticule")}}},"drawGraticule"),T=(0,o.K2)((t,e,a,r)=>{const n=e.length;for(let i=0;i<n;i++){const s=e[i].label,o=2*i*Math.PI/n-Math.PI/2;t.append("line").attr("x1",0).attr("y1",0).attr("x2",a*r.axisScaleFactor*Math.cos(o)).attr("y2",a*r.axisScaleFactor*Math.sin(o)).attr("class","radarAxisLine"),t.append("text").text(s).attr("x",a*r.axisLabelFactor*Math.cos(o)).attr("y",a*r.axisLabelFactor*Math.sin(o)).attr("class","radarAxisLabel")}},"drawAxes");function L(t,e,a,r,n,i,s){const o=e.length,l=Math.min(s.width,s.height)/2;a.forEach((e,a)=>{if(e.entries.length!==o)return;const c=e.entries.map((t,e)=>{const a=2*Math.PI*e/o-Math.PI/2,i=k(t,r,n,l);return{x:i*Math.cos(a),y:i*Math.sin(a)}});"circle"===i?t.append("path").attr("d",A(c,s.curveTension)).attr("class",`radarCurve-${a}`):"polygon"===i&&t.append("polygon").attr("points",c.map(t=>`${t.x},${t.y}`).join(" ")).attr("class",`radarCurve-${a}`)})}function k(t,e,a,r){return r*(Math.min(Math.max(t,e),a)-e)/(a-e)}function A(t,e){const a=t.length;let r=`M${t[0].x},${t[0].y}`;for(let n=0;n<a;n++){const i=t[(n-1+a)%a],s=t[n],o=t[(n+1)%a],l=t[(n+2)%a],c={x:s.x+(o.x-i.x)*e,y:s.y+(o.y-i.y)*e},d={x:o.x-(l.x-s.x)*e,y:o.y-(l.y-s.y)*e};r+=` C${c.x},${c.y} ${d.x},${d.y} ${o.x},${o.y}`}return`${r} Z`}function O(t,e,a,r){if(!a)return;const n=3*(r.width/2+r.marginRight)/4,i=3*-(r.height/2+r.marginTop)/4;e.forEach((e,a)=>{const r=t.append("g").attr("transform",`translate(${n}, ${i+20*a})`);r.append("rect").attr("width",12).attr("height",12).attr("class",`radarLegendBox-${a}`),r.append("text").attr("x",16).attr("y",0).attr("class","radarLegendText").text(e.label)})}(0,o.K2)(L,"drawCurves"),(0,o.K2)(k,"relativeRadius"),(0,o.K2)(A,"closedRoundCurve"),(0,o.K2)(O,"drawLegend");var S={draw:C},I=(0,o.K2)((t,e)=>{let a="";for(let r=0;r<t.THEME_COLOR_LIMIT;r++){const n=t[`cScale${r}`];a+=`\n\t\t.radarCurve-${r} {\n\t\t\tcolor: ${n};\n\t\t\tfill: ${n};\n\t\t\tfill-opacity: ${e.curveOpacity};\n\t\t\tstroke: ${n};\n\t\t\tstroke-width: ${e.curveStrokeWidth};\n\t\t}\n\t\t.radarLegendBox-${r} {\n\t\t\tfill: ${n};\n\t\t\tfill-opacity: ${e.curveOpacity};\n\t\t\tstroke: ${n};\n\t\t}\n\t\t`}return a},"genIndexStyles"),D=(0,o.K2)(t=>{const e=(0,s.P$)(),a=(0,s.zj)(),r=(0,i.$t)(e,a.themeVariables);return{themeVariables:r,radarOptions:(0,i.$t)(r.radar,t)}},"buildRadarStyleOptions"),z={parser:w,db:v,renderer:S,styles:(0,o.K2)(({radar:t}={})=>{const{themeVariables:e,radarOptions:a}=D(t);return`\n\t.radarTitle {\n\t\tfont-size: ${e.fontSize};\n\t\tcolor: ${e.titleColor};\n\t\tdominant-baseline: hanging;\n\t\ttext-anchor: middle;\n\t}\n\t.radarAxisLine {\n\t\tstroke: ${a.axisColor};\n\t\tstroke-width: ${a.axisStrokeWidth};\n\t}\n\t.radarAxisLabel {\n\t\tdominant-baseline: middle;\n\t\ttext-anchor: middle;\n\t\tfont-size: ${a.axisLabelFontSize}px;\n\t\tcolor: ${a.axisColor};\n\t}\n\t.radarGraticule {\n\t\tfill: ${a.graticuleColor};\n\t\tfill-opacity: ${a.graticuleOpacity};\n\t\tstroke: ${a.graticuleColor};\n\t\tstroke-width: ${a.graticuleStrokeWidth};\n\t}\n\t.radarLegendText {\n\t\ttext-anchor: start;\n\t\tfont-size: ${a.legendFontSize}px;\n\t\tdominant-baseline: hanging;\n\t}\n\t${I(e,a)}\n\t`},"styles")}},25871:(t,e,a)=>{function r(t,e){t.accDescr&&e.setAccDescription?.(t.accDescr),t.accTitle&&e.setAccTitle?.(t.accTitle),t.title&&e.setDiagramTitle?.(t.title)}a.d(e,{S:()=>r}),(0,a(40797).K2)(r,"populateCommonDb")}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/6c830a9a.2ca9c905.js b/pr-preview/pr-4027/assets/js/6c830a9a.2ca9c905.js deleted file mode 100644 index 480e168a2..000000000 --- a/pr-preview/pr-4027/assets/js/6c830a9a.2ca9c905.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[402],{25313:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Basics","slug":"/category/basics","permalink":"/constellation/pr-preview/pr-4027/2.23/category/basics","sidebar":"docs","navigation":{"previous":{"title":"Introduction","permalink":"/constellation/pr-preview/pr-4027/2.23/"},"next":{"title":"Confidential Kubernetes","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/confidential-kubernetes"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/6d0fae35.5f40d092.js b/pr-preview/pr-4027/assets/js/6d0fae35.5f40d092.js deleted file mode 100644 index def7a156c..000000000 --- a/pr-preview/pr-4027/assets/js/6d0fae35.5f40d092.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6897],{29554:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Architecture","slug":"/category/architecture","permalink":"/constellation/pr-preview/pr-4027/2.23/category/architecture","sidebar":"docs","navigation":{"previous":{"title":"Troubleshooting","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/troubleshooting"},"next":{"title":"Overview","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/overview"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/6df30968.12fac903.js b/pr-preview/pr-4027/assets/js/6df30968.12fac903.js deleted file mode 100644 index e24f484e4..000000000 --- a/pr-preview/pr-4027/assets/js/6df30968.12fac903.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6823],{6074:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"getting-started/examples/filestash-s3proxy","title":"Deploying Filestash","description":"Filestash is a web frontend for different storage backends, including S3.","source":"@site/docs/getting-started/examples/filestash-s3proxy.md","sourceDirName":"getting-started/examples","slug":"/getting-started/examples/filestash-s3proxy","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/examples/filestash-s3proxy","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/getting-started/examples/filestash-s3proxy.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Horizontal Pod Autoscaling","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/examples/horizontal-scaling"},"next":{"title":"Workflows","permalink":"/constellation/pr-preview/pr-4027/next/category/workflows"}}');var o=t(74848),a=t(28453);const r={},c="Deploying Filestash",i={},l=[];function d(e){const s={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.header,{children:(0,o.jsx)(s.h1,{id:"deploying-filestash",children:"Deploying Filestash"})}),"\n",(0,o.jsx)(s.p,{children:"Filestash is a web frontend for different storage backends, including S3.\nIt's a useful application to showcase s3proxy in action."}),"\n",(0,o.jsxs)(s.ol,{children:["\n",(0,o.jsxs)(s.li,{children:["Deploy s3proxy as described in ",(0,o.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/s3proxy#deployment",children:"Deployment"}),"."]}),"\n",(0,o.jsx)(s.li,{children:"Create a deployment file for Filestash with one pod:"}),"\n"]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-sh",children:'cat << EOF > "deployment-filestash.yaml"\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: filestash\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: filestash\n template:\n metadata:\n labels:\n app: filestash\n spec:\n hostAliases:\n - ip: $(kubectl get svc s3proxy-service -o=jsonpath=\'{.spec.clusterIP}\')\n hostnames:\n - "s3.us-east-1.amazonaws.com"\n - "s3.us-east-2.amazonaws.com"\n - "s3.us-west-1.amazonaws.com"\n - "s3.us-west-2.amazonaws.com"\n - "s3.eu-north-1.amazonaws.com"\n - "s3.eu-south-1.amazonaws.com"\n - "s3.eu-south-2.amazonaws.com"\n - "s3.eu-west-1.amazonaws.com"\n - "s3.eu-west-2.amazonaws.com"\n - "s3.eu-west-3.amazonaws.com"\n - "s3.eu-central-1.amazonaws.com"\n - "s3.eu-central-2.amazonaws.com"\n - "s3.ap-northeast-1.amazonaws.com"\n - "s3.ap-northeast-2.amazonaws.com"\n - "s3.ap-northeast-3.amazonaws.com"\n - "s3.ap-east-1.amazonaws.com"\n - "s3.ap-southeast-1.amazonaws.com"\n - "s3.ap-southeast-2.amazonaws.com"\n - "s3.ap-southeast-3.amazonaws.com"\n - "s3.ap-southeast-4.amazonaws.com"\n - "s3.ap-south-1.amazonaws.com"\n - "s3.ap-south-2.amazonaws.com"\n - "s3.me-south-1.amazonaws.com"\n - "s3.me-central-1.amazonaws.com"\n - "s3.il-central-1.amazonaws.com"\n - "s3.af-south-1.amazonaws.com"\n - "s3.ca-central-1.amazonaws.com"\n - "s3.sa-east-1.amazonaws.com"\n containers:\n - name: filestash\n image: machines/filestash:latest\n ports:\n - containerPort: 8334\n volumeMounts:\n - name: ca-cert\n mountPath: /etc/ssl/certs/kube-ca.crt\n subPath: kube-ca.crt\n volumes:\n - name: ca-cert\n secret:\n secretName: s3proxy-tls\n items:\n - key: ca.crt\n path: kube-ca.crt\nEOF\n'})}),"\n",(0,o.jsxs)(s.p,{children:["The pod spec includes the ",(0,o.jsx)(s.code,{children:"hostAliases"})," key, which adds an entry to the pod's ",(0,o.jsx)(s.code,{children:"/etc/hosts"}),".\nThe entry forwards all requests for any of the currently defined AWS regions to the Kubernetes service ",(0,o.jsx)(s.code,{children:"s3proxy-service"}),".\nIf you followed the s3proxy ",(0,o.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/s3proxy#deployment",children:"Deployment"})," guide, this service points to a s3proxy pod."]}),"\n",(0,o.jsxs)(s.p,{children:["The deployment specifies all regions explicitly to prevent accidental data leaks.\nIf one of your buckets were located in a region that's not part of the ",(0,o.jsx)(s.code,{children:"hostAliases"})," key, traffic towards those buckets would not be redirected to s3proxy.\nSimilarly, if you want to exclude data for specific regions from going through s3proxy you can remove those regions from the deployment."]}),"\n",(0,o.jsxs)(s.p,{children:["The spec also includes a volume mount for the TLS certificate and adds it to the pod's certificate trust store.\nThe volume is called ",(0,o.jsx)(s.code,{children:"ca-cert"}),".\nThe key ",(0,o.jsx)(s.code,{children:"ca.crt"})," of that volume is mounted to ",(0,o.jsx)(s.code,{children:"/etc/ssl/certs/kube-ca.crt"}),", which is the default certificate trust store location for that container's OpenSSL library.\nNot adding the CA certificate will result in TLS authentication errors."]}),"\n",(0,o.jsxs)(s.ol,{start:"3",children:["\n",(0,o.jsxs)(s.li,{children:["Apply the file: ",(0,o.jsx)(s.code,{children:"kubectl apply -f deployment-filestash.yaml"})]}),"\n"]}),"\n",(0,o.jsxs)(s.p,{children:["Afterward, you can use a port forward to access the Filestash pod:\n",(0,o.jsx)(s.code,{children:"kubectl port-forward pod/$(kubectl get pod --selector='app=filestash' -o=jsonpath='{.items[*].metadata.name}') 8334:8334"})]}),"\n",(0,o.jsxs)(s.ol,{start:"4",children:["\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["After browsing to ",(0,o.jsx)(s.code,{children:"localhost:8443"}),", Filestash will ask you to set an administrator password.\nAfter setting it, you can directly leave the admin area by clicking the blue cloud symbol in the top left corner.\nSubsequently, you can select S3 as storage backend and enter your credentials.\nThis will bring you to an overview of your buckets.\nIf you want to deploy Filestash in production, take a look at its ",(0,o.jsx)(s.a,{href:"https://www.filestash.app/docs/",children:"documentation"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["To see the logs of s3proxy intercepting requests made to S3, run: ",(0,o.jsx)(s.code,{children:"kubectl logs -f pod/$(kubectl get pod --selector='app=s3proxy' -o=jsonpath='{.items[*].metadata.name}')"}),"\nLook out for log messages labeled ",(0,o.jsx)(s.code,{children:"intercepting"}),".\nThere is one such log message for each message that's encrypted, decrypted, or blocked."]}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["Once you have uploaded a file with Filestash, you should be able to view the file in Filestash.\nHowever, if you go to the AWS S3 ",(0,o.jsx)(s.a,{href:"https://s3.console.aws.amazon.com/s3/home",children:"Web UI"})," and download the file you just uploaded in Filestash, you won't be able to read it.\nAnother way to spot encrypted files without downloading them is to click on a file, scroll to the Metadata section, and look for the header named ",(0,o.jsx)(s.code,{children:"x-amz-meta-constellation-encryption"}),".\nThis header holds the encrypted data encryption key of the object and is only present on objects that are encrypted by s3proxy."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>r,x:()=>c});var n=t(96540);const o={},a=n.createContext(o);function r(e){const s=n.useContext(a);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/6e43ec2e.a12e9194.js b/pr-preview/pr-4027/assets/js/6e43ec2e.a12e9194.js deleted file mode 100644 index f28171082..000000000 --- a/pr-preview/pr-4027/assets/js/6e43ec2e.a12e9194.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2928],{28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>a});var n=r(96540);const s={},i=n.createContext(s);function o(e){const t=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),n.createElement(i.Provider,{value:t},e.children)}},74186:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"architecture/orchestration","title":"Orchestrating Constellation clusters","description":"You can use the CLI to create a cluster on the supported cloud platforms.","source":"@site/versioned_docs/version-2.22/architecture/orchestration.md","sourceDirName":"architecture","slug":"/architecture/orchestration","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/architecture/orchestration.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/overview"},"next":{"title":"Versions and support","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/versions"}}');var s=r(74848),i=r(28453);const o={},a="Orchestrating Constellation clusters",c={},l=[{value:"Workspaces",id:"workspaces",level:2},{value:"Cluster creation process",id:"cluster-creation-process",level:2},{value:"Creation process details",id:"creation-process-details",level:3},{value:"Post-installation configuration",id:"post-installation-configuration",level:2},{value:"Upgrades",id:"upgrades",level:2},{value:"Attestation of upgrades",id:"attestation-of-upgrades",level:3}];function h(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"orchestrating-constellation-clusters",children:"Orchestrating Constellation clusters"})}),"\n",(0,s.jsx)(t.p,{children:"You can use the CLI to create a cluster on the supported cloud platforms.\nThe CLI provisions the resources in your cloud environment and initiates the initialization of your cluster.\nIt uses a set of parameters and an optional configuration file to manage your cluster installation.\nThe CLI is also used for updating your cluster."}),"\n",(0,s.jsx)(t.h2,{id:"workspaces",children:"Workspaces"}),"\n",(0,s.jsxs)(t.p,{children:["Each Constellation cluster has an associated ",(0,s.jsx)(t.em,{children:"workspace"}),".\nThe workspace is where data such as the Constellation state and config files are stored.\nEach workspace is associated with a single cluster and configuration.\nThe CLI stores state in the local filesystem making the current directory the active workspace.\nMultiple clusters require multiple workspaces, hence, multiple directories.\nNote that every operation on a cluster always has to be performed from the directory associated with its workspace."]}),"\n",(0,s.jsx)(t.p,{children:"You may copy files from the workspace to other locations,\nbut you shouldn't move or delete them while the cluster is still being used.\nThe Constellation CLI takes care of managing the workspace.\nOnly when a cluster was terminated, and you are sure the files aren't needed anymore, should you remove a workspace."}),"\n",(0,s.jsx)(t.h2,{id:"cluster-creation-process",children:"Cluster creation process"}),"\n",(0,s.jsxs)(t.p,{children:["To allow for fine-grained configuration of your cluster and cloud environment, Constellation supports an extensive configuration file with strong defaults. ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/config",children:"Generating the configuration file"})," is typically the first thing you do in the workspace."]}),"\n",(0,s.jsx)(t.p,{children:"Altogether, the following files are generated during the creation of a Constellation cluster and stored in the current workspace:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"a configuration file"}),"\n",(0,s.jsx)(t.li,{children:"a state file"}),"\n",(0,s.jsx)(t.li,{children:"a Base64-encoded master secret"}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/reference/terraform",children:"Terraform artifacts"}),", stored in subdirectories"]}),"\n",(0,s.jsxs)(t.li,{children:["a Kubernetes ",(0,s.jsx)(t.code,{children:"kubeconfig"})," file."]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["After the initialization of your cluster, the CLI will provide you with a Kubernetes ",(0,s.jsx)(t.code,{children:"kubeconfig"})," file.\nThis file grants you access to your Kubernetes cluster and configures the ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/",children:"kubectl"})," tool.\nIn addition, the cluster's ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration#post-installation-configuration",children:"identifier"})," is returned and stored in the state file."]}),"\n",(0,s.jsx)(t.h3,{id:"creation-process-details",children:"Creation process details"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["The CLI ",(0,s.jsx)(t.code,{children:"apply"})," command first creates the confidential VM (CVM) resources in your cloud environment and configures the network"]}),"\n",(0,s.jsx)(t.li,{children:"Each CVM boots the Constellation node image and measures every component in the boot chain"}),"\n",(0,s.jsxs)(t.li,{children:["The first microservice launched in each node is the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#bootstrapper",children:(0,s.jsx)(t.em,{children:"Bootstrapper"})})]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"Bootstrapper"})," waits until it either receives an initialization request or discovers an initialized cluster"]}),"\n",(0,s.jsxs)(t.li,{children:["The CLI then connects to the ",(0,s.jsx)(t.em,{children:"Bootstrapper"})," of a selected node, sends the configuration, and initiates the initialization of the cluster"]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"Bootstrapper"})," of ",(0,s.jsx)(t.strong,{children:"that"})," node ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#bootstrapper",children:"initializes the Kubernetes cluster"})," and deploys the other Constellation ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices",children:"microservices"})," including the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#joinservice",children:(0,s.jsx)(t.em,{children:"JoinService"})})]}),"\n",(0,s.jsxs)(t.li,{children:["Subsequently, the ",(0,s.jsx)(t.em,{children:"Bootstrappers"})," of the other nodes discover the initialized cluster and send join requests to the ",(0,s.jsx)(t.em,{children:"JoinService"})]}),"\n",(0,s.jsx)(t.li,{children:"As part of the join request each node includes an attestation statement of its boot measurements as authentication"}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"JoinService"})," verifies the attestation statements and joins the nodes to the Kubernetes cluster"]}),"\n",(0,s.jsx)(t.li,{children:"This process is repeated for every node joining the cluster later (e.g., through autoscaling)"}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"post-installation-configuration",children:"Post-installation configuration"}),"\n",(0,s.jsxs)(t.p,{children:["Post-installation the CLI provides a configuration for ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-api/",children:"accessing the cluster using the Kubernetes API"}),".\nThe ",(0,s.jsx)(t.code,{children:"kubeconfig"})," file provides the credentials and configuration for connecting and authenticating to the API server.\nOnce configured, orchestrate the Kubernetes cluster via ",(0,s.jsx)(t.code,{children:"kubectl"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"After the initialization, the CLI will present you with a couple of tokens:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys#master-secret",children:(0,s.jsx)(t.em,{children:"master secret"})})," (stored in the ",(0,s.jsx)(t.code,{children:"constellation-mastersecret.json"})," file by default)"]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys#cluster-identity",children:(0,s.jsx)(t.em,{children:"clusterID"})})," of your cluster in Base64 encoding"]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["You can read more about these values and their meaning in the guide on ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys#cluster-identity",children:"cluster identity"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.em,{children:"master secret"})," must be kept secret and can be used to ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/recovery",children:"recover your cluster"}),".\nInstead of managing this secret manually, you can ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys#user-managed-key-management",children:"use your key management solution of choice"})," with Constellation."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.em,{children:"clusterID"})," uniquely identifies a cluster and can be used to ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cluster",children:"verify your cluster"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"upgrades",children:"Upgrades"}),"\n",(0,s.jsxs)(t.p,{children:["Constellation images and microservices may need to be upgraded to new versions during the lifetime of a cluster.\nConstellation implements a rolling update mechanism ensuring no downtime of the control or data plane.\nYou can upgrade a Constellation cluster with a single operation by using the CLI.\nFor step-by-step instructions on how to do this, refer to ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade",children:"Upgrade your cluster"}),"."]}),"\n",(0,s.jsx)(t.h3,{id:"attestation-of-upgrades",children:"Attestation of upgrades"}),"\n",(0,s.jsxs)(t.p,{children:["With every new image, corresponding measurements are released.\nDuring an update procedure, the CLI provides new measurements to the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#joinservice",children:"JoinService"})," securely.\nNew measurements for an updated image are automatically pulled and verified by the CLI following the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#chain-of-trust",children:"supply chain security concept"})," of Constellation.\nThe ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#cluster-facing-attestation",children:"attestation section"})," describes in detail how these measurements are then used by the JoinService for the attestation of nodes."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/6fe48d2e.ad8f8319.js b/pr-preview/pr-4027/assets/js/6fe48d2e.ad8f8319.js deleted file mode 100644 index ed3d34eaa..000000000 --- a/pr-preview/pr-4027/assets/js/6fe48d2e.ad8f8319.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8619],{64496:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Getting started","slug":"/category/getting-started","permalink":"/constellation/pr-preview/pr-4027/2.22/category/getting-started","sidebar":"docs","navigation":{"previous":{"title":"License","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/license"},"next":{"title":"Installation","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/install"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/70248ece.ce4c28e6.js b/pr-preview/pr-4027/assets/js/70248ece.ce4c28e6.js deleted file mode 100644 index cbea313f9..000000000 --- a/pr-preview/pr-4027/assets/js/70248ece.ce4c28e6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6373],{23925:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"workflows/verify-cli","title":"Verify the CLI","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","source":"@site/versioned_docs/version-2.22/workflows/verify-cli.md","sourceDirName":"workflows","slug":"/workflows/verify-cli","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/workflows/verify-cli.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Workflows","permalink":"/constellation/pr-preview/pr-4027/2.22/category/workflows"},"next":{"title":"Configure your cluster","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/config"}}');var i=n(74848),o=n(28453);const r={},a="Verify the CLI",l={},c=[{value:"Verify the signature",id:"verify-the-signature",level:2},{value:"Optional: Manually inspect the transparency log",id:"optional-manually-inspect-the-transparency-log",level:3},{value:"Verify the provenance",id:"verify-the-provenance",level:2}];function d(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",...(0,o.R)(),...e.components},{AsciinemaWidget:n}=s;return n||function(e,s){throw new Error("Expected "+(s?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("AsciinemaWidget",!0),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.header,{children:(0,i.jsx)(s.h1,{id:"verify-the-cli",children:"Verify the CLI"})}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details."})}),"\n",(0,i.jsx)(n,{src:"/constellation/assets/verify-cli.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsxs)(s.p,{children:["Edgeless Systems uses ",(0,i.jsx)(s.a,{href:"https://www.sigstore.dev/",children:"sigstore"})," and ",(0,i.jsx)(s.a,{href:"https://slsa.dev",children:"SLSA"}),' to ensure supply-chain security for the Constellation CLI and node images ("artifacts"). sigstore consists of three components: ',(0,i.jsx)(s.a,{href:"https://docs.sigstore.dev/cosign/signing/overview/",children:"Cosign"}),", ",(0,i.jsx)(s.a,{href:"https://docs.sigstore.dev/logging/overview",children:"Rekor"}),", and Fulcio. Edgeless Systems uses Cosign to sign artifacts. All signatures are uploaded to the public Rekor transparency log, which resides at ",(0,i.jsx)(s.code,{children:"https://rekor.sigstore.dev"}),"."]}),"\n",(0,i.jsxs)(s.admonition,{type:"note",children:[(0,i.jsx)(s.p,{children:"The public key for Edgeless Systems' long-term code-signing key is:"}),(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT\nJmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==\n-----END PUBLIC KEY-----\n"})}),(0,i.jsxs)(s.p,{children:["The public key is also available for download at ",(0,i.jsx)(s.a,{href:"https://edgeless.systems/es.pub",children:"https://edgeless.systems/es.pub"})," and in the Twitter profile ",(0,i.jsx)(s.a,{href:"https://twitter.com/EdgelessSystems",children:"@EdgelessSystems"}),"."]})]}),"\n",(0,i.jsx)(s.p,{children:"The Rekor transparency log is a public append-only ledger that verifies and records signatures and associated metadata. The Rekor transparency log enables everyone to observe the sequence of (software) signatures issued by Edgeless Systems and many other parties. The transparency log allows for the public identification of dubious or malicious signatures."}),"\n",(0,i.jsx)(s.p,{children:"You should always ensure that (1) your CLI executable was signed with the private key corresponding to the above public key and that (2) there is a corresponding entry in the Rekor transparency log. Both can be done as described in the following."}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"You don't need to verify the Constellation node images. This is done automatically by your CLI and the rest of Constellation."})}),"\n",(0,i.jsx)(s.h2,{id:"verify-the-signature",children:"Verify the signature"}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"This guide assumes Linux on an amd64 processor. The exact steps for other platforms differ slightly."})}),"\n",(0,i.jsxs)(s.p,{children:["First, ",(0,i.jsx)(s.a,{href:"https://docs.sigstore.dev/cosign/system_config/installation/",children:"install the Cosign CLI"}),". Next, ",(0,i.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"download"})," and verify the signature that accompanies your CLI executable, for example:"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:"$ cosign verify-blob --key https://edgeless.systems/es.pub --signature constellation-linux-amd64.sig constellation-linux-amd64\n\nVerified OK\n"})}),"\n",(0,i.jsxs)(s.p,{children:["The above performs an offline verification of the provided public key, signature, and executable. To also verify that a corresponding entry exists in the public Rekor transparency log, add the variable ",(0,i.jsx)(s.code,{children:"COSIGN_EXPERIMENTAL=1"}),":"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:"$ COSIGN_EXPERIMENTAL=1 cosign verify-blob --key https://edgeless.systems/es.pub --signature constellation-linux-amd64.sig constellation-linux-amd64\n\ntlog entry verified with uuid: afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13 index: 3477047\nVerified OK\n"})}),"\n",(0,i.jsx)(s.p,{children:"\ud83c\udfc1 You now know that your CLI executable was officially released and signed by Edgeless Systems."}),"\n",(0,i.jsx)(s.h3,{id:"optional-manually-inspect-the-transparency-log",children:"Optional: Manually inspect the transparency log"}),"\n",(0,i.jsxs)(s.p,{children:["To further inspect the public Rekor transparency log, ",(0,i.jsx)(s.a,{href:"https://docs.sigstore.dev/logging/installation",children:"install the Rekor CLI"}),". A search for the CLI executable should give a single UUID. (Note that this UUID contains the UUID from the previous ",(0,i.jsx)(s.code,{children:"cosign"})," command.)"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:"$ rekor-cli search --artifact constellation-linux-amd64\n\nFound matching entries (listed by UUID):\n362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13\n"})}),"\n",(0,i.jsx)(s.p,{children:"With this UUID you can get the full entry from the transparency log:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:'$ rekor-cli get --uuid=362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13\n\nLogID: c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d\nIndex: 3477047\nIntegratedTime: 2022-09-12T22:28:16Z\nUUID: afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13\nBody: {\n "HashedRekordObj": {\n "data": {\n "hash": {\n "algorithm": "sha256",\n "value": "40e137b9b9b8204d672642fd1e181c6d5ccb50cfc5cc7fcbb06a8c2c78f44aff"\n }\n },\n "signature": {\n "content": "MEUCIQCSER3mGj+j5Pr2kOXTlCIHQC3gT30I7qkLr9Awt6eUUQIgcLUKRIlY50UN8JGwVeNgkBZyYD8HMxwC/LFRWoMn180=",\n "publicKey": {\n "content": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFZjhGMWhwbXdFK1lDRlh6akd0YVFjckw2WFpWVApKbUVlNWlTTHZHMVN5UVNBZXc3V2RNS0Y2bzl0OGUyVEZ1Q2t6bE9oaGx3czJPSFdiaUZabkZXQ0Z3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=="\n }\n }\n }\n}\n'})}),"\n",(0,i.jsxs)(s.p,{children:["The field ",(0,i.jsx)(s.code,{children:"publicKey"})," should contain Edgeless Systems' public key in Base64 encoding."]}),"\n",(0,i.jsx)(s.p,{children:"You can get an exhaustive list of artifact signatures issued by Edgeless Systems via the following command:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-bash",children:"rekor-cli search --public-key https://edgeless.systems/es.pub --pki-format x509\n"})}),"\n",(0,i.jsx)(s.p,{children:"Edgeless Systems monitors this list to detect potential unauthorized use of its private key."}),"\n",(0,i.jsx)(s.h2,{id:"verify-the-provenance",children:"Verify the provenance"}),"\n",(0,i.jsxs)(s.p,{children:["Provenance attests that a software artifact was produced by a specific repository and build system invocation. For more information on provenance visit ",(0,i.jsx)(s.a,{href:"https://slsa.dev/provenance/v0.2",children:"slsa.dev"})," and learn about the ",(0,i.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.22/reference/slsa",children:"adoption of SLSA for Constellation"}),"."]}),"\n",(0,i.jsx)(s.p,{children:"Just as checking its signature proves that the CLI hasn't been manipulated, checking the provenance proves that the artifact was produced by the expected build process and hasn't been tampered with."}),"\n",(0,i.jsxs)(s.p,{children:["To verify the provenance, first install the ",(0,i.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-verifier",children:"slsa-verifier"}),". Then make sure you have the provenance file (",(0,i.jsx)(s.code,{children:"constellation.intoto.jsonl"}),") and Constellation CLI downloaded. Both are available on the ",(0,i.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub release page"}),"."]}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"The same provenance file is valid for all Constellation CLI executables of a given version independent of the target platform."})}),"\n",(0,i.jsx)(s.p,{children:"Use the verifier to perform the check:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:"$ slsa-verifier verify-artifact constellation-linux-amd64 \\\n --provenance-path constellation.intoto.jsonl \\\n --source-uri github.com/edgelesssys/constellation\n\nVerified signature against tlog entry index 7771317 at URL: https://rekor.sigstore.dev/api/v1/log/entries/24296fb24b8ad77af2c04c8b4ae0d5bc5...\nVerified build using builder https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v1.2.2 at commit 18e9924b416323c37b9cdfd6cc728de8a947424a\nPASSED: Verified SLSA provenance\n"})})]})}function h(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>r,x:()=>a});var t=n(96540);const i={},o=t.createContext(i);function r(e){const s=t.useContext(o);return t.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),t.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/70f89ddc.a8ec7c51.js b/pr-preview/pr-4027/assets/js/70f89ddc.a8ec7c51.js deleted file mode 100644 index 11f90f992..000000000 --- a/pr-preview/pr-4027/assets/js/70f89ddc.a8ec7c51.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8428],{28453:(e,s,i)=>{i.d(s,{R:()=>o,x:()=>l});var n=i(96540);const t={},r=n.createContext(t);function o(e){const s=n.useContext(r);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),n.createElement(r.Provider,{value:s},e.children)}},99197:(e,s,i)=>{i.r(s),i.d(s,{assets:()=>d,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"workflows/reproducible-builds","title":"Reproduce released artifacts","description":"Constellation has first-class support for reproducible builds.","source":"@site/docs/workflows/reproducible-builds.md","sourceDirName":"workflows","slug":"/workflows/reproducible-builds","permalink":"/constellation/pr-preview/pr-4027/next/workflows/reproducible-builds","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/workflows/reproducible-builds.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Consume SBOMs","permalink":"/constellation/pr-preview/pr-4027/next/workflows/sbom"},"next":{"title":"Troubleshooting","permalink":"/constellation/pr-preview/pr-4027/next/workflows/troubleshooting"}}');var t=i(74848),r=i(28453);const o={},l="Reproduce released artifacts",d={},c=[{value:"Build environment prerequisites",id:"build-environment-prerequisites",level:2},{value:"Run the build",id:"run-the-build",level:2},{value:"Feedback",id:"feedback",level:2}];function a(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"reproduce-released-artifacts",children:"Reproduce released artifacts"})}),"\n",(0,t.jsxs)(s.p,{children:["Constellation has first-class support for ",(0,t.jsx)(s.a,{href:"https://reproducible-builds.org",children:"reproducible builds"}),".\nReproducing the released artifacts is an alternative to ",(0,t.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/verify-cli",children:"signature verification"})," that doesn't require trusting Edgeless Systems' release process.\nThe following sections describe how to rebuild an artifact and how Constellation ensures that the rebuild reproduces the artifacts bit-by-bit."]}),"\n",(0,t.jsx)(s.h2,{id:"build-environment-prerequisites",children:"Build environment prerequisites"}),"\n",(0,t.jsxs)(s.p,{children:["The build systems used by Constellation - ",(0,t.jsx)(s.a,{href:"https://bazel.build/",children:"Bazel"})," and ",(0,t.jsx)(s.a,{href:"https://nixos.org",children:"Nix"})," - are designed for deterministic, reproducible builds.\nThese two dependencies should be the only prerequisites for a successful build.\nHowever, it can't be ruled out completely that peculiarities of the host affect the build result.\nThus, we recommend the following host setup for best results:"]}),"\n",(0,t.jsxs)(s.ol,{children:["\n",(0,t.jsx)(s.li,{children:"A Linux operating system not older than v5.4."}),"\n",(0,t.jsxs)(s.li,{children:["The GNU C library not older than v2.31 (avoid ",(0,t.jsx)(s.code,{children:"musl"}),")."]}),"\n",(0,t.jsxs)(s.li,{children:["GNU ",(0,t.jsx)(s.code,{children:"coreutils"})," not older than v8.30 (avoid ",(0,t.jsx)(s.code,{children:"busybox"}),")."]}),"\n",(0,t.jsxs)(s.li,{children:["An ",(0,t.jsx)(s.code,{children:"ext4"})," filesystem for building."]}),"\n",(0,t.jsx)(s.li,{children:"AppArmor turned off."}),"\n"]}),"\n",(0,t.jsx)(s.p,{children:"This is given, for example, on an Ubuntu 22.04 system, which is also used for reproducibility tests."}),"\n",(0,t.jsx)(s.admonition,{type:"note",children:(0,t.jsx)(s.p,{children:"To avoid any backwards-compatibility issues, the host software versions should also not be much newer than the Constellation release."})}),"\n",(0,t.jsx)(s.h2,{id:"run-the-build",children:"Run the build"}),"\n",(0,t.jsxs)(s.p,{children:["The following instructions outline qualitatively how to reproduce a build.\nConstellation implements these instructions in the ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/actions/workflows/reproducible-builds.yml",children:"Reproducible Builds workflow"}),", which continuously tests for reproducibility.\nThe workflow is a good place to look up specific version numbers and build steps."]}),"\n",(0,t.jsxs)(s.ol,{children:["\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsx)(s.p,{children:"Check out the Constellation repository at the tag corresponding to the release."}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"git clone https://github.com/edgelesssys/constellation.git\ncd constellation\ngit checkout v2.20.0\n"})}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"https://bazel.build/install",children:"Install the Bazel release"})," specified in ",(0,t.jsx)(s.code,{children:".bazelversion"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"https://nixos.org/download/",children:"Install Nix"})," (any recent version should do)."]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsxs)(s.p,{children:["Run the build with ",(0,t.jsx)(s.code,{children:"bazel build $target"})," for one of the following targets of interest:"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-data",children:"//cli:cli_enterprise_darwin_amd64\n//cli:cli_enterprise_darwin_arm64\n//cli:cli_enterprise_linux_amd64\n//cli:cli_enterprise_linux_arm64\n//cli:cli_enterprise_windows_amd64\n"})}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsx)(s.p,{children:"Compare the build result with the downloaded release artifact."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"feedback",children:"Feedback"}),"\n",(0,t.jsxs)(s.p,{children:["Reproduction failures often indicate a bug in the build system or in the build definitions.\nTherefore, we're interested in any reproducibility issues you might encounter.\n",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/issues/new/choose",children:"Start a bug report"})," and describe the details of your build environment.\nMake sure to include your result binary or a ",(0,t.jsx)(s.a,{href:"https://diffoscope.org/",children:(0,t.jsx)(s.code,{children:"diffoscope"})})," report, if possible."]})]})}function u(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/71dfee10.81e5ecaf.js b/pr-preview/pr-4027/assets/js/71dfee10.81e5ecaf.js deleted file mode 100644 index 307d0f404..000000000 --- a/pr-preview/pr-4027/assets/js/71dfee10.81e5ecaf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[832],{26640:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"workflows/sbom","title":"Consume software bill of materials (SBOMs)","description":"---","source":"@site/versioned_docs/version-2.23/workflows/sbom.md","sourceDirName":"workflows","slug":"/workflows/sbom","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/sbom","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/workflows/sbom.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Use the Terraform provider","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/terraform-provider"},"next":{"title":"Reproduce release artifacts","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/reproducible-builds"}}');var t=n(74848),i=n(28453);const r={},a="Consume software bill of materials (SBOMs)",l={},c=[{value:"Verify and download SBOMs",id:"verify-and-download-sboms",level:2},{value:"Constellation CLI",id:"constellation-cli",level:3},{value:"Container Images",id:"container-images",level:3},{value:"Vulnerability scanning",id:"vulnerability-scanning",level:2},{value:"Grype",id:"grype",level:3},{value:"Dependency Track",id:"dependency-track",level:3}];function d(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",...(0,i.R)(),...e.components},{AsciinemaWidget:n}=s;return n||function(e,s){throw new Error("Expected "+(s?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("AsciinemaWidget",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"consume-software-bill-of-materials-sboms",children:"Consume software bill of materials (SBOMs)"})}),"\n",(0,t.jsx)(n,{src:"/constellation/assets/check-sbom.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,t.jsx)(s.hr,{}),"\n",(0,t.jsxs)(s.p,{children:["Constellation builds produce a ",(0,t.jsx)(s.a,{href:"https://www.ntia.gov/SBOM",children:"software bill of materials (SBOM)"})," for each generated ",(0,t.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices",children:"artifact"}),".\nYou can use SBOMs to make informed decisions about dependencies and vulnerabilities in a given application. Enterprises rely on SBOMs to maintain an inventory of used applications, which allows them to take data-driven approaches to managing risks related to vulnerabilities."]}),"\n",(0,t.jsxs)(s.p,{children:["SBOMs for Constellation are generated using ",(0,t.jsx)(s.a,{href:"https://github.com/anchore/syft",children:"Syft"}),", signed using ",(0,t.jsx)(s.a,{href:"https://github.com/sigstore/cosign",children:"Cosign"}),", and stored with the produced artifact."]}),"\n",(0,t.jsxs)(s.admonition,{type:"note",children:[(0,t.jsx)(s.p,{children:"The public key for Edgeless Systems' long-term code-signing key is:"}),(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT\nJmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==\n-----END PUBLIC KEY-----\n"})}),(0,t.jsxs)(s.p,{children:["The public key is also available for download at ",(0,t.jsx)(s.a,{href:"https://edgeless.systems/es.pub",children:"https://edgeless.systems/es.pub"})," and in the Twitter profile ",(0,t.jsx)(s.a,{href:"https://twitter.com/EdgelessSystems",children:"@EdgelessSystems"}),"."]}),(0,t.jsxs)(s.p,{children:["Make sure the key is available in a file named ",(0,t.jsx)(s.code,{children:"cosign.pub"})," to execute the following examples."]})]}),"\n",(0,t.jsx)(s.h2,{id:"verify-and-download-sboms",children:"Verify and download SBOMs"}),"\n",(0,t.jsx)(s.p,{children:"The following sections detail how to work with each type of artifact to verify and extract the SBOM."}),"\n",(0,t.jsx)(s.h3,{id:"constellation-cli",children:"Constellation CLI"}),"\n",(0,t.jsxs)(s.p,{children:["The SBOM for Constellation CLI is made available on the ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub release page"}),". The SBOM (",(0,t.jsx)(s.code,{children:"constellation.spdx.sbom"}),") and corresponding signature (",(0,t.jsx)(s.code,{children:"constellation.spdx.sbom.sig"}),") are valid for each Constellation CLI for a given version, regardless of architecture and operating system."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom\ncurl -LO https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom.sig\ncosign verify-blob --key cosign.pub --signature constellation.spdx.sbom.sig constellation.spdx.sbom\n"})}),"\n",(0,t.jsx)(s.h3,{id:"container-images",children:"Container Images"}),"\n",(0,t.jsxs)(s.p,{children:["SBOMs for container images are ",(0,t.jsx)(s.a,{href:"https://docs.sigstore.dev/cosign/signing/other_types/#sboms-software-bill-of-materials",children:"attached to the image using Cosign"})," and uploaded to the same registry."]}),"\n",(0,t.jsx)(s.p,{children:"As a consumer, use cosign to download and verify the SBOM:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"# Verify and download the attestation statement\ncosign verify-attestation ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --type 'https://cyclonedx.org/bom' --key cosign.pub --output-file verification-service.att.json\n# Extract SBOM from attestation statement\njq -r .payload verification-service.att.json | base64 -d > verification-service.cyclonedx.sbom\n"})}),"\n",(0,t.jsx)(s.p,{children:"A successful verification should result in similar output:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-shell-session",children:"$ cosign verify-attestation ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --type 'https://cyclonedx.org/bom' --key cosign.pub --output-file verification-service.sbom\n\nVerification for ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --\nThe following checks were performed on each of these signatures:\n - The cosign claims were validated\n - The signatures were verified against the specified public key\n$ jq -r .payload verification-service.sbom | base64 -d > verification-service.cyclonedx.sbom\n"})}),"\n",(0,t.jsx)(s.admonition,{type:"note",children:(0,t.jsxs)(s.p,{children:["This example considers only the ",(0,t.jsx)(s.code,{children:"verification-service"}),". The same approach works for all containers in the ",(0,t.jsx)(s.a,{href:"https://github.com/orgs/edgelesssys/packages?repo_name=constellation",children:"Constellation container registry"}),"."]})}),"\n",(0,t.jsx)(s.h2,{id:"vulnerability-scanning",children:"Vulnerability scanning"}),"\n",(0,t.jsxs)(s.p,{children:["You can use a plethora of tools to consume SBOMs. This section provides suggestions for tools that are popular and known to produce reliable results, but any tool that consumes ",(0,t.jsx)(s.a,{href:"https://spdx.dev/",children:"SPDX"})," or ",(0,t.jsx)(s.a,{href:"https://cyclonedx.org/",children:"CycloneDX"})," files should work."]}),"\n",(0,t.jsxs)(s.p,{children:["Syft is able to ",(0,t.jsx)(s.a,{href:"https://github.com/anchore/syft#format-conversion-experimental",children:"convert between the two formats"})," in case you require a specific type."]}),"\n",(0,t.jsx)(s.h3,{id:"grype",children:"Grype"}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"https://github.com/anchore/grype",children:"Grype"})," is a CLI tool that lends itself well for integration into CI/CD systems or local developer machines. It's also able to consume the signed attestation statement directly and does the verification in one go."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"grype att:verification-service.sbom --key cosign.pub --add-cpes-if-none -q\n"})}),"\n",(0,t.jsx)(s.h3,{id:"dependency-track",children:"Dependency Track"}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"https://dependencytrack.org/",children:"Dependency Track"})," is one of the oldest and most mature solutions when it comes to managing software inventory and vulnerabilities. Once imported, it continuously scans SBOMs for new vulnerabilities. It supports the CycloneDX format and provides direct guidance on how to comply with ",(0,t.jsx)(s.a,{href:"https://docs.dependencytrack.org/usage/executive-order-14028/",children:"U.S. Executive Order 14028"}),"."]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>r,x:()=>a});var o=n(96540);const t={},i=o.createContext(t);function r(e){const s=o.useContext(i);return o.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),o.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/72a880f4.9f7828f1.js b/pr-preview/pr-4027/assets/js/72a880f4.9f7828f1.js deleted file mode 100644 index 9b642730f..000000000 --- a/pr-preview/pr-4027/assets/js/72a880f4.9f7828f1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3533],{13589:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>c,contentTitle:()=>l,default:()=>u,frontMatter:()=>i,metadata:()=>t,toc:()=>a});const t=JSON.parse('{"id":"architecture/versions","title":"Versions and support policy","description":"All components of Constellation use a three-digit version number of the form v...","source":"@site/docs/architecture/versions.md","sourceDirName":"architecture","slug":"/architecture/versions","permalink":"/constellation/pr-preview/pr-4027/next/architecture/versions","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/architecture/versions.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Cluster orchestration","permalink":"/constellation/pr-preview/pr-4027/next/architecture/orchestration"},"next":{"title":"Microservices","permalink":"/constellation/pr-preview/pr-4027/next/architecture/microservices"}}');var n=r(74848),o=r(28453);const i={},l="Versions and support policy",c={},a=[{value:"Kubernetes support policy",id:"kubernetes-support-policy",level:2}];function p(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"versions-and-support-policy",children:"Versions and support policy"})}),"\n",(0,n.jsxs)(s.p,{children:["All components of Constellation use a three-digit version number of the form ",(0,n.jsx)(s.code,{children:"v<MAJOR>.<MINOR>.<PATCH>"}),".\nThe components are released in lock step, usually on the first Tuesday of every month. This release primarily introduces new features, but may also include security or performance improvements. The ",(0,n.jsx)(s.code,{children:"MINOR"})," version will be incremented as part of this release."]}),"\n",(0,n.jsxs)(s.p,{children:["Additional ",(0,n.jsx)(s.code,{children:"PATCH"})," releases may be created on demand, to fix security issues or bugs before the next ",(0,n.jsx)(s.code,{children:"MINOR"})," release window."]}),"\n",(0,n.jsxs)(s.p,{children:["New releases are published on ",(0,n.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"kubernetes-support-policy",children:"Kubernetes support policy"}),"\n",(0,n.jsxs)(s.p,{children:["Constellation is aligned to the ",(0,n.jsx)(s.a,{href:"https://kubernetes.io/releases/version-skew-policy/#supported-versions",children:"version support policy of Kubernetes"}),", and therefore usually supports the most recent three minor versions.\nWhen a new minor version of Kubernetes is released, support is added to the next Constellation release, and that version then supports four Kubernetes versions.\nSubsequent Constellation releases drop support for the oldest (and deprecated) Kubernetes version."]}),"\n",(0,n.jsx)(s.p,{children:"The following Kubernetes versions are currently supported:"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:"v1.30.14"}),"\n",(0,n.jsx)(s.li,{children:"v1.31.13"}),"\n",(0,n.jsx)(s.li,{children:"v1.32.9"}),"\n"]})]})}function u(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>i,x:()=>l});var t=r(96540);const n={},o=t.createContext(n);function i(e){const s=t.useContext(o);return t.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),t.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/72c2c1f0.b96352b6.js b/pr-preview/pr-4027/assets/js/72c2c1f0.b96352b6.js deleted file mode 100644 index c866c3f46..000000000 --- a/pr-preview/pr-4027/assets/js/72c2c1f0.b96352b6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[301],{94773:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"2.23","label":"2.23","banner":"unmaintained","badge":true,"noIndex":false,"className":"docs-version-2.23","isLast":false,"docsSidebars":{"docs":[{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/","label":"Introduction","docId":"intro","unlisted":false},{"type":"category","label":"Basics","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/overview/confidential-kubernetes","label":"Confidential Kubernetes","docId":"overview/confidential-kubernetes","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/overview/security-benefits","label":"Security benefits","docId":"overview/security-benefits","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/overview/product","label":"Product features","docId":"overview/product","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/overview/clouds","label":"Feature status of clouds","docId":"overview/clouds","unlisted":false},{"type":"category","label":"Performance","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/overview/performance/compute","label":"Compute benchmarks","docId":"overview/performance/compute","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/overview/performance/io","label":"I/O benchmarks","docId":"overview/performance/io","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/overview/performance/application","label":"Application benchmarks","docId":"overview/performance/application","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/2.23/overview/performance/"},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/overview/license","label":"License","docId":"overview/license","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/2.23/category/basics"},{"type":"category","label":"Getting started","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/getting-started/install","label":"Installation","docId":"getting-started/install","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps","label":"First steps (cloud)","docId":"getting-started/first-steps","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps-local","label":"First steps (local)","docId":"getting-started/first-steps-local","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/getting-started/marketplaces","label":"Cloud Marketplaces","docId":"getting-started/marketplaces","unlisted":false},{"type":"category","label":"Examples","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/emojivoto","label":"Emojivoto","docId":"getting-started/examples/emojivoto","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/online-boutique","label":"Online Boutique","docId":"getting-started/examples/online-boutique","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/horizontal-scaling","label":"Horizontal Pod Autoscaling","docId":"getting-started/examples/horizontal-scaling","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/filestash-s3proxy","label":"Filestash with s3proxy","docId":"getting-started/examples/filestash-s3proxy","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples"}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/2.23/category/getting-started"},{"type":"category","label":"Workflows","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cli","label":"Verify the CLI","docId":"workflows/verify-cli","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/workflows/config","label":"Configure your cluster","docId":"workflows/config","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/workflows/create","label":"Create your cluster","docId":"workflows/create","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/workflows/scale","label":"Scale your cluster","docId":"workflows/scale","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/workflows/upgrade","label":"Upgrade your cluster","docId":"workflows/upgrade","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/workflows/lb","label":"Expose a service","docId":"workflows/lb","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/workflows/cert-manager","label":"Install cert-manager","docId":"workflows/cert-manager","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/workflows/s3proxy","label":"Install s3proxy","docId":"workflows/s3proxy","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/workflows/terminate","label":"Terminate your cluster","docId":"workflows/terminate","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/workflows/recovery","label":"Recover your cluster","docId":"workflows/recovery","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cluster","label":"Verify your cluster","docId":"workflows/verify-cluster","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/workflows/storage","label":"Use persistent storage","docId":"workflows/storage","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/workflows/terraform-provider","label":"Use the Terraform provider","docId":"workflows/terraform-provider","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/workflows/sbom","label":"Consume SBOMs","docId":"workflows/sbom","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/workflows/reproducible-builds","label":"Reproduce release artifacts","docId":"workflows/reproducible-builds","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/workflows/troubleshooting","label":"Troubleshooting","docId":"workflows/troubleshooting","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/2.23/category/workflows"},{"type":"category","label":"Architecture","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/architecture/overview","label":"Overview","docId":"architecture/overview","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/architecture/orchestration","label":"Cluster orchestration","docId":"architecture/orchestration","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/architecture/versions","label":"Versions and support","docId":"architecture/versions","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/architecture/microservices","label":"Microservices","docId":"architecture/microservices","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/architecture/attestation","label":"Attestation","docId":"architecture/attestation","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/architecture/images","label":"Images","docId":"architecture/images","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/architecture/keys","label":"Keys and cryptographic primitives","docId":"architecture/keys","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage","label":"Encrypted persistent storage","docId":"architecture/encrypted-storage","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/architecture/networking","label":"Networking","docId":"architecture/networking","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/architecture/observability","label":"Observability","docId":"architecture/observability","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/2.23/category/architecture"},{"type":"category","label":"Reference","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/reference/cli","label":"CLI","docId":"reference/cli","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/reference/migration","label":"Configuration migrations","docId":"reference/migration","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/reference/terraform","label":"Terraform usage","docId":"reference/terraform","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.23/reference/slsa","label":"SLSA adoption","docId":"reference/slsa","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/2.23/category/reference"}]},"docs":{"architecture/attestation":{"id":"architecture/attestation","title":"Attestation","description":"This page explains Constellation\'s attestation process and highlights the cornerstones of its trust model.","sidebar":"docs"},"architecture/encrypted-storage":{"id":"architecture/encrypted-storage","title":"Encrypted persistent storage","description":"Confidential VMs provide runtime memory encryption to protect data in use.","sidebar":"docs"},"architecture/images":{"id":"architecture/images","title":"Constellation images","description":"Constellation uses a minimal version of Fedora as the operating system running inside confidential VMs. This Linux distribution is optimized for containers and designed to be stateless.","sidebar":"docs"},"architecture/keys":{"id":"architecture/keys","title":"Key management and cryptographic primitives","description":"Constellation protects and isolates your cluster and workloads.","sidebar":"docs"},"architecture/microservices":{"id":"architecture/microservices","title":"Microservices","description":"Constellation takes care of bootstrapping and initializing a Confidential Kubernetes cluster.","sidebar":"docs"},"architecture/networking":{"id":"architecture/networking","title":"Network encryption","description":"Constellation encrypts all pod communication using the container network interface (CNI).","sidebar":"docs"},"architecture/observability":{"id":"architecture/observability","title":"Observability","description":"In Kubernetes, observability is the ability to gain insight into the behavior and performance of applications.","sidebar":"docs"},"architecture/orchestration":{"id":"architecture/orchestration","title":"Orchestrating Constellation clusters","description":"You can use the CLI to create a cluster on the supported cloud platforms.","sidebar":"docs"},"architecture/overview":{"id":"architecture/overview","title":"Overview","description":"Constellation is a cloud-based confidential orchestration platform.","sidebar":"docs"},"architecture/versions":{"id":"architecture/versions","title":"Versions and support policy","description":"All components of Constellation use a three-digit version number of the form v...","sidebar":"docs"},"getting-started/examples":{"id":"getting-started/examples","title":"Examples","description":"After you installed the CLI and created your first cluster, you\'re ready to deploy applications. Why not start with one of the following examples?","sidebar":"docs"},"getting-started/examples/emojivoto":{"id":"getting-started/examples/emojivoto","title":"Emojivoto","description":"Emojivoto is a simple and fun application that\'s well suited to test the basic functionality of your cluster.","sidebar":"docs"},"getting-started/examples/filestash-s3proxy":{"id":"getting-started/examples/filestash-s3proxy","title":"Deploying Filestash","description":"Filestash is a web frontend for different storage backends, including S3.","sidebar":"docs"},"getting-started/examples/horizontal-scaling":{"id":"getting-started/examples/horizontal-scaling","title":"Horizontal Pod Autoscaling","description":"This example demonstrates Constellation\'s autoscaling capabilities. It\'s based on the Kubernetes HorizontalPodAutoscaler Walkthrough. During the following steps, Constellation will spawn new VMs on demand, verify them, add them to the cluster, and delete them again when the load has settled down.","sidebar":"docs"},"getting-started/examples/online-boutique":{"id":"getting-started/examples/online-boutique","title":"Online Boutique","description":"Online Boutique is an e-commerce demo application by Google consisting of 11 separate microservices. In this demo, Constellation automatically sets up a load balancer on your CSP, making it easy to expose services from your confidential cluster.","sidebar":"docs"},"getting-started/first-steps":{"id":"getting-started/first-steps","title":"First steps with Constellation","description":"The following steps guide you through the process of creating a cluster and deploying a sample app. This example assumes that you have successfully installed and set up Constellation,","sidebar":"docs"},"getting-started/first-steps-local":{"id":"getting-started/first-steps-local","title":"First steps with a local cluster","description":"A local cluster lets you deploy and test Constellation without a cloud subscription.","sidebar":"docs"},"getting-started/install":{"id":"getting-started/install","title":"Installation and setup","description":"Constellation runs entirely in your cloud environment and can be controlled via a dedicated command-line interface (CLI) or a Terraform provider.","sidebar":"docs"},"getting-started/marketplaces":{"id":"getting-started/marketplaces","title":"Using Constellation via Cloud Marketplaces","description":"Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please contact us.","sidebar":"docs"},"intro":{"id":"intro","title":"Introduction","description":"Welcome to the documentation of Constellation! Constellation is a Kubernetes engine that aims to provide the best possible data security.","sidebar":"docs"},"overview/clouds":{"id":"overview/clouds","title":"Feature status of clouds","description":"What works on which cloud? Currently, Confidential VMs (CVMs) are available in varying quality on the different clouds and software stacks.","sidebar":"docs"},"overview/confidential-kubernetes":{"id":"overview/confidential-kubernetes","title":"Confidential Kubernetes","description":"We use the term Confidential Kubernetes to refer to the concept of using confidential-computing technology to shield entire Kubernetes clusters from the infrastructure. The three defining properties of this concept are:","sidebar":"docs"},"overview/license":{"id":"overview/license","title":"License","description":"Constellation is available under the Business Source License 1.1.","sidebar":"docs"},"overview/performance/application":{"id":"overview/performance/application","title":"Application benchmarks","description":"HashiCorp Vault","sidebar":"docs"},"overview/performance/compute":{"id":"overview/performance/compute","title":"Impact of runtime encryption on compute performance","description":"All nodes in a Constellation cluster are executed inside Confidential VMs (CVMs). Consequently, the performance of Constellation is inherently linked to the performance of these CVMs.","sidebar":"docs"},"overview/performance/io":{"id":"overview/performance/io","title":"I/O performance benchmarks","description":"To assess the overall performance of Constellation, this benchmark evaluates Constellation v2.6.0 in terms of storage I/O using fio and network performance using the Kubernetes Network Benchmark.","sidebar":"docs"},"overview/performance/performance":{"id":"overview/performance/performance","title":"Performance analysis of Constellation","description":"This section provides a comprehensive examination of the performance characteristics of Constellation.","sidebar":"docs"},"overview/product":{"id":"overview/product","title":"Product features","description":"Constellation is a Kubernetes engine that aims to provide the best possible data security in combination with enterprise-grade scalability and reliability features---and a smooth user experience.","sidebar":"docs"},"overview/security-benefits":{"id":"overview/security-benefits","title":"Security benefits and threat model","description":"Constellation implements the Confidential Kubernetes concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be verified.","sidebar":"docs"},"reference/cli":{"id":"reference/cli","title":"CLI reference","description":"Use the Constellation CLI to create and manage your clusters.","sidebar":"docs"},"reference/migration":{"id":"reference/migration","title":"Migrations","description":"This document describes breaking changes and migrations between Constellation releases.","sidebar":"docs"},"reference/slsa":{"id":"reference/slsa","title":"Supply chain levels for software artifacts (SLSA) adoption","description":"Supply chain Levels for Software Artifacts, or SLSA (salsa) is a framework for improving and grading a project\'s build system and engineering processes. SLSA focuses on security improvements for source code storage as well as build system definition, execution, and observation. SLSA is structured in four levels. This page describes the adoption of SLSA for Constellation.","sidebar":"docs"},"reference/terraform":{"id":"reference/terraform","title":"Terraform usage","description":"Terraform is an Infrastructure as Code (IaC) framework to manage cloud resources. This page explains how Constellation uses it internally and how advanced users may manually use it to have more control over the resource creation.","sidebar":"docs"},"workflows/cert-manager":{"id":"workflows/cert-manager","title":"Install cert-manager","description":"If you want to use cert-manager with Constellation, pay attention to the following to avoid potential pitfalls.","sidebar":"docs"},"workflows/config":{"id":"workflows/config","title":"Configure your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","sidebar":"docs"},"workflows/create":{"id":"workflows/create","title":"Create your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","sidebar":"docs"},"workflows/lb":{"id":"workflows/lb","title":"Expose a service","description":"Constellation integrates the native load balancers of each CSP. Therefore, to expose a service simply create a service of type LoadBalancer.","sidebar":"docs"},"workflows/recovery":{"id":"workflows/recovery","title":"Recover your cluster","description":"Recovery of a Constellation cluster means getting it back into a healthy state after too many concurrent node failures in the control plane.","sidebar":"docs"},"workflows/reproducible-builds":{"id":"workflows/reproducible-builds","title":"Reproduce released artifacts","description":"Constellation has first-class support for reproducible builds.","sidebar":"docs"},"workflows/s3proxy":{"id":"workflows/s3proxy","title":"Install s3proxy","description":"Constellation includes a transparent client-side encryption proxy for AWS S3 and compatible stores.","sidebar":"docs"},"workflows/sbom":{"id":"workflows/sbom","title":"Consume software bill of materials (SBOMs)","description":"---","sidebar":"docs"},"workflows/scale":{"id":"workflows/scale","title":"Scale your cluster","description":"Constellation provides all features of a Kubernetes cluster including scaling and autoscaling.","sidebar":"docs"},"workflows/storage":{"id":"workflows/storage","title":"Use persistent storage","description":"Persistent storage in Kubernetes requires cloud-specific configuration.","sidebar":"docs"},"workflows/terminate":{"id":"workflows/terminate","title":"Terminate your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","sidebar":"docs"},"workflows/terraform-provider":{"id":"workflows/terraform-provider","title":"Use the Terraform provider","description":"The Constellation Terraform provider allows to manage the full lifecycle of a Constellation cluster (namely creation, upgrades, and deletion) via Terraform.","sidebar":"docs"},"workflows/troubleshooting":{"id":"workflows/troubleshooting","title":"Troubleshooting","description":"This section aids you in finding problems when working with Constellation.","sidebar":"docs"},"workflows/trusted-launch":{"id":"workflows/trusted-launch","title":"Use Azure trusted launch VMs","description":"Constellation also supports trusted launch VMs on Microsoft Azure. Trusted launch VMs don\'t offer the same level of security as Confidential VMs, but are available in more regions and in larger quantities. The main difference between trusted launch VMs and normal VMs is that the former offer vTPM-based remote attestation. When used with trusted launch VMs, Constellation relies on vTPM-based remote attestation to verify nodes."},"workflows/upgrade":{"id":"workflows/upgrade","title":"Upgrade your cluster","description":"Constellation provides an easy way to upgrade all components of your cluster, without disrupting its availability.","sidebar":"docs"},"workflows/verify-cli":{"id":"workflows/verify-cli","title":"Verify the CLI","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","sidebar":"docs"},"workflows/verify-cluster":{"id":"workflows/verify-cluster","title":"Verify your cluster","description":"Constellation\'s attestation feature allows you, or a third party, to verify the integrity and confidentiality of your Constellation cluster.","sidebar":"docs"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/74afccd1.fff6f3ba.js b/pr-preview/pr-4027/assets/js/74afccd1.fff6f3ba.js deleted file mode 100644 index f0089b6ea..000000000 --- a/pr-preview/pr-4027/assets/js/74afccd1.fff6f3ba.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5128],{28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>a});var n=r(96540);const i={},s=n.createContext(i);function o(e){const t=n.useContext(s);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),n.createElement(s.Provider,{value:t},e.children)}},56386:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"architecture/encrypted-storage","title":"Encrypted persistent storage","description":"Confidential VMs provide runtime memory encryption to protect data in use.","source":"@site/versioned_docs/version-2.23/architecture/encrypted-storage.md","sourceDirName":"architecture","slug":"/architecture/encrypted-storage","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/architecture/encrypted-storage.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Keys and cryptographic primitives","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/keys"},"next":{"title":"Networking","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/networking"}}');var i=r(74848),s=r(28453);const o={},a="Encrypted persistent storage",c={},d=[{value:"Cloud provider-managed encryption",id:"cloud-provider-managed-encryption",level:2},{value:"Constellation-managed encryption",id:"constellation-managed-encryption",level:2},{value:"Cryptographic algorithms",id:"cryptographic-algorithms",level:2},{value:"dm-crypt",id:"dm-crypt",level:3},{value:"dm-integrity",id:"dm-integrity",level:3},{value:"Encrypted S3 object storage",id:"encrypted-s3-object-storage",level:2}];function l(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"encrypted-persistent-storage",children:"Encrypted persistent storage"})}),"\n",(0,i.jsxs)(t.p,{children:["Confidential VMs provide runtime memory encryption to protect data in use.\nIn the context of Kubernetes, this is sufficient for the confidentiality and integrity of stateless services.\nConsider a front-end web server, for example, that keeps all connection information cached in main memory.\nNo sensitive data is ever written to an insecure medium.\nHowever, many real-world applications need some form of state or data-lake service that's connected to a persistent storage device and requires encryption at rest.\nAs described in ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/storage",children:"Use persistent storage"}),", cloud service providers (CSPs) use the container storage interface (CSI) to make their storage solutions available to Kubernetes workloads.\nThese CSI storage solutions often support some sort of encryption.\nFor example, Google Cloud ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/security/encryption/default-encryption",children:"encrypts data at rest by default"}),", without any action required by the customer."]}),"\n",(0,i.jsx)(t.h2,{id:"cloud-provider-managed-encryption",children:"Cloud provider-managed encryption"}),"\n",(0,i.jsx)(t.p,{children:"CSP-managed storage solutions encrypt the data in the cloud backend before writing it physically to disk.\nIn the context of confidential computing and Constellation, the CSP and its managed services aren't trusted.\nHence, cloud provider-managed encryption protects your data from offline hardware access to physical storage devices.\nIt doesn't protect it from anyone with infrastructure-level access to the storage backend or a malicious insider in the cloud platform.\nEven with \"bring your own key\" or similar concepts, the CSP performs the encryption process with access to the keys and plaintext data."}),"\n",(0,i.jsx)(t.p,{children:"In the security model of Constellation, securing persistent storage and thereby data at rest requires that all cryptographic operations are performed inside a trusted execution environment.\nConsequently, using CSP-managed encryption of persistent storage usually isn't an option."}),"\n",(0,i.jsx)(t.h2,{id:"constellation-managed-encryption",children:"Constellation-managed encryption"}),"\n",(0,i.jsxs)(t.p,{children:["Constellation provides CSI drivers for storage solutions in all major clouds with built-in encryption support.\nBlock storage provisioned by the CSP is ",(0,i.jsx)(t.a,{href:"https://guix.gnu.org/manual/en/html_node/Mapped-Devices.html",children:"mapped"})," using the ",(0,i.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-crypt.html",children:"dm-crypt"}),", and optionally the ",(0,i.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-integrity.html",children:"dm-integrity"}),", kernel modules, before it's formatted and accessed by the Kubernetes workloads.\nAll cryptographic operations happen inside the trusted environment of the confidential Constellation node."]}),"\n",(0,i.jsxs)(t.p,{children:["Note that for integrity-protected disks, ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/blog/2018/07/12/resizing-persistent-volumes-using-kubernetes/",children:"volume expansion"})," isn't supported."]}),"\n",(0,i.jsxs)(t.p,{children:["By default the driver uses data encryption keys (DEKs) issued by the Constellation ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#keyservice",children:(0,i.jsx)(t.em,{children:"KeyService"})}),".\nThe DEKs are in turn derived from the Constellation's key encryption key (KEK), which is directly derived from the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys#master-secret",children:"master secret"}),".\nThis is the recommended mode of operation, and also requires the least amount of setup by the cluster administrator."]}),"\n",(0,i.jsx)(t.p,{children:"Alternatively, the driver can be configured to use a key management system to store and access KEKs and DEKs."}),"\n",(0,i.jsxs)(t.p,{children:["Refer to ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys",children:"keys and cryptography"})," for more details on key management in Constellation."]}),"\n",(0,i.jsx)(t.p,{children:"Once deployed and configured, the CSI driver ensures transparent encryption and integrity of all persistent volumes provisioned via its storage class.\nData at rest is secured without any additional actions required by the developer."}),"\n",(0,i.jsx)(t.h2,{id:"cryptographic-algorithms",children:"Cryptographic algorithms"}),"\n",(0,i.jsx)(t.p,{children:"This section gives an overview of the libraries, cryptographic algorithms, and their configurations, used in Constellation's CSI drivers."}),"\n",(0,i.jsx)(t.h3,{id:"dm-crypt",children:"dm-crypt"}),"\n",(0,i.jsxs)(t.p,{children:["To interact with the dm-crypt kernel module, Constellation uses ",(0,i.jsx)(t.a,{href:"https://gitlab.com/cryptsetup/cryptsetup/",children:"libcryptsetup"}),".\nNew devices are formatted as ",(0,i.jsx)(t.a,{href:"https://gitlab.com/cryptsetup/LUKS2-docs/-/tree/master",children:"LUKS2"})," partitions with a sector size of 4096 bytes.\nThe used key derivation function is ",(0,i.jsx)(t.a,{href:"https://datatracker.ietf.org/doc/html/rfc9106",children:"Argon2id"})," with the ",(0,i.jsx)(t.a,{href:"https://datatracker.ietf.org/doc/html/rfc9106#section-7.4",children:"recommended parameters for memory-constrained environments"})," of 3 iterations and 64 MiB of memory, utilizing 4 parallel threads.\nFor encryption Constellation uses AES in XTS-Plain64. The key size is 512 bit."]}),"\n",(0,i.jsx)(t.h3,{id:"dm-integrity",children:"dm-integrity"}),"\n",(0,i.jsxs)(t.p,{children:["To interact with the dm-integrity kernel module, Constellation uses ",(0,i.jsx)(t.a,{href:"https://gitlab.com/cryptsetup/cryptsetup/",children:"libcryptsetup"}),".\nWhen enabled, the used data integrity algorithm is ",(0,i.jsx)(t.a,{href:"https://datatracker.ietf.org/doc/html/rfc2104",children:"HMAC"})," with SHA256 as the hash function.\nThe tag size is 32 Bytes."]}),"\n",(0,i.jsx)(t.h2,{id:"encrypted-s3-object-storage",children:"Encrypted S3 object storage"}),"\n",(0,i.jsxs)(t.p,{children:["Constellation comes with a service that you can use to transparently retrofit client-side encryption to existing applications that use S3 (AWS or compatible) for storage.\nTo learn more, check out the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/s3proxy",children:"s3proxy documentation"}),"."]})]})}function p(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/7592.ee6b88a7.js b/pr-preview/pr-4027/assets/js/7592.ee6b88a7.js deleted file mode 100644 index 335b61f70..000000000 --- a/pr-preview/pr-4027/assets/js/7592.ee6b88a7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7592],{17592:(t,e,a)=>{a.d(e,{diagram:()=>vt});var r=a(92875),s=a(73981),i=a(72938),n=a(13226),o=a(67633),c=a(40797),l=a(70451),h=a(16750),d=function(){var t=(0,c.K2)(function(t,e,a,r){for(a=a||{},r=t.length;r--;a[t[r]]=e);return a},"o"),e=[1,2],a=[1,3],r=[1,4],s=[2,4],i=[1,9],n=[1,11],o=[1,13],l=[1,14],h=[1,16],d=[1,17],p=[1,18],g=[1,24],u=[1,25],x=[1,26],y=[1,27],m=[1,28],b=[1,29],T=[1,30],f=[1,31],E=[1,32],w=[1,33],I=[1,34],L=[1,35],_=[1,36],P=[1,37],k=[1,38],N=[1,39],A=[1,41],v=[1,42],M=[1,43],O=[1,44],D=[1,45],S=[1,46],R=[1,4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,48,49,50,52,53,55,60,61,62,63,71],$=[2,71],C=[4,5,16,50,52,53],Y=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,55,60,61,62,63,71],K=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,49,50,52,53,55,60,61,62,63,71],B=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,48,50,52,53,55,60,61,62,63,71],V=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,50,52,53,55,60,61,62,63,71],F=[69,70,71],W=[1,127],q={trace:(0,c.K2)(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SPACE:4,NEWLINE:5,SD:6,document:7,line:8,statement:9,box_section:10,box_line:11,participant_statement:12,create:13,box:14,restOfLine:15,end:16,signal:17,autonumber:18,NUM:19,off:20,activate:21,actor:22,deactivate:23,note_statement:24,links_statement:25,link_statement:26,properties_statement:27,details_statement:28,title:29,legacy_title:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,loop:36,rect:37,opt:38,alt:39,else_sections:40,par:41,par_sections:42,par_over:43,critical:44,option_sections:45,break:46,option:47,and:48,else:49,participant:50,AS:51,participant_actor:52,destroy:53,actor_with_config:54,note:55,placement:56,text2:57,over:58,actor_pair:59,links:60,link:61,properties:62,details:63,spaceList:64,",":65,left_of:66,right_of:67,signaltype:68,"+":69,"-":70,ACTOR:71,config_object:72,CONFIG_START:73,CONFIG_CONTENT:74,CONFIG_END:75,SOLID_OPEN_ARROW:76,DOTTED_OPEN_ARROW:77,SOLID_ARROW:78,BIDIRECTIONAL_SOLID_ARROW:79,DOTTED_ARROW:80,BIDIRECTIONAL_DOTTED_ARROW:81,SOLID_CROSS:82,DOTTED_CROSS:83,SOLID_POINT:84,DOTTED_POINT:85,TXT:86,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NEWLINE",6:"SD",13:"create",14:"box",15:"restOfLine",16:"end",18:"autonumber",19:"NUM",20:"off",21:"activate",23:"deactivate",29:"title",30:"legacy_title",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",36:"loop",37:"rect",38:"opt",39:"alt",41:"par",43:"par_over",44:"critical",46:"break",47:"option",48:"and",49:"else",50:"participant",51:"AS",52:"participant_actor",53:"destroy",55:"note",58:"over",60:"links",61:"link",62:"properties",63:"details",65:",",66:"left_of",67:"right_of",69:"+",70:"-",71:"ACTOR",73:"CONFIG_START",74:"CONFIG_CONTENT",75:"CONFIG_END",76:"SOLID_OPEN_ARROW",77:"DOTTED_OPEN_ARROW",78:"SOLID_ARROW",79:"BIDIRECTIONAL_SOLID_ARROW",80:"DOTTED_ARROW",81:"BIDIRECTIONAL_DOTTED_ARROW",82:"SOLID_CROSS",83:"DOTTED_CROSS",84:"SOLID_POINT",85:"DOTTED_POINT",86:"TXT"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[10,0],[10,2],[11,2],[11,1],[11,1],[9,1],[9,2],[9,4],[9,2],[9,4],[9,3],[9,3],[9,2],[9,3],[9,3],[9,2],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[9,2],[9,2],[9,1],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[45,1],[45,4],[42,1],[42,4],[40,1],[40,4],[12,5],[12,3],[12,5],[12,3],[12,3],[12,3],[24,4],[24,4],[25,3],[26,3],[27,3],[28,3],[64,2],[64,1],[59,3],[59,1],[56,1],[56,1],[17,5],[17,5],[17,4],[54,2],[72,3],[22,1],[68,1],[68,1],[68,1],[68,1],[68,1],[68,1],[68,1],[68,1],[68,1],[68,1],[57,1]],performAction:(0,c.K2)(function(t,e,a,r,s,i,n){var o=i.length-1;switch(s){case 3:return r.apply(i[o]),i[o];case 4:case 9:case 8:case 13:this.$=[];break;case 5:case 10:i[o-1].push(i[o]),this.$=i[o-1];break;case 6:case 7:case 11:case 12:case 63:this.$=i[o];break;case 15:i[o].type="createParticipant",this.$=i[o];break;case 16:i[o-1].unshift({type:"boxStart",boxData:r.parseBoxData(i[o-2])}),i[o-1].push({type:"boxEnd",boxText:i[o-2]}),this.$=i[o-1];break;case 18:this.$={type:"sequenceIndex",sequenceIndex:Number(i[o-2]),sequenceIndexStep:Number(i[o-1]),sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 19:this.$={type:"sequenceIndex",sequenceIndex:Number(i[o-1]),sequenceIndexStep:1,sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 20:this.$={type:"sequenceIndex",sequenceVisible:!1,signalType:r.LINETYPE.AUTONUMBER};break;case 21:this.$={type:"sequenceIndex",sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 22:this.$={type:"activeStart",signalType:r.LINETYPE.ACTIVE_START,actor:i[o-1].actor};break;case 23:this.$={type:"activeEnd",signalType:r.LINETYPE.ACTIVE_END,actor:i[o-1].actor};break;case 29:r.setDiagramTitle(i[o].substring(6)),this.$=i[o].substring(6);break;case 30:r.setDiagramTitle(i[o].substring(7)),this.$=i[o].substring(7);break;case 31:this.$=i[o].trim(),r.setAccTitle(this.$);break;case 32:case 33:this.$=i[o].trim(),r.setAccDescription(this.$);break;case 34:i[o-1].unshift({type:"loopStart",loopText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.LOOP_START}),i[o-1].push({type:"loopEnd",loopText:i[o-2],signalType:r.LINETYPE.LOOP_END}),this.$=i[o-1];break;case 35:i[o-1].unshift({type:"rectStart",color:r.parseMessage(i[o-2]),signalType:r.LINETYPE.RECT_START}),i[o-1].push({type:"rectEnd",color:r.parseMessage(i[o-2]),signalType:r.LINETYPE.RECT_END}),this.$=i[o-1];break;case 36:i[o-1].unshift({type:"optStart",optText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.OPT_START}),i[o-1].push({type:"optEnd",optText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.OPT_END}),this.$=i[o-1];break;case 37:i[o-1].unshift({type:"altStart",altText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.ALT_START}),i[o-1].push({type:"altEnd",signalType:r.LINETYPE.ALT_END}),this.$=i[o-1];break;case 38:i[o-1].unshift({type:"parStart",parText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.PAR_START}),i[o-1].push({type:"parEnd",signalType:r.LINETYPE.PAR_END}),this.$=i[o-1];break;case 39:i[o-1].unshift({type:"parStart",parText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.PAR_OVER_START}),i[o-1].push({type:"parEnd",signalType:r.LINETYPE.PAR_END}),this.$=i[o-1];break;case 40:i[o-1].unshift({type:"criticalStart",criticalText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.CRITICAL_START}),i[o-1].push({type:"criticalEnd",signalType:r.LINETYPE.CRITICAL_END}),this.$=i[o-1];break;case 41:i[o-1].unshift({type:"breakStart",breakText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.BREAK_START}),i[o-1].push({type:"breakEnd",optText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.BREAK_END}),this.$=i[o-1];break;case 43:this.$=i[o-3].concat([{type:"option",optionText:r.parseMessage(i[o-1]),signalType:r.LINETYPE.CRITICAL_OPTION},i[o]]);break;case 45:this.$=i[o-3].concat([{type:"and",parText:r.parseMessage(i[o-1]),signalType:r.LINETYPE.PAR_AND},i[o]]);break;case 47:this.$=i[o-3].concat([{type:"else",altText:r.parseMessage(i[o-1]),signalType:r.LINETYPE.ALT_ELSE},i[o]]);break;case 48:i[o-3].draw="participant",i[o-3].type="addParticipant",i[o-3].description=r.parseMessage(i[o-1]),this.$=i[o-3];break;case 49:case 53:i[o-1].draw="participant",i[o-1].type="addParticipant",this.$=i[o-1];break;case 50:i[o-3].draw="actor",i[o-3].type="addParticipant",i[o-3].description=r.parseMessage(i[o-1]),this.$=i[o-3];break;case 51:i[o-1].draw="actor",i[o-1].type="addParticipant",this.$=i[o-1];break;case 52:i[o-1].type="destroyParticipant",this.$=i[o-1];break;case 54:this.$=[i[o-1],{type:"addNote",placement:i[o-2],actor:i[o-1].actor,text:i[o]}];break;case 55:i[o-2]=[].concat(i[o-1],i[o-1]).slice(0,2),i[o-2][0]=i[o-2][0].actor,i[o-2][1]=i[o-2][1].actor,this.$=[i[o-1],{type:"addNote",placement:r.PLACEMENT.OVER,actor:i[o-2].slice(0,2),text:i[o]}];break;case 56:this.$=[i[o-1],{type:"addLinks",actor:i[o-1].actor,text:i[o]}];break;case 57:this.$=[i[o-1],{type:"addALink",actor:i[o-1].actor,text:i[o]}];break;case 58:this.$=[i[o-1],{type:"addProperties",actor:i[o-1].actor,text:i[o]}];break;case 59:this.$=[i[o-1],{type:"addDetails",actor:i[o-1].actor,text:i[o]}];break;case 62:this.$=[i[o-2],i[o]];break;case 64:this.$=r.PLACEMENT.LEFTOF;break;case 65:this.$=r.PLACEMENT.RIGHTOF;break;case 66:this.$=[i[o-4],i[o-1],{type:"addMessage",from:i[o-4].actor,to:i[o-1].actor,signalType:i[o-3],msg:i[o],activate:!0},{type:"activeStart",signalType:r.LINETYPE.ACTIVE_START,actor:i[o-1].actor}];break;case 67:this.$=[i[o-4],i[o-1],{type:"addMessage",from:i[o-4].actor,to:i[o-1].actor,signalType:i[o-3],msg:i[o]},{type:"activeEnd",signalType:r.LINETYPE.ACTIVE_END,actor:i[o-4].actor}];break;case 68:this.$=[i[o-3],i[o-1],{type:"addMessage",from:i[o-3].actor,to:i[o-1].actor,signalType:i[o-2],msg:i[o]}];break;case 69:this.$={type:"addParticipant",actor:i[o-1],config:i[o]};break;case 70:this.$=i[o-1].trim();break;case 71:this.$={type:"addParticipant",actor:i[o]};break;case 72:this.$=r.LINETYPE.SOLID_OPEN;break;case 73:this.$=r.LINETYPE.DOTTED_OPEN;break;case 74:this.$=r.LINETYPE.SOLID;break;case 75:this.$=r.LINETYPE.BIDIRECTIONAL_SOLID;break;case 76:this.$=r.LINETYPE.DOTTED;break;case 77:this.$=r.LINETYPE.BIDIRECTIONAL_DOTTED;break;case 78:this.$=r.LINETYPE.SOLID_CROSS;break;case 79:this.$=r.LINETYPE.DOTTED_CROSS;break;case 80:this.$=r.LINETYPE.SOLID_POINT;break;case 81:this.$=r.LINETYPE.DOTTED_POINT;break;case 82:this.$=r.parseMessage(i[o].trim().substring(1))}},"anonymous"),table:[{3:1,4:e,5:a,6:r},{1:[3]},{3:5,4:e,5:a,6:r},{3:6,4:e,5:a,6:r},t([1,4,5,13,14,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,55,60,61,62,63,71],s,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:i,5:n,8:8,9:10,12:12,13:o,14:l,17:15,18:h,21:d,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,50:P,52:k,53:N,55:A,60:v,61:M,62:O,63:D,71:S},t(R,[2,5]),{9:47,12:12,13:o,14:l,17:15,18:h,21:d,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,50:P,52:k,53:N,55:A,60:v,61:M,62:O,63:D,71:S},t(R,[2,7]),t(R,[2,8]),t(R,[2,14]),{12:48,50:P,52:k,53:N},{15:[1,49]},{5:[1,50]},{5:[1,53],19:[1,51],20:[1,52]},{22:54,71:S},{22:55,71:S},{5:[1,56]},{5:[1,57]},{5:[1,58]},{5:[1,59]},{5:[1,60]},t(R,[2,29]),t(R,[2,30]),{32:[1,61]},{34:[1,62]},t(R,[2,33]),{15:[1,63]},{15:[1,64]},{15:[1,65]},{15:[1,66]},{15:[1,67]},{15:[1,68]},{15:[1,69]},{15:[1,70]},{22:71,54:72,71:[1,73]},{22:74,71:S},{22:75,71:S},{68:76,76:[1,77],77:[1,78],78:[1,79],79:[1,80],80:[1,81],81:[1,82],82:[1,83],83:[1,84],84:[1,85],85:[1,86]},{56:87,58:[1,88],66:[1,89],67:[1,90]},{22:91,71:S},{22:92,71:S},{22:93,71:S},{22:94,71:S},t([5,51,65,76,77,78,79,80,81,82,83,84,85,86],$),t(R,[2,6]),t(R,[2,15]),t(C,[2,9],{10:95}),t(R,[2,17]),{5:[1,97],19:[1,96]},{5:[1,98]},t(R,[2,21]),{5:[1,99]},{5:[1,100]},t(R,[2,24]),t(R,[2,25]),t(R,[2,26]),t(R,[2,27]),t(R,[2,28]),t(R,[2,31]),t(R,[2,32]),t(Y,s,{7:101}),t(Y,s,{7:102}),t(Y,s,{7:103}),t(K,s,{40:104,7:105}),t(B,s,{42:106,7:107}),t(B,s,{7:107,42:108}),t(V,s,{45:109,7:110}),t(Y,s,{7:111}),{5:[1,113],51:[1,112]},{5:[1,114]},t([5,51],$,{72:115,73:[1,116]}),{5:[1,118],51:[1,117]},{5:[1,119]},{22:122,69:[1,120],70:[1,121],71:S},t(F,[2,72]),t(F,[2,73]),t(F,[2,74]),t(F,[2,75]),t(F,[2,76]),t(F,[2,77]),t(F,[2,78]),t(F,[2,79]),t(F,[2,80]),t(F,[2,81]),{22:123,71:S},{22:125,59:124,71:S},{71:[2,64]},{71:[2,65]},{57:126,86:W},{57:128,86:W},{57:129,86:W},{57:130,86:W},{4:[1,133],5:[1,135],11:132,12:134,16:[1,131],50:P,52:k,53:N},{5:[1,136]},t(R,[2,19]),t(R,[2,20]),t(R,[2,22]),t(R,[2,23]),{4:i,5:n,8:8,9:10,12:12,13:o,14:l,16:[1,137],17:15,18:h,21:d,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,50:P,52:k,53:N,55:A,60:v,61:M,62:O,63:D,71:S},{4:i,5:n,8:8,9:10,12:12,13:o,14:l,16:[1,138],17:15,18:h,21:d,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,50:P,52:k,53:N,55:A,60:v,61:M,62:O,63:D,71:S},{4:i,5:n,8:8,9:10,12:12,13:o,14:l,16:[1,139],17:15,18:h,21:d,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,50:P,52:k,53:N,55:A,60:v,61:M,62:O,63:D,71:S},{16:[1,140]},{4:i,5:n,8:8,9:10,12:12,13:o,14:l,16:[2,46],17:15,18:h,21:d,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,49:[1,141],50:P,52:k,53:N,55:A,60:v,61:M,62:O,63:D,71:S},{16:[1,142]},{4:i,5:n,8:8,9:10,12:12,13:o,14:l,16:[2,44],17:15,18:h,21:d,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,48:[1,143],50:P,52:k,53:N,55:A,60:v,61:M,62:O,63:D,71:S},{16:[1,144]},{16:[1,145]},{4:i,5:n,8:8,9:10,12:12,13:o,14:l,16:[2,42],17:15,18:h,21:d,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,47:[1,146],50:P,52:k,53:N,55:A,60:v,61:M,62:O,63:D,71:S},{4:i,5:n,8:8,9:10,12:12,13:o,14:l,16:[1,147],17:15,18:h,21:d,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,50:P,52:k,53:N,55:A,60:v,61:M,62:O,63:D,71:S},{15:[1,148]},t(R,[2,49]),t(R,[2,53]),{5:[2,69]},{74:[1,149]},{15:[1,150]},t(R,[2,51]),t(R,[2,52]),{22:151,71:S},{22:152,71:S},{57:153,86:W},{57:154,86:W},{57:155,86:W},{65:[1,156],86:[2,63]},{5:[2,56]},{5:[2,82]},{5:[2,57]},{5:[2,58]},{5:[2,59]},t(R,[2,16]),t(C,[2,10]),{12:157,50:P,52:k,53:N},t(C,[2,12]),t(C,[2,13]),t(R,[2,18]),t(R,[2,34]),t(R,[2,35]),t(R,[2,36]),t(R,[2,37]),{15:[1,158]},t(R,[2,38]),{15:[1,159]},t(R,[2,39]),t(R,[2,40]),{15:[1,160]},t(R,[2,41]),{5:[1,161]},{75:[1,162]},{5:[1,163]},{57:164,86:W},{57:165,86:W},{5:[2,68]},{5:[2,54]},{5:[2,55]},{22:166,71:S},t(C,[2,11]),t(K,s,{7:105,40:167}),t(B,s,{7:107,42:168}),t(V,s,{7:110,45:169}),t(R,[2,48]),{5:[2,70]},t(R,[2,50]),{5:[2,66]},{5:[2,67]},{86:[2,62]},{16:[2,47]},{16:[2,45]},{16:[2,43]}],defaultActions:{5:[2,1],6:[2,2],89:[2,64],90:[2,65],115:[2,69],126:[2,56],127:[2,82],128:[2,57],129:[2,58],130:[2,59],153:[2,68],154:[2,54],155:[2,55],162:[2,70],164:[2,66],165:[2,67],166:[2,62],167:[2,47],168:[2,45],169:[2,43]},parseError:(0,c.K2)(function(t,e){if(!e.recoverable){var a=new Error(t);throw a.hash=e,a}this.trace(t)},"parseError"),parse:(0,c.K2)(function(t){var e=this,a=[0],r=[],s=[null],i=[],n=this.table,o="",l=0,h=0,d=0,p=i.slice.call(arguments,1),g=Object.create(this.lexer),u={yy:{}};for(var x in this.yy)Object.prototype.hasOwnProperty.call(this.yy,x)&&(u.yy[x]=this.yy[x]);g.setInput(t,u.yy),u.yy.lexer=g,u.yy.parser=this,void 0===g.yylloc&&(g.yylloc={});var y=g.yylloc;i.push(y);var m=g.options&&g.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||g.lex()||1)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,c.K2)(function(t){a.length=a.length-2*t,s.length=s.length-t,i.length=i.length-t},"popStack"),(0,c.K2)(b,"lex");for(var T,f,E,w,I,L,_,P,k,N={};;){if(E=a[a.length-1],this.defaultActions[E]?w=this.defaultActions[E]:(null==T&&(T=b()),w=n[E]&&n[E][T]),void 0===w||!w.length||!w[0]){var A="";for(L in k=[],n[E])this.terminals_[L]&&L>2&&k.push("'"+this.terminals_[L]+"'");A=g.showPosition?"Parse error on line "+(l+1)+":\n"+g.showPosition()+"\nExpecting "+k.join(", ")+", got '"+(this.terminals_[T]||T)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==T?"end of input":"'"+(this.terminals_[T]||T)+"'"),this.parseError(A,{text:g.match,token:this.terminals_[T]||T,line:g.yylineno,loc:y,expected:k})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+E+", token: "+T);switch(w[0]){case 1:a.push(T),s.push(g.yytext),i.push(g.yylloc),a.push(w[1]),T=null,f?(T=f,f=null):(h=g.yyleng,o=g.yytext,l=g.yylineno,y=g.yylloc,d>0&&d--);break;case 2:if(_=this.productions_[w[1]][1],N.$=s[s.length-_],N._$={first_line:i[i.length-(_||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(_||1)].first_column,last_column:i[i.length-1].last_column},m&&(N._$.range=[i[i.length-(_||1)].range[0],i[i.length-1].range[1]]),void 0!==(I=this.performAction.apply(N,[o,h,l,u.yy,w[1],s,i].concat(p))))return I;_&&(a=a.slice(0,-1*_*2),s=s.slice(0,-1*_),i=i.slice(0,-1*_)),a.push(this.productions_[w[1]][0]),s.push(N.$),i.push(N._$),P=n[a[a.length-2]][a[a.length-1]],a.push(P);break;case 3:return!0}}return!0},"parse")},z=function(){return{EOF:1,parseError:(0,c.K2)(function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},"parseError"),setInput:(0,c.K2)(function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:(0,c.K2)(function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},"input"),unput:(0,c.K2)(function(t){var e=t.length,a=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),a.length-1&&(this.yylineno-=a.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:a?(a.length===r.length?this.yylloc.first_column:0)+r[r.length-a.length].length-a[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},"unput"),more:(0,c.K2)(function(){return this._more=!0,this},"more"),reject:(0,c.K2)(function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"reject"),less:(0,c.K2)(function(t){this.unput(this.match.slice(t))},"less"),pastInput:(0,c.K2)(function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:(0,c.K2)(function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:(0,c.K2)(function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},"showPosition"),test_match:(0,c.K2)(function(t,e){var a,r,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],a=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),a)return a;if(this._backtrack){for(var i in s)this[i]=s[i];return!1}return!1},"test_match"),next:(0,c.K2)(function(){if(this.done)return this.EOF;var t,e,a,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),i=0;i<s.length;i++)if((a=this._input.match(this.rules[s[i]]))&&(!e||a[0].length>e[0].length)){if(e=a,r=i,this.options.backtrack_lexer){if(!1!==(t=this.test_match(a,s[i])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:(0,c.K2)(function(){var t=this.next();return t||this.lex()},"lex"),begin:(0,c.K2)(function(t){this.conditionStack.push(t)},"begin"),popState:(0,c.K2)(function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:(0,c.K2)(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:(0,c.K2)(function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},"topState"),pushState:(0,c.K2)(function(t){this.begin(t)},"pushState"),stateStackSize:(0,c.K2)(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,c.K2)(function(t,e,a,r){switch(a){case 0:case 56:case 72:return 5;case 1:case 2:case 3:case 4:case 5:break;case 6:return 19;case 7:return this.begin("CONFIG"),73;case 8:return 74;case 9:return this.popState(),this.popState(),75;case 10:case 57:return e.yytext=e.yytext.trim(),71;case 11:case 17:return e.yytext=e.yytext.trim(),this.begin("ALIAS"),71;case 12:return this.begin("LINE"),14;case 13:return this.begin("ID"),50;case 14:return this.begin("ID"),52;case 15:return 13;case 16:return this.begin("ID"),53;case 18:return this.popState(),this.popState(),this.begin("LINE"),51;case 19:return this.popState(),this.popState(),5;case 20:return this.begin("LINE"),36;case 21:return this.begin("LINE"),37;case 22:return this.begin("LINE"),38;case 23:return this.begin("LINE"),39;case 24:return this.begin("LINE"),49;case 25:return this.begin("LINE"),41;case 26:return this.begin("LINE"),43;case 27:return this.begin("LINE"),48;case 28:return this.begin("LINE"),44;case 29:return this.begin("LINE"),47;case 30:return this.begin("LINE"),46;case 31:return this.popState(),15;case 32:return 16;case 33:return 66;case 34:return 67;case 35:return 60;case 36:return 61;case 37:return 62;case 38:return 63;case 39:return 58;case 40:return 55;case 41:return this.begin("ID"),21;case 42:return this.begin("ID"),23;case 43:return 29;case 44:return 30;case 45:return this.begin("acc_title"),31;case 46:return this.popState(),"acc_title_value";case 47:return this.begin("acc_descr"),33;case 48:return this.popState(),"acc_descr_value";case 49:this.begin("acc_descr_multiline");break;case 50:this.popState();break;case 51:return"acc_descr_multiline_value";case 52:return 6;case 53:return 18;case 54:return 20;case 55:return 65;case 58:return 78;case 59:return 79;case 60:return 80;case 61:return 81;case 62:return 76;case 63:return 77;case 64:return 82;case 65:return 83;case 66:return 84;case 67:return 85;case 68:case 69:return 86;case 70:return 69;case 71:return 70;case 73:return"INVALID"}},"anonymous"),rules:[/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[0-9]+(?=[ \n]+))/i,/^(?:@\{)/i,/^(?:[^\}]+)/i,/^(?:\})/i,/^(?:[^\<->\->:\n,;@\s]+(?=@\{))/i,/^(?:[^\<->\->:\n,;@]+?([\-]*[^\<->\->:\n,;@]+?)*?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:box\b)/i,/^(?:participant\b)/i,/^(?:actor\b)/i,/^(?:create\b)/i,/^(?:destroy\b)/i,/^(?:[^<\->\->:\n,;]+?([\-]*[^<\->\->:\n,;]+?)*?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:rect\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:par_over\b)/i,/^(?:and\b)/i,/^(?:critical\b)/i,/^(?:option\b)/i,/^(?:break\b)/i,/^(?:(?:[:]?(?:no)?wrap)?[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:links\b)/i,/^(?:link\b)/i,/^(?:properties\b)/i,/^(?:details\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:title:\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:sequenceDiagram\b)/i,/^(?:autonumber\b)/i,/^(?:off\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^+<\->\->:\n,;]+((?!(-x|--x|-\)|--\)))[\-]*[^\+<\->\->:\n,;]+)*)/i,/^(?:->>)/i,/^(?:<<->>)/i,/^(?:-->>)/i,/^(?:<<-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?:-[\)])/i,/^(?:--[\)])/i,/^(?::(?:(?:no)?wrap)?[^#\n;]*)/i,/^(?::)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[50,51],inclusive:!1},acc_descr:{rules:[48],inclusive:!1},acc_title:{rules:[46],inclusive:!1},ID:{rules:[2,3,7,10,11,17],inclusive:!1},ALIAS:{rules:[2,3,18,19],inclusive:!1},LINE:{rules:[2,3,31],inclusive:!1},CONFIG:{rules:[8,9],inclusive:!1},CONFIG_DATA:{rules:[],inclusive:!1},INITIAL:{rules:[0,1,3,4,5,6,12,13,14,15,16,20,21,22,23,24,25,26,27,28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,47,49,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73],inclusive:!0}}}}();function H(){this.yy={}}return q.lexer=z,(0,c.K2)(H,"Parser"),H.prototype=q,q.Parser=H,new H}();d.parser=d;var p=d,g={SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25,AUTONUMBER:26,CRITICAL_START:27,CRITICAL_OPTION:28,CRITICAL_END:29,BREAK_START:30,BREAK_END:31,PAR_OVER_START:32,BIDIRECTIONAL_SOLID:33,BIDIRECTIONAL_DOTTED:34},u={FILLED:0,OPEN:1},x={LEFTOF:0,RIGHTOF:1,OVER:2},y="actor",m="control",b="database",T="entity",f=class{constructor(){this.state=new i.m(()=>({prevActor:void 0,actors:new Map,createdActors:new Map,destroyedActors:new Map,boxes:[],messages:[],notes:[],sequenceNumbersEnabled:!1,wrapEnabled:void 0,currentBox:void 0,lastCreated:void 0,lastDestroyed:void 0})),this.setAccTitle=o.SV,this.setAccDescription=o.EI,this.setDiagramTitle=o.ke,this.getAccTitle=o.iN,this.getAccDescription=o.m7,this.getDiagramTitle=o.ab,this.apply=this.apply.bind(this),this.parseBoxData=this.parseBoxData.bind(this),this.parseMessage=this.parseMessage.bind(this),this.clear(),this.setWrap((0,o.D7)().wrap),this.LINETYPE=g,this.ARROWTYPE=u,this.PLACEMENT=x}static{(0,c.K2)(this,"SequenceDB")}addBox(t){this.state.records.boxes.push({name:t.text,wrap:t.wrap??this.autoWrap(),fill:t.color,actorKeys:[]}),this.state.records.currentBox=this.state.records.boxes.slice(-1)[0]}addActor(t,e,a,r,i){let n,o=this.state.records.currentBox;if(void 0!==i){let t;t=i.includes("\n")?i+"\n":"{\n"+i+"\n}",n=(0,s.H)(t,{schema:s.r})}r=n?.type??r;const c=this.state.records.actors.get(t);if(c){if(this.state.records.currentBox&&c.box&&this.state.records.currentBox!==c.box)throw new Error(`A same participant should only be defined in one Box: ${c.name} can't be in '${c.box.name}' and in '${this.state.records.currentBox.name}' at the same time.`);if(o=c.box?c.box:this.state.records.currentBox,c.box=o,c&&e===c.name&&null==a)return}if(null==a?.text&&(a={text:e,type:r}),null!=r&&null!=a.text||(a={text:e,type:r}),this.state.records.actors.set(t,{box:o,name:e,description:a.text,wrap:a.wrap??this.autoWrap(),prevActor:this.state.records.prevActor,links:{},properties:{},actorCnt:null,rectData:null,type:r??"participant"}),this.state.records.prevActor){const e=this.state.records.actors.get(this.state.records.prevActor);e&&(e.nextActor=t)}this.state.records.currentBox&&this.state.records.currentBox.actorKeys.push(t),this.state.records.prevActor=t}activationCount(t){let e,a=0;if(!t)return 0;for(e=0;e<this.state.records.messages.length;e++)this.state.records.messages[e].type===this.LINETYPE.ACTIVE_START&&this.state.records.messages[e].from===t&&a++,this.state.records.messages[e].type===this.LINETYPE.ACTIVE_END&&this.state.records.messages[e].from===t&&a--;return a}addMessage(t,e,a,r){this.state.records.messages.push({id:this.state.records.messages.length.toString(),from:t,to:e,message:a.text,wrap:a.wrap??this.autoWrap(),answer:r})}addSignal(t,e,a,r,s=!1){if(r===this.LINETYPE.ACTIVE_END){if(this.activationCount(t??"")<1){const e=new Error("Trying to inactivate an inactive participant ("+t+")");throw e.hash={text:"->>-",token:"->>-",line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["'ACTIVE_PARTICIPANT'"]},e}}return this.state.records.messages.push({id:this.state.records.messages.length.toString(),from:t,to:e,message:a?.text??"",wrap:a?.wrap??this.autoWrap(),type:r,activate:s}),!0}hasAtLeastOneBox(){return this.state.records.boxes.length>0}hasAtLeastOneBoxWithTitle(){return this.state.records.boxes.some(t=>t.name)}getMessages(){return this.state.records.messages}getBoxes(){return this.state.records.boxes}getActors(){return this.state.records.actors}getCreatedActors(){return this.state.records.createdActors}getDestroyedActors(){return this.state.records.destroyedActors}getActor(t){return this.state.records.actors.get(t)}getActorKeys(){return[...this.state.records.actors.keys()]}enableSequenceNumbers(){this.state.records.sequenceNumbersEnabled=!0}disableSequenceNumbers(){this.state.records.sequenceNumbersEnabled=!1}showSequenceNumbers(){return this.state.records.sequenceNumbersEnabled}setWrap(t){this.state.records.wrapEnabled=t}extractWrap(t){if(void 0===t)return{};t=t.trim();const e=null!==/^:?wrap:/.exec(t)||null===/^:?nowrap:/.exec(t)&&void 0;return{cleanedText:(void 0===e?t:t.replace(/^:?(?:no)?wrap:/,"")).trim(),wrap:e}}autoWrap(){return void 0!==this.state.records.wrapEnabled?this.state.records.wrapEnabled:(0,o.D7)().sequence?.wrap??!1}clear(){this.state.reset(),(0,o.IU)()}parseMessage(t){const e=t.trim(),{wrap:a,cleanedText:r}=this.extractWrap(e),s={text:r,wrap:a};return c.Rm.debug(`parseMessage: ${JSON.stringify(s)}`),s}parseBoxData(t){const e=/^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/.exec(t);let a=e?.[1]?e[1].trim():"transparent",r=e?.[2]?e[2].trim():void 0;if(window?.CSS)window.CSS.supports("color",a)||(a="transparent",r=t.trim());else{const e=(new Option).style;e.color=a,e.color!==a&&(a="transparent",r=t.trim())}const{wrap:s,cleanedText:i}=this.extractWrap(r);return{text:i?(0,o.jZ)(i,(0,o.D7)()):void 0,color:a,wrap:s}}addNote(t,e,a){const r={actor:t,placement:e,message:a.text,wrap:a.wrap??this.autoWrap()},s=[].concat(t,t);this.state.records.notes.push(r),this.state.records.messages.push({id:this.state.records.messages.length.toString(),from:s[0],to:s[1],message:a.text,wrap:a.wrap??this.autoWrap(),type:this.LINETYPE.NOTE,placement:e})}addLinks(t,e){const a=this.getActor(t);try{let t=(0,o.jZ)(e.text,(0,o.D7)());t=t.replace(/=/g,"="),t=t.replace(/&/g,"&");const r=JSON.parse(t);this.insertLinks(a,r)}catch(r){c.Rm.error("error while parsing actor link text",r)}}addALink(t,e){const a=this.getActor(t);try{const t={};let r=(0,o.jZ)(e.text,(0,o.D7)());const s=r.indexOf("@");r=r.replace(/=/g,"="),r=r.replace(/&/g,"&");const i=r.slice(0,s-1).trim(),n=r.slice(s+1).trim();t[i]=n,this.insertLinks(a,t)}catch(r){c.Rm.error("error while parsing actor link text",r)}}insertLinks(t,e){if(null==t.links)t.links=e;else for(const a in e)t.links[a]=e[a]}addProperties(t,e){const a=this.getActor(t);try{const t=(0,o.jZ)(e.text,(0,o.D7)()),r=JSON.parse(t);this.insertProperties(a,r)}catch(r){c.Rm.error("error while parsing actor properties text",r)}}insertProperties(t,e){if(null==t.properties)t.properties=e;else for(const a in e)t.properties[a]=e[a]}boxEnd(){this.state.records.currentBox=void 0}addDetails(t,e){const a=this.getActor(t),r=document.getElementById(e.text);try{const t=r.innerHTML,e=JSON.parse(t);e.properties&&this.insertProperties(a,e.properties),e.links&&this.insertLinks(a,e.links)}catch(s){c.Rm.error("error while parsing actor details text",s)}}getActorProperty(t,e){if(void 0!==t?.properties)return t.properties[e]}apply(t){if(Array.isArray(t))t.forEach(t=>{this.apply(t)});else switch(t.type){case"sequenceIndex":this.state.records.messages.push({id:this.state.records.messages.length.toString(),from:void 0,to:void 0,message:{start:t.sequenceIndex,step:t.sequenceIndexStep,visible:t.sequenceVisible},wrap:!1,type:t.signalType});break;case"addParticipant":this.addActor(t.actor,t.actor,t.description,t.draw,t.config);break;case"createParticipant":if(this.state.records.actors.has(t.actor))throw new Error("It is not possible to have actors with the same id, even if one is destroyed before the next is created. Use 'AS' aliases to simulate the behavior");this.state.records.lastCreated=t.actor,this.addActor(t.actor,t.actor,t.description,t.draw,t.config),this.state.records.createdActors.set(t.actor,this.state.records.messages.length);break;case"destroyParticipant":this.state.records.lastDestroyed=t.actor,this.state.records.destroyedActors.set(t.actor,this.state.records.messages.length);break;case"activeStart":case"activeEnd":this.addSignal(t.actor,void 0,void 0,t.signalType);break;case"addNote":this.addNote(t.actor,t.placement,t.text);break;case"addLinks":this.addLinks(t.actor,t.text);break;case"addALink":this.addALink(t.actor,t.text);break;case"addProperties":this.addProperties(t.actor,t.text);break;case"addDetails":this.addDetails(t.actor,t.text);break;case"addMessage":if(this.state.records.lastCreated){if(t.to!==this.state.records.lastCreated)throw new Error("The created participant "+this.state.records.lastCreated.name+" does not have an associated creating message after its declaration. Please check the sequence diagram.");this.state.records.lastCreated=void 0}else if(this.state.records.lastDestroyed){if(t.to!==this.state.records.lastDestroyed&&t.from!==this.state.records.lastDestroyed)throw new Error("The destroyed participant "+this.state.records.lastDestroyed.name+" does not have an associated destroying message after its declaration. Please check the sequence diagram.");this.state.records.lastDestroyed=void 0}this.addSignal(t.from,t.to,t.msg,t.signalType,t.activate);break;case"boxStart":this.addBox(t.boxData);break;case"boxEnd":this.boxEnd();break;case"loopStart":this.addSignal(void 0,void 0,t.loopText,t.signalType);break;case"loopEnd":case"rectEnd":case"optEnd":case"altEnd":case"parEnd":case"criticalEnd":case"breakEnd":this.addSignal(void 0,void 0,void 0,t.signalType);break;case"rectStart":this.addSignal(void 0,void 0,t.color,t.signalType);break;case"optStart":this.addSignal(void 0,void 0,t.optText,t.signalType);break;case"altStart":case"else":this.addSignal(void 0,void 0,t.altText,t.signalType);break;case"setAccTitle":(0,o.SV)(t.text);break;case"parStart":case"and":this.addSignal(void 0,void 0,t.parText,t.signalType);break;case"criticalStart":this.addSignal(void 0,void 0,t.criticalText,t.signalType);break;case"option":this.addSignal(void 0,void 0,t.optionText,t.signalType);break;case"breakStart":this.addSignal(void 0,void 0,t.breakText,t.signalType)}}getConfig(){return(0,o.D7)().sequence}},E=(0,c.K2)(t=>`.actor {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n\n text.actor > tspan {\n fill: ${t.actorTextColor};\n stroke: none;\n }\n\n .actor-line {\n stroke: ${t.actorLineColor};\n }\n \n .innerArc {\n stroke-width: 1.5;\n stroke-dasharray: none;\n }\n\n .messageLine0 {\n stroke-width: 1.5;\n stroke-dasharray: none;\n stroke: ${t.signalColor};\n }\n\n .messageLine1 {\n stroke-width: 1.5;\n stroke-dasharray: 2, 2;\n stroke: ${t.signalColor};\n }\n\n #arrowhead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .sequenceNumber {\n fill: ${t.sequenceNumberColor};\n }\n\n #sequencenumber {\n fill: ${t.signalColor};\n }\n\n #crosshead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .messageText {\n fill: ${t.signalTextColor};\n stroke: none;\n }\n\n .labelBox {\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBkgColor};\n }\n\n .labelText, .labelText > tspan {\n fill: ${t.labelTextColor};\n stroke: none;\n }\n\n .loopText, .loopText > tspan {\n fill: ${t.loopTextColor};\n stroke: none;\n }\n\n .loopLine {\n stroke-width: 2px;\n stroke-dasharray: 2, 2;\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBorderColor};\n }\n\n .note {\n //stroke: #decc93;\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n }\n\n .noteText, .noteText > tspan {\n fill: ${t.noteTextColor};\n stroke: none;\n }\n\n .activation0 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation1 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation2 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .actorPopupMenu {\n position: absolute;\n }\n\n .actorPopupMenuPanel {\n position: absolute;\n fill: ${t.actorBkg};\n box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);\n filter: drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));\n}\n .actor-man line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n .actor-man circle, line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n stroke-width: 2px;\n }\n\n`,"getStyles"),w="actor-top",I="actor-bottom",L="actor-box",_="actor-man",P=(0,c.K2)(function(t,e){return(0,r.tk)(t,e)},"drawRect"),k=(0,c.K2)(function(t,e,a,r,s){if(void 0===e.links||null===e.links||0===Object.keys(e.links).length)return{height:0,width:0};const i=e.links,n=e.actorCnt,o=e.rectData;var c="none";s&&(c="block !important");const l=t.append("g");l.attr("id","actor"+n+"_popup"),l.attr("class","actorPopupMenu"),l.attr("display",c);var d="";void 0!==o.class&&(d=" "+o.class);let p=o.width>a?o.width:a;const g=l.append("rect");if(g.attr("class","actorPopupMenuPanel"+d),g.attr("x",o.x),g.attr("y",o.height),g.attr("fill",o.fill),g.attr("stroke",o.stroke),g.attr("width",p),g.attr("height",o.height),g.attr("rx",o.rx),g.attr("ry",o.ry),null!=i){var u=20;for(let t in i){var x=l.append("a"),y=(0,h.J)(i[t]);x.attr("xlink:href",y),x.attr("target","_blank"),st(r)(t,x,o.x+10,o.height+u,p,20,{class:"actor"},r),u+=30}}return g.attr("height",u),{height:o.height+u,width:p}},"drawPopup"),N=(0,c.K2)(function(t){return"var pu = document.getElementById('"+t+"'); if (pu != null) { pu.style.display = pu.style.display == 'block' ? 'none' : 'block'; }"},"popupMenuToggle"),A=(0,c.K2)(async function(t,e,a=null){let r=t.append("foreignObject");const s=await(0,o.dj)(e.text,(0,o.zj)()),i=r.append("xhtml:div").attr("style","width: fit-content;").attr("xmlns","http://www.w3.org/1999/xhtml").html(s).node().getBoundingClientRect();if(r.attr("height",Math.round(i.height)).attr("width",Math.round(i.width)),"noteText"===e.class){const a=t.node().firstChild;a.setAttribute("height",i.height+2*e.textMargin);const s=a.getBBox();r.attr("x",Math.round(s.x+s.width/2-i.width/2)).attr("y",Math.round(s.y+s.height/2-i.height/2))}else if(a){let{startx:t,stopx:s,starty:n}=a;if(t>s){const e=t;t=s,s=e}r.attr("x",Math.round(t+Math.abs(t-s)/2-i.width/2)),"loopText"===e.class?r.attr("y",Math.round(n)):r.attr("y",Math.round(n-i.height))}return[r]},"drawKatex"),v=(0,c.K2)(function(t,e){let a=0,r=0;const s=e.text.split(o.Y2.lineBreakRegex),[i,l]=(0,n.I5)(e.fontSize);let h=[],d=0,p=(0,c.K2)(()=>e.y,"yfunc");if(void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0)switch(e.valign){case"top":case"start":p=(0,c.K2)(()=>Math.round(e.y+e.textMargin),"yfunc");break;case"middle":case"center":p=(0,c.K2)(()=>Math.round(e.y+(a+r+e.textMargin)/2),"yfunc");break;case"bottom":case"end":p=(0,c.K2)(()=>Math.round(e.y+(a+r+2*e.textMargin)-e.textMargin),"yfunc")}if(void 0!==e.anchor&&void 0!==e.textMargin&&void 0!==e.width)switch(e.anchor){case"left":case"start":e.x=Math.round(e.x+e.textMargin),e.anchor="start",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"middle":case"center":e.x=Math.round(e.x+e.width/2),e.anchor="middle",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"right":case"end":e.x=Math.round(e.x+e.width-e.textMargin),e.anchor="end",e.dominantBaseline="middle",e.alignmentBaseline="middle"}for(let[o,c]of s.entries()){void 0!==e.textMargin&&0===e.textMargin&&void 0!==i&&(d=o*i);const s=t.append("text");s.attr("x",e.x),s.attr("y",p()),void 0!==e.anchor&&s.attr("text-anchor",e.anchor).attr("dominant-baseline",e.dominantBaseline).attr("alignment-baseline",e.alignmentBaseline),void 0!==e.fontFamily&&s.style("font-family",e.fontFamily),void 0!==l&&s.style("font-size",l),void 0!==e.fontWeight&&s.style("font-weight",e.fontWeight),void 0!==e.fill&&s.attr("fill",e.fill),void 0!==e.class&&s.attr("class",e.class),void 0!==e.dy?s.attr("dy",e.dy):0!==d&&s.attr("dy",d);const g=c||n.pe;if(e.tspan){const t=s.append("tspan");t.attr("x",e.x),void 0!==e.fill&&t.attr("fill",e.fill),t.text(g)}else s.text(g);void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0&&(r+=(s._groups||s)[0][0].getBBox().height,a=r),h.push(s)}return h},"drawText"),M=(0,c.K2)(function(t,e){function a(t,e,a,r,s){return t+","+e+" "+(t+a)+","+e+" "+(t+a)+","+(e+r-s)+" "+(t+a-1.2*s)+","+(e+r)+" "+t+","+(e+r)}(0,c.K2)(a,"genPoints");const r=t.append("polygon");return r.attr("points",a(e.x,e.y,e.width,e.height,7)),r.attr("class","labelBox"),e.y=e.y+e.height/2,v(t,e),r},"drawLabel"),O=-1,D=(0,c.K2)((t,e,a,r)=>{t.select&&a.forEach(a=>{const s=e.get(a),i=t.select("#actor"+s.actorCnt);!r.mirrorActors&&s.stopy?i.attr("y2",s.stopy+s.height/2):r.mirrorActors&&i.attr("y2",s.stopy)})},"fixLifeLineHeights"),S=(0,c.K2)(function(t,e,a,s){const i=s?e.stopy:e.starty,n=e.x+e.width/2,c=i+e.height,l=t.append("g").lower();var h=l;s||(O++,Object.keys(e.links||{}).length&&!a.forceMenus&&h.attr("onclick",N(`actor${O}_popup`)).attr("cursor","pointer"),h.append("line").attr("id","actor"+O).attr("x1",n).attr("y1",c).attr("x2",n).attr("y2",2e3).attr("class","actor-line 200").attr("stroke-width","0.5px").attr("stroke","#999").attr("name",e.name),h=l.append("g"),e.actorCnt=O,null!=e.links&&h.attr("id","root-"+O));const d=(0,r.PB)();var p="actor";e.properties?.class?p=e.properties.class:d.fill="#eaeaea",p+=s?` ${I}`:` ${w}`,d.x=e.x,d.y=i,d.width=e.width,d.height=e.height,d.class=p,d.rx=3,d.ry=3,d.name=e.name;const g=P(h,d);if(e.rectData=d,e.properties?.icon){const t=e.properties.icon.trim();"@"===t.charAt(0)?(0,r.CP)(h,d.x+d.width-20,d.y+10,t.substr(1)):(0,r.aC)(h,d.x+d.width-20,d.y+10,t)}rt(a,(0,o.Wi)(e.description))(e.description,h,d.x,d.y,d.width,d.height,{class:`actor ${L}`},a);let u=e.height;if(g.node){const t=g.node().getBBox();e.height=t.height,u=t.height}return u},"drawActorTypeParticipant"),R=(0,c.K2)(function(t,e,a,s){const i=s?e.stopy:e.starty,n=e.x+e.width/2,c=i+e.height,l=t.append("g").lower();var h=l;s||(O++,Object.keys(e.links||{}).length&&!a.forceMenus&&h.attr("onclick",N(`actor${O}_popup`)).attr("cursor","pointer"),h.append("line").attr("id","actor"+O).attr("x1",n).attr("y1",c).attr("x2",n).attr("y2",2e3).attr("class","actor-line 200").attr("stroke-width","0.5px").attr("stroke","#999").attr("name",e.name),h=l.append("g"),e.actorCnt=O,null!=e.links&&h.attr("id","root-"+O));const d=(0,r.PB)();var p="actor";e.properties?.class?p=e.properties.class:d.fill="#eaeaea",p+=s?` ${I}`:` ${w}`,d.x=e.x,d.y=i,d.width=e.width,d.height=e.height,d.class=p,d.name=e.name;const g={...d,x:d.x+-6,y:d.y+6,class:"actor"},u=P(h,d);if(P(h,g),e.rectData=d,e.properties?.icon){const t=e.properties.icon.trim();"@"===t.charAt(0)?(0,r.CP)(h,d.x+d.width-20,d.y+10,t.substr(1)):(0,r.aC)(h,d.x+d.width-20,d.y+10,t)}rt(a,(0,o.Wi)(e.description))(e.description,h,d.x-6,d.y+6,d.width,d.height,{class:`actor ${L}`},a);let x=e.height;if(u.node){const t=u.node().getBBox();e.height=t.height,x=t.height}return x},"drawActorTypeCollections"),$=(0,c.K2)(function(t,e,a,s){const i=s?e.stopy:e.starty,n=e.x+e.width/2,c=i+e.height,l=t.append("g").lower();let h=l;s||(O++,Object.keys(e.links||{}).length&&!a.forceMenus&&h.attr("onclick",N(`actor${O}_popup`)).attr("cursor","pointer"),h.append("line").attr("id","actor"+O).attr("x1",n).attr("y1",c).attr("x2",n).attr("y2",2e3).attr("class","actor-line 200").attr("stroke-width","0.5px").attr("stroke","#999").attr("name",e.name),h=l.append("g"),e.actorCnt=O,null!=e.links&&h.attr("id","root-"+O));const d=(0,r.PB)();let p="actor";e.properties?.class?p=e.properties.class:d.fill="#eaeaea",p+=s?` ${I}`:` ${w}`,d.x=e.x,d.y=i,d.width=e.width,d.height=e.height,d.class=p,d.name=e.name;const g=d.height/2,u=g/(2.5+d.height/50),x=h.append("g"),y=h.append("g");if(x.append("path").attr("d",`M ${d.x},${d.y+g}\n a ${u},${g} 0 0 0 0,${d.height}\n h ${d.width-2*u}\n a ${u},${g} 0 0 0 0,-${d.height}\n Z\n `).attr("class",p),y.append("path").attr("d",`M ${d.x},${d.y+g}\n a ${u},${g} 0 0 0 0,${d.height}`).attr("stroke","#666").attr("stroke-width","1px").attr("class",p),x.attr("transform",`translate(${u}, ${-d.height/2})`),y.attr("transform",`translate(${d.width-u}, ${-d.height/2})`),e.rectData=d,e.properties?.icon){const t=e.properties.icon.trim(),a=d.x+d.width-20,s=d.y+10;"@"===t.charAt(0)?(0,r.CP)(h,a,s,t.substr(1)):(0,r.aC)(h,a,s,t)}rt(a,(0,o.Wi)(e.description))(e.description,h,d.x,d.y,d.width,d.height,{class:`actor ${L}`},a);let m=e.height;const b=x.select("path:last-child");if(b.node()){const t=b.node().getBBox();e.height=t.height,m=t.height}return m},"drawActorTypeQueue"),C=(0,c.K2)(function(t,e,a,s){const i=s?e.stopy:e.starty,n=e.x+e.width/2,c=i+75,l=t.append("g").lower();s||(O++,l.append("line").attr("id","actor"+O).attr("x1",n).attr("y1",c).attr("x2",n).attr("y2",2e3).attr("class","actor-line 200").attr("stroke-width","0.5px").attr("stroke","#999").attr("name",e.name),e.actorCnt=O);const h=t.append("g");let d=_;d+=s?` ${I}`:` ${w}`,h.attr("class",d),h.attr("name",e.name);const p=(0,r.PB)();p.x=e.x,p.y=i,p.fill="#eaeaea",p.width=e.width,p.height=e.height,p.class="actor";const g=e.x+e.width/2,u=i+30;h.append("defs").append("marker").attr("id","filled-head-control").attr("refX",11).attr("refY",5.8).attr("markerWidth",20).attr("markerHeight",28).attr("orient","172.5").append("path").attr("d","M 14.4 5.6 L 7.2 10.4 L 8.8 5.6 L 7.2 0.8 Z"),h.append("circle").attr("cx",g).attr("cy",u).attr("r",18).attr("fill","#eaeaf7").attr("stroke","#666").attr("stroke-width",1.2),h.append("line").attr("marker-end","url(#filled-head-control)").attr("transform",`translate(${g}, ${u-18})`);const x=h.node().getBBox();return e.height=x.height+2*(a?.sequence?.labelBoxHeight??0),rt(a,(0,o.Wi)(e.description))(e.description,h,p.x,p.y+18+(s?5:10),p.width,p.height,{class:`actor ${_}`},a),e.height},"drawActorTypeControl"),Y=(0,c.K2)(function(t,e,a,s){const i=s?e.stopy:e.starty,n=e.x+e.width/2,c=i+75,l=t.append("g").lower(),h=t.append("g");let d=_;d+=s?` ${I}`:` ${w}`,h.attr("class",d),h.attr("name",e.name);const p=(0,r.PB)();p.x=e.x,p.y=i,p.fill="#eaeaea",p.width=e.width,p.height=e.height,p.class="actor";const g=e.x+e.width/2,u=i+(s?10:25),x=18;h.append("circle").attr("cx",g).attr("cy",u).attr("r",x).attr("width",e.width).attr("height",e.height),h.append("line").attr("x1",g-x).attr("x2",g+x).attr("y1",u+x).attr("y2",u+x).attr("stroke","#333").attr("stroke-width",2);const y=h.node().getBBox();return e.height=y.height+(a?.sequence?.labelBoxHeight??0),s||(O++,l.append("line").attr("id","actor"+O).attr("x1",n).attr("y1",c).attr("x2",n).attr("y2",2e3).attr("class","actor-line 200").attr("stroke-width","0.5px").attr("stroke","#999").attr("name",e.name),e.actorCnt=O),rt(a,(0,o.Wi)(e.description))(e.description,h,p.x,p.y+(s?(u-i+x-5)/2:(u+x-i)/2),p.width,p.height,{class:`actor ${_}`},a),h.attr("transform","translate(0, 9)"),e.height},"drawActorTypeEntity"),K=(0,c.K2)(function(t,e,a,s){const i=s?e.stopy:e.starty,n=e.x+e.width/2,c=i+e.height+2*a.boxTextMargin,l=t.append("g").lower();let h=l;s||(O++,Object.keys(e.links||{}).length&&!a.forceMenus&&h.attr("onclick",N(`actor${O}_popup`)).attr("cursor","pointer"),h.append("line").attr("id","actor"+O).attr("x1",n).attr("y1",c).attr("x2",n).attr("y2",2e3).attr("class","actor-line 200").attr("stroke-width","0.5px").attr("stroke","#999").attr("name",e.name),h=l.append("g"),e.actorCnt=O,null!=e.links&&h.attr("id","root-"+O));const d=(0,r.PB)();let p="actor";e.properties?.class?p=e.properties.class:d.fill="#eaeaea",p+=s?` ${I}`:` ${w}`,d.x=e.x,d.y=i,d.width=e.width,d.height=e.height,d.class=p,d.name=e.name,d.x=e.x,d.y=i;const g=d.width/4,u=d.width/4,x=g/2,y=x/(2.5+g/50),m=h.append("g"),b=`\n M ${d.x},${d.y+y}\n a ${x},${y} 0 0 0 ${g},0\n a ${x},${y} 0 0 0 -${g},0\n l 0,${u-2*y}\n a ${x},${y} 0 0 0 ${g},0\n l 0,-${u-2*y}\n`;m.append("path").attr("d",b).attr("fill","#eaeaea").attr("stroke","#000").attr("stroke-width",1).attr("class",p),s?m.attr("transform",`translate(${1.5*g}, ${d.height/4-2*y})`):m.attr("transform",`translate(${1.5*g}, ${(d.height+y)/4})`),e.rectData=d,rt(a,(0,o.Wi)(e.description))(e.description,h,d.x,d.y+(s?(d.height+u)/4:(d.height+y)/2),d.width,d.height,{class:`actor ${L}`},a);const T=m.select("path:last-child");if(T.node()){const t=T.node().getBBox();e.height=t.height+(a.sequence.labelBoxHeight??0)}return e.height},"drawActorTypeDatabase"),B=(0,c.K2)(function(t,e,a,s){const i=s?e.stopy:e.starty,n=e.x+e.width/2,c=i+80,l=30,h=t.append("g").lower();s||(O++,h.append("line").attr("id","actor"+O).attr("x1",n).attr("y1",c).attr("x2",n).attr("y2",2e3).attr("class","actor-line 200").attr("stroke-width","0.5px").attr("stroke","#999").attr("name",e.name),e.actorCnt=O);const d=t.append("g");let p=_;p+=s?` ${I}`:` ${w}`,d.attr("class",p),d.attr("name",e.name);const g=(0,r.PB)();g.x=e.x,g.y=i,g.fill="#eaeaea",g.width=e.width,g.height=e.height,g.class="actor",d.append("line").attr("id","actor-man-torso"+O).attr("x1",e.x+e.width/2-75).attr("y1",i+10).attr("x2",e.x+e.width/2-15).attr("y2",i+10),d.append("line").attr("id","actor-man-arms"+O).attr("x1",e.x+e.width/2-75).attr("y1",i+0).attr("x2",e.x+e.width/2-75).attr("y2",i+20),d.append("circle").attr("cx",e.x+e.width/2).attr("cy",i+10).attr("r",l);const u=d.node().getBBox();return e.height=u.height+(a.sequence.labelBoxHeight??0),rt(a,(0,o.Wi)(e.description))(e.description,d,g.x,g.y+(s?11:18),g.width,g.height,{class:`actor ${_}`},a),d.attr("transform","translate(0,22)"),e.height},"drawActorTypeBoundary"),V=(0,c.K2)(function(t,e,a,s){const i=s?e.stopy:e.starty,n=e.x+e.width/2,c=i+80,l=t.append("g").lower();s||(O++,l.append("line").attr("id","actor"+O).attr("x1",n).attr("y1",c).attr("x2",n).attr("y2",2e3).attr("class","actor-line 200").attr("stroke-width","0.5px").attr("stroke","#999").attr("name",e.name),e.actorCnt=O);const h=t.append("g");let d=_;d+=s?` ${I}`:` ${w}`,h.attr("class",d),h.attr("name",e.name);const p=(0,r.PB)();p.x=e.x,p.y=i,p.fill="#eaeaea",p.width=e.width,p.height=e.height,p.class="actor",p.rx=3,p.ry=3,h.append("line").attr("id","actor-man-torso"+O).attr("x1",n).attr("y1",i+25).attr("x2",n).attr("y2",i+45),h.append("line").attr("id","actor-man-arms"+O).attr("x1",n-18).attr("y1",i+33).attr("x2",n+18).attr("y2",i+33),h.append("line").attr("x1",n-18).attr("y1",i+60).attr("x2",n).attr("y2",i+45),h.append("line").attr("x1",n).attr("y1",i+45).attr("x2",n+18-2).attr("y2",i+60);const g=h.append("circle");g.attr("cx",e.x+e.width/2),g.attr("cy",i+10),g.attr("r",15),g.attr("width",e.width),g.attr("height",e.height);const u=h.node().getBBox();return e.height=u.height,rt(a,(0,o.Wi)(e.description))(e.description,h,p.x,p.y+35,p.width,p.height,{class:`actor ${_}`},a),e.height},"drawActorTypeActor"),F=(0,c.K2)(async function(t,e,a,r){switch(e.type){case"actor":return await V(t,e,a,r);case"participant":return await S(t,e,a,r);case"boundary":return await B(t,e,a,r);case"control":return await C(t,e,a,r);case"entity":return await Y(t,e,a,r);case"database":return await K(t,e,a,r);case"collections":return await R(t,e,a,r);case"queue":return await $(t,e,a,r)}},"drawActor"),W=(0,c.K2)(function(t,e,a){const r=t.append("g");j(r,e),e.name&&rt(a)(e.name,r,e.x,e.y+a.boxTextMargin+(e.textMaxHeight||0)/2,e.width,0,{class:"text"},a),r.lower()},"drawBox"),q=(0,c.K2)(function(t){return t.append("g")},"anchorElement"),z=(0,c.K2)(function(t,e,a,s,i){const n=(0,r.PB)(),o=e.anchored;n.x=e.startx,n.y=e.starty,n.class="activation"+i%3,n.width=e.stopx-e.startx,n.height=a-e.starty,P(o,n)},"drawActivation"),H=(0,c.K2)(async function(t,e,a,s){const{boxMargin:i,boxTextMargin:n,labelBoxHeight:l,labelBoxWidth:h,messageFontFamily:d,messageFontSize:p,messageFontWeight:g}=s,u=t.append("g"),x=(0,c.K2)(function(t,e,a,r){return u.append("line").attr("x1",t).attr("y1",e).attr("x2",a).attr("y2",r).attr("class","loopLine")},"drawLoopLine");x(e.startx,e.starty,e.stopx,e.starty),x(e.stopx,e.starty,e.stopx,e.stopy),x(e.startx,e.stopy,e.stopx,e.stopy),x(e.startx,e.starty,e.startx,e.stopy),void 0!==e.sections&&e.sections.forEach(function(t){x(e.startx,t.y,e.stopx,t.y).style("stroke-dasharray","3, 3")});let y=(0,r.HT)();y.text=a,y.x=e.startx,y.y=e.starty,y.fontFamily=d,y.fontSize=p,y.fontWeight=g,y.anchor="middle",y.valign="middle",y.tspan=!1,y.width=h||50,y.height=l||20,y.textMargin=n,y.class="labelText",M(u,y),y=et(),y.text=e.title,y.x=e.startx+h/2+(e.stopx-e.startx)/2,y.y=e.starty+i+n,y.anchor="middle",y.valign="middle",y.textMargin=n,y.class="loopText",y.fontFamily=d,y.fontSize=p,y.fontWeight=g,y.wrap=!0;let m=(0,o.Wi)(y.text)?await A(u,y,e):v(u,y);if(void 0!==e.sectionTitles)for(const[r,c]of Object.entries(e.sectionTitles))if(c.message){y.text=c.message,y.x=e.startx+(e.stopx-e.startx)/2,y.y=e.sections[r].y+i+n,y.class="loopText",y.anchor="middle",y.valign="middle",y.tspan=!1,y.fontFamily=d,y.fontSize=p,y.fontWeight=g,y.wrap=e.wrap,(0,o.Wi)(y.text)?(e.starty=e.sections[r].y,await A(u,y,e)):v(u,y);let t=Math.round(m.map(t=>(t._groups||t)[0][0].getBBox().height).reduce((t,e)=>t+e));e.sections[r].height+=t-(i+n)}return e.height=Math.round(e.stopy-e.starty),u},"drawLoop"),j=(0,c.K2)(function(t,e){(0,r.lC)(t,e)},"drawBackgroundRect"),U=(0,c.K2)(function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},"insertDatabaseIcon"),G=(0,c.K2)(function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},"insertComputerIcon"),X=(0,c.K2)(function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")},"insertClockIcon"),J=(0,c.K2)(function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",7.9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto-start-reverse").append("path").attr("d","M -1 0 L 10 5 L 0 10 z")},"insertArrowHead"),Z=(0,c.K2)(function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",15.5).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},"insertArrowFilledHead"),Q=(0,c.K2)(function(t){t.append("defs").append("marker").attr("id","sequencenumber").attr("refX",15).attr("refY",15).attr("markerWidth",60).attr("markerHeight",40).attr("orient","auto").append("circle").attr("cx",15).attr("cy",15).attr("r",6)},"insertSequenceNumber"),tt=(0,c.K2)(function(t){t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",4).attr("refY",4.5).append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1pt").attr("d","M 1,2 L 6,7 M 6,2 L 1,7")},"insertArrowCrossHead"),et=(0,c.K2)(function(){return{x:0,y:0,fill:void 0,anchor:void 0,style:"#666",width:void 0,height:void 0,textMargin:0,rx:0,ry:0,tspan:!0,valign:void 0}},"getTextObj"),at=(0,c.K2)(function(){return{x:0,y:0,fill:"#EDF2AE",stroke:"#666",width:100,anchor:"start",height:100,rx:0,ry:0}},"getNoteRect"),rt=function(){function t(t,e,a,r,i,n,o){s(e.append("text").attr("x",a+i/2).attr("y",r+n/2+5).style("text-anchor","middle").text(t),o)}function e(t,e,a,r,i,c,l,h){const{actorFontSize:d,actorFontFamily:p,actorFontWeight:g}=h,[u,x]=(0,n.I5)(d),y=t.split(o.Y2.lineBreakRegex);for(let n=0;n<y.length;n++){const t=n*u-u*(y.length-1)/2,o=e.append("text").attr("x",a+i/2).attr("y",r).style("text-anchor","middle").style("font-size",x).style("font-weight",g).style("font-family",p);o.append("tspan").attr("x",a+i/2).attr("dy",t).text(y[n]),o.attr("y",r+c/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),s(o,l)}}function a(t,a,r,i,n,o,c,l){const h=a.append("switch"),d=h.append("foreignObject").attr("x",r).attr("y",i).attr("width",n).attr("height",o).append("xhtml:div").style("display","table").style("height","100%").style("width","100%");d.append("div").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,r,i,n,o,c,l),s(d,c)}async function r(t,a,r,i,n,c,l,h){const d=await(0,o.Dl)(t,(0,o.zj)()),p=a.append("switch"),g=p.append("foreignObject").attr("x",r+n/2-d.width/2).attr("y",i+c/2-d.height/2).attr("width",d.width).attr("height",d.height).append("xhtml:div").style("height","100%").style("width","100%");g.append("div").style("text-align","center").style("vertical-align","middle").html(await(0,o.dj)(t,(0,o.zj)())),e(t,p,r,i,n,c,l,h),s(g,l)}function s(t,e){for(const a in e)e.hasOwnProperty(a)&&t.attr(a,e[a])}return(0,c.K2)(t,"byText"),(0,c.K2)(e,"byTspan"),(0,c.K2)(a,"byFo"),(0,c.K2)(r,"byKatex"),(0,c.K2)(s,"_setTextAttrs"),function(s,i=!1){return i?r:"fo"===s.textPlacement?a:"old"===s.textPlacement?t:e}}(),st=function(){function t(t,e,a,s,i,n,o){r(e.append("text").attr("x",a).attr("y",s).style("text-anchor","start").text(t),o)}function e(t,e,a,s,i,n,c,l){const{actorFontSize:h,actorFontFamily:d,actorFontWeight:p}=l,g=t.split(o.Y2.lineBreakRegex);for(let o=0;o<g.length;o++){const t=o*h-h*(g.length-1)/2,i=e.append("text").attr("x",a).attr("y",s).style("text-anchor","start").style("font-size",h).style("font-weight",p).style("font-family",d);i.append("tspan").attr("x",a).attr("dy",t).text(g[o]),i.attr("y",s+n/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),r(i,c)}}function a(t,a,s,i,n,o,c,l){const h=a.append("switch"),d=h.append("foreignObject").attr("x",s).attr("y",i).attr("width",n).attr("height",o).append("xhtml:div").style("display","table").style("height","100%").style("width","100%");d.append("div").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,s,i,0,o,c,l),r(d,c)}function r(t,e){for(const a in e)e.hasOwnProperty(a)&&t.attr(a,e[a])}return(0,c.K2)(t,"byText"),(0,c.K2)(e,"byTspan"),(0,c.K2)(a,"byFo"),(0,c.K2)(r,"_setTextAttrs"),function(r){return"fo"===r.textPlacement?a:"old"===r.textPlacement?t:e}}(),it={drawRect:P,drawText:v,drawLabel:M,drawActor:F,drawBox:W,drawPopup:k,anchorElement:q,drawActivation:z,drawLoop:H,drawBackgroundRect:j,insertArrowHead:J,insertArrowFilledHead:Z,insertSequenceNumber:Q,insertArrowCrossHead:tt,insertDatabaseIcon:U,insertComputerIcon:G,insertClockIcon:X,getTextObj:et,getNoteRect:at,fixLifeLineHeights:D,sanitizeUrl:h.J},nt={},ot={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],activations:[],models:{getHeight:(0,c.K2)(function(){return Math.max.apply(null,0===this.actors.length?[0]:this.actors.map(t=>t.height||0))+(0===this.loops.length?0:this.loops.map(t=>t.height||0).reduce((t,e)=>t+e))+(0===this.messages.length?0:this.messages.map(t=>t.height||0).reduce((t,e)=>t+e))+(0===this.notes.length?0:this.notes.map(t=>t.height||0).reduce((t,e)=>t+e))},"getHeight"),clear:(0,c.K2)(function(){this.actors=[],this.boxes=[],this.loops=[],this.messages=[],this.notes=[]},"clear"),addBox:(0,c.K2)(function(t){this.boxes.push(t)},"addBox"),addActor:(0,c.K2)(function(t){this.actors.push(t)},"addActor"),addLoop:(0,c.K2)(function(t){this.loops.push(t)},"addLoop"),addMessage:(0,c.K2)(function(t){this.messages.push(t)},"addMessage"),addNote:(0,c.K2)(function(t){this.notes.push(t)},"addNote"),lastActor:(0,c.K2)(function(){return this.actors[this.actors.length-1]},"lastActor"),lastLoop:(0,c.K2)(function(){return this.loops[this.loops.length-1]},"lastLoop"),lastMessage:(0,c.K2)(function(){return this.messages[this.messages.length-1]},"lastMessage"),lastNote:(0,c.K2)(function(){return this.notes[this.notes.length-1]},"lastNote"),actors:[],boxes:[],loops:[],messages:[],notes:[]},init:(0,c.K2)(function(){this.sequenceItems=[],this.activations=[],this.models.clear(),this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0,mt((0,o.D7)())},"init"),updateVal:(0,c.K2)(function(t,e,a,r){void 0===t[e]?t[e]=a:t[e]=r(a,t[e])},"updateVal"),updateBounds:(0,c.K2)(function(t,e,a,r){const s=this;let i=0;function n(n){return(0,c.K2)(function(o){i++;const c=s.sequenceItems.length-i+1;s.updateVal(o,"starty",e-c*nt.boxMargin,Math.min),s.updateVal(o,"stopy",r+c*nt.boxMargin,Math.max),s.updateVal(ot.data,"startx",t-c*nt.boxMargin,Math.min),s.updateVal(ot.data,"stopx",a+c*nt.boxMargin,Math.max),"activation"!==n&&(s.updateVal(o,"startx",t-c*nt.boxMargin,Math.min),s.updateVal(o,"stopx",a+c*nt.boxMargin,Math.max),s.updateVal(ot.data,"starty",e-c*nt.boxMargin,Math.min),s.updateVal(ot.data,"stopy",r+c*nt.boxMargin,Math.max))},"updateItemBounds")}(0,c.K2)(n,"updateFn"),this.sequenceItems.forEach(n()),this.activations.forEach(n("activation"))},"updateBounds"),insert:(0,c.K2)(function(t,e,a,r){const s=o.Y2.getMin(t,a),i=o.Y2.getMax(t,a),n=o.Y2.getMin(e,r),c=o.Y2.getMax(e,r);this.updateVal(ot.data,"startx",s,Math.min),this.updateVal(ot.data,"starty",n,Math.min),this.updateVal(ot.data,"stopx",i,Math.max),this.updateVal(ot.data,"stopy",c,Math.max),this.updateBounds(s,n,i,c)},"insert"),newActivation:(0,c.K2)(function(t,e,a){const r=a.get(t.from),s=bt(t.from).length||0,i=r.x+r.width/2+(s-1)*nt.activationWidth/2;this.activations.push({startx:i,starty:this.verticalPos+2,stopx:i+nt.activationWidth,stopy:void 0,actor:t.from,anchored:it.anchorElement(e)})},"newActivation"),endActivation:(0,c.K2)(function(t){const e=this.activations.map(function(t){return t.actor}).lastIndexOf(t.from);return this.activations.splice(e,1)[0]},"endActivation"),createLoop:(0,c.K2)(function(t={message:void 0,wrap:!1,width:void 0},e){return{startx:void 0,starty:this.verticalPos,stopx:void 0,stopy:void 0,title:t.message,wrap:t.wrap,width:t.width,height:0,fill:e}},"createLoop"),newLoop:(0,c.K2)(function(t={message:void 0,wrap:!1,width:void 0},e){this.sequenceItems.push(this.createLoop(t,e))},"newLoop"),endLoop:(0,c.K2)(function(){return this.sequenceItems.pop()},"endLoop"),isLoopOverlap:(0,c.K2)(function(){return!!this.sequenceItems.length&&this.sequenceItems[this.sequenceItems.length-1].overlap},"isLoopOverlap"),addSectionToLoop:(0,c.K2)(function(t){const e=this.sequenceItems.pop();e.sections=e.sections||[],e.sectionTitles=e.sectionTitles||[],e.sections.push({y:ot.getVerticalPos(),height:0}),e.sectionTitles.push(t),this.sequenceItems.push(e)},"addSectionToLoop"),saveVerticalPos:(0,c.K2)(function(){this.isLoopOverlap()&&(this.savedVerticalPos=this.verticalPos)},"saveVerticalPos"),resetVerticalPos:(0,c.K2)(function(){this.isLoopOverlap()&&(this.verticalPos=this.savedVerticalPos)},"resetVerticalPos"),bumpVerticalPos:(0,c.K2)(function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=o.Y2.getMax(this.data.stopy,this.verticalPos)},"bumpVerticalPos"),getVerticalPos:(0,c.K2)(function(){return this.verticalPos},"getVerticalPos"),getBounds:(0,c.K2)(function(){return{bounds:this.data,models:this.models}},"getBounds")},ct=(0,c.K2)(async function(t,e){ot.bumpVerticalPos(nt.boxMargin),e.height=nt.boxMargin,e.starty=ot.getVerticalPos();const a=(0,r.PB)();a.x=e.startx,a.y=e.starty,a.width=e.width||nt.width,a.class="note";const s=t.append("g"),i=it.drawRect(s,a),n=(0,r.HT)();n.x=e.startx,n.y=e.starty,n.width=a.width,n.dy="1em",n.text=e.message,n.class="noteText",n.fontFamily=nt.noteFontFamily,n.fontSize=nt.noteFontSize,n.fontWeight=nt.noteFontWeight,n.anchor=nt.noteAlign,n.textMargin=nt.noteMargin,n.valign="center";const c=(0,o.Wi)(n.text)?await A(s,n):v(s,n),l=Math.round(c.map(t=>(t._groups||t)[0][0].getBBox().height).reduce((t,e)=>t+e));i.attr("height",l+2*nt.noteMargin),e.height+=l+2*nt.noteMargin,ot.bumpVerticalPos(l+2*nt.noteMargin),e.stopy=e.starty+l+2*nt.noteMargin,e.stopx=e.startx+a.width,ot.insert(e.startx,e.starty,e.stopx,e.stopy),ot.models.addNote(e)},"drawNote"),lt=(0,c.K2)(t=>({fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight}),"messageFont"),ht=(0,c.K2)(t=>({fontFamily:t.noteFontFamily,fontSize:t.noteFontSize,fontWeight:t.noteFontWeight}),"noteFont"),dt=(0,c.K2)(t=>({fontFamily:t.actorFontFamily,fontSize:t.actorFontSize,fontWeight:t.actorFontWeight}),"actorFont");async function pt(t,e){ot.bumpVerticalPos(10);const{startx:a,stopx:r,message:s}=e,i=o.Y2.splitBreaks(s).length,c=(0,o.Wi)(s),l=c?await(0,o.Dl)(s,(0,o.D7)()):n._K.calculateTextDimensions(s,lt(nt));if(!c){const t=l.height/i;e.height+=t,ot.bumpVerticalPos(t)}let h,d=l.height-10;const p=l.width;if(a===r){h=ot.getVerticalPos()+d,nt.rightAngles||(d+=nt.boxMargin,h=ot.getVerticalPos()+d),d+=30;const t=o.Y2.getMax(p/2,nt.width/2);ot.insert(a-t,ot.getVerticalPos()-10+d,r+t,ot.getVerticalPos()+30+d)}else d+=nt.boxMargin,h=ot.getVerticalPos()+d,ot.insert(a,h-10,r,h);return ot.bumpVerticalPos(d),e.height+=d,e.stopy=e.starty+e.height,ot.insert(e.fromBounds,e.starty,e.toBounds,e.stopy),h}(0,c.K2)(pt,"boundMessage");var gt=(0,c.K2)(async function(t,e,a,s){const{startx:i,stopx:c,starty:l,message:h,type:d,sequenceIndex:p,sequenceVisible:g}=e,u=n._K.calculateTextDimensions(h,lt(nt)),x=(0,r.HT)();x.x=i,x.y=l+10,x.width=c-i,x.class="messageText",x.dy="1em",x.text=h,x.fontFamily=nt.messageFontFamily,x.fontSize=nt.messageFontSize,x.fontWeight=nt.messageFontWeight,x.anchor=nt.messageAlign,x.valign="center",x.textMargin=nt.wrapPadding,x.tspan=!1,(0,o.Wi)(x.text)?await A(t,x,{startx:i,stopx:c,starty:a}):v(t,x);const y=u.width;let m;i===c?m=nt.rightAngles?t.append("path").attr("d",`M ${i},${a} H ${i+o.Y2.getMax(nt.width/2,y/2)} V ${a+25} H ${i}`):t.append("path").attr("d","M "+i+","+a+" C "+(i+60)+","+(a-10)+" "+(i+60)+","+(a+30)+" "+i+","+(a+20)):(m=t.append("line"),m.attr("x1",i),m.attr("y1",a),m.attr("x2",c),m.attr("y2",a)),d===s.db.LINETYPE.DOTTED||d===s.db.LINETYPE.DOTTED_CROSS||d===s.db.LINETYPE.DOTTED_POINT||d===s.db.LINETYPE.DOTTED_OPEN||d===s.db.LINETYPE.BIDIRECTIONAL_DOTTED?(m.style("stroke-dasharray","3, 3"),m.attr("class","messageLine1")):m.attr("class","messageLine0");let b="";if(nt.arrowMarkerAbsolute&&(b=(0,o.ID)(!0)),m.attr("stroke-width",2),m.attr("stroke","none"),m.style("fill","none"),d!==s.db.LINETYPE.SOLID&&d!==s.db.LINETYPE.DOTTED||m.attr("marker-end","url("+b+"#arrowhead)"),d!==s.db.LINETYPE.BIDIRECTIONAL_SOLID&&d!==s.db.LINETYPE.BIDIRECTIONAL_DOTTED||(m.attr("marker-start","url("+b+"#arrowhead)"),m.attr("marker-end","url("+b+"#arrowhead)")),d!==s.db.LINETYPE.SOLID_POINT&&d!==s.db.LINETYPE.DOTTED_POINT||m.attr("marker-end","url("+b+"#filled-head)"),d!==s.db.LINETYPE.SOLID_CROSS&&d!==s.db.LINETYPE.DOTTED_CROSS||m.attr("marker-end","url("+b+"#crosshead)"),g||nt.showSequenceNumbers){if(d===s.db.LINETYPE.BIDIRECTIONAL_SOLID||d===s.db.LINETYPE.BIDIRECTIONAL_DOTTED){const t=6;i<c?m.attr("x1",i+2*t):m.attr("x1",i+t)}t.append("line").attr("x1",i).attr("y1",a).attr("x2",i).attr("y2",a).attr("stroke-width",0).attr("marker-start","url("+b+"#sequencenumber)"),t.append("text").attr("x",i).attr("y",a+4).attr("font-family","sans-serif").attr("font-size","12px").attr("text-anchor","middle").attr("class","sequenceNumber").text(p)}},"drawMessage"),ut=(0,c.K2)(function(t,e,a,r,s,i,n){let c,l=0,h=0,d=0;for(const p of r){const t=e.get(p),r=t.box;c&&c!=r&&(n||ot.models.addBox(c),h+=nt.boxMargin+c.margin),r&&r!=c&&(n||(r.x=l+h,r.y=s),h+=r.margin),t.width=t.width||nt.width,t.height=o.Y2.getMax(t.height||nt.height,nt.height),t.margin=t.margin||nt.actorMargin,d=o.Y2.getMax(d,t.height),a.get(t.name)&&(h+=t.width/2),t.x=l+h,t.starty=ot.getVerticalPos(),ot.insert(t.x,s,t.x+t.width,t.height),l+=t.width+h,t.box&&(t.box.width=l+r.margin-t.box.x),h=t.margin,c=t.box,ot.models.addActor(t)}c&&!n&&ot.models.addBox(c),ot.bumpVerticalPos(d)},"addActorRenderingData"),xt=(0,c.K2)(async function(t,e,a,r){if(r){let r=0;ot.bumpVerticalPos(2*nt.boxMargin);for(const s of a){const a=e.get(s);a.stopy||(a.stopy=ot.getVerticalPos());const i=await it.drawActor(t,a,nt,!0);r=o.Y2.getMax(r,i)}ot.bumpVerticalPos(r+nt.boxMargin)}else for(const s of a){const a=e.get(s);await it.drawActor(t,a,nt,!1)}},"drawActors"),yt=(0,c.K2)(function(t,e,a,r){let s=0,i=0;for(const n of a){const a=e.get(n),o=Lt(a),c=it.drawPopup(t,a,o,nt,nt.forceMenus,r);c.height>s&&(s=c.height),c.width+a.x>i&&(i=c.width+a.x)}return{maxHeight:s,maxWidth:i}},"drawActorsPopup"),mt=(0,c.K2)(function(t){(0,o.hH)(nt,t),t.fontFamily&&(nt.actorFontFamily=nt.noteFontFamily=nt.messageFontFamily=t.fontFamily),t.fontSize&&(nt.actorFontSize=nt.noteFontSize=nt.messageFontSize=t.fontSize),t.fontWeight&&(nt.actorFontWeight=nt.noteFontWeight=nt.messageFontWeight=t.fontWeight)},"setConf"),bt=(0,c.K2)(function(t){return ot.activations.filter(function(e){return e.actor===t})},"actorActivations"),Tt=(0,c.K2)(function(t,e){const a=e.get(t),r=bt(t);return[r.reduce(function(t,e){return o.Y2.getMin(t,e.startx)},a.x+a.width/2-1),r.reduce(function(t,e){return o.Y2.getMax(t,e.stopx)},a.x+a.width/2+1)]},"activationBounds");function ft(t,e,a,r,s){ot.bumpVerticalPos(a);let i=r;if(e.id&&e.message&&t[e.id]){const a=t[e.id].width,s=lt(nt);e.message=n._K.wrapLabel(`[${e.message}]`,a-2*nt.wrapPadding,s),e.width=a,e.wrap=!0;const l=n._K.calculateTextDimensions(e.message,s),h=o.Y2.getMax(l.height,nt.labelBoxHeight);i=r+h,c.Rm.debug(`${h} - ${e.message}`)}s(e),ot.bumpVerticalPos(i)}function Et(t,e,a,r,s,i,n){function o(a,r){a.x<s.get(t.from).x?(ot.insert(e.stopx-r,e.starty,e.startx,e.stopy+a.height/2+nt.noteMargin),e.stopx=e.stopx+r):(ot.insert(e.startx,e.starty,e.stopx+r,e.stopy+a.height/2+nt.noteMargin),e.stopx=e.stopx-r)}function l(a,r){a.x<s.get(t.to).x?(ot.insert(e.startx-r,e.starty,e.stopx,e.stopy+a.height/2+nt.noteMargin),e.startx=e.startx+r):(ot.insert(e.stopx,e.starty,e.startx+r,e.stopy+a.height/2+nt.noteMargin),e.startx=e.startx-r)}(0,c.K2)(o,"receiverAdjustment"),(0,c.K2)(l,"senderAdjustment");const h=[y,m,T,b];if(i.get(t.to)==r){const e=s.get(t.to);o(e,h.includes(e.type)?21:e.width/2+3),e.starty=a-e.height/2,ot.bumpVerticalPos(e.height/2)}else if(n.get(t.from)==r){const e=s.get(t.from);if(nt.mirrorActors){l(e,h.includes(e.type)?18:e.width/2)}e.stopy=a-e.height/2,ot.bumpVerticalPos(e.height/2)}else if(n.get(t.to)==r){const e=s.get(t.to);if(nt.mirrorActors){o(e,h.includes(e.type)?21:e.width/2+3)}e.stopy=a-e.height/2,ot.bumpVerticalPos(e.height/2)}}(0,c.K2)(ft,"adjustLoopHeightForWrap"),(0,c.K2)(Et,"adjustCreatedDestroyedData");var wt=(0,c.K2)(async function(t,e,a,r){const{securityLevel:s,sequence:i}=(0,o.D7)();let n;nt=i,"sandbox"===s&&(n=(0,l.Ltv)("#i"+e));const h="sandbox"===s?(0,l.Ltv)(n.nodes()[0].contentDocument.body):(0,l.Ltv)("body"),d="sandbox"===s?n.nodes()[0].contentDocument:document;ot.init(),c.Rm.debug(r.db);const p="sandbox"===s?h.select(`[id="${e}"]`):(0,l.Ltv)(`[id="${e}"]`),g=r.db.getActors(),u=r.db.getCreatedActors(),x=r.db.getDestroyedActors(),y=r.db.getBoxes();let m=r.db.getActorKeys();const b=r.db.getMessages(),T=r.db.getDiagramTitle(),f=r.db.hasAtLeastOneBox(),E=r.db.hasAtLeastOneBoxWithTitle(),w=await It(g,b,r);if(nt.height=await _t(g,w,y),it.insertComputerIcon(p),it.insertDatabaseIcon(p),it.insertClockIcon(p),f&&(ot.bumpVerticalPos(nt.boxMargin),E&&ot.bumpVerticalPos(y[0].textMaxHeight)),!0===nt.hideUnusedParticipants){const t=new Set;b.forEach(e=>{t.add(e.from),t.add(e.to)}),m=m.filter(e=>t.has(e))}ut(p,g,u,m,0,b,!1);const I=await Nt(b,g,w,r);function L(t,e){const a=ot.endActivation(t);a.starty+18>e&&(a.starty=e-6,e+=12),it.drawActivation(p,a,e,nt,bt(t.from).length),ot.insert(a.startx,e-10,a.stopx,e)}it.insertArrowHead(p),it.insertArrowCrossHead(p),it.insertArrowFilledHead(p),it.insertSequenceNumber(p),(0,c.K2)(L,"activeEnd");let _=1,P=1;const k=[],N=[];let A=0;for(const o of b){let t,e,a;switch(o.type){case r.db.LINETYPE.NOTE:ot.resetVerticalPos(),e=o.noteModel,await ct(p,e);break;case r.db.LINETYPE.ACTIVE_START:ot.newActivation(o,p,g);break;case r.db.LINETYPE.ACTIVE_END:L(o,ot.getVerticalPos());break;case r.db.LINETYPE.LOOP_START:ft(I,o,nt.boxMargin,nt.boxMargin+nt.boxTextMargin,t=>ot.newLoop(t));break;case r.db.LINETYPE.LOOP_END:t=ot.endLoop(),await it.drawLoop(p,t,"loop",nt),ot.bumpVerticalPos(t.stopy-ot.getVerticalPos()),ot.models.addLoop(t);break;case r.db.LINETYPE.RECT_START:ft(I,o,nt.boxMargin,nt.boxMargin,t=>ot.newLoop(void 0,t.message));break;case r.db.LINETYPE.RECT_END:t=ot.endLoop(),N.push(t),ot.models.addLoop(t),ot.bumpVerticalPos(t.stopy-ot.getVerticalPos());break;case r.db.LINETYPE.OPT_START:ft(I,o,nt.boxMargin,nt.boxMargin+nt.boxTextMargin,t=>ot.newLoop(t));break;case r.db.LINETYPE.OPT_END:t=ot.endLoop(),await it.drawLoop(p,t,"opt",nt),ot.bumpVerticalPos(t.stopy-ot.getVerticalPos()),ot.models.addLoop(t);break;case r.db.LINETYPE.ALT_START:ft(I,o,nt.boxMargin,nt.boxMargin+nt.boxTextMargin,t=>ot.newLoop(t));break;case r.db.LINETYPE.ALT_ELSE:ft(I,o,nt.boxMargin+nt.boxTextMargin,nt.boxMargin,t=>ot.addSectionToLoop(t));break;case r.db.LINETYPE.ALT_END:t=ot.endLoop(),await it.drawLoop(p,t,"alt",nt),ot.bumpVerticalPos(t.stopy-ot.getVerticalPos()),ot.models.addLoop(t);break;case r.db.LINETYPE.PAR_START:case r.db.LINETYPE.PAR_OVER_START:ft(I,o,nt.boxMargin,nt.boxMargin+nt.boxTextMargin,t=>ot.newLoop(t)),ot.saveVerticalPos();break;case r.db.LINETYPE.PAR_AND:ft(I,o,nt.boxMargin+nt.boxTextMargin,nt.boxMargin,t=>ot.addSectionToLoop(t));break;case r.db.LINETYPE.PAR_END:t=ot.endLoop(),await it.drawLoop(p,t,"par",nt),ot.bumpVerticalPos(t.stopy-ot.getVerticalPos()),ot.models.addLoop(t);break;case r.db.LINETYPE.AUTONUMBER:_=o.message.start||_,P=o.message.step||P,o.message.visible?r.db.enableSequenceNumbers():r.db.disableSequenceNumbers();break;case r.db.LINETYPE.CRITICAL_START:ft(I,o,nt.boxMargin,nt.boxMargin+nt.boxTextMargin,t=>ot.newLoop(t));break;case r.db.LINETYPE.CRITICAL_OPTION:ft(I,o,nt.boxMargin+nt.boxTextMargin,nt.boxMargin,t=>ot.addSectionToLoop(t));break;case r.db.LINETYPE.CRITICAL_END:t=ot.endLoop(),await it.drawLoop(p,t,"critical",nt),ot.bumpVerticalPos(t.stopy-ot.getVerticalPos()),ot.models.addLoop(t);break;case r.db.LINETYPE.BREAK_START:ft(I,o,nt.boxMargin,nt.boxMargin+nt.boxTextMargin,t=>ot.newLoop(t));break;case r.db.LINETYPE.BREAK_END:t=ot.endLoop(),await it.drawLoop(p,t,"break",nt),ot.bumpVerticalPos(t.stopy-ot.getVerticalPos()),ot.models.addLoop(t);break;default:try{a=o.msgModel,a.starty=ot.getVerticalPos(),a.sequenceIndex=_,a.sequenceVisible=r.db.showSequenceNumbers();const t=await pt(0,a);Et(o,a,t,A,g,u,x),k.push({messageModel:a,lineStartY:t}),ot.models.addMessage(a)}catch(Y){c.Rm.error("error while drawing message",Y)}}[r.db.LINETYPE.SOLID_OPEN,r.db.LINETYPE.DOTTED_OPEN,r.db.LINETYPE.SOLID,r.db.LINETYPE.DOTTED,r.db.LINETYPE.SOLID_CROSS,r.db.LINETYPE.DOTTED_CROSS,r.db.LINETYPE.SOLID_POINT,r.db.LINETYPE.DOTTED_POINT,r.db.LINETYPE.BIDIRECTIONAL_SOLID,r.db.LINETYPE.BIDIRECTIONAL_DOTTED].includes(o.type)&&(_+=P),A++}c.Rm.debug("createdActors",u),c.Rm.debug("destroyedActors",x),await xt(p,g,m,!1);for(const o of k)await gt(p,o.messageModel,o.lineStartY,r);nt.mirrorActors&&await xt(p,g,m,!0),N.forEach(t=>it.drawBackgroundRect(p,t)),D(p,g,m,nt);for(const o of ot.models.boxes){o.height=ot.getVerticalPos()-o.y,ot.insert(o.x,o.y,o.x+o.width,o.height);const t=2*nt.boxMargin;o.startx=o.x-t,o.starty=o.y-.25*t,o.stopx=o.startx+o.width+2*t,o.stopy=o.starty+o.height+.75*t,o.stroke="rgb(0,0,0, 0.5)",it.drawBox(p,o,nt)}f&&ot.bumpVerticalPos(nt.boxMargin);const v=yt(p,g,m,d),{bounds:M}=ot.getBounds();void 0===M.startx&&(M.startx=0),void 0===M.starty&&(M.starty=0),void 0===M.stopx&&(M.stopx=0),void 0===M.stopy&&(M.stopy=0);let O=M.stopy-M.starty;O<v.maxHeight&&(O=v.maxHeight);let S=O+2*nt.diagramMarginY;nt.mirrorActors&&(S=S-nt.boxMargin+nt.bottomMarginAdj);let R=M.stopx-M.startx;R<v.maxWidth&&(R=v.maxWidth);const $=R+2*nt.diagramMarginX;T&&p.append("text").text(T).attr("x",(M.stopx-M.startx)/2-2*nt.diagramMarginX).attr("y",-25),(0,o.a$)(p,S,$,nt.useMaxWidth);const C=T?40:0;p.attr("viewBox",M.startx-nt.diagramMarginX+" -"+(nt.diagramMarginY+C)+" "+$+" "+(S+C)),c.Rm.debug("models:",ot.models)},"draw");async function It(t,e,a){const r={};for(const s of e)if(t.get(s.to)&&t.get(s.from)){const e=t.get(s.to);if(s.placement===a.db.PLACEMENT.LEFTOF&&!e.prevActor)continue;if(s.placement===a.db.PLACEMENT.RIGHTOF&&!e.nextActor)continue;const i=void 0!==s.placement,c=!i,l=i?ht(nt):lt(nt),h=s.wrap?n._K.wrapLabel(s.message,nt.width-2*nt.wrapPadding,l):s.message,d=((0,o.Wi)(h)?await(0,o.Dl)(s.message,(0,o.D7)()):n._K.calculateTextDimensions(h,l)).width+2*nt.wrapPadding;c&&s.from===e.nextActor?r[s.to]=o.Y2.getMax(r[s.to]||0,d):c&&s.from===e.prevActor?r[s.from]=o.Y2.getMax(r[s.from]||0,d):c&&s.from===s.to?(r[s.from]=o.Y2.getMax(r[s.from]||0,d/2),r[s.to]=o.Y2.getMax(r[s.to]||0,d/2)):s.placement===a.db.PLACEMENT.RIGHTOF?r[s.from]=o.Y2.getMax(r[s.from]||0,d):s.placement===a.db.PLACEMENT.LEFTOF?r[e.prevActor]=o.Y2.getMax(r[e.prevActor]||0,d):s.placement===a.db.PLACEMENT.OVER&&(e.prevActor&&(r[e.prevActor]=o.Y2.getMax(r[e.prevActor]||0,d/2)),e.nextActor&&(r[s.from]=o.Y2.getMax(r[s.from]||0,d/2)))}return c.Rm.debug("maxMessageWidthPerActor:",r),r}(0,c.K2)(It,"getMaxMessageWidthPerActor");var Lt=(0,c.K2)(function(t){let e=0;const a=dt(nt);for(const r in t.links){const t=n._K.calculateTextDimensions(r,a).width+2*nt.wrapPadding+2*nt.boxMargin;e<t&&(e=t)}return e},"getRequiredPopupWidth");async function _t(t,e,a){let r=0;for(const i of t.keys()){const e=t.get(i);e.wrap&&(e.description=n._K.wrapLabel(e.description,nt.width-2*nt.wrapPadding,dt(nt)));const a=(0,o.Wi)(e.description)?await(0,o.Dl)(e.description,(0,o.D7)()):n._K.calculateTextDimensions(e.description,dt(nt));e.width=e.wrap?nt.width:o.Y2.getMax(nt.width,a.width+2*nt.wrapPadding),e.height=e.wrap?o.Y2.getMax(a.height,nt.height):nt.height,r=o.Y2.getMax(r,e.height)}for(const i in e){const a=t.get(i);if(!a)continue;const r=t.get(a.nextActor);if(!r){const t=e[i]+nt.actorMargin-a.width/2;a.margin=o.Y2.getMax(t,nt.actorMargin);continue}const s=e[i]+nt.actorMargin-a.width/2-r.width/2;a.margin=o.Y2.getMax(s,nt.actorMargin)}let s=0;return a.forEach(e=>{const a=lt(nt);let r=e.actorKeys.reduce((e,a)=>e+(t.get(a).width+(t.get(a).margin||0)),0);r+=8*nt.boxMargin,r-=2*nt.boxTextMargin,e.wrap&&(e.name=n._K.wrapLabel(e.name,r-2*nt.wrapPadding,a));const i=n._K.calculateTextDimensions(e.name,a);s=o.Y2.getMax(i.height,s);const c=o.Y2.getMax(r,i.width+2*nt.wrapPadding);if(e.margin=nt.boxTextMargin,r<c){const t=(c-r)/2;e.margin+=t}}),a.forEach(t=>t.textMaxHeight=s),o.Y2.getMax(r,nt.height)}(0,c.K2)(_t,"calculateActorMargins");var Pt=(0,c.K2)(async function(t,e,a){const r=e.get(t.from),s=e.get(t.to),i=r.x,l=s.x,h=t.wrap&&t.message;let d=(0,o.Wi)(t.message)?await(0,o.Dl)(t.message,(0,o.D7)()):n._K.calculateTextDimensions(h?n._K.wrapLabel(t.message,nt.width,ht(nt)):t.message,ht(nt));const p={width:h?nt.width:o.Y2.getMax(nt.width,d.width+2*nt.noteMargin),height:0,startx:r.x,stopx:0,starty:0,stopy:0,message:t.message};return t.placement===a.db.PLACEMENT.RIGHTOF?(p.width=h?o.Y2.getMax(nt.width,d.width):o.Y2.getMax(r.width/2+s.width/2,d.width+2*nt.noteMargin),p.startx=i+(r.width+nt.actorMargin)/2):t.placement===a.db.PLACEMENT.LEFTOF?(p.width=h?o.Y2.getMax(nt.width,d.width+2*nt.noteMargin):o.Y2.getMax(r.width/2+s.width/2,d.width+2*nt.noteMargin),p.startx=i-p.width+(r.width-nt.actorMargin)/2):t.to===t.from?(d=n._K.calculateTextDimensions(h?n._K.wrapLabel(t.message,o.Y2.getMax(nt.width,r.width),ht(nt)):t.message,ht(nt)),p.width=h?o.Y2.getMax(nt.width,r.width):o.Y2.getMax(r.width,nt.width,d.width+2*nt.noteMargin),p.startx=i+(r.width-p.width)/2):(p.width=Math.abs(i+r.width/2-(l+s.width/2))+nt.actorMargin,p.startx=i<l?i+r.width/2-nt.actorMargin/2:l+s.width/2-nt.actorMargin/2),h&&(p.message=n._K.wrapLabel(t.message,p.width-2*nt.wrapPadding,ht(nt))),c.Rm.debug(`NM:[${p.startx},${p.stopx},${p.starty},${p.stopy}:${p.width},${p.height}=${t.message}]`),p},"buildNoteModel"),kt=(0,c.K2)(function(t,e,a){if(![a.db.LINETYPE.SOLID_OPEN,a.db.LINETYPE.DOTTED_OPEN,a.db.LINETYPE.SOLID,a.db.LINETYPE.DOTTED,a.db.LINETYPE.SOLID_CROSS,a.db.LINETYPE.DOTTED_CROSS,a.db.LINETYPE.SOLID_POINT,a.db.LINETYPE.DOTTED_POINT,a.db.LINETYPE.BIDIRECTIONAL_SOLID,a.db.LINETYPE.BIDIRECTIONAL_DOTTED].includes(t.type))return{};const[r,s]=Tt(t.from,e),[i,l]=Tt(t.to,e),h=r<=i;let d=h?s:r,p=h?i:l;const g=Math.abs(i-l)>2,u=(0,c.K2)(t=>h?-t:t,"adjustValue");t.from===t.to?p=d:(t.activate&&!g&&(p+=u(nt.activationWidth/2-1)),[a.db.LINETYPE.SOLID_OPEN,a.db.LINETYPE.DOTTED_OPEN].includes(t.type)||(p+=u(3)),[a.db.LINETYPE.BIDIRECTIONAL_SOLID,a.db.LINETYPE.BIDIRECTIONAL_DOTTED].includes(t.type)&&(d-=u(3)));const x=[r,s,i,l],y=Math.abs(d-p);t.wrap&&t.message&&(t.message=n._K.wrapLabel(t.message,o.Y2.getMax(y+2*nt.wrapPadding,nt.width),lt(nt)));const m=n._K.calculateTextDimensions(t.message,lt(nt));return{width:o.Y2.getMax(t.wrap?0:m.width+2*nt.wrapPadding,y+2*nt.wrapPadding,nt.width),height:0,startx:d,stopx:p,starty:0,stopy:0,message:t.message,type:t.type,wrap:t.wrap,fromBounds:Math.min.apply(null,x),toBounds:Math.max.apply(null,x)}},"buildMessageModel"),Nt=(0,c.K2)(async function(t,e,a,r){const s={},i=[];let n,l,h;for(const c of t){switch(c.type){case r.db.LINETYPE.LOOP_START:case r.db.LINETYPE.ALT_START:case r.db.LINETYPE.OPT_START:case r.db.LINETYPE.PAR_START:case r.db.LINETYPE.PAR_OVER_START:case r.db.LINETYPE.CRITICAL_START:case r.db.LINETYPE.BREAK_START:i.push({id:c.id,msg:c.message,from:Number.MAX_SAFE_INTEGER,to:Number.MIN_SAFE_INTEGER,width:0});break;case r.db.LINETYPE.ALT_ELSE:case r.db.LINETYPE.PAR_AND:case r.db.LINETYPE.CRITICAL_OPTION:c.message&&(n=i.pop(),s[n.id]=n,s[c.id]=n,i.push(n));break;case r.db.LINETYPE.LOOP_END:case r.db.LINETYPE.ALT_END:case r.db.LINETYPE.OPT_END:case r.db.LINETYPE.PAR_END:case r.db.LINETYPE.CRITICAL_END:case r.db.LINETYPE.BREAK_END:n=i.pop(),s[n.id]=n;break;case r.db.LINETYPE.ACTIVE_START:{const t=e.get(c.from?c.from:c.to.actor),a=bt(c.from?c.from:c.to.actor).length,r=t.x+t.width/2+(a-1)*nt.activationWidth/2,s={startx:r,stopx:r+nt.activationWidth,actor:c.from,enabled:!0};ot.activations.push(s)}break;case r.db.LINETYPE.ACTIVE_END:{const t=ot.activations.map(t=>t.actor).lastIndexOf(c.from);ot.activations.splice(t,1).splice(0,1)}}void 0!==c.placement?(l=await Pt(c,e,r),c.noteModel=l,i.forEach(t=>{n=t,n.from=o.Y2.getMin(n.from,l.startx),n.to=o.Y2.getMax(n.to,l.startx+l.width),n.width=o.Y2.getMax(n.width,Math.abs(n.from-n.to))-nt.labelBoxWidth})):(h=kt(c,e,r),c.msgModel=h,h.startx&&h.stopx&&i.length>0&&i.forEach(t=>{if(n=t,h.startx===h.stopx){const t=e.get(c.from),a=e.get(c.to);n.from=o.Y2.getMin(t.x-h.width/2,t.x-t.width/2,n.from),n.to=o.Y2.getMax(a.x+h.width/2,a.x+t.width/2,n.to),n.width=o.Y2.getMax(n.width,Math.abs(n.to-n.from))-nt.labelBoxWidth}else n.from=o.Y2.getMin(h.startx,n.from),n.to=o.Y2.getMax(h.stopx,n.to),n.width=o.Y2.getMax(n.width,h.width)-nt.labelBoxWidth}))}return ot.activations=[],c.Rm.debug("Loop type widths:",s),s},"calculateLoopBounds"),At={bounds:ot,drawActors:xt,drawActorsPopup:yt,setConf:mt,draw:wt},vt={parser:p,get db(){return new f},renderer:At,styles:E,init:(0,c.K2)(t=>{t.sequence||(t.sequence={}),t.wrap&&(t.sequence.wrap=t.wrap,(0,o.XV)({sequence:{wrap:t.wrap}}))},"init")}},72938:(t,e,a)=>{a.d(e,{m:()=>s});var r=a(40797),s=class{constructor(t){this.init=t,this.records=this.init()}static{(0,r.K2)(this,"ImperativeState")}reset(){this.records=this.init()}}},92875:(t,e,a)=>{a.d(e,{CP:()=>h,HT:()=>p,PB:()=>d,aC:()=>l,lC:()=>o,m:()=>c,tk:()=>n});var r=a(67633),s=a(40797),i=a(16750),n=(0,s.K2)((t,e)=>{const a=t.append("rect");if(a.attr("x",e.x),a.attr("y",e.y),a.attr("fill",e.fill),a.attr("stroke",e.stroke),a.attr("width",e.width),a.attr("height",e.height),e.name&&a.attr("name",e.name),e.rx&&a.attr("rx",e.rx),e.ry&&a.attr("ry",e.ry),void 0!==e.attrs)for(const r in e.attrs)a.attr(r,e.attrs[r]);return e.class&&a.attr("class",e.class),a},"drawRect"),o=(0,s.K2)((t,e)=>{const a={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};n(t,a).lower()},"drawBackgroundRect"),c=(0,s.K2)((t,e)=>{const a=e.text.replace(r.H1," "),s=t.append("text");s.attr("x",e.x),s.attr("y",e.y),s.attr("class","legend"),s.style("text-anchor",e.anchor),e.class&&s.attr("class",e.class);const i=s.append("tspan");return i.attr("x",e.x+2*e.textMargin),i.text(a),s},"drawText"),l=(0,s.K2)((t,e,a,r)=>{const s=t.append("image");s.attr("x",e),s.attr("y",a);const n=(0,i.J)(r);s.attr("xlink:href",n)},"drawImage"),h=(0,s.K2)((t,e,a,r)=>{const s=t.append("use");s.attr("x",e),s.attr("y",a);const n=(0,i.J)(r);s.attr("xlink:href",`#${n}`)},"drawEmbeddedImage"),d=(0,s.K2)(()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),"getNoteRect"),p=(0,s.K2)(()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0}),"getTextObj")}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/75a3ea9f.4aa32bc7.js b/pr-preview/pr-4027/assets/js/75a3ea9f.4aa32bc7.js deleted file mode 100644 index ea6228dc2..000000000 --- a/pr-preview/pr-4027/assets/js/75a3ea9f.4aa32bc7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3132],{28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>i});var o=n(96540);const s={},a=o.createContext(s);function r(e){const t=o.useContext(a);return o.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(a.Provider,{value:t},e.children)}},43916:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>r,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"workflows/cert-manager","title":"Install cert-manager","description":"If you want to use cert-manager with Constellation, pay attention to the following to avoid potential pitfalls.","source":"@site/versioned_docs/version-2.23/workflows/cert-manager.md","sourceDirName":"workflows","slug":"/workflows/cert-manager","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/cert-manager","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/workflows/cert-manager.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Expose a service","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/lb"},"next":{"title":"Install s3proxy","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/s3proxy"}}');var s=n(74848),a=n(28453);const r={},i="Install cert-manager",l={},c=[];function d(e){const t={admonition:"admonition",code:"code",h1:"h1",header:"header",p:"p",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"install-cert-manager",children:"Install cert-manager"})}),"\n",(0,s.jsx)(t.admonition,{type:"caution",children:(0,s.jsx)(t.p,{children:"If you want to use cert-manager with Constellation, pay attention to the following to avoid potential pitfalls."})}),"\n",(0,s.jsxs)(t.p,{children:["Constellation ships with cert-manager preinstalled.\nThe default installation is part of the ",(0,s.jsx)(t.code,{children:"kube-system"})," namespace, as all other Constellation-managed microservices.\nYou are free to install more instances of cert-manager into other namespaces.\nHowever, be aware that any new installation needs to use the same version as the one installed with Constellation or rely on the same CRD versions.\nAlso remember to set the ",(0,s.jsx)(t.code,{children:"installCRDs"})," value to ",(0,s.jsx)(t.code,{children:"false"})," when installing new cert-manager instances.\nIt will create problems if you have two installations of cert-manager depending on different versions of the installed CRDs.\nCRDs are cluster-wide resources and cert-manager depends on specific versions of those CRDs for each release."]})]})}function p(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/76b2ab15.bf48cdb7.js b/pr-preview/pr-4027/assets/js/76b2ab15.bf48cdb7.js deleted file mode 100644 index 7e6418999..000000000 --- a/pr-preview/pr-4027/assets/js/76b2ab15.bf48cdb7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1415],{19645:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>m,frontMatter:()=>a,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"overview/performance/performance","title":"Performance analysis of Constellation","description":"This section provides a comprehensive examination of the performance characteristics of Constellation.","source":"@site/docs/overview/performance/performance.md","sourceDirName":"overview/performance","slug":"/overview/performance/","permalink":"/constellation/pr-preview/pr-4027/next/overview/performance/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/overview/performance/performance.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Feature status of clouds","permalink":"/constellation/pr-preview/pr-4027/next/overview/clouds"},"next":{"title":"Compute benchmarks","permalink":"/constellation/pr-preview/pr-4027/next/overview/performance/compute"}}');var t=o(74848),i=o(28453);const a={},s="Performance analysis of Constellation",c={},l=[{value:"Runtime encryption",id:"runtime-encryption",level:2},{value:"I/O performance benchmarks",id:"io-performance-benchmarks",level:2},{value:"Application benchmarking",id:"application-benchmarking",level:2}];function p(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"performance-analysis-of-constellation",children:"Performance analysis of Constellation"})}),"\n",(0,t.jsx)(n.p,{children:"This section provides a comprehensive examination of the performance characteristics of Constellation."}),"\n",(0,t.jsx)(n.h2,{id:"runtime-encryption",children:"Runtime encryption"}),"\n",(0,t.jsxs)(n.p,{children:["Runtime encryption affects compute performance. ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/overview/performance/compute",children:"Benchmarks by Azure and Google"})," show that the performance degradation of Confidential VMs (CVMs) is small, ranging from 2% to 8% for compute-intensive workloads."]}),"\n",(0,t.jsx)(n.h2,{id:"io-performance-benchmarks",children:"I/O performance benchmarks"}),"\n",(0,t.jsxs)(n.p,{children:["We evaluated the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/overview/performance/io",children:"I/O performance"})," of Constellation, utilizing a collection of synthetic benchmarks targeting networking and storage.\nWe further compared this performance to native managed Kubernetes offerings from various cloud providers, to better understand how Constellation stands in relation to standard practices."]}),"\n",(0,t.jsx)(n.h2,{id:"application-benchmarking",children:"Application benchmarking"}),"\n",(0,t.jsxs)(n.p,{children:["To gauge Constellation's applicability to well-known applications, we performed a ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/overview/performance/application",children:"benchmark of HashiCorp Vault"})," running on Constellation.\nThe results were then compared to deployments on the managed Kubernetes offerings from different cloud providers, providing a tangible perspective on Constellation's performance in actual deployment scenarios."]})]})}function m(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>a,x:()=>s});var r=o(96540);const t={},i=r.createContext(t);function a(e){const n=r.useContext(i);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/76f884e3.86f1f394.js b/pr-preview/pr-4027/assets/js/76f884e3.86f1f394.js deleted file mode 100644 index 211eb32bc..000000000 --- a/pr-preview/pr-4027/assets/js/76f884e3.86f1f394.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9766],{21798:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"getting-started/examples","title":"Examples","description":"After you installed the CLI and created your first cluster, you\'re ready to deploy applications. Why not start with one of the following examples?","source":"@site/versioned_docs/version-2.23/getting-started/examples.md","sourceDirName":"getting-started","slug":"/getting-started/examples","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/getting-started/examples.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Cloud Marketplaces","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/marketplaces"},"next":{"title":"Emojivoto","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/emojivoto"}}');var o=n(74848),i=n(28453);const r={},a="Examples",l={},c=[];function p(e){const t={a:"a",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"examples",children:"Examples"})}),"\n",(0,o.jsxs)(t.p,{children:["After you ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/install",children:"installed the CLI"})," and ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps",children:"created your first cluster"}),", you're ready to deploy applications. Why not start with one of the following examples?"]}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/emojivoto",children:"Emojivoto"}),": a simple but fun web application"]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/online-boutique",children:"Online Boutique"}),": an e-commerce demo application by Google consisting of 11 separate microservices"]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/horizontal-scaling",children:"Horizontal Pod Autoscaling"}),": an example demonstrating Constellation's autoscaling capabilities"]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var s=n(96540);const o={},i=s.createContext(o);function r(e){const t=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/786b68f5.8a000b59.js b/pr-preview/pr-4027/assets/js/786b68f5.8a000b59.js deleted file mode 100644 index 105c6c3fb..000000000 --- a/pr-preview/pr-4027/assets/js/786b68f5.8a000b59.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3539],{89016:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Workflows","slug":"/category/workflows","permalink":"/constellation/pr-preview/pr-4027/next/category/workflows","sidebar":"docs","navigation":{"previous":{"title":"Filestash with s3proxy","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/examples/filestash-s3proxy"},"next":{"title":"Verify the CLI","permalink":"/constellation/pr-preview/pr-4027/next/workflows/verify-cli"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/786c60fb.d7dfd23a.js b/pr-preview/pr-4027/assets/js/786c60fb.d7dfd23a.js deleted file mode 100644 index 461774388..000000000 --- a/pr-preview/pr-4027/assets/js/786c60fb.d7dfd23a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[253],{28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var s=n(96540);const r={},i=s.createContext(r);function a(e){const t=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:t},e.children)}},30850:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/tcb-424516bbf9d20afe12576bc1305ebc29.svg"},83789:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"overview/security-benefits","title":"Security benefits and threat model","description":"Constellation implements the Confidential Kubernetes concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be verified.","source":"@site/docs/overview/security-benefits.md","sourceDirName":"overview","slug":"/overview/security-benefits","permalink":"/constellation/pr-preview/pr-4027/next/overview/security-benefits","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/overview/security-benefits.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential Kubernetes","permalink":"/constellation/pr-preview/pr-4027/next/overview/confidential-kubernetes"},"next":{"title":"Product features","permalink":"/constellation/pr-preview/pr-4027/next/overview/product"}}');var r=n(74848),i=n(28453);const a={},o="Security benefits and threat model",c={},l=[{value:"Insider access",id:"insider-access",level:2},{value:"Infrastructure-based attacks",id:"infrastructure-based-attacks",level:2},{value:"Supply chain attacks",id:"supply-chain-attacks",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",p:"p",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"security-benefits-and-threat-model",children:"Security benefits and threat model"})}),"\n",(0,r.jsxs)(t.p,{children:["Constellation implements the ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/overview/confidential-kubernetes",children:"Confidential Kubernetes"})," concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the ",(0,r.jsx)(t.em,{children:"cloud & datacenter infrastructure"})," and the ",(0,r.jsx)(t.em,{children:"physical hosts"}),", including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/verify-cluster",children:"verified"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"TCB comparison",src:n(30850).A+"",width:"3988",height:"1380"})}),"\n",(0,r.jsx)(t.p,{children:"Given this background, the following describes the concrete threat classes that Constellation addresses."}),"\n",(0,r.jsx)(t.h2,{id:"insider-access",children:"Insider access"}),"\n",(0,r.jsx)(t.p,{children:"Employees and third-party contractors of cloud service providers (CSPs) have access to different layers of the cloud infrastructure.\nThis opens up a large attack surface where workloads and data can be read, copied, or manipulated. With Constellation, Kubernetes deployments are shielded from the infrastructure and thus such accesses are prevented."}),"\n",(0,r.jsx)(t.h2,{id:"infrastructure-based-attacks",children:"Infrastructure-based attacks"}),"\n",(0,r.jsxs)(t.p,{children:['Malicious cloud users ("hackers") may break out of their tenancy and access other tenants\' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. Analogously to the ',(0,r.jsx)(t.em,{children:"insider access"})," scenario, Constellation also prevents access to a deployment's data in this scenario."]}),"\n",(0,r.jsx)(t.h2,{id:"supply-chain-attacks",children:"Supply chain attacks"}),"\n",(0,r.jsxs)(t.p,{children:["Supply chain security is receiving lots of attention recently due to an ",(0,r.jsx)(t.a,{href:"https://www.enisa.europa.eu/news/enisa-news/understanding-the-increase-in-supply-chain-security-attacks",children:"increasing number of recorded attacks"}),". For instance, a malicious actor could attempt to tamper Constellation node images (including Kubernetes and other software) before they're loaded in the confidential VMs of a cluster. Constellation uses ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/attestation",children:"remote attestation"})," in conjunction with public ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/verify-cli",children:"transparency logs"})," to prevent this."]}),"\n",(0,r.jsx)(t.p,{children:"In the future, Constellation will extend this feature to customer workloads. This will enable cluster owners to create auditable policies that precisely define which containers can run in a given deployment."})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/7873.2b83eb4c.js b/pr-preview/pr-4027/assets/js/7873.2b83eb4c.js deleted file mode 100644 index 0b26d156b..000000000 --- a/pr-preview/pr-4027/assets/js/7873.2b83eb4c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7873],{50053:(e,n,t)=>{t.d(n,{A:()=>i});var r=t(68675);const i=function(e){return(0,r.A)(e,4)}},57873:(e,n,t)=>{t.r(n),t.d(n,{render:()=>k});var r=t(5164),i=(t(28698),t(5894)),a=t(63245),o=(t(32387),t(30092),t(13226),t(67633)),d=t(40797),s=t(62334),c=t(69592),g=t(50053),l=t(74722);t(37981);function f(e){var n={options:{directed:e.isDirected(),multigraph:e.isMultigraph(),compound:e.isCompound()},nodes:h(e),edges:p(e)};return c.A(e.graph())||(n.value=g.A(e.graph())),n}function h(e){return l.A(e.nodes(),function(n){var t=e.node(n),r=e.parent(n),i={v:n};return c.A(t)||(i.value=t),c.A(r)||(i.parent=r),i})}function p(e){return l.A(e.edges(),function(n){var t=e.edge(n),r={v:n.v,w:n.w};return c.A(n.name)||(r.name=n.name),c.A(t)||(r.value=t),r})}var u=t(697),m=new Map,w=new Map,R=new Map,v=(0,d.K2)(()=>{w.clear(),R.clear(),m.clear()},"clear"),y=(0,d.K2)((e,n)=>{const t=w.get(n)||[];return d.Rm.trace("In isDescendant",n," ",e," = ",t.includes(e)),t.includes(e)},"isDescendant"),X=(0,d.K2)((e,n)=>{const t=w.get(n)||[];return d.Rm.info("Descendants of ",n," is ",t),d.Rm.info("Edge is ",e),e.v!==n&&e.w!==n&&(t?t.includes(e.v)||y(e.v,n)||y(e.w,n)||t.includes(e.w):(d.Rm.debug("Tilt, ",n,",not in descendants"),!1))},"edgeInCluster"),b=(0,d.K2)((e,n,t,r)=>{d.Rm.warn("Copying children of ",e,"root",r,"data",n.node(e),r);const i=n.children(e)||[];e!==r&&i.push(e),d.Rm.warn("Copying (nodes) clusterId",e,"nodes",i),i.forEach(i=>{if(n.children(i).length>0)b(i,n,t,r);else{const a=n.node(i);d.Rm.info("cp ",i," to ",r," with parent ",e),t.setNode(i,a),r!==n.parent(i)&&(d.Rm.warn("Setting parent",i,n.parent(i)),t.setParent(i,n.parent(i))),e!==r&&i!==e?(d.Rm.debug("Setting parent",i,e),t.setParent(i,e)):(d.Rm.info("In copy ",e,"root",r,"data",n.node(e),r),d.Rm.debug("Not Setting parent for node=",i,"cluster!==rootId",e!==r,"node!==clusterId",i!==e));const o=n.edges(i);d.Rm.debug("Copying Edges",o),o.forEach(i=>{d.Rm.info("Edge",i);const a=n.edge(i.v,i.w,i.name);d.Rm.info("Edge data",a,r);try{X(i,r)?(d.Rm.info("Copying as ",i.v,i.w,a,i.name),t.setEdge(i.v,i.w,a,i.name),d.Rm.info("newGraph edges ",t.edges(),t.edge(t.edges()[0]))):d.Rm.info("Skipping copy of edge ",i.v,"--\x3e",i.w," rootId: ",r," clusterId:",e)}catch(o){d.Rm.error(o)}})}d.Rm.debug("Removing node",i),n.removeNode(i)})},"copy"),E=(0,d.K2)((e,n)=>{const t=n.children(e);let r=[...t];for(const i of t)R.set(i,e),r=[...r,...E(i,n)];return r},"extractDescendants"),N=(0,d.K2)((e,n,t)=>{const r=e.edges().filter(e=>e.v===n||e.w===n),i=e.edges().filter(e=>e.v===t||e.w===t),a=r.map(e=>({v:e.v===n?t:e.v,w:e.w===n?n:e.w})),o=i.map(e=>({v:e.v,w:e.w}));return a.filter(e=>o.some(n=>e.v===n.v&&e.w===n.w))},"findCommonEdges"),C=(0,d.K2)((e,n,t)=>{const r=n.children(e);if(d.Rm.trace("Searching children of id ",e,r),r.length<1)return e;let i;for(const a of r){const e=C(a,n,t),r=N(n,t,e);if(e){if(!(r.length>0))return e;i=e}}return i},"findNonClusterChild"),S=(0,d.K2)(e=>m.has(e)&&m.get(e).externalConnections&&m.has(e)?m.get(e).id:e,"getAnchorId"),x=(0,d.K2)((e,n)=>{if(!e||n>10)d.Rm.debug("Opting out, no graph ");else{d.Rm.debug("Opting in, graph "),e.nodes().forEach(function(n){e.children(n).length>0&&(d.Rm.warn("Cluster identified",n," Replacement id in edges: ",C(n,e,n)),w.set(n,E(n,e)),m.set(n,{id:C(n,e,n),clusterData:e.node(n)}))}),e.nodes().forEach(function(n){const t=e.children(n),r=e.edges();t.length>0?(d.Rm.debug("Cluster identified",n,w),r.forEach(e=>{y(e.v,n)^y(e.w,n)&&(d.Rm.warn("Edge: ",e," leaves cluster ",n),d.Rm.warn("Descendants of XXX ",n,": ",w.get(n)),m.get(n).externalConnections=!0)})):d.Rm.debug("Not a cluster ",n,w)});for(let n of m.keys()){const t=m.get(n).id,r=e.parent(t);r!==n&&m.has(r)&&!m.get(r).externalConnections&&(m.get(n).id=r)}e.edges().forEach(function(n){const t=e.edge(n);d.Rm.warn("Edge "+n.v+" -> "+n.w+": "+JSON.stringify(n)),d.Rm.warn("Edge "+n.v+" -> "+n.w+": "+JSON.stringify(e.edge(n)));let r=n.v,i=n.w;if(d.Rm.warn("Fix XXX",m,"ids:",n.v,n.w,"Translating: ",m.get(n.v)," --- ",m.get(n.w)),m.get(n.v)||m.get(n.w)){if(d.Rm.warn("Fixing and trying - removing XXX",n.v,n.w,n.name),r=S(n.v),i=S(n.w),e.removeEdge(n.v,n.w,n.name),r!==n.v){const i=e.parent(r);m.get(i).externalConnections=!0,t.fromCluster=n.v}if(i!==n.w){const r=e.parent(i);m.get(r).externalConnections=!0,t.toCluster=n.w}d.Rm.warn("Fix Replacing with XXX",r,i,n.name),e.setEdge(r,i,t,n.name)}}),d.Rm.warn("Adjusted Graph",f(e)),I(e,0),d.Rm.trace(m)}},"adjustClustersAndEdges"),I=(0,d.K2)((e,n)=>{if(d.Rm.warn("extractor - ",n,f(e),e.children("D")),n>10)return void d.Rm.error("Bailing out");let t=e.nodes(),r=!1;for(const i of t){const n=e.children(i);r=r||n.length>0}if(r){d.Rm.debug("Nodes = ",t,n);for(const r of t)if(d.Rm.debug("Extracting node",r,m,m.has(r)&&!m.get(r).externalConnections,!e.parent(r),e.node(r),e.children("D")," Depth ",n),m.has(r))if(!m.get(r).externalConnections&&e.children(r)&&e.children(r).length>0){d.Rm.warn("Cluster without external connections, without a parent and with children",r,n);let t="TB"===e.graph().rankdir?"LR":"TB";m.get(r)?.clusterData?.dir&&(t=m.get(r).clusterData.dir,d.Rm.warn("Fixing dir",m.get(r).clusterData.dir,t));const i=new u.T({multigraph:!0,compound:!0}).setGraph({rankdir:t,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}});d.Rm.warn("Old graph before copy",f(e)),b(r,e,i,r),e.setNode(r,{clusterNode:!0,id:r,clusterData:m.get(r).clusterData,label:m.get(r).label,graph:i}),d.Rm.warn("New graph after copy node: (",r,")",f(i)),d.Rm.debug("Old graph after copy",f(e))}else d.Rm.warn("Cluster ** ",r," **not meeting the criteria !externalConnections:",!m.get(r).externalConnections," no parent: ",!e.parent(r)," children ",e.children(r)&&e.children(r).length>0,e.children("D"),n),d.Rm.debug(m);else d.Rm.debug("Not a cluster",r,n);t=e.nodes(),d.Rm.warn("New list of nodes",t);for(const r of t){const t=e.node(r);d.Rm.warn(" Now next level",r,t),t?.clusterNode&&I(t.graph,n+1)}}else d.Rm.debug("Done, no node has children",e.nodes())},"extractor"),D=(0,d.K2)((e,n)=>{if(0===n.length)return[];let t=Object.assign([],n);return n.forEach(n=>{const r=e.children(n),i=D(e,r);t=[...t,...i]}),t},"sorter"),A=(0,d.K2)(e=>D(e,e.children()),"sortNodesByHierarchy"),O=(0,d.K2)(async(e,n,t,o,c,g)=>{d.Rm.warn("Graph in recursive render:XAX",f(n),c);const l=n.graph().rankdir;d.Rm.trace("Dir in recursive render - dir:",l);const h=e.insert("g").attr("class","root");n.nodes()?d.Rm.info("Recursive render XXX",n.nodes()):d.Rm.info("No nodes found for",n),n.edges().length>0&&d.Rm.info("Recursive edges",n.edge(n.edges()[0]));const p=h.insert("g").attr("class","clusters"),u=h.insert("g").attr("class","edgePaths"),w=h.insert("g").attr("class","edgeLabels"),R=h.insert("g").attr("class","nodes");await Promise.all(n.nodes().map(async function(e){const r=n.node(e);if(void 0!==c){const t=JSON.parse(JSON.stringify(c.clusterData));d.Rm.trace("Setting data for parent cluster XXX\n Node.id = ",e,"\n data=",t.height,"\nParent cluster",c.height),n.setNode(c.id,t),n.parent(e)||(d.Rm.trace("Setting parent",e,c.id),n.setParent(e,c.id,t))}if(d.Rm.info("(Insert) Node XXX"+e+": "+JSON.stringify(n.node(e))),r?.clusterNode){d.Rm.info("Cluster identified XBX",e,r.width,n.node(e));const{ranksep:a,nodesep:s}=n.graph();r.graph.setGraph({...r.graph.graph(),ranksep:a+25,nodesep:s});const c=await O(R,r.graph,t,o,n.node(e),g),l=c.elem;(0,i.lC)(r,l),r.diff=c.diff||0,d.Rm.info("New compound node after recursive render XAX",e,"width",r.width,"height",r.height),(0,i.U7)(l,r)}else n.children(e).length>0?(d.Rm.trace("Cluster - the non recursive path XBX",e,r.id,r,r.width,"Graph:",n),d.Rm.trace(C(r.id,n)),m.set(r.id,{id:C(r.id,n),node:r})):(d.Rm.trace("Node - the non recursive path XAX",e,R,n.node(e),l),await(0,i.on)(R,n.node(e),{config:g,dir:l}))}));const v=(0,d.K2)(async()=>{const e=n.edges().map(async function(e){const t=n.edge(e.v,e.w,e.name);d.Rm.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(e)),d.Rm.info("Edge "+e.v+" -> "+e.w+": ",e," ",JSON.stringify(n.edge(e))),d.Rm.info("Fix",m,"ids:",e.v,e.w,"Translating: ",m.get(e.v),m.get(e.w)),await(0,r.jP)(w,t)});await Promise.all(e)},"processEdges");await v(),d.Rm.info("Graph before layout:",JSON.stringify(f(n))),d.Rm.info("############################################# XXX"),d.Rm.info("### Layout ### XXX"),d.Rm.info("############################################# XXX"),(0,s.Zp)(n),d.Rm.info("Graph after layout:",JSON.stringify(f(n)));let y=0,{subGraphTitleTotalMargin:X}=(0,a.O)(g);return await Promise.all(A(n).map(async function(e){const t=n.node(e);if(d.Rm.info("Position XBX => "+e+": ("+t.x,","+t.y,") width: ",t.width," height: ",t.height),t?.clusterNode)t.y+=X,d.Rm.info("A tainted cluster node XBX1",e,t.id,t.width,t.height,t.x,t.y,n.parent(e)),m.get(t.id).node=t,(0,i.U_)(t);else if(n.children(e).length>0){d.Rm.info("A pure cluster node XBX1",e,t.id,t.x,t.y,t.width,t.height,n.parent(e)),t.height+=X,n.node(t.parentId);const r=t?.padding/2||0,a=t?.labelBBox?.height||0,o=a-r||0;d.Rm.debug("OffsetY",o,"labelHeight",a,"halfPadding",r),await(0,i.U)(p,t),m.get(t.id).node=t}else{const e=n.node(t.parentId);t.y+=X/2,d.Rm.info("A regular node XBX1 - using the padding",t.id,"parent",t.parentId,t.width,t.height,t.x,t.y,"offsetY",t.offsetY,"parent",e,e?.offsetY,t),(0,i.U_)(t)}})),n.edges().forEach(function(e){const i=n.edge(e);d.Rm.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(i),i),i.points.forEach(e=>e.y+=X/2);const a=n.node(e.v);var s=n.node(e.w);const c=(0,r.Jo)(u,i,m,t,a,s,o);(0,r.T_)(i,c)}),n.nodes().forEach(function(e){const t=n.node(e);d.Rm.info(e,t.type,t.diff),t.isGroup&&(y=t.diff)}),d.Rm.warn("Returning from recursive render XAX",h,y),{elem:h,diff:y}},"recursiveRender"),k=(0,d.K2)(async(e,n)=>{const t=new u.T({multigraph:!0,compound:!0}).setGraph({rankdir:e.direction,nodesep:e.config?.nodeSpacing||e.config?.flowchart?.nodeSpacing||e.nodeSpacing,ranksep:e.config?.rankSpacing||e.config?.flowchart?.rankSpacing||e.rankSpacing,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}}),a=n.select("g");(0,r.g0)(a,e.markers,e.type,e.diagramId),(0,i.gh)(),(0,r.IU)(),(0,i.IU)(),v(),e.nodes.forEach(e=>{t.setNode(e.id,{...e}),e.parentId&&t.setParent(e.id,e.parentId)}),d.Rm.debug("Edges:",e.edges),e.edges.forEach(e=>{if(e.start===e.end){const n=e.start,r=n+"---"+n+"---1",i=n+"---"+n+"---2",a=t.node(n);t.setNode(r,{domId:r,id:r,parentId:a.parentId,labelStyle:"",label:"",padding:0,shape:"labelRect",style:"",width:10,height:10}),t.setParent(r,a.parentId),t.setNode(i,{domId:i,id:i,parentId:a.parentId,labelStyle:"",padding:0,shape:"labelRect",label:"",style:"",width:10,height:10}),t.setParent(i,a.parentId);const o=structuredClone(e),d=structuredClone(e),s=structuredClone(e);o.label="",o.arrowTypeEnd="none",o.id=n+"-cyclic-special-1",d.arrowTypeStart="none",d.arrowTypeEnd="none",d.id=n+"-cyclic-special-mid",s.label="",a.isGroup&&(o.fromCluster=n,s.toCluster=n),s.id=n+"-cyclic-special-2",s.arrowTypeStart="none",t.setEdge(n,r,o,n+"-cyclic-special-0"),t.setEdge(r,i,d,n+"-cyclic-special-1"),t.setEdge(i,n,s,n+"-cyc<lic-special-2")}else t.setEdge(e.start,e.end,{...e},e.id)}),d.Rm.warn("Graph at first:",JSON.stringify(f(t))),x(t),d.Rm.warn("Graph after XAX:",JSON.stringify(f(t)));const s=(0,o.D7)();await O(a,t,e.type,e.diagramId,void 0,s)},"render")}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/7928.292d9849.js b/pr-preview/pr-4027/assets/js/7928.292d9849.js deleted file mode 100644 index 71dd7a02d..000000000 --- a/pr-preview/pr-4027/assets/js/7928.292d9849.js +++ /dev/null @@ -1 +0,0 @@ -(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7928],{23143:function(t){var e;e=function(){return function(t){var e={};function i(r){if(e[r])return e[r].exports;var n=e[r]={i:r,l:!1,exports:{}};return t[r].call(n.exports,n,n.exports,i),n.l=!0,n.exports}return i.m=t,i.c=e,i.i=function(t){return t},i.d=function(t,e,r){i.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:r})},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=26)}([function(t,e,i){"use strict";function r(){}r.QUALITY=1,r.DEFAULT_CREATE_BENDS_AS_NEEDED=!1,r.DEFAULT_INCREMENTAL=!1,r.DEFAULT_ANIMATION_ON_LAYOUT=!0,r.DEFAULT_ANIMATION_DURING_LAYOUT=!1,r.DEFAULT_ANIMATION_PERIOD=50,r.DEFAULT_UNIFORM_LEAF_NODE_SIZES=!1,r.DEFAULT_GRAPH_MARGIN=15,r.NODE_DIMENSIONS_INCLUDE_LABELS=!1,r.SIMPLE_NODE_SIZE=40,r.SIMPLE_NODE_HALF_SIZE=r.SIMPLE_NODE_SIZE/2,r.EMPTY_COMPOUND_NODE_SIZE=40,r.MIN_EDGE_LENGTH=1,r.WORLD_BOUNDARY=1e6,r.INITIAL_WORLD_BOUNDARY=r.WORLD_BOUNDARY/1e3,r.WORLD_CENTER_X=1200,r.WORLD_CENTER_Y=900,t.exports=r},function(t,e,i){"use strict";var r=i(2),n=i(8),o=i(9);function s(t,e,i){r.call(this,i),this.isOverlapingSourceAndTarget=!1,this.vGraphObject=i,this.bendpoints=[],this.source=t,this.target=e}for(var a in s.prototype=Object.create(r.prototype),r)s[a]=r[a];s.prototype.getSource=function(){return this.source},s.prototype.getTarget=function(){return this.target},s.prototype.isInterGraph=function(){return this.isInterGraph},s.prototype.getLength=function(){return this.length},s.prototype.isOverlapingSourceAndTarget=function(){return this.isOverlapingSourceAndTarget},s.prototype.getBendpoints=function(){return this.bendpoints},s.prototype.getLca=function(){return this.lca},s.prototype.getSourceInLca=function(){return this.sourceInLca},s.prototype.getTargetInLca=function(){return this.targetInLca},s.prototype.getOtherEnd=function(t){if(this.source===t)return this.target;if(this.target===t)return this.source;throw"Node is not incident with this edge"},s.prototype.getOtherEndInGraph=function(t,e){for(var i=this.getOtherEnd(t),r=e.getGraphManager().getRoot();;){if(i.getOwner()==e)return i;if(i.getOwner()==r)break;i=i.getOwner().getParent()}return null},s.prototype.updateLength=function(){var t=new Array(4);this.isOverlapingSourceAndTarget=n.getIntersection(this.target.getRect(),this.source.getRect(),t),this.isOverlapingSourceAndTarget||(this.lengthX=t[0]-t[2],this.lengthY=t[1]-t[3],Math.abs(this.lengthX)<1&&(this.lengthX=o.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=o.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY))},s.prototype.updateLengthSimple=function(){this.lengthX=this.target.getCenterX()-this.source.getCenterX(),this.lengthY=this.target.getCenterY()-this.source.getCenterY(),Math.abs(this.lengthX)<1&&(this.lengthX=o.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=o.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY)},t.exports=s},function(t,e,i){"use strict";t.exports=function(t){this.vGraphObject=t}},function(t,e,i){"use strict";var r=i(2),n=i(10),o=i(13),s=i(0),a=i(16),h=i(4);function l(t,e,i,s){null==i&&null==s&&(s=e),r.call(this,s),null!=t.graphManager&&(t=t.graphManager),this.estimatedSize=n.MIN_VALUE,this.inclusionTreeDepth=n.MAX_VALUE,this.vGraphObject=s,this.edges=[],this.graphManager=t,this.rect=null!=i&&null!=e?new o(e.x,e.y,i.width,i.height):new o}for(var g in l.prototype=Object.create(r.prototype),r)l[g]=r[g];l.prototype.getEdges=function(){return this.edges},l.prototype.getChild=function(){return this.child},l.prototype.getOwner=function(){return this.owner},l.prototype.getWidth=function(){return this.rect.width},l.prototype.setWidth=function(t){this.rect.width=t},l.prototype.getHeight=function(){return this.rect.height},l.prototype.setHeight=function(t){this.rect.height=t},l.prototype.getCenterX=function(){return this.rect.x+this.rect.width/2},l.prototype.getCenterY=function(){return this.rect.y+this.rect.height/2},l.prototype.getCenter=function(){return new h(this.rect.x+this.rect.width/2,this.rect.y+this.rect.height/2)},l.prototype.getLocation=function(){return new h(this.rect.x,this.rect.y)},l.prototype.getRect=function(){return this.rect},l.prototype.getDiagonal=function(){return Math.sqrt(this.rect.width*this.rect.width+this.rect.height*this.rect.height)},l.prototype.getHalfTheDiagonal=function(){return Math.sqrt(this.rect.height*this.rect.height+this.rect.width*this.rect.width)/2},l.prototype.setRect=function(t,e){this.rect.x=t.x,this.rect.y=t.y,this.rect.width=e.width,this.rect.height=e.height},l.prototype.setCenter=function(t,e){this.rect.x=t-this.rect.width/2,this.rect.y=e-this.rect.height/2},l.prototype.setLocation=function(t,e){this.rect.x=t,this.rect.y=e},l.prototype.moveBy=function(t,e){this.rect.x+=t,this.rect.y+=e},l.prototype.getEdgeListToNode=function(t){var e=[],i=this;return i.edges.forEach(function(r){if(r.target==t){if(r.source!=i)throw"Incorrect edge source!";e.push(r)}}),e},l.prototype.getEdgesBetween=function(t){var e=[],i=this;return i.edges.forEach(function(r){if(r.source!=i&&r.target!=i)throw"Incorrect edge source and/or target";r.target!=t&&r.source!=t||e.push(r)}),e},l.prototype.getNeighborsList=function(){var t=new Set,e=this;return e.edges.forEach(function(i){if(i.source==e)t.add(i.target);else{if(i.target!=e)throw"Incorrect incidency!";t.add(i.source)}}),t},l.prototype.withChildren=function(){var t=new Set;if(t.add(this),null!=this.child)for(var e=this.child.getNodes(),i=0;i<e.length;i++)e[i].withChildren().forEach(function(e){t.add(e)});return t},l.prototype.getNoOfChildren=function(){var t=0;if(null==this.child)t=1;else for(var e=this.child.getNodes(),i=0;i<e.length;i++)t+=e[i].getNoOfChildren();return 0==t&&(t=1),t},l.prototype.getEstimatedSize=function(){if(this.estimatedSize==n.MIN_VALUE)throw"assert failed";return this.estimatedSize},l.prototype.calcEstimatedSize=function(){return null==this.child?this.estimatedSize=(this.rect.width+this.rect.height)/2:(this.estimatedSize=this.child.calcEstimatedSize(),this.rect.width=this.estimatedSize,this.rect.height=this.estimatedSize,this.estimatedSize)},l.prototype.scatter=function(){var t,e,i=-s.INITIAL_WORLD_BOUNDARY,r=s.INITIAL_WORLD_BOUNDARY;t=s.WORLD_CENTER_X+a.nextDouble()*(r-i)+i;var n=-s.INITIAL_WORLD_BOUNDARY,o=s.INITIAL_WORLD_BOUNDARY;e=s.WORLD_CENTER_Y+a.nextDouble()*(o-n)+n,this.rect.x=t,this.rect.y=e},l.prototype.updateBounds=function(){if(null==this.getChild())throw"assert failed";if(0!=this.getChild().getNodes().length){var t=this.getChild();if(t.updateBounds(!0),this.rect.x=t.getLeft(),this.rect.y=t.getTop(),this.setWidth(t.getRight()-t.getLeft()),this.setHeight(t.getBottom()-t.getTop()),s.NODE_DIMENSIONS_INCLUDE_LABELS){var e=t.getRight()-t.getLeft(),i=t.getBottom()-t.getTop();this.labelWidth>e&&(this.rect.x-=(this.labelWidth-e)/2,this.setWidth(this.labelWidth)),this.labelHeight>i&&("center"==this.labelPos?this.rect.y-=(this.labelHeight-i)/2:"top"==this.labelPos&&(this.rect.y-=this.labelHeight-i),this.setHeight(this.labelHeight))}}},l.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==n.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},l.prototype.transform=function(t){var e=this.rect.x;e>s.WORLD_BOUNDARY?e=s.WORLD_BOUNDARY:e<-s.WORLD_BOUNDARY&&(e=-s.WORLD_BOUNDARY);var i=this.rect.y;i>s.WORLD_BOUNDARY?i=s.WORLD_BOUNDARY:i<-s.WORLD_BOUNDARY&&(i=-s.WORLD_BOUNDARY);var r=new h(e,i),n=t.inverseTransformPoint(r);this.setLocation(n.x,n.y)},l.prototype.getLeft=function(){return this.rect.x},l.prototype.getRight=function(){return this.rect.x+this.rect.width},l.prototype.getTop=function(){return this.rect.y},l.prototype.getBottom=function(){return this.rect.y+this.rect.height},l.prototype.getParent=function(){return null==this.owner?null:this.owner.getParent()},t.exports=l},function(t,e,i){"use strict";function r(t,e){null==t&&null==e?(this.x=0,this.y=0):(this.x=t,this.y=e)}r.prototype.getX=function(){return this.x},r.prototype.getY=function(){return this.y},r.prototype.setX=function(t){this.x=t},r.prototype.setY=function(t){this.y=t},r.prototype.getDifference=function(t){return new DimensionD(this.x-t.x,this.y-t.y)},r.prototype.getCopy=function(){return new r(this.x,this.y)},r.prototype.translate=function(t){return this.x+=t.width,this.y+=t.height,this},t.exports=r},function(t,e,i){"use strict";var r=i(2),n=i(10),o=i(0),s=i(6),a=i(3),h=i(1),l=i(13),g=i(12),u=i(11);function c(t,e,i){r.call(this,i),this.estimatedSize=n.MIN_VALUE,this.margin=o.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=t,null!=e&&e instanceof s?this.graphManager=e:null!=e&&e instanceof Layout&&(this.graphManager=e.graphManager)}for(var d in c.prototype=Object.create(r.prototype),r)c[d]=r[d];c.prototype.getNodes=function(){return this.nodes},c.prototype.getEdges=function(){return this.edges},c.prototype.getGraphManager=function(){return this.graphManager},c.prototype.getParent=function(){return this.parent},c.prototype.getLeft=function(){return this.left},c.prototype.getRight=function(){return this.right},c.prototype.getTop=function(){return this.top},c.prototype.getBottom=function(){return this.bottom},c.prototype.isConnected=function(){return this.isConnected},c.prototype.add=function(t,e,i){if(null==e&&null==i){var r=t;if(null==this.graphManager)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(r)>-1)throw"Node already in graph!";return r.owner=this,this.getNodes().push(r),r}var n=t;if(!(this.getNodes().indexOf(e)>-1&&this.getNodes().indexOf(i)>-1))throw"Source or target not in graph!";if(e.owner!=i.owner||e.owner!=this)throw"Both owners must be this graph!";return e.owner!=i.owner?null:(n.source=e,n.target=i,n.isInterGraph=!1,this.getEdges().push(n),e.edges.push(n),i!=e&&i.edges.push(n),n)},c.prototype.remove=function(t){var e=t;if(t instanceof a){if(null==e)throw"Node is null!";if(null==e.owner||e.owner!=this)throw"Owner graph is invalid!";if(null==this.graphManager)throw"Owner graph manager is invalid!";for(var i=e.edges.slice(),r=i.length,n=0;n<r;n++)(o=i[n]).isInterGraph?this.graphManager.remove(o):o.source.owner.remove(o);if(-1==(s=this.nodes.indexOf(e)))throw"Node not in owner node list!";this.nodes.splice(s,1)}else if(t instanceof h){var o;if(null==(o=t))throw"Edge is null!";if(null==o.source||null==o.target)throw"Source and/or target is null!";if(null==o.source.owner||null==o.target.owner||o.source.owner!=this||o.target.owner!=this)throw"Source and/or target owner is invalid!";var s,l=o.source.edges.indexOf(o),g=o.target.edges.indexOf(o);if(!(l>-1&&g>-1))throw"Source and/or target doesn't know this edge!";if(o.source.edges.splice(l,1),o.target!=o.source&&o.target.edges.splice(g,1),-1==(s=o.source.owner.getEdges().indexOf(o)))throw"Not in owner's edge list!";o.source.owner.getEdges().splice(s,1)}},c.prototype.updateLeftTop=function(){for(var t,e,i,r=n.MAX_VALUE,o=n.MAX_VALUE,s=this.getNodes(),a=s.length,h=0;h<a;h++){var l=s[h];r>(t=l.getTop())&&(r=t),o>(e=l.getLeft())&&(o=e)}return r==n.MAX_VALUE?null:(i=null!=s[0].getParent().paddingLeft?s[0].getParent().paddingLeft:this.margin,this.left=o-i,this.top=r-i,new g(this.left,this.top))},c.prototype.updateBounds=function(t){for(var e,i,r,o,s,a=n.MAX_VALUE,h=-n.MAX_VALUE,g=n.MAX_VALUE,u=-n.MAX_VALUE,c=this.nodes,d=c.length,p=0;p<d;p++){var f=c[p];t&&null!=f.child&&f.updateBounds(),a>(e=f.getLeft())&&(a=e),h<(i=f.getRight())&&(h=i),g>(r=f.getTop())&&(g=r),u<(o=f.getBottom())&&(u=o)}var y=new l(a,g,h-a,u-g);a==n.MAX_VALUE&&(this.left=this.parent.getLeft(),this.right=this.parent.getRight(),this.top=this.parent.getTop(),this.bottom=this.parent.getBottom()),s=null!=c[0].getParent().paddingLeft?c[0].getParent().paddingLeft:this.margin,this.left=y.x-s,this.right=y.x+y.width+s,this.top=y.y-s,this.bottom=y.y+y.height+s},c.calculateBounds=function(t){for(var e,i,r,o,s=n.MAX_VALUE,a=-n.MAX_VALUE,h=n.MAX_VALUE,g=-n.MAX_VALUE,u=t.length,c=0;c<u;c++){var d=t[c];s>(e=d.getLeft())&&(s=e),a<(i=d.getRight())&&(a=i),h>(r=d.getTop())&&(h=r),g<(o=d.getBottom())&&(g=o)}return new l(s,h,a-s,g-h)},c.prototype.getInclusionTreeDepth=function(){return this==this.graphManager.getRoot()?1:this.parent.getInclusionTreeDepth()},c.prototype.getEstimatedSize=function(){if(this.estimatedSize==n.MIN_VALUE)throw"assert failed";return this.estimatedSize},c.prototype.calcEstimatedSize=function(){for(var t=0,e=this.nodes,i=e.length,r=0;r<i;r++)t+=e[r].calcEstimatedSize();return this.estimatedSize=0==t?o.EMPTY_COMPOUND_NODE_SIZE:t/Math.sqrt(this.nodes.length),this.estimatedSize},c.prototype.updateConnected=function(){var t=this;if(0!=this.nodes.length){var e,i,r=new u,n=new Set,o=this.nodes[0];for(o.withChildren().forEach(function(t){r.push(t),n.add(t)});0!==r.length;)for(var s=(e=(o=r.shift()).getEdges()).length,a=0;a<s;a++)null==(i=e[a].getOtherEndInGraph(o,this))||n.has(i)||i.withChildren().forEach(function(t){r.push(t),n.add(t)});if(this.isConnected=!1,n.size>=this.nodes.length){var h=0;n.forEach(function(e){e.owner==t&&h++}),h==this.nodes.length&&(this.isConnected=!0)}}else this.isConnected=!0},t.exports=c},function(t,e,i){"use strict";var r,n=i(1);function o(t){r=i(5),this.layout=t,this.graphs=[],this.edges=[]}o.prototype.addRoot=function(){var t=this.layout.newGraph(),e=this.layout.newNode(null),i=this.add(t,e);return this.setRootGraph(i),this.rootGraph},o.prototype.add=function(t,e,i,r,n){if(null==i&&null==r&&null==n){if(null==t)throw"Graph is null!";if(null==e)throw"Parent node is null!";if(this.graphs.indexOf(t)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(t),null!=t.parent)throw"Already has a parent!";if(null!=e.child)throw"Already has a child!";return t.parent=e,e.child=t,t}n=i,i=t;var o=(r=e).getOwner(),s=n.getOwner();if(null==o||o.getGraphManager()!=this)throw"Source not in this graph mgr!";if(null==s||s.getGraphManager()!=this)throw"Target not in this graph mgr!";if(o==s)return i.isInterGraph=!1,o.add(i,r,n);if(i.isInterGraph=!0,i.source=r,i.target=n,this.edges.indexOf(i)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(i),null==i.source||null==i.target)throw"Edge source and/or target is null!";if(-1!=i.source.edges.indexOf(i)||-1!=i.target.edges.indexOf(i))throw"Edge already in source and/or target incidency list!";return i.source.edges.push(i),i.target.edges.push(i),i},o.prototype.remove=function(t){if(t instanceof r){var e=t;if(e.getGraphManager()!=this)throw"Graph not in this graph mgr";if(e!=this.rootGraph&&(null==e.parent||e.parent.graphManager!=this))throw"Invalid parent node!";for(var i,o=[],s=(o=o.concat(e.getEdges())).length,a=0;a<s;a++)i=o[a],e.remove(i);var h,l=[];for(s=(l=l.concat(e.getNodes())).length,a=0;a<s;a++)h=l[a],e.remove(h);e==this.rootGraph&&this.setRootGraph(null);var g=this.graphs.indexOf(e);this.graphs.splice(g,1),e.parent=null}else if(t instanceof n){if(null==(i=t))throw"Edge is null!";if(!i.isInterGraph)throw"Not an inter-graph edge!";if(null==i.source||null==i.target)throw"Source and/or target is null!";if(-1==i.source.edges.indexOf(i)||-1==i.target.edges.indexOf(i))throw"Source and/or target doesn't know this edge!";if(g=i.source.edges.indexOf(i),i.source.edges.splice(g,1),g=i.target.edges.indexOf(i),i.target.edges.splice(g,1),null==i.source.owner||null==i.source.owner.getGraphManager())throw"Edge owner graph or owner graph manager is null!";if(-1==i.source.owner.getGraphManager().edges.indexOf(i))throw"Not in owner graph manager's edge list!";g=i.source.owner.getGraphManager().edges.indexOf(i),i.source.owner.getGraphManager().edges.splice(g,1)}},o.prototype.updateBounds=function(){this.rootGraph.updateBounds(!0)},o.prototype.getGraphs=function(){return this.graphs},o.prototype.getAllNodes=function(){if(null==this.allNodes){for(var t=[],e=this.getGraphs(),i=e.length,r=0;r<i;r++)t=t.concat(e[r].getNodes());this.allNodes=t}return this.allNodes},o.prototype.resetAllNodes=function(){this.allNodes=null},o.prototype.resetAllEdges=function(){this.allEdges=null},o.prototype.resetAllNodesToApplyGravitation=function(){this.allNodesToApplyGravitation=null},o.prototype.getAllEdges=function(){if(null==this.allEdges){for(var t=[],e=this.getGraphs(),i=(e.length,0);i<e.length;i++)t=t.concat(e[i].getEdges());t=t.concat(this.edges),this.allEdges=t}return this.allEdges},o.prototype.getAllNodesToApplyGravitation=function(){return this.allNodesToApplyGravitation},o.prototype.setAllNodesToApplyGravitation=function(t){if(null!=this.allNodesToApplyGravitation)throw"assert failed";this.allNodesToApplyGravitation=t},o.prototype.getRoot=function(){return this.rootGraph},o.prototype.setRootGraph=function(t){if(t.getGraphManager()!=this)throw"Root not in this graph mgr!";this.rootGraph=t,null==t.parent&&(t.parent=this.layout.newNode("Root node"))},o.prototype.getLayout=function(){return this.layout},o.prototype.isOneAncestorOfOther=function(t,e){if(null==t||null==e)throw"assert failed";if(t==e)return!0;for(var i,r=t.getOwner();null!=(i=r.getParent());){if(i==e)return!0;if(null==(r=i.getOwner()))break}for(r=e.getOwner();null!=(i=r.getParent());){if(i==t)return!0;if(null==(r=i.getOwner()))break}return!1},o.prototype.calcLowestCommonAncestors=function(){for(var t,e,i,r,n,o=this.getAllEdges(),s=o.length,a=0;a<s;a++)if(e=(t=o[a]).source,i=t.target,t.lca=null,t.sourceInLca=e,t.targetInLca=i,e!=i){for(r=e.getOwner();null==t.lca;){for(t.targetInLca=i,n=i.getOwner();null==t.lca;){if(n==r){t.lca=n;break}if(n==this.rootGraph)break;if(null!=t.lca)throw"assert failed";t.targetInLca=n.getParent(),n=t.targetInLca.getOwner()}if(r==this.rootGraph)break;null==t.lca&&(t.sourceInLca=r.getParent(),r=t.sourceInLca.getOwner())}if(null==t.lca)throw"assert failed"}else t.lca=e.getOwner()},o.prototype.calcLowestCommonAncestor=function(t,e){if(t==e)return t.getOwner();for(var i=t.getOwner();null!=i;){for(var r=e.getOwner();null!=r;){if(r==i)return r;r=r.getParent().getOwner()}i=i.getParent().getOwner()}return i},o.prototype.calcInclusionTreeDepths=function(t,e){var i;null==t&&null==e&&(t=this.rootGraph,e=1);for(var r=t.getNodes(),n=r.length,o=0;o<n;o++)(i=r[o]).inclusionTreeDepth=e,null!=i.child&&this.calcInclusionTreeDepths(i.child,e+1)},o.prototype.includesInvalidEdge=function(){for(var t,e=this.edges.length,i=0;i<e;i++)if(t=this.edges[i],this.isOneAncestorOfOther(t.source,t.target))return!0;return!1},t.exports=o},function(t,e,i){"use strict";var r=i(0);function n(){}for(var o in r)n[o]=r[o];n.MAX_ITERATIONS=2500,n.DEFAULT_EDGE_LENGTH=50,n.DEFAULT_SPRING_STRENGTH=.45,n.DEFAULT_REPULSION_STRENGTH=4500,n.DEFAULT_GRAVITY_STRENGTH=.4,n.DEFAULT_COMPOUND_GRAVITY_STRENGTH=1,n.DEFAULT_GRAVITY_RANGE_FACTOR=3.8,n.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=1.5,n.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION=!0,n.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION=!0,n.DEFAULT_COOLING_FACTOR_INCREMENTAL=.3,n.COOLING_ADAPTATION_FACTOR=.33,n.ADAPTATION_LOWER_NODE_LIMIT=1e3,n.ADAPTATION_UPPER_NODE_LIMIT=5e3,n.MAX_NODE_DISPLACEMENT_INCREMENTAL=100,n.MAX_NODE_DISPLACEMENT=3*n.MAX_NODE_DISPLACEMENT_INCREMENTAL,n.MIN_REPULSION_DIST=n.DEFAULT_EDGE_LENGTH/10,n.CONVERGENCE_CHECK_PERIOD=100,n.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=.1,n.MIN_EDGE_LENGTH=1,n.GRID_CALCULATION_CHECK_PERIOD=10,t.exports=n},function(t,e,i){"use strict";var r=i(12);function n(){}n.calcSeparationAmount=function(t,e,i,r){if(!t.intersects(e))throw"assert failed";var n=new Array(2);this.decideDirectionsForOverlappingNodes(t,e,n),i[0]=Math.min(t.getRight(),e.getRight())-Math.max(t.x,e.x),i[1]=Math.min(t.getBottom(),e.getBottom())-Math.max(t.y,e.y),t.getX()<=e.getX()&&t.getRight()>=e.getRight()?i[0]+=Math.min(e.getX()-t.getX(),t.getRight()-e.getRight()):e.getX()<=t.getX()&&e.getRight()>=t.getRight()&&(i[0]+=Math.min(t.getX()-e.getX(),e.getRight()-t.getRight())),t.getY()<=e.getY()&&t.getBottom()>=e.getBottom()?i[1]+=Math.min(e.getY()-t.getY(),t.getBottom()-e.getBottom()):e.getY()<=t.getY()&&e.getBottom()>=t.getBottom()&&(i[1]+=Math.min(t.getY()-e.getY(),e.getBottom()-t.getBottom()));var o=Math.abs((e.getCenterY()-t.getCenterY())/(e.getCenterX()-t.getCenterX()));e.getCenterY()===t.getCenterY()&&e.getCenterX()===t.getCenterX()&&(o=1);var s=o*i[0],a=i[1]/o;i[0]<a?a=i[0]:s=i[1],i[0]=-1*n[0]*(a/2+r),i[1]=-1*n[1]*(s/2+r)},n.decideDirectionsForOverlappingNodes=function(t,e,i){t.getCenterX()<e.getCenterX()?i[0]=-1:i[0]=1,t.getCenterY()<e.getCenterY()?i[1]=-1:i[1]=1},n.getIntersection2=function(t,e,i){var r=t.getCenterX(),n=t.getCenterY(),o=e.getCenterX(),s=e.getCenterY();if(t.intersects(e))return i[0]=r,i[1]=n,i[2]=o,i[3]=s,!0;var a=t.getX(),h=t.getY(),l=t.getRight(),g=t.getX(),u=t.getBottom(),c=t.getRight(),d=t.getWidthHalf(),p=t.getHeightHalf(),f=e.getX(),y=e.getY(),E=e.getRight(),v=e.getX(),A=e.getBottom(),N=e.getRight(),T=e.getWidthHalf(),L=e.getHeightHalf(),_=!1,m=!1;if(r===o){if(n>s)return i[0]=r,i[1]=h,i[2]=o,i[3]=A,!1;if(n<s)return i[0]=r,i[1]=u,i[2]=o,i[3]=y,!1}else if(n===s){if(r>o)return i[0]=a,i[1]=n,i[2]=E,i[3]=s,!1;if(r<o)return i[0]=l,i[1]=n,i[2]=f,i[3]=s,!1}else{var O=t.height/t.width,I=e.height/e.width,D=(s-n)/(o-r),w=void 0,R=void 0,C=void 0,M=void 0,G=void 0,x=void 0;if(-O===D?r>o?(i[0]=g,i[1]=u,_=!0):(i[0]=l,i[1]=h,_=!0):O===D&&(r>o?(i[0]=a,i[1]=h,_=!0):(i[0]=c,i[1]=u,_=!0)),-I===D?o>r?(i[2]=v,i[3]=A,m=!0):(i[2]=E,i[3]=y,m=!0):I===D&&(o>r?(i[2]=f,i[3]=y,m=!0):(i[2]=N,i[3]=A,m=!0)),_&&m)return!1;if(r>o?n>s?(w=this.getCardinalDirection(O,D,4),R=this.getCardinalDirection(I,D,2)):(w=this.getCardinalDirection(-O,D,3),R=this.getCardinalDirection(-I,D,1)):n>s?(w=this.getCardinalDirection(-O,D,1),R=this.getCardinalDirection(-I,D,3)):(w=this.getCardinalDirection(O,D,2),R=this.getCardinalDirection(I,D,4)),!_)switch(w){case 1:M=h,C=r+-p/D,i[0]=C,i[1]=M;break;case 2:C=c,M=n+d*D,i[0]=C,i[1]=M;break;case 3:M=u,C=r+p/D,i[0]=C,i[1]=M;break;case 4:C=g,M=n+-d*D,i[0]=C,i[1]=M}if(!m)switch(R){case 1:x=y,G=o+-L/D,i[2]=G,i[3]=x;break;case 2:G=N,x=s+T*D,i[2]=G,i[3]=x;break;case 3:x=A,G=o+L/D,i[2]=G,i[3]=x;break;case 4:G=v,x=s+-T*D,i[2]=G,i[3]=x}}return!1},n.getCardinalDirection=function(t,e,i){return t>e?i:1+i%4},n.getIntersection=function(t,e,i,n){if(null==n)return this.getIntersection2(t,e,i);var o,s,a,h,l,g,u,c=t.x,d=t.y,p=e.x,f=e.y,y=i.x,E=i.y,v=n.x,A=n.y;return 0===(u=(o=f-d)*(h=y-v)-(s=A-E)*(a=c-p))?null:new r((a*(g=v*E-y*A)-h*(l=p*d-c*f))/u,(s*l-o*g)/u)},n.angleOfVector=function(t,e,i,r){var n=void 0;return t!==i?(n=Math.atan((r-e)/(i-t)),i<t?n+=Math.PI:r<e&&(n+=this.TWO_PI)):n=r<e?this.ONE_AND_HALF_PI:this.HALF_PI,n},n.doIntersect=function(t,e,i,r){var n=t.x,o=t.y,s=e.x,a=e.y,h=i.x,l=i.y,g=r.x,u=r.y,c=(s-n)*(u-l)-(g-h)*(a-o);if(0===c)return!1;var d=((u-l)*(g-n)+(h-g)*(u-o))/c,p=((o-a)*(g-n)+(s-n)*(u-o))/c;return 0<d&&d<1&&0<p&&p<1},n.HALF_PI=.5*Math.PI,n.ONE_AND_HALF_PI=1.5*Math.PI,n.TWO_PI=2*Math.PI,n.THREE_PI=3*Math.PI,t.exports=n},function(t,e,i){"use strict";function r(){}r.sign=function(t){return t>0?1:t<0?-1:0},r.floor=function(t){return t<0?Math.ceil(t):Math.floor(t)},r.ceil=function(t){return t<0?Math.floor(t):Math.ceil(t)},t.exports=r},function(t,e,i){"use strict";function r(){}r.MAX_VALUE=2147483647,r.MIN_VALUE=-2147483648,t.exports=r},function(t,e,i){"use strict";var r=function(){function t(t,e){for(var i=0;i<e.length;i++){var r=e[i];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,i,r){return i&&t(e.prototype,i),r&&t(e,r),e}}(),n=function(t){return{value:t,next:null,prev:null}},o=function(t,e,i,r){return null!==t?t.next=e:r.head=e,null!==i?i.prev=e:r.tail=e,e.prev=t,e.next=i,r.length++,e},s=function(t,e){var i=t.prev,r=t.next;return null!==i?i.next=r:e.head=r,null!==r?r.prev=i:e.tail=i,t.prev=t.next=null,e.length--,t},a=function(){function t(e){var i=this;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.length=0,this.head=null,this.tail=null,null!=e&&e.forEach(function(t){return i.push(t)})}return r(t,[{key:"size",value:function(){return this.length}},{key:"insertBefore",value:function(t,e){return o(e.prev,n(t),e,this)}},{key:"insertAfter",value:function(t,e){return o(e,n(t),e.next,this)}},{key:"insertNodeBefore",value:function(t,e){return o(e.prev,t,e,this)}},{key:"insertNodeAfter",value:function(t,e){return o(e,t,e.next,this)}},{key:"push",value:function(t){return o(this.tail,n(t),null,this)}},{key:"unshift",value:function(t){return o(null,n(t),this.head,this)}},{key:"remove",value:function(t){return s(t,this)}},{key:"pop",value:function(){return s(this.tail,this).value}},{key:"popNode",value:function(){return s(this.tail,this)}},{key:"shift",value:function(){return s(this.head,this).value}},{key:"shiftNode",value:function(){return s(this.head,this)}},{key:"get_object_at",value:function(t){if(t<=this.length()){for(var e=1,i=this.head;e<t;)i=i.next,e++;return i.value}}},{key:"set_object_at",value:function(t,e){if(t<=this.length()){for(var i=1,r=this.head;i<t;)r=r.next,i++;r.value=e}}}]),t}();t.exports=a},function(t,e,i){"use strict";function r(t,e,i){this.x=null,this.y=null,null==t&&null==e&&null==i?(this.x=0,this.y=0):"number"==typeof t&&"number"==typeof e&&null==i?(this.x=t,this.y=e):"Point"==t.constructor.name&&null==e&&null==i&&(i=t,this.x=i.x,this.y=i.y)}r.prototype.getX=function(){return this.x},r.prototype.getY=function(){return this.y},r.prototype.getLocation=function(){return new r(this.x,this.y)},r.prototype.setLocation=function(t,e,i){"Point"==t.constructor.name&&null==e&&null==i?(i=t,this.setLocation(i.x,i.y)):"number"==typeof t&&"number"==typeof e&&null==i&&(parseInt(t)==t&&parseInt(e)==e?this.move(t,e):(this.x=Math.floor(t+.5),this.y=Math.floor(e+.5)))},r.prototype.move=function(t,e){this.x=t,this.y=e},r.prototype.translate=function(t,e){this.x+=t,this.y+=e},r.prototype.equals=function(t){if("Point"==t.constructor.name){var e=t;return this.x==e.x&&this.y==e.y}return this==t},r.prototype.toString=function(){return(new r).constructor.name+"[x="+this.x+",y="+this.y+"]"},t.exports=r},function(t,e,i){"use strict";function r(t,e,i,r){this.x=0,this.y=0,this.width=0,this.height=0,null!=t&&null!=e&&null!=i&&null!=r&&(this.x=t,this.y=e,this.width=i,this.height=r)}r.prototype.getX=function(){return this.x},r.prototype.setX=function(t){this.x=t},r.prototype.getY=function(){return this.y},r.prototype.setY=function(t){this.y=t},r.prototype.getWidth=function(){return this.width},r.prototype.setWidth=function(t){this.width=t},r.prototype.getHeight=function(){return this.height},r.prototype.setHeight=function(t){this.height=t},r.prototype.getRight=function(){return this.x+this.width},r.prototype.getBottom=function(){return this.y+this.height},r.prototype.intersects=function(t){return!(this.getRight()<t.x||this.getBottom()<t.y||t.getRight()<this.x||t.getBottom()<this.y)},r.prototype.getCenterX=function(){return this.x+this.width/2},r.prototype.getMinX=function(){return this.getX()},r.prototype.getMaxX=function(){return this.getX()+this.width},r.prototype.getCenterY=function(){return this.y+this.height/2},r.prototype.getMinY=function(){return this.getY()},r.prototype.getMaxY=function(){return this.getY()+this.height},r.prototype.getWidthHalf=function(){return this.width/2},r.prototype.getHeightHalf=function(){return this.height/2},t.exports=r},function(t,e,i){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};function n(){}n.lastID=0,n.createID=function(t){return n.isPrimitive(t)?t:(null!=t.uniqueID||(t.uniqueID=n.getString(),n.lastID++),t.uniqueID)},n.getString=function(t){return null==t&&(t=n.lastID),"Object#"+t},n.isPrimitive=function(t){var e=void 0===t?"undefined":r(t);return null==t||"object"!=e&&"function"!=e},t.exports=n},function(t,e,i){"use strict";function r(t){if(Array.isArray(t)){for(var e=0,i=Array(t.length);e<t.length;e++)i[e]=t[e];return i}return Array.from(t)}var n=i(0),o=i(6),s=i(3),a=i(1),h=i(5),l=i(4),g=i(17),u=i(27);function c(t){u.call(this),this.layoutQuality=n.QUALITY,this.createBendsAsNeeded=n.DEFAULT_CREATE_BENDS_AS_NEEDED,this.incremental=n.DEFAULT_INCREMENTAL,this.animationOnLayout=n.DEFAULT_ANIMATION_ON_LAYOUT,this.animationDuringLayout=n.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=n.DEFAULT_ANIMATION_PERIOD,this.uniformLeafNodeSizes=n.DEFAULT_UNIFORM_LEAF_NODE_SIZES,this.edgeToDummyNodes=new Map,this.graphManager=new o(this),this.isLayoutFinished=!1,this.isSubLayout=!1,this.isRemoteUse=!1,null!=t&&(this.isRemoteUse=t)}c.RANDOM_SEED=1,c.prototype=Object.create(u.prototype),c.prototype.getGraphManager=function(){return this.graphManager},c.prototype.getAllNodes=function(){return this.graphManager.getAllNodes()},c.prototype.getAllEdges=function(){return this.graphManager.getAllEdges()},c.prototype.getAllNodesToApplyGravitation=function(){return this.graphManager.getAllNodesToApplyGravitation()},c.prototype.newGraphManager=function(){var t=new o(this);return this.graphManager=t,t},c.prototype.newGraph=function(t){return new h(null,this.graphManager,t)},c.prototype.newNode=function(t){return new s(this.graphManager,t)},c.prototype.newEdge=function(t){return new a(null,null,t)},c.prototype.checkLayoutSuccess=function(){return null==this.graphManager.getRoot()||0==this.graphManager.getRoot().getNodes().length||this.graphManager.includesInvalidEdge()},c.prototype.runLayout=function(){var t;return this.isLayoutFinished=!1,this.tilingPreLayout&&this.tilingPreLayout(),this.initParameters(),t=!this.checkLayoutSuccess()&&this.layout(),"during"!==n.ANIMATE&&(t&&(this.isSubLayout||this.doPostLayout()),this.tilingPostLayout&&this.tilingPostLayout(),this.isLayoutFinished=!0,t)},c.prototype.doPostLayout=function(){this.incremental||this.transform(),this.update()},c.prototype.update2=function(){if(this.createBendsAsNeeded&&(this.createBendpointsFromDummyNodes(),this.graphManager.resetAllEdges()),!this.isRemoteUse){for(var t=this.graphManager.getAllEdges(),e=0;e<t.length;e++)t[e];var i=this.graphManager.getRoot().getNodes();for(e=0;e<i.length;e++)i[e];this.update(this.graphManager.getRoot())}},c.prototype.update=function(t){if(null==t)this.update2();else if(t instanceof s){var e=t;if(null!=e.getChild())for(var i=e.getChild().getNodes(),r=0;r<i.length;r++)update(i[r]);null!=e.vGraphObject&&e.vGraphObject.update(e)}else if(t instanceof a){var n=t;null!=n.vGraphObject&&n.vGraphObject.update(n)}else if(t instanceof h){var o=t;null!=o.vGraphObject&&o.vGraphObject.update(o)}},c.prototype.initParameters=function(){this.isSubLayout||(this.layoutQuality=n.QUALITY,this.animationDuringLayout=n.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=n.DEFAULT_ANIMATION_PERIOD,this.animationOnLayout=n.DEFAULT_ANIMATION_ON_LAYOUT,this.incremental=n.DEFAULT_INCREMENTAL,this.createBendsAsNeeded=n.DEFAULT_CREATE_BENDS_AS_NEEDED,this.uniformLeafNodeSizes=n.DEFAULT_UNIFORM_LEAF_NODE_SIZES),this.animationDuringLayout&&(this.animationOnLayout=!1)},c.prototype.transform=function(t){if(null==t)this.transform(new l(0,0));else{var e=new g,i=this.graphManager.getRoot().updateLeftTop();if(null!=i){e.setWorldOrgX(t.x),e.setWorldOrgY(t.y),e.setDeviceOrgX(i.x),e.setDeviceOrgY(i.y);for(var r=this.getAllNodes(),n=0;n<r.length;n++)r[n].transform(e)}}},c.prototype.positionNodesRandomly=function(t){if(null==t)this.positionNodesRandomly(this.getGraphManager().getRoot()),this.getGraphManager().getRoot().updateBounds(!0);else for(var e,i,r=t.getNodes(),n=0;n<r.length;n++)null==(i=(e=r[n]).getChild())||0==i.getNodes().length?e.scatter():(this.positionNodesRandomly(i),e.updateBounds())},c.prototype.getFlatForest=function(){for(var t=[],e=!0,i=this.graphManager.getRoot().getNodes(),n=!0,o=0;o<i.length;o++)null!=i[o].getChild()&&(n=!1);if(!n)return t;var s=new Set,a=[],h=new Map,l=[];for(l=l.concat(i);l.length>0&&e;){for(a.push(l[0]);a.length>0&&e;){var g=a[0];a.splice(0,1),s.add(g);var u=g.getEdges();for(o=0;o<u.length;o++){var c=u[o].getOtherEnd(g);if(h.get(g)!=c){if(s.has(c)){e=!1;break}a.push(c),h.set(c,g)}}}if(e){var d=[].concat(r(s));for(t.push(d),o=0;o<d.length;o++){var p=d[o],f=l.indexOf(p);f>-1&&l.splice(f,1)}s=new Set,h=new Map}else t=[]}return t},c.prototype.createDummyNodesForBendpoints=function(t){for(var e=[],i=t.source,r=this.graphManager.calcLowestCommonAncestor(t.source,t.target),n=0;n<t.bendpoints.length;n++){var o=this.newNode(null);o.setRect(new Point(0,0),new Dimension(1,1)),r.add(o);var s=this.newEdge(null);this.graphManager.add(s,i,o),e.add(o),i=o}return s=this.newEdge(null),this.graphManager.add(s,i,t.target),this.edgeToDummyNodes.set(t,e),t.isInterGraph()?this.graphManager.remove(t):r.remove(t),e},c.prototype.createBendpointsFromDummyNodes=function(){var t=[];t=t.concat(this.graphManager.getAllEdges()),t=[].concat(r(this.edgeToDummyNodes.keys())).concat(t);for(var e=0;e<t.length;e++){var i=t[e];if(i.bendpoints.length>0){for(var n=this.edgeToDummyNodes.get(i),o=0;o<n.length;o++){var s=n[o],a=new l(s.getCenterX(),s.getCenterY()),h=i.bendpoints.get(o);h.x=a.x,h.y=a.y,s.getOwner().remove(s)}this.graphManager.add(i,i.source,i.target)}}},c.transform=function(t,e,i,r){if(null!=i&&null!=r){var n=e;return t<=50?n-=(e-e/i)/50*(50-t):n+=(e*r-e)/50*(t-50),n}var o,s;return t<=50?(o=9*e/500,s=e/10):(o=9*e/50,s=-8*e),o*t+s},c.findCenterOfTree=function(t){var e=[];e=e.concat(t);var i=[],r=new Map,n=!1,o=null;1!=e.length&&2!=e.length||(n=!0,o=e[0]);for(var s=0;s<e.length;s++){var a=(g=e[s]).getNeighborsList().size;r.set(g,g.getNeighborsList().size),1==a&&i.push(g)}var h=[];for(h=h.concat(i);!n;){var l=[];for(l=l.concat(h),h=[],s=0;s<e.length;s++){var g=e[s],u=e.indexOf(g);u>=0&&e.splice(u,1),g.getNeighborsList().forEach(function(t){if(i.indexOf(t)<0){var e=r.get(t)-1;1==e&&h.push(t),r.set(t,e)}})}i=i.concat(h),1!=e.length&&2!=e.length||(n=!0,o=e[0])}return o},c.prototype.setGraphManager=function(t){this.graphManager=t},t.exports=c},function(t,e,i){"use strict";function r(){}r.seed=1,r.x=0,r.nextDouble=function(){return r.x=1e4*Math.sin(r.seed++),r.x-Math.floor(r.x)},t.exports=r},function(t,e,i){"use strict";var r=i(4);function n(t,e){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}n.prototype.getWorldOrgX=function(){return this.lworldOrgX},n.prototype.setWorldOrgX=function(t){this.lworldOrgX=t},n.prototype.getWorldOrgY=function(){return this.lworldOrgY},n.prototype.setWorldOrgY=function(t){this.lworldOrgY=t},n.prototype.getWorldExtX=function(){return this.lworldExtX},n.prototype.setWorldExtX=function(t){this.lworldExtX=t},n.prototype.getWorldExtY=function(){return this.lworldExtY},n.prototype.setWorldExtY=function(t){this.lworldExtY=t},n.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},n.prototype.setDeviceOrgX=function(t){this.ldeviceOrgX=t},n.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},n.prototype.setDeviceOrgY=function(t){this.ldeviceOrgY=t},n.prototype.getDeviceExtX=function(){return this.ldeviceExtX},n.prototype.setDeviceExtX=function(t){this.ldeviceExtX=t},n.prototype.getDeviceExtY=function(){return this.ldeviceExtY},n.prototype.setDeviceExtY=function(t){this.ldeviceExtY=t},n.prototype.transformX=function(t){var e=0,i=this.lworldExtX;return 0!=i&&(e=this.ldeviceOrgX+(t-this.lworldOrgX)*this.ldeviceExtX/i),e},n.prototype.transformY=function(t){var e=0,i=this.lworldExtY;return 0!=i&&(e=this.ldeviceOrgY+(t-this.lworldOrgY)*this.ldeviceExtY/i),e},n.prototype.inverseTransformX=function(t){var e=0,i=this.ldeviceExtX;return 0!=i&&(e=this.lworldOrgX+(t-this.ldeviceOrgX)*this.lworldExtX/i),e},n.prototype.inverseTransformY=function(t){var e=0,i=this.ldeviceExtY;return 0!=i&&(e=this.lworldOrgY+(t-this.ldeviceOrgY)*this.lworldExtY/i),e},n.prototype.inverseTransformPoint=function(t){return new r(this.inverseTransformX(t.x),this.inverseTransformY(t.y))},t.exports=n},function(t,e,i){"use strict";var r=i(15),n=i(7),o=i(0),s=i(8),a=i(9);function h(){r.call(this),this.useSmartIdealEdgeLengthCalculation=n.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.idealEdgeLength=n.DEFAULT_EDGE_LENGTH,this.springConstant=n.DEFAULT_SPRING_STRENGTH,this.repulsionConstant=n.DEFAULT_REPULSION_STRENGTH,this.gravityConstant=n.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=n.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=n.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=n.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.displacementThresholdPerNode=3*n.DEFAULT_EDGE_LENGTH/100,this.coolingFactor=n.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.initialCoolingFactor=n.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.totalDisplacement=0,this.oldTotalDisplacement=0,this.maxIterations=n.MAX_ITERATIONS}for(var l in h.prototype=Object.create(r.prototype),r)h[l]=r[l];h.prototype.initParameters=function(){r.prototype.initParameters.call(this,arguments),this.totalIterations=0,this.notAnimatedIterations=0,this.useFRGridVariant=n.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION,this.grid=[]},h.prototype.calcIdealEdgeLengths=function(){for(var t,e,i,r,s,a,h=this.getGraphManager().getAllEdges(),l=0;l<h.length;l++)(t=h[l]).idealLength=this.idealEdgeLength,t.isInterGraph&&(i=t.getSource(),r=t.getTarget(),s=t.getSourceInLca().getEstimatedSize(),a=t.getTargetInLca().getEstimatedSize(),this.useSmartIdealEdgeLengthCalculation&&(t.idealLength+=s+a-2*o.SIMPLE_NODE_SIZE),e=t.getLca().getInclusionTreeDepth(),t.idealLength+=n.DEFAULT_EDGE_LENGTH*n.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR*(i.getInclusionTreeDepth()+r.getInclusionTreeDepth()-2*e))},h.prototype.initSpringEmbedder=function(){var t=this.getAllNodes().length;this.incremental?(t>n.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*n.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(t-n.ADAPTATION_LOWER_NODE_LIMIT)/(n.ADAPTATION_UPPER_NODE_LIMIT-n.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-n.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=n.MAX_NODE_DISPLACEMENT_INCREMENTAL):(t>n.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(n.COOLING_ADAPTATION_FACTOR,1-(t-n.ADAPTATION_LOWER_NODE_LIMIT)/(n.ADAPTATION_UPPER_NODE_LIMIT-n.ADAPTATION_LOWER_NODE_LIMIT)*(1-n.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=n.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(5*this.getAllNodes().length,this.maxIterations),this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},h.prototype.calcSpringForces=function(){for(var t,e=this.getAllEdges(),i=0;i<e.length;i++)t=e[i],this.calcSpringForce(t,t.idealLength)},h.prototype.calcRepulsionForces=function(){var t,e,i,r,o,s=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],a=arguments.length>1&&void 0!==arguments[1]&&arguments[1],h=this.getAllNodes();if(this.useFRGridVariant)for(this.totalIterations%n.GRID_CALCULATION_CHECK_PERIOD==1&&s&&this.updateGrid(),o=new Set,t=0;t<h.length;t++)i=h[t],this.calculateRepulsionForceOfANode(i,o,s,a),o.add(i);else for(t=0;t<h.length;t++)for(i=h[t],e=t+1;e<h.length;e++)r=h[e],i.getOwner()==r.getOwner()&&this.calcRepulsionForce(i,r)},h.prototype.calcGravitationalForces=function(){for(var t,e=this.getAllNodesToApplyGravitation(),i=0;i<e.length;i++)t=e[i],this.calcGravitationalForce(t)},h.prototype.moveNodes=function(){for(var t=this.getAllNodes(),e=0;e<t.length;e++)t[e].move()},h.prototype.calcSpringForce=function(t,e){var i,r,n,o,s=t.getSource(),a=t.getTarget();if(this.uniformLeafNodeSizes&&null==s.getChild()&&null==a.getChild())t.updateLengthSimple();else if(t.updateLength(),t.isOverlapingSourceAndTarget)return;0!=(i=t.getLength())&&(n=(r=this.springConstant*(i-e))*(t.lengthX/i),o=r*(t.lengthY/i),s.springForceX+=n,s.springForceY+=o,a.springForceX-=n,a.springForceY-=o)},h.prototype.calcRepulsionForce=function(t,e){var i,r,o,h,l,g,u,c=t.getRect(),d=e.getRect(),p=new Array(2),f=new Array(4);if(c.intersects(d)){s.calcSeparationAmount(c,d,p,n.DEFAULT_EDGE_LENGTH/2),g=2*p[0],u=2*p[1];var y=t.noOfChildren*e.noOfChildren/(t.noOfChildren+e.noOfChildren);t.repulsionForceX-=y*g,t.repulsionForceY-=y*u,e.repulsionForceX+=y*g,e.repulsionForceY+=y*u}else this.uniformLeafNodeSizes&&null==t.getChild()&&null==e.getChild()?(i=d.getCenterX()-c.getCenterX(),r=d.getCenterY()-c.getCenterY()):(s.getIntersection(c,d,f),i=f[2]-f[0],r=f[3]-f[1]),Math.abs(i)<n.MIN_REPULSION_DIST&&(i=a.sign(i)*n.MIN_REPULSION_DIST),Math.abs(r)<n.MIN_REPULSION_DIST&&(r=a.sign(r)*n.MIN_REPULSION_DIST),o=i*i+r*r,h=Math.sqrt(o),g=(l=this.repulsionConstant*t.noOfChildren*e.noOfChildren/o)*i/h,u=l*r/h,t.repulsionForceX-=g,t.repulsionForceY-=u,e.repulsionForceX+=g,e.repulsionForceY+=u},h.prototype.calcGravitationalForce=function(t){var e,i,r,n,o,s,a,h;i=((e=t.getOwner()).getRight()+e.getLeft())/2,r=(e.getTop()+e.getBottom())/2,n=t.getCenterX()-i,o=t.getCenterY()-r,s=Math.abs(n)+t.getWidth()/2,a=Math.abs(o)+t.getHeight()/2,t.getOwner()==this.graphManager.getRoot()?(s>(h=e.getEstimatedSize()*this.gravityRangeFactor)||a>h)&&(t.gravitationForceX=-this.gravityConstant*n,t.gravitationForceY=-this.gravityConstant*o):(s>(h=e.getEstimatedSize()*this.compoundGravityRangeFactor)||a>h)&&(t.gravitationForceX=-this.gravityConstant*n*this.compoundGravityConstant,t.gravitationForceY=-this.gravityConstant*o*this.compoundGravityConstant)},h.prototype.isConverged=function(){var t,e=!1;return this.totalIterations>this.maxIterations/3&&(e=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),t=this.totalDisplacement<this.totalDisplacementThreshold,this.oldTotalDisplacement=this.totalDisplacement,t||e},h.prototype.animate=function(){this.animationDuringLayout&&!this.isSubLayout&&(this.notAnimatedIterations==this.animationPeriod?(this.update(),this.notAnimatedIterations=0):this.notAnimatedIterations++)},h.prototype.calcNoOfChildrenForAllNodes=function(){for(var t,e=this.graphManager.getAllNodes(),i=0;i<e.length;i++)(t=e[i]).noOfChildren=t.getNoOfChildren()},h.prototype.calcGrid=function(t){var e,i;e=parseInt(Math.ceil((t.getRight()-t.getLeft())/this.repulsionRange)),i=parseInt(Math.ceil((t.getBottom()-t.getTop())/this.repulsionRange));for(var r=new Array(e),n=0;n<e;n++)r[n]=new Array(i);for(n=0;n<e;n++)for(var o=0;o<i;o++)r[n][o]=new Array;return r},h.prototype.addNodeToGrid=function(t,e,i){var r,n,o,s;r=parseInt(Math.floor((t.getRect().x-e)/this.repulsionRange)),n=parseInt(Math.floor((t.getRect().width+t.getRect().x-e)/this.repulsionRange)),o=parseInt(Math.floor((t.getRect().y-i)/this.repulsionRange)),s=parseInt(Math.floor((t.getRect().height+t.getRect().y-i)/this.repulsionRange));for(var a=r;a<=n;a++)for(var h=o;h<=s;h++)this.grid[a][h].push(t),t.setGridCoordinates(r,n,o,s)},h.prototype.updateGrid=function(){var t,e,i=this.getAllNodes();for(this.grid=this.calcGrid(this.graphManager.getRoot()),t=0;t<i.length;t++)e=i[t],this.addNodeToGrid(e,this.graphManager.getRoot().getLeft(),this.graphManager.getRoot().getTop())},h.prototype.calculateRepulsionForceOfANode=function(t,e,i,r){if(this.totalIterations%n.GRID_CALCULATION_CHECK_PERIOD==1&&i||r){var o,s=new Set;t.surrounding=new Array;for(var a=this.grid,h=t.startX-1;h<t.finishX+2;h++)for(var l=t.startY-1;l<t.finishY+2;l++)if(!(h<0||l<0||h>=a.length||l>=a[0].length))for(var g=0;g<a[h][l].length;g++)if(o=a[h][l][g],t.getOwner()==o.getOwner()&&t!=o&&!e.has(o)&&!s.has(o)){var u=Math.abs(t.getCenterX()-o.getCenterX())-(t.getWidth()/2+o.getWidth()/2),c=Math.abs(t.getCenterY()-o.getCenterY())-(t.getHeight()/2+o.getHeight()/2);u<=this.repulsionRange&&c<=this.repulsionRange&&s.add(o)}t.surrounding=[].concat(function(t){if(Array.isArray(t)){for(var e=0,i=Array(t.length);e<t.length;e++)i[e]=t[e];return i}return Array.from(t)}(s))}for(h=0;h<t.surrounding.length;h++)this.calcRepulsionForce(t,t.surrounding[h])},h.prototype.calcRepulsionRange=function(){return 0},t.exports=h},function(t,e,i){"use strict";var r=i(1),n=i(7);function o(t,e,i){r.call(this,t,e,i),this.idealLength=n.DEFAULT_EDGE_LENGTH}for(var s in o.prototype=Object.create(r.prototype),r)o[s]=r[s];t.exports=o},function(t,e,i){"use strict";var r=i(3);function n(t,e,i,n){r.call(this,t,e,i,n),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0,this.startX=0,this.finishX=0,this.startY=0,this.finishY=0,this.surrounding=[]}for(var o in n.prototype=Object.create(r.prototype),r)n[o]=r[o];n.prototype.setGridCoordinates=function(t,e,i,r){this.startX=t,this.finishX=e,this.startY=i,this.finishY=r},t.exports=n},function(t,e,i){"use strict";function r(t,e){this.width=0,this.height=0,null!==t&&null!==e&&(this.height=e,this.width=t)}r.prototype.getWidth=function(){return this.width},r.prototype.setWidth=function(t){this.width=t},r.prototype.getHeight=function(){return this.height},r.prototype.setHeight=function(t){this.height=t},t.exports=r},function(t,e,i){"use strict";var r=i(14);function n(){this.map={},this.keys=[]}n.prototype.put=function(t,e){var i=r.createID(t);this.contains(i)||(this.map[i]=e,this.keys.push(t))},n.prototype.contains=function(t){return r.createID(t),null!=this.map[t]},n.prototype.get=function(t){var e=r.createID(t);return this.map[e]},n.prototype.keySet=function(){return this.keys},t.exports=n},function(t,e,i){"use strict";var r=i(14);function n(){this.set={}}n.prototype.add=function(t){var e=r.createID(t);this.contains(e)||(this.set[e]=t)},n.prototype.remove=function(t){delete this.set[r.createID(t)]},n.prototype.clear=function(){this.set={}},n.prototype.contains=function(t){return this.set[r.createID(t)]==t},n.prototype.isEmpty=function(){return 0===this.size()},n.prototype.size=function(){return Object.keys(this.set).length},n.prototype.addAllTo=function(t){for(var e=Object.keys(this.set),i=e.length,r=0;r<i;r++)t.push(this.set[e[r]])},n.prototype.size=function(){return Object.keys(this.set).length},n.prototype.addAll=function(t){for(var e=t.length,i=0;i<e;i++){var r=t[i];this.add(r)}},t.exports=n},function(t,e,i){"use strict";var r=function(){function t(t,e){for(var i=0;i<e.length;i++){var r=e[i];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,i,r){return i&&t(e.prototype,i),r&&t(e,r),e}}(),n=i(11),o=function(){function t(e,i){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),null===i&&void 0===i||(this.compareFunction=this._defaultCompareFunction);var r=void 0;r=e instanceof n?e.size():e.length,this._quicksort(e,0,r-1)}return r(t,[{key:"_quicksort",value:function(t,e,i){if(e<i){var r=this._partition(t,e,i);this._quicksort(t,e,r),this._quicksort(t,r+1,i)}}},{key:"_partition",value:function(t,e,i){for(var r=this._get(t,e),n=e,o=i;;){for(;this.compareFunction(r,this._get(t,o));)o--;for(;this.compareFunction(this._get(t,n),r);)n++;if(!(n<o))return o;this._swap(t,n,o),n++,o--}}},{key:"_get",value:function(t,e){return t instanceof n?t.get_object_at(e):t[e]}},{key:"_set",value:function(t,e,i){t instanceof n?t.set_object_at(e,i):t[e]=i}},{key:"_swap",value:function(t,e,i){var r=this._get(t,e);this._set(t,e,this._get(t,i)),this._set(t,i,r)}},{key:"_defaultCompareFunction",value:function(t,e){return e>t}}]),t}();t.exports=o},function(t,e,i){"use strict";var r=function(){function t(t,e){for(var i=0;i<e.length;i++){var r=e[i];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,i,r){return i&&t(e.prototype,i),r&&t(e,r),e}}(),n=function(){function t(e,i){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:-1,o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:-1;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.sequence1=e,this.sequence2=i,this.match_score=r,this.mismatch_penalty=n,this.gap_penalty=o,this.iMax=e.length+1,this.jMax=i.length+1,this.grid=new Array(this.iMax);for(var s=0;s<this.iMax;s++){this.grid[s]=new Array(this.jMax);for(var a=0;a<this.jMax;a++)this.grid[s][a]=0}this.tracebackGrid=new Array(this.iMax);for(var h=0;h<this.iMax;h++){this.tracebackGrid[h]=new Array(this.jMax);for(var l=0;l<this.jMax;l++)this.tracebackGrid[h][l]=[null,null,null]}this.alignments=[],this.score=-1,this.computeGrids()}return r(t,[{key:"getScore",value:function(){return this.score}},{key:"getAlignments",value:function(){return this.alignments}},{key:"computeGrids",value:function(){for(var t=1;t<this.jMax;t++)this.grid[0][t]=this.grid[0][t-1]+this.gap_penalty,this.tracebackGrid[0][t]=[!1,!1,!0];for(var e=1;e<this.iMax;e++)this.grid[e][0]=this.grid[e-1][0]+this.gap_penalty,this.tracebackGrid[e][0]=[!1,!0,!1];for(var i=1;i<this.iMax;i++)for(var r=1;r<this.jMax;r++){var n=[this.sequence1[i-1]===this.sequence2[r-1]?this.grid[i-1][r-1]+this.match_score:this.grid[i-1][r-1]+this.mismatch_penalty,this.grid[i-1][r]+this.gap_penalty,this.grid[i][r-1]+this.gap_penalty],o=this.arrayAllMaxIndexes(n);this.grid[i][r]=n[o[0]],this.tracebackGrid[i][r]=[o.includes(0),o.includes(1),o.includes(2)]}this.score=this.grid[this.iMax-1][this.jMax-1]}},{key:"alignmentTraceback",value:function(){var t=[];for(t.push({pos:[this.sequence1.length,this.sequence2.length],seq1:"",seq2:""});t[0];){var e=t[0],i=this.tracebackGrid[e.pos[0]][e.pos[1]];i[0]&&t.push({pos:[e.pos[0]-1,e.pos[1]-1],seq1:this.sequence1[e.pos[0]-1]+e.seq1,seq2:this.sequence2[e.pos[1]-1]+e.seq2}),i[1]&&t.push({pos:[e.pos[0]-1,e.pos[1]],seq1:this.sequence1[e.pos[0]-1]+e.seq1,seq2:"-"+e.seq2}),i[2]&&t.push({pos:[e.pos[0],e.pos[1]-1],seq1:"-"+e.seq1,seq2:this.sequence2[e.pos[1]-1]+e.seq2}),0===e.pos[0]&&0===e.pos[1]&&this.alignments.push({sequence1:e.seq1,sequence2:e.seq2}),t.shift()}return this.alignments}},{key:"getAllIndexes",value:function(t,e){for(var i=[],r=-1;-1!==(r=t.indexOf(e,r+1));)i.push(r);return i}},{key:"arrayAllMaxIndexes",value:function(t){return this.getAllIndexes(t,Math.max.apply(null,t))}}]),t}();t.exports=n},function(t,e,i){"use strict";var r=function(){};r.FDLayout=i(18),r.FDLayoutConstants=i(7),r.FDLayoutEdge=i(19),r.FDLayoutNode=i(20),r.DimensionD=i(21),r.HashMap=i(22),r.HashSet=i(23),r.IGeometry=i(8),r.IMath=i(9),r.Integer=i(10),r.Point=i(12),r.PointD=i(4),r.RandomSeed=i(16),r.RectangleD=i(13),r.Transform=i(17),r.UniqueIDGeneretor=i(14),r.Quicksort=i(24),r.LinkedList=i(11),r.LGraphObject=i(2),r.LGraph=i(5),r.LEdge=i(1),r.LGraphManager=i(6),r.LNode=i(3),r.Layout=i(15),r.LayoutConstants=i(0),r.NeedlemanWunsch=i(25),t.exports=r},function(t,e,i){"use strict";function r(){this.listeners=[]}var n=r.prototype;n.addListener=function(t,e){this.listeners.push({event:t,callback:e})},n.removeListener=function(t,e){for(var i=this.listeners.length;i>=0;i--){var r=this.listeners[i];r.event===t&&r.callback===e&&this.listeners.splice(i,1)}},n.emit=function(t,e){for(var i=0;i<this.listeners.length;i++){var r=this.listeners[i];t===r.event&&r.callback(e)}},t.exports=r}])},t.exports=e()},43457:function(t,e,i){var r;r=function(t){return function(t){var e={};function i(r){if(e[r])return e[r].exports;var n=e[r]={i:r,l:!1,exports:{}};return t[r].call(n.exports,n,n.exports,i),n.l=!0,n.exports}return i.m=t,i.c=e,i.i=function(t){return t},i.d=function(t,e,r){i.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:r})},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=1)}([function(e,i){e.exports=t},function(t,e,i){"use strict";var r=i(0).layoutBase.LayoutConstants,n=i(0).layoutBase.FDLayoutConstants,o=i(0).CoSEConstants,s=i(0).CoSELayout,a=i(0).CoSENode,h=i(0).layoutBase.PointD,l=i(0).layoutBase.DimensionD,g={ready:function(){},stop:function(){},quality:"default",nodeDimensionsIncludeLabels:!1,refresh:30,fit:!0,padding:10,randomize:!0,nodeRepulsion:4500,idealEdgeLength:50,edgeElasticity:.45,nestingFactor:.1,gravity:.25,numIter:2500,tile:!0,animate:"end",animationDuration:500,tilingPaddingVertical:10,tilingPaddingHorizontal:10,gravityRangeCompound:1.5,gravityCompound:1,gravityRange:3.8,initialEnergyOnIncremental:.5};function u(t){this.options=function(t,e){var i={};for(var r in t)i[r]=t[r];for(var r in e)i[r]=e[r];return i}(g,t),c(this.options)}var c=function(t){null!=t.nodeRepulsion&&(o.DEFAULT_REPULSION_STRENGTH=n.DEFAULT_REPULSION_STRENGTH=t.nodeRepulsion),null!=t.idealEdgeLength&&(o.DEFAULT_EDGE_LENGTH=n.DEFAULT_EDGE_LENGTH=t.idealEdgeLength),null!=t.edgeElasticity&&(o.DEFAULT_SPRING_STRENGTH=n.DEFAULT_SPRING_STRENGTH=t.edgeElasticity),null!=t.nestingFactor&&(o.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=n.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=t.nestingFactor),null!=t.gravity&&(o.DEFAULT_GRAVITY_STRENGTH=n.DEFAULT_GRAVITY_STRENGTH=t.gravity),null!=t.numIter&&(o.MAX_ITERATIONS=n.MAX_ITERATIONS=t.numIter),null!=t.gravityRange&&(o.DEFAULT_GRAVITY_RANGE_FACTOR=n.DEFAULT_GRAVITY_RANGE_FACTOR=t.gravityRange),null!=t.gravityCompound&&(o.DEFAULT_COMPOUND_GRAVITY_STRENGTH=n.DEFAULT_COMPOUND_GRAVITY_STRENGTH=t.gravityCompound),null!=t.gravityRangeCompound&&(o.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=n.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=t.gravityRangeCompound),null!=t.initialEnergyOnIncremental&&(o.DEFAULT_COOLING_FACTOR_INCREMENTAL=n.DEFAULT_COOLING_FACTOR_INCREMENTAL=t.initialEnergyOnIncremental),"draft"==t.quality?r.QUALITY=0:"proof"==t.quality?r.QUALITY=2:r.QUALITY=1,o.NODE_DIMENSIONS_INCLUDE_LABELS=n.NODE_DIMENSIONS_INCLUDE_LABELS=r.NODE_DIMENSIONS_INCLUDE_LABELS=t.nodeDimensionsIncludeLabels,o.DEFAULT_INCREMENTAL=n.DEFAULT_INCREMENTAL=r.DEFAULT_INCREMENTAL=!t.randomize,o.ANIMATE=n.ANIMATE=r.ANIMATE=t.animate,o.TILE=t.tile,o.TILING_PADDING_VERTICAL="function"==typeof t.tilingPaddingVertical?t.tilingPaddingVertical.call():t.tilingPaddingVertical,o.TILING_PADDING_HORIZONTAL="function"==typeof t.tilingPaddingHorizontal?t.tilingPaddingHorizontal.call():t.tilingPaddingHorizontal};u.prototype.run=function(){var t,e,i=this.options,r=(this.idToLNode={},this.layout=new s),n=this;n.stopped=!1,this.cy=this.options.cy,this.cy.trigger({type:"layoutstart",layout:this});var o=r.newGraphManager();this.gm=o;var a=this.options.eles.nodes(),h=this.options.eles.edges();this.root=o.addRoot(),this.processChildrenList(this.root,this.getTopMostNodes(a),r);for(var l=0;l<h.length;l++){var g=h[l],u=this.idToLNode[g.data("source")],c=this.idToLNode[g.data("target")];u!==c&&0==u.getEdgesBetween(c).length&&(o.add(r.newEdge(),u,c).id=g.id())}var d=function(t,e){"number"==typeof t&&(t=e);var i=t.data("id"),r=n.idToLNode[i];return{x:r.getRect().getCenterX(),y:r.getRect().getCenterY()}},p=function o(){for(var s,a=function(){i.fit&&i.cy.fit(i.eles,i.padding),t||(t=!0,n.cy.one("layoutready",i.ready),n.cy.trigger({type:"layoutready",layout:n}))},h=n.options.refresh,l=0;l<h&&!s;l++)s=n.stopped||n.layout.tick();if(s)return r.checkLayoutSuccess()&&!r.isSubLayout&&r.doPostLayout(),r.tilingPostLayout&&r.tilingPostLayout(),r.isLayoutFinished=!0,n.options.eles.nodes().positions(d),a(),n.cy.one("layoutstop",n.options.stop),n.cy.trigger({type:"layoutstop",layout:n}),e&&cancelAnimationFrame(e),void(t=!1);var g=n.layout.getPositionsData();i.eles.nodes().positions(function(t,e){if("number"==typeof t&&(t=e),!t.isParent()){for(var i=t.id(),r=g[i],n=t;null==r&&(r=g[n.data("parent")]||g["DummyCompound_"+n.data("parent")],g[i]=r,null!=(n=n.parent()[0])););return null!=r?{x:r.x,y:r.y}:{x:t.position("x"),y:t.position("y")}}}),a(),e=requestAnimationFrame(o)};return r.addListener("layoutstarted",function(){"during"===n.options.animate&&(e=requestAnimationFrame(p))}),r.runLayout(),"during"!==this.options.animate&&(n.options.eles.nodes().not(":parent").layoutPositions(n,n.options,d),t=!1),this},u.prototype.getTopMostNodes=function(t){for(var e={},i=0;i<t.length;i++)e[t[i].id()]=!0;var r=t.filter(function(t,i){"number"==typeof t&&(t=i);for(var r=t.parent()[0];null!=r;){if(e[r.id()])return!1;r=r.parent()[0]}return!0});return r},u.prototype.processChildrenList=function(t,e,i){for(var r=e.length,n=0;n<r;n++){var o,s,g=e[n],u=g.children(),c=g.layoutDimensions({nodeDimensionsIncludeLabels:this.options.nodeDimensionsIncludeLabels});if((o=null!=g.outerWidth()&&null!=g.outerHeight()?t.add(new a(i.graphManager,new h(g.position("x")-c.w/2,g.position("y")-c.h/2),new l(parseFloat(c.w),parseFloat(c.h)))):t.add(new a(this.graphManager))).id=g.data("id"),o.paddingLeft=parseInt(g.css("padding")),o.paddingTop=parseInt(g.css("padding")),o.paddingRight=parseInt(g.css("padding")),o.paddingBottom=parseInt(g.css("padding")),this.options.nodeDimensionsIncludeLabels&&g.isParent()){var d=g.boundingBox({includeLabels:!0,includeNodes:!1}).w,p=g.boundingBox({includeLabels:!0,includeNodes:!1}).h,f=g.css("text-halign");o.labelWidth=d,o.labelHeight=p,o.labelPos=f}this.idToLNode[g.data("id")]=o,isNaN(o.rect.x)&&(o.rect.x=0),isNaN(o.rect.y)&&(o.rect.y=0),null!=u&&u.length>0&&(s=i.getGraphManager().add(i.newGraph(),o),this.processChildrenList(s,u,i))}},u.prototype.stop=function(){return this.stopped=!0,this};var d=function(t){t("layout","cose-bilkent",u)};"undefined"!=typeof cytoscape&&d(cytoscape),t.exports=d}])},t.exports=r(i(87799))},77928:(t,e,i)=>{"use strict";i.r(e),i.d(e,{render:()=>p});var r=i(40797),n=i(90165),o=i(43457),s=i(70451);function a(t,e){t.forEach(t=>{const i={id:t.id,labelText:t.label,height:t.height,width:t.width,padding:t.padding??0};Object.keys(t).forEach(e=>{["id","label","height","width","padding","x","y"].includes(e)||(i[e]=t[e])}),e.add({group:"nodes",data:i,position:{x:t.x??0,y:t.y??0}})})}function h(t,e){t.forEach(t=>{const i={id:t.id,source:t.start,target:t.end};Object.keys(t).forEach(e=>{["id","start","end"].includes(e)||(i[e]=t[e])}),e.add({group:"edges",data:i})})}function l(t){return new Promise(e=>{const i=(0,s.Ltv)("body").append("div").attr("id","cy").attr("style","display:none"),o=(0,n.A)({container:document.getElementById("cy"),style:[{selector:"edge",style:{"curve-style":"bezier"}}]});i.remove(),a(t.nodes,o),h(t.edges,o),o.nodes().forEach(function(t){t.layoutDimensions=()=>{const e=t.data();return{w:e.width,h:e.height}}});o.layout({name:"cose-bilkent",quality:"proof",styleEnabled:!1,animate:!1}).run(),o.ready(t=>{r.Rm.info("Cytoscape ready",t),e(o)})})}function g(t){return t.nodes().map(t=>{const e=t.data(),i=t.position(),r={id:e.id,x:i.x,y:i.y};return Object.keys(e).forEach(t=>{"id"!==t&&(r[t]=e[t])}),r})}function u(t){return t.edges().map(t=>{const e=t.data(),i=t._private.rscratch,r={id:e.id,source:e.source,target:e.target,startX:i.startX,startY:i.startY,midX:i.midX,midY:i.midY,endX:i.endX,endY:i.endY};return Object.keys(e).forEach(t=>{["id","source","target"].includes(t)||(r[t]=e[t])}),r})}async function c(t,e){r.Rm.debug("Starting cose-bilkent layout algorithm");try{d(t);const e=await l(t),i=g(e),n=u(e);return r.Rm.debug(`Layout completed: ${i.length} nodes, ${n.length} edges`),{nodes:i,edges:n}}catch(i){throw r.Rm.error("Error in cose-bilkent layout algorithm:",i),i}}function d(t){if(!t)throw new Error("Layout data is required");if(!t.config)throw new Error("Configuration is required in layout data");if(!t.rootNode)throw new Error("Root node is required");if(!t.nodes||!Array.isArray(t.nodes))throw new Error("No nodes found in layout data");if(!Array.isArray(t.edges))throw new Error("Edges array is required in layout data");return!0}n.A.use(o),(0,r.K2)(a,"addNodes"),(0,r.K2)(h,"addEdges"),(0,r.K2)(l,"createCytoscapeInstance"),(0,r.K2)(g,"extractPositionedNodes"),(0,r.K2)(u,"extractPositionedEdges"),(0,r.K2)(c,"executeCoseBilkentLayout"),(0,r.K2)(d,"validateLayoutData");var p=(0,r.K2)(async(t,e,{insertCluster:i,insertEdge:r,insertEdgeLabel:n,insertMarkers:o,insertNode:s,log:a,positionEdgeLabel:h},{algorithm:l})=>{const g={},u={},d=e.select("g");o(d,t.markers,t.type,t.diagramId);const p=d.insert("g").attr("class","subgraphs"),f=d.insert("g").attr("class","edgePaths"),y=d.insert("g").attr("class","edgeLabels"),E=d.insert("g").attr("class","nodes");a.debug("Inserting nodes into DOM for dimension calculation"),await Promise.all(t.nodes.map(async e=>{if(e.isGroup){const t={...e};u[e.id]=t,g[e.id]=t,await i(p,e)}else{const i={...e};g[e.id]=i;const r=await s(E,e,{config:t.config,dir:t.direction||"TB"}),n=r.node().getBBox();i.width=n.width,i.height=n.height,i.domId=r,a.debug(`Node ${e.id} dimensions: ${n.width}x${n.height}`)}})),a.debug("Running cose-bilkent layout algorithm");const v={...t,nodes:t.nodes.map(t=>{const e=g[t.id];return{...t,width:e.width,height:e.height}})},A=await c(v,t.config);a.debug("Positioning nodes based on layout results"),A.nodes.forEach(t=>{const e=g[t.id];e?.domId&&(e.domId.attr("transform",`translate(${t.x}, ${t.y})`),e.x=t.x,e.y=t.y,a.debug(`Positioned node ${e.id} at center (${t.x}, ${t.y})`))}),A.edges.forEach(e=>{const i=t.edges.find(t=>t.id===e.id);i&&(i.points=[{x:e.startX,y:e.startY},{x:e.midX,y:e.midY},{x:e.endX,y:e.endY}])}),a.debug("Inserting and positioning edges"),await Promise.all(t.edges.map(async e=>{await n(y,e);const i=g[e.start??""],o=g[e.end??""];if(i&&o){const n=A.edges.find(t=>t.id===e.id);if(n){a.debug("APA01 positionedEdge",n);const s={...e},l=r(f,s,u,t.type,i,o,t.diagramId);h(s,l)}else{const n={...e,points:[{x:i.x||0,y:i.y||0},{x:o.x||0,y:o.y||0}]},s=r(f,n,u,t.type,i,o,t.diagramId);h(n,s)}}})),a.debug("Cose-bilkent rendering completed")},"render")},87799:function(t,e,i){var r;r=function(t){return function(t){var e={};function i(r){if(e[r])return e[r].exports;var n=e[r]={i:r,l:!1,exports:{}};return t[r].call(n.exports,n,n.exports,i),n.l=!0,n.exports}return i.m=t,i.c=e,i.i=function(t){return t},i.d=function(t,e,r){i.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:r})},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=7)}([function(e,i){e.exports=t},function(t,e,i){"use strict";var r=i(0).FDLayoutConstants;function n(){}for(var o in r)n[o]=r[o];n.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,n.DEFAULT_RADIAL_SEPARATION=r.DEFAULT_EDGE_LENGTH,n.DEFAULT_COMPONENT_SEPERATION=60,n.TILE=!0,n.TILING_PADDING_VERTICAL=10,n.TILING_PADDING_HORIZONTAL=10,n.TREE_REDUCTION_ON_INCREMENTAL=!1,t.exports=n},function(t,e,i){"use strict";var r=i(0).FDLayoutEdge;function n(t,e,i){r.call(this,t,e,i)}for(var o in n.prototype=Object.create(r.prototype),r)n[o]=r[o];t.exports=n},function(t,e,i){"use strict";var r=i(0).LGraph;function n(t,e,i){r.call(this,t,e,i)}for(var o in n.prototype=Object.create(r.prototype),r)n[o]=r[o];t.exports=n},function(t,e,i){"use strict";var r=i(0).LGraphManager;function n(t){r.call(this,t)}for(var o in n.prototype=Object.create(r.prototype),r)n[o]=r[o];t.exports=n},function(t,e,i){"use strict";var r=i(0).FDLayoutNode,n=i(0).IMath;function o(t,e,i,n){r.call(this,t,e,i,n)}for(var s in o.prototype=Object.create(r.prototype),r)o[s]=r[s];o.prototype.move=function(){var t=this.graphManager.getLayout();this.displacementX=t.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY=t.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren,Math.abs(this.displacementX)>t.coolingFactor*t.maxNodeDisplacement&&(this.displacementX=t.coolingFactor*t.maxNodeDisplacement*n.sign(this.displacementX)),Math.abs(this.displacementY)>t.coolingFactor*t.maxNodeDisplacement&&(this.displacementY=t.coolingFactor*t.maxNodeDisplacement*n.sign(this.displacementY)),null==this.child||0==this.child.getNodes().length?this.moveBy(this.displacementX,this.displacementY):this.propogateDisplacementToChildren(this.displacementX,this.displacementY),t.totalDisplacement+=Math.abs(this.displacementX)+Math.abs(this.displacementY),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0},o.prototype.propogateDisplacementToChildren=function(t,e){for(var i,r=this.getChild().getNodes(),n=0;n<r.length;n++)null==(i=r[n]).getChild()?(i.moveBy(t,e),i.displacementX+=t,i.displacementY+=e):i.propogateDisplacementToChildren(t,e)},o.prototype.setPred1=function(t){this.pred1=t},o.prototype.getPred1=function(){return pred1},o.prototype.getPred2=function(){return pred2},o.prototype.setNext=function(t){this.next=t},o.prototype.getNext=function(){return next},o.prototype.setProcessed=function(t){this.processed=t},o.prototype.isProcessed=function(){return processed},t.exports=o},function(t,e,i){"use strict";var r=i(0).FDLayout,n=i(4),o=i(3),s=i(5),a=i(2),h=i(1),l=i(0).FDLayoutConstants,g=i(0).LayoutConstants,u=i(0).Point,c=i(0).PointD,d=i(0).Layout,p=i(0).Integer,f=i(0).IGeometry,y=i(0).LGraph,E=i(0).Transform;function v(){r.call(this),this.toBeTiled={}}for(var A in v.prototype=Object.create(r.prototype),r)v[A]=r[A];v.prototype.newGraphManager=function(){var t=new n(this);return this.graphManager=t,t},v.prototype.newGraph=function(t){return new o(null,this.graphManager,t)},v.prototype.newNode=function(t){return new s(this.graphManager,t)},v.prototype.newEdge=function(t){return new a(null,null,t)},v.prototype.initParameters=function(){r.prototype.initParameters.call(this,arguments),this.isSubLayout||(h.DEFAULT_EDGE_LENGTH<10?this.idealEdgeLength=10:this.idealEdgeLength=h.DEFAULT_EDGE_LENGTH,this.useSmartIdealEdgeLengthCalculation=h.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.springConstant=l.DEFAULT_SPRING_STRENGTH,this.repulsionConstant=l.DEFAULT_REPULSION_STRENGTH,this.gravityConstant=l.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=l.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=l.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=l.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.prunedNodesAll=[],this.growTreeIterations=0,this.afterGrowthIterations=0,this.isTreeGrowing=!1,this.isGrowthFinished=!1,this.coolingCycle=0,this.maxCoolingCycle=this.maxIterations/l.CONVERGENCE_CHECK_PERIOD,this.finalTemperature=l.CONVERGENCE_CHECK_PERIOD/this.maxIterations,this.coolingAdjuster=1)},v.prototype.layout=function(){return g.DEFAULT_CREATE_BENDS_AS_NEEDED&&(this.createBendpoints(),this.graphManager.resetAllEdges()),this.level=0,this.classicLayout()},v.prototype.classicLayout=function(){if(this.nodesWithGravity=this.calculateNodesToApplyGravitationTo(),this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity),this.calcNoOfChildrenForAllNodes(),this.graphManager.calcLowestCommonAncestors(),this.graphManager.calcInclusionTreeDepths(),this.graphManager.getRoot().calcEstimatedSize(),this.calcIdealEdgeLengths(),this.incremental)h.TREE_REDUCTION_ON_INCREMENTAL&&(this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation(),e=new Set(this.getAllNodes()),i=this.nodesWithGravity.filter(function(t){return e.has(t)}),this.graphManager.setAllNodesToApplyGravitation(i));else{var t=this.getFlatForest();if(t.length>0)this.positionNodesRadially(t);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var e=new Set(this.getAllNodes()),i=this.nodesWithGravity.filter(function(t){return e.has(t)});this.graphManager.setAllNodesToApplyGravitation(i),this.positionNodesRandomly()}}return this.initSpringEmbedder(),this.runSpringEmbedder(),!0},v.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished){if(!(this.prunedNodesAll.length>0))return!0;this.isTreeGrowing=!0}if(this.totalIterations%l.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged()){if(!(this.prunedNodesAll.length>0))return!0;this.isTreeGrowing=!0}this.coolingCycle++,0==this.layoutQuality?this.coolingAdjuster=this.coolingCycle:1==this.layoutQuality&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var t=new Set(this.getAllNodes()),e=this.nodesWithGravity.filter(function(e){return t.has(e)});this.graphManager.setAllNodesToApplyGravitation(e),this.graphManager.updateBounds(),this.updateGrid(),this.coolingFactor=l.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),this.coolingFactor=l.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var i=!this.isTreeGrowing&&!this.isGrowthFinished,r=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(i,r),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},v.prototype.getPositionsData=function(){for(var t=this.graphManager.getAllNodes(),e={},i=0;i<t.length;i++){var r=t[i].rect,n=t[i].id;e[n]={id:n,x:r.getCenterX(),y:r.getCenterY(),w:r.width,h:r.height}}return e},v.prototype.runSpringEmbedder=function(){this.initialAnimationPeriod=25,this.animationPeriod=this.initialAnimationPeriod;var t=!1;if("during"===l.ANIMATE)this.emit("layoutstarted");else{for(;!t;)t=this.tick();this.graphManager.updateBounds()}},v.prototype.calculateNodesToApplyGravitationTo=function(){var t,e,i=[],r=this.graphManager.getGraphs(),n=r.length;for(e=0;e<n;e++)(t=r[e]).updateConnected(),t.isConnected||(i=i.concat(t.getNodes()));return i},v.prototype.createBendpoints=function(){var t=[];t=t.concat(this.graphManager.getAllEdges());var e,i=new Set;for(e=0;e<t.length;e++){var r=t[e];if(!i.has(r)){var n=r.getSource(),o=r.getTarget();if(n==o)r.getBendpoints().push(new c),r.getBendpoints().push(new c),this.createDummyNodesForBendpoints(r),i.add(r);else{var s=[];if(s=(s=s.concat(n.getEdgeListToNode(o))).concat(o.getEdgeListToNode(n)),!i.has(s[0])){var a;if(s.length>1)for(a=0;a<s.length;a++){var h=s[a];h.getBendpoints().push(new c),this.createDummyNodesForBendpoints(h)}s.forEach(function(t){i.add(t)})}}}if(i.size==t.length)break}},v.prototype.positionNodesRadially=function(t){for(var e=new u(0,0),i=Math.ceil(Math.sqrt(t.length)),r=0,n=0,o=0,s=new c(0,0),a=0;a<t.length;a++){a%i==0&&(o=0,n=r,0!=a&&(n+=h.DEFAULT_COMPONENT_SEPERATION),r=0);var l=t[a],p=d.findCenterOfTree(l);e.x=o,e.y=n,(s=v.radialLayout(l,p,e)).y>r&&(r=Math.floor(s.y)),o=Math.floor(s.x+h.DEFAULT_COMPONENT_SEPERATION)}this.transform(new c(g.WORLD_CENTER_X-s.x/2,g.WORLD_CENTER_Y-s.y/2))},v.radialLayout=function(t,e,i){var r=Math.max(this.maxDiagonalInTree(t),h.DEFAULT_RADIAL_SEPARATION);v.branchRadialLayout(e,null,0,359,0,r);var n=y.calculateBounds(t),o=new E;o.setDeviceOrgX(n.getMinX()),o.setDeviceOrgY(n.getMinY()),o.setWorldOrgX(i.x),o.setWorldOrgY(i.y);for(var s=0;s<t.length;s++)t[s].transform(o);var a=new c(n.getMaxX(),n.getMaxY());return o.inverseTransformPoint(a)},v.branchRadialLayout=function(t,e,i,r,n,o){var s=(r-i+1)/2;s<0&&(s+=180);var a=(s+i)%360*f.TWO_PI/360,h=(Math.cos(a),n*Math.cos(a)),l=n*Math.sin(a);t.setCenter(h,l);var g=[],u=(g=g.concat(t.getEdges())).length;null!=e&&u--;for(var c,d=0,p=g.length,y=t.getEdgesBetween(e);y.length>1;){var E=y[0];y.splice(0,1);var A=g.indexOf(E);A>=0&&g.splice(A,1),p--,u--}c=null!=e?(g.indexOf(y[0])+1)%p:0;for(var N=Math.abs(r-i)/u,T=c;d!=u;T=++T%p){var L=g[T].getOtherEnd(t);if(L!=e){var _=(i+d*N)%360,m=(_+N)%360;v.branchRadialLayout(L,t,_,m,n+o,o),d++}}},v.maxDiagonalInTree=function(t){for(var e=p.MIN_VALUE,i=0;i<t.length;i++){var r=t[i].getDiagonal();r>e&&(e=r)}return e},v.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},v.prototype.groupZeroDegreeMembers=function(){var t=this,e={};this.memberGroups={},this.idToDummyNode={};for(var i=[],r=this.graphManager.getAllNodes(),n=0;n<r.length;n++){var o=(a=r[n]).getParent();0!==this.getNodeDegreeWithChildren(a)||null!=o.id&&this.getToBeTiled(o)||i.push(a)}for(n=0;n<i.length;n++){var a,h=(a=i[n]).getParent().id;void 0===e[h]&&(e[h]=[]),e[h]=e[h].concat(a)}Object.keys(e).forEach(function(i){if(e[i].length>1){var r="DummyCompound_"+i;t.memberGroups[r]=e[i];var n=e[i][0].getParent(),o=new s(t.graphManager);o.id=r,o.paddingLeft=n.paddingLeft||0,o.paddingRight=n.paddingRight||0,o.paddingBottom=n.paddingBottom||0,o.paddingTop=n.paddingTop||0,t.idToDummyNode[r]=o;var a=t.getGraphManager().add(t.newGraph(),o),h=n.getChild();h.add(o);for(var l=0;l<e[i].length;l++){var g=e[i][l];h.remove(g),a.add(g)}}})},v.prototype.clearCompounds=function(){var t={},e={};this.performDFSOnCompounds();for(var i=0;i<this.compoundOrder.length;i++)e[this.compoundOrder[i].id]=this.compoundOrder[i],t[this.compoundOrder[i].id]=[].concat(this.compoundOrder[i].getChild().getNodes()),this.graphManager.remove(this.compoundOrder[i].getChild()),this.compoundOrder[i].child=null;this.graphManager.resetAllNodes(),this.tileCompoundMembers(t,e)},v.prototype.clearZeroDegreeMembers=function(){var t=this,e=this.tiledZeroDegreePack=[];Object.keys(this.memberGroups).forEach(function(i){var r=t.idToDummyNode[i];e[i]=t.tileNodes(t.memberGroups[i],r.paddingLeft+r.paddingRight),r.rect.width=e[i].width,r.rect.height=e[i].height})},v.prototype.repopulateCompounds=function(){for(var t=this.compoundOrder.length-1;t>=0;t--){var e=this.compoundOrder[t],i=e.id,r=e.paddingLeft,n=e.paddingTop;this.adjustLocations(this.tiledMemberPack[i],e.rect.x,e.rect.y,r,n)}},v.prototype.repopulateZeroDegreeMembers=function(){var t=this,e=this.tiledZeroDegreePack;Object.keys(e).forEach(function(i){var r=t.idToDummyNode[i],n=r.paddingLeft,o=r.paddingTop;t.adjustLocations(e[i],r.rect.x,r.rect.y,n,o)})},v.prototype.getToBeTiled=function(t){var e=t.id;if(null!=this.toBeTiled[e])return this.toBeTiled[e];var i=t.getChild();if(null==i)return this.toBeTiled[e]=!1,!1;for(var r=i.getNodes(),n=0;n<r.length;n++){var o=r[n];if(this.getNodeDegree(o)>0)return this.toBeTiled[e]=!1,!1;if(null!=o.getChild()){if(!this.getToBeTiled(o))return this.toBeTiled[e]=!1,!1}else this.toBeTiled[o.id]=!1}return this.toBeTiled[e]=!0,!0},v.prototype.getNodeDegree=function(t){t.id;for(var e=t.getEdges(),i=0,r=0;r<e.length;r++){var n=e[r];n.getSource().id!==n.getTarget().id&&(i+=1)}return i},v.prototype.getNodeDegreeWithChildren=function(t){var e=this.getNodeDegree(t);if(null==t.getChild())return e;for(var i=t.getChild().getNodes(),r=0;r<i.length;r++){var n=i[r];e+=this.getNodeDegreeWithChildren(n)}return e},v.prototype.performDFSOnCompounds=function(){this.compoundOrder=[],this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes())},v.prototype.fillCompexOrderByDFS=function(t){for(var e=0;e<t.length;e++){var i=t[e];null!=i.getChild()&&this.fillCompexOrderByDFS(i.getChild().getNodes()),this.getToBeTiled(i)&&this.compoundOrder.push(i)}},v.prototype.adjustLocations=function(t,e,i,r,n){i+=n;for(var o=e+=r,s=0;s<t.rows.length;s++){var a=t.rows[s];e=o;for(var h=0,l=0;l<a.length;l++){var g=a[l];g.rect.x=e,g.rect.y=i,e+=g.rect.width+t.horizontalPadding,g.rect.height>h&&(h=g.rect.height)}i+=h+t.verticalPadding}},v.prototype.tileCompoundMembers=function(t,e){var i=this;this.tiledMemberPack=[],Object.keys(t).forEach(function(r){var n=e[r];i.tiledMemberPack[r]=i.tileNodes(t[r],n.paddingLeft+n.paddingRight),n.rect.width=i.tiledMemberPack[r].width,n.rect.height=i.tiledMemberPack[r].height})},v.prototype.tileNodes=function(t,e){var i={rows:[],rowWidth:[],rowHeight:[],width:0,height:e,verticalPadding:h.TILING_PADDING_VERTICAL,horizontalPadding:h.TILING_PADDING_HORIZONTAL};t.sort(function(t,e){return t.rect.width*t.rect.height>e.rect.width*e.rect.height?-1:t.rect.width*t.rect.height<e.rect.width*e.rect.height?1:0});for(var r=0;r<t.length;r++){var n=t[r];0==i.rows.length?this.insertNodeToRow(i,n,0,e):this.canAddHorizontal(i,n.rect.width,n.rect.height)?this.insertNodeToRow(i,n,this.getShortestRowIndex(i),e):this.insertNodeToRow(i,n,i.rows.length,e),this.shiftToLastRow(i)}return i},v.prototype.insertNodeToRow=function(t,e,i,r){var n=r;i==t.rows.length&&(t.rows.push([]),t.rowWidth.push(n),t.rowHeight.push(0));var o=t.rowWidth[i]+e.rect.width;t.rows[i].length>0&&(o+=t.horizontalPadding),t.rowWidth[i]=o,t.width<o&&(t.width=o);var s=e.rect.height;i>0&&(s+=t.verticalPadding);var a=0;s>t.rowHeight[i]&&(a=t.rowHeight[i],t.rowHeight[i]=s,a=t.rowHeight[i]-a),t.height+=a,t.rows[i].push(e)},v.prototype.getShortestRowIndex=function(t){for(var e=-1,i=Number.MAX_VALUE,r=0;r<t.rows.length;r++)t.rowWidth[r]<i&&(e=r,i=t.rowWidth[r]);return e},v.prototype.getLongestRowIndex=function(t){for(var e=-1,i=Number.MIN_VALUE,r=0;r<t.rows.length;r++)t.rowWidth[r]>i&&(e=r,i=t.rowWidth[r]);return e},v.prototype.canAddHorizontal=function(t,e,i){var r=this.getShortestRowIndex(t);if(r<0)return!0;var n=t.rowWidth[r];if(n+t.horizontalPadding+e<=t.width)return!0;var o,s,a=0;return t.rowHeight[r]<i&&r>0&&(a=i+t.verticalPadding-t.rowHeight[r]),o=t.width-n>=e+t.horizontalPadding?(t.height+a)/(n+e+t.horizontalPadding):(t.height+a)/t.width,a=i+t.verticalPadding,(s=t.width<e?(t.height+a)/e:(t.height+a)/t.width)<1&&(s=1/s),o<1&&(o=1/o),o<s},v.prototype.shiftToLastRow=function(t){var e=this.getLongestRowIndex(t),i=t.rowWidth.length-1,r=t.rows[e],n=r[r.length-1],o=n.width+t.horizontalPadding;if(t.width-t.rowWidth[i]>o&&e!=i){r.splice(-1,1),t.rows[i].push(n),t.rowWidth[e]=t.rowWidth[e]-o,t.rowWidth[i]=t.rowWidth[i]+o,t.width=t.rowWidth[instance.getLongestRowIndex(t)];for(var s=Number.MIN_VALUE,a=0;a<r.length;a++)r[a].height>s&&(s=r[a].height);e>0&&(s+=t.verticalPadding);var h=t.rowHeight[e]+t.rowHeight[i];t.rowHeight[e]=s,t.rowHeight[i]<n.height+t.verticalPadding&&(t.rowHeight[i]=n.height+t.verticalPadding);var l=t.rowHeight[e]+t.rowHeight[i];t.height+=l-h,this.shiftToLastRow(t)}},v.prototype.tilingPreLayout=function(){h.TILE&&(this.groupZeroDegreeMembers(),this.clearCompounds(),this.clearZeroDegreeMembers())},v.prototype.tilingPostLayout=function(){h.TILE&&(this.repopulateZeroDegreeMembers(),this.repopulateCompounds())},v.prototype.reduceTrees=function(){for(var t,e=[],i=!0;i;){var r=this.graphManager.getAllNodes(),n=[];i=!1;for(var o=0;o<r.length;o++)1!=(t=r[o]).getEdges().length||t.getEdges()[0].isInterGraph||null!=t.getChild()||(n.push([t,t.getEdges()[0],t.getOwner()]),i=!0);if(1==i){for(var s=[],a=0;a<n.length;a++)1==n[a][0].getEdges().length&&(s.push(n[a]),n[a][0].getOwner().remove(n[a][0]));e.push(s),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()}}this.prunedNodesAll=e},v.prototype.growTree=function(t){for(var e,i=t[t.length-1],r=0;r<i.length;r++)e=i[r],this.findPlaceforPrunedNode(e),e[2].add(e[0]),e[2].add(e[1],e[1].source,e[1].target);t.splice(t.length-1,1),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()},v.prototype.findPlaceforPrunedNode=function(t){var e,i,r=t[0],n=(i=r==t[1].source?t[1].target:t[1].source).startX,o=i.finishX,s=i.startY,a=i.finishY,h=[0,0,0,0];if(s>0)for(var g=n;g<=o;g++)h[0]+=this.grid[g][s-1].length+this.grid[g][s].length-1;if(o<this.grid.length-1)for(g=s;g<=a;g++)h[1]+=this.grid[o+1][g].length+this.grid[o][g].length-1;if(a<this.grid[0].length-1)for(g=n;g<=o;g++)h[2]+=this.grid[g][a+1].length+this.grid[g][a].length-1;if(n>0)for(g=s;g<=a;g++)h[3]+=this.grid[n-1][g].length+this.grid[n][g].length-1;for(var u,c,d=p.MAX_VALUE,f=0;f<h.length;f++)h[f]<d?(d=h[f],u=1,c=f):h[f]==d&&u++;if(3==u&&0==d)0==h[0]&&0==h[1]&&0==h[2]?e=1:0==h[0]&&0==h[1]&&0==h[3]?e=0:0==h[0]&&0==h[2]&&0==h[3]?e=3:0==h[1]&&0==h[2]&&0==h[3]&&(e=2);else if(2==u&&0==d){var y=Math.floor(2*Math.random());e=0==h[0]&&0==h[1]?0==y?0:1:0==h[0]&&0==h[2]?0==y?0:2:0==h[0]&&0==h[3]?0==y?0:3:0==h[1]&&0==h[2]?0==y?1:2:0==h[1]&&0==h[3]?0==y?1:3:0==y?2:3}else e=4==u&&0==d?y=Math.floor(4*Math.random()):c;0==e?r.setCenter(i.getCenterX(),i.getCenterY()-i.getHeight()/2-l.DEFAULT_EDGE_LENGTH-r.getHeight()/2):1==e?r.setCenter(i.getCenterX()+i.getWidth()/2+l.DEFAULT_EDGE_LENGTH+r.getWidth()/2,i.getCenterY()):2==e?r.setCenter(i.getCenterX(),i.getCenterY()+i.getHeight()/2+l.DEFAULT_EDGE_LENGTH+r.getHeight()/2):r.setCenter(i.getCenterX()-i.getWidth()/2-l.DEFAULT_EDGE_LENGTH-r.getWidth()/2,i.getCenterY())},t.exports=v},function(t,e,i){"use strict";var r={};r.layoutBase=i(0),r.CoSEConstants=i(1),r.CoSEEdge=i(2),r.CoSEGraph=i(3),r.CoSEGraphManager=i(4),r.CoSELayout=i(6),r.CoSENode=i(5),t.exports=r}])},t.exports=r(i(23143))}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/794987bd.fa5e8276.js b/pr-preview/pr-4027/assets/js/794987bd.fa5e8276.js deleted file mode 100644 index 777f2c063..000000000 --- a/pr-preview/pr-4027/assets/js/794987bd.fa5e8276.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2947],{28453:(e,s,t)=>{t.d(s,{R:()=>o,x:()=>l});var n=t(96540);const r={},i=n.createContext(r);function o(e){const s=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(i.Provider,{value:s},e.children)}},73955:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"workflows/storage","title":"Use persistent storage","description":"Persistent storage in Kubernetes requires cloud-specific configuration.","source":"@site/versioned_docs/version-2.24/workflows/storage.md","sourceDirName":"workflows","slug":"/workflows/storage","permalink":"/constellation/pr-preview/pr-4027/workflows/storage","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/workflows/storage.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Verify your cluster","permalink":"/constellation/pr-preview/pr-4027/workflows/verify-cluster"},"next":{"title":"Use the Terraform provider","permalink":"/constellation/pr-preview/pr-4027/workflows/terraform-provider"}}');var r=t(74848),i=t(28453);const o={},l="Use persistent storage",a={},c=[{value:"Confidential storage",id:"confidential-storage",level:2},{value:"CSI drivers",id:"csi-drivers",level:2},{value:"Installation",id:"installation",level:2},{value:"Change the default storage class",id:"change-the-default-storage-class",level:3}];function d(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components},{TabItem:t,Tabs:n}=s;return t||p("TabItem",!0),n||p("Tabs",!0),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"use-persistent-storage",children:"Use persistent storage"})}),"\n",(0,r.jsxs)(s.p,{children:["Persistent storage in Kubernetes requires cloud-specific configuration.\nFor abstraction of container storage, Kubernetes offers ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/volumes/",children:"volumes"}),",\nallowing users to mount storage solutions directly into containers.\nThe ",(0,r.jsx)(s.a,{href:"https://kubernetes-csi.github.io/docs/",children:"Container Storage Interface (CSI)"})," is the standard interface for exposing arbitrary block and file storage systems into containers in Kubernetes.\nCloud service providers (CSPs) offer their own CSI-based solutions for cloud storage."]}),"\n",(0,r.jsx)(s.h2,{id:"confidential-storage",children:"Confidential storage"}),"\n",(0,r.jsxs)(s.p,{children:["Most cloud storage solutions support encryption, such as ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/kubernetes-engine/docs/how-to/using-cmek",children:"GCE Persistent Disks (PD)"}),".\nConstellation supports the available CSI-based storage options for Kubernetes engines in AWS, Azure, GCP, and STACKIT.\nHowever, their encryption takes place in the storage backend and is managed by the CSP.\nThus, using the default CSI drivers for these storage types means trusting the CSP with your persistent data."]}),"\n",(0,r.jsxs)(s.p,{children:["To address this, Constellation provides CSI drivers for AWS EBS, Azure Disk, GCE PD, and OpenStack Cinder, offering ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys#storage-encryption",children:"encryption on the node level"}),". They enable transparent encryption for persistent volumes without needing to trust the cloud backend. Plaintext data never leaves the confidential VM context, offering you confidential storage."]}),"\n",(0,r.jsxs)(s.p,{children:["For more details see ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/architecture/encrypted-storage",children:"encrypted persistent storage"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"csi-drivers",children:"CSI drivers"}),"\n",(0,r.jsx)(s.p,{children:"Constellation supports the following drivers, which offer node-level encryption and optional integrity protection."}),"\n",(0,r.jsxs)(n,{groupId:"csp",children:[(0,r.jsx)(t,{value:"aws",label:"AWS",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Constellation CSI driver for AWS Elastic Block Store"}),"\nMount ",(0,r.jsx)(s.a,{href:"https://aws.amazon.com/ebs/",children:"Elastic Block Store"})," storage volumes into your Constellation cluster.\nFollow the instructions on how to ",(0,r.jsx)(s.a,{href:"#installation",children:"install the Constellation CSI driver"})," or check out the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation-aws-ebs-csi-driver",children:"repository"})," for more information."]})}),(0,r.jsx)(t,{value:"azure",label:"Azure",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Constellation CSI driver for Azure Disk"}),":\nMount Azure ",(0,r.jsx)(s.a,{href:"https://azure.microsoft.com/en-us/services/storage/disks/#overview",children:"Disk Storage"})," into your Constellation cluster.\nSee the instructions on how to ",(0,r.jsx)(s.a,{href:"#installation",children:"install the Constellation CSI driver"})," or check out the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation-azuredisk-csi-driver",children:"repository"})," for more information.\nSince Azure Disks are mounted as ",(0,r.jsx)(s.code,{children:"ReadWriteOnce"}),", they're only available to a single pod."]})}),(0,r.jsx)(t,{value:"gcp",label:"GCP",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Constellation CSI driver for GCP Persistent Disk"}),":\nMount ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/persistent-disk",children:"Persistent Disk"})," block storage into your Constellation cluster.\nFollow the instructions on how to ",(0,r.jsx)(s.a,{href:"#installation",children:"install the Constellation CSI driver"})," or check out the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation-gcp-compute-persistent-disk-csi-driver",children:"repository"})," for more information."]})}),(0,r.jsx)(t,{value:"stackit",label:"STACKIT",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Constellation CSI driver for STACKIT / OpenStack Cinder"}),"\nMount ",(0,r.jsx)(s.a,{href:"https://docs.openstack.org/cinder/latest/",children:"Cinder"})," block storage volumes into your Constellation cluster.\nFollow the instructions on how to ",(0,r.jsx)(s.a,{href:"#installation",children:"install the Constellation CSI driver"})," or check out the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation-cloud-provider-openstack",children:"repository"})," for more information."]})})]}),"\n",(0,r.jsxs)(s.p,{children:["Note that in case the options above aren't a suitable solution for you, Constellation is compatible with all other CSI-based storage options. For example, you can use ",(0,r.jsx)(s.a,{href:"https://docs.aws.amazon.com/en_en/eks/latest/userguide/efs-csi.html",children:"AWS EFS"}),", ",(0,r.jsx)(s.a,{href:"https://docs.microsoft.com/en-us/azure/storage/files/storage-files-introduction",children:"Azure Files"}),", or ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/filestore",children:"GCP Filestore"})," with Constellation out of the box. Constellation is just not providing transparent encryption on the node level for these storage types yet."]}),"\n",(0,r.jsx)(s.h2,{id:"installation",children:"Installation"}),"\n",(0,r.jsxs)(s.p,{children:["The Constellation CLI automatically installs Constellation's CSI driver for the selected CSP in your cluster.\nIf you don't need a CSI driver or wish to deploy your own, you can disable the automatic installation by setting ",(0,r.jsx)(s.code,{children:"deployCSIDriver"})," to ",(0,r.jsx)(s.code,{children:"false"})," in your Constellation config file."]}),"\n",(0,r.jsxs)(n,{groupId:"csp",children:[(0,r.jsxs)(t,{value:"aws",label:"AWS",children:[(0,r.jsx)(s.p,{children:"AWS comes with two storage classes by default."}),(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsxs)(s.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volume-types.html",children:["SSDs of ",(0,r.jsx)(s.code,{children:"gp3"})," type"]})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsxs)(s.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volume-types.html",children:["SSDs of ",(0,r.jsx)(s.code,{children:"gp3"})," type"]})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n",(0,r.jsx)(s.li,{children:"Integrity protection of data written to disk"}),"\n"]}),"\n"]}),"\n"]}),(0,r.jsxs)(s.p,{children:["For more information on encryption algorithms and key sizes, refer to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/architecture/encrypted-storage#cryptographic-algorithms",children:"cryptographic algorithms"}),"."]}),(0,r.jsxs)(s.admonition,{type:"info",children:[(0,r.jsxs)(s.p,{children:["The default storage class is set to ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," for performance reasons.\nIf you want integrity-protected storage, set the ",(0,r.jsx)(s.code,{children:"storageClassName"})," parameter of your persistent volume claim to ",(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"."]}),(0,r.jsxs)(s.p,{children:["Alternatively, you can create your own storage class with integrity protection enabled by adding ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: ext4-integrity"})," to the class ",(0,r.jsx)(s.code,{children:"parameters"}),".\nOr use another filesystem by specifying another file system type with the suffix ",(0,r.jsx)(s.code,{children:"-integrity"}),", e.g., ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: xfs-integrity"}),"."]}),(0,r.jsx)(s.p,{children:"Note that volume expansion isn't supported for integrity-protected disks."})]})]}),(0,r.jsxs)(t,{value:"azure",label:"Azure",children:[(0,r.jsx)(s.p,{children:"Azure comes with two storage classes by default."}),(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsx)(s.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/disks-types#standard-ssds",children:"Standard SSDs"})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsx)(s.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/disks-types#premium-ssds",children:"Premium SSDs"})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n",(0,r.jsx)(s.li,{children:"Integrity protection of data written to disk"}),"\n"]}),"\n"]}),"\n"]}),(0,r.jsxs)(s.p,{children:["For more information on encryption algorithms and key sizes, refer to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/architecture/encrypted-storage#cryptographic-algorithms",children:"cryptographic algorithms"}),"."]}),(0,r.jsxs)(s.admonition,{type:"info",children:[(0,r.jsxs)(s.p,{children:["The default storage class is set to ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," for performance reasons.\nIf you want integrity-protected storage, set the ",(0,r.jsx)(s.code,{children:"storageClassName"})," parameter of your persistent volume claim to ",(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"."]}),(0,r.jsxs)(s.p,{children:["Alternatively, you can create your own storage class with integrity protection enabled by adding ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: ext4-integrity"})," to the class ",(0,r.jsx)(s.code,{children:"parameters"}),".\nOr use another filesystem by specifying another file system type with the suffix ",(0,r.jsx)(s.code,{children:"-integrity"}),", e.g., ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: xfs-integrity"}),"."]}),(0,r.jsx)(s.p,{children:"Note that volume expansion isn't supported for integrity-protected disks."})]})]}),(0,r.jsxs)(t,{value:"gcp",label:"GCP",children:[(0,r.jsx)(s.p,{children:"GCP comes with two storage classes by default."}),(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/compute/docs/disks#pdspecs",children:"standard persistent disks"})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/compute/docs/disks#pdspecs",children:"performance (SSD) persistent disks"})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n",(0,r.jsx)(s.li,{children:"Integrity protection of data written to disk"}),"\n"]}),"\n"]}),"\n"]}),(0,r.jsxs)(s.p,{children:["For more information on encryption algorithms and key sizes, refer to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/architecture/encrypted-storage#cryptographic-algorithms",children:"cryptographic algorithms"}),"."]}),(0,r.jsxs)(s.admonition,{type:"info",children:[(0,r.jsxs)(s.p,{children:["The default storage class is set to ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," for performance reasons.\nIf you want integrity-protected storage, set the ",(0,r.jsx)(s.code,{children:"storageClassName"})," parameter of your persistent volume claim to ",(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"."]}),(0,r.jsxs)(s.p,{children:["Alternatively, you can create your own storage class with integrity protection enabled by adding ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: ext4-integrity"})," to the class ",(0,r.jsx)(s.code,{children:"parameters"}),".\nOr use another filesystem by specifying another file system type with the suffix ",(0,r.jsx)(s.code,{children:"-integrity"}),", e.g., ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: xfs-integrity"}),"."]}),(0,r.jsx)(s.p,{children:"Note that volume expansion isn't supported for integrity-protected disks."})]})]}),(0,r.jsxs)(t,{value:"stackit",label:"STACKIT",children:[(0,r.jsx)(s.p,{children:"STACKIT comes with two storage classes by default."}),(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsxs)(s.a,{href:"https://docs.stackit.cloud/stackit/en/service-plans-blockstorage-75137974.html",children:["disks of ",(0,r.jsx)(s.code,{children:"storage_premium_perf1"})," type"]})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsxs)(s.a,{href:"https://docs.stackit.cloud/stackit/en/service-plans-blockstorage-75137974.html",children:["disks of ",(0,r.jsx)(s.code,{children:"storage_premium_perf1"})," type"]})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n",(0,r.jsx)(s.li,{children:"Integrity protection of data written to disk"}),"\n"]}),"\n"]}),"\n"]}),(0,r.jsxs)(s.p,{children:["For more information on encryption algorithms and key sizes, refer to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/architecture/encrypted-storage#cryptographic-algorithms",children:"cryptographic algorithms"}),"."]}),(0,r.jsxs)(s.admonition,{type:"info",children:[(0,r.jsxs)(s.p,{children:["The default storage class is set to ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," for performance reasons.\nIf you want integrity-protected storage, set the ",(0,r.jsx)(s.code,{children:"storageClassName"})," parameter of your persistent volume claim to ",(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"."]}),(0,r.jsxs)(s.p,{children:["Alternatively, you can create your own storage class with integrity protection enabled by adding ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: ext4-integrity"})," to the class ",(0,r.jsx)(s.code,{children:"parameters"}),".\nOr use another filesystem by specifying another file system type with the suffix ",(0,r.jsx)(s.code,{children:"-integrity"}),", e.g., ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: xfs-integrity"}),"."]}),(0,r.jsx)(s.p,{children:"Note that volume expansion isn't supported for integrity-protected disks."})]})]})]}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["Create a ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/",children:"persistent volume"})]}),"\n",(0,r.jsxs)(s.p,{children:["A ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims",children:"persistent volume claim"})," is a request for storage with certain properties.\nIt can refer to a storage class.\nThe following creates a persistent volume claim, requesting 20 GB of storage via the ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," storage class:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"cat <<EOF | kubectl apply -f -\nkind: PersistentVolumeClaim\napiVersion: v1\nmetadata:\n name: pvc-example\n namespace: default\nspec:\n accessModes:\n - ReadWriteOnce\n storageClassName: encrypted-rwo\n resources:\n requests:\n storage: 20Gi\nEOF\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Create a Pod with persistent storage"}),"\n",(0,r.jsx)(s.p,{children:"You can assign a persistent volume claim to an application in need of persistent storage.\nThe mounted volume will persist restarts.\nThe following creates a pod that uses the previously created persistent volume claim:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"cat <<EOF | kubectl apply -f -\napiVersion: v1\nkind: Pod\nmetadata:\n name: web-server\n namespace: default\nspec:\n containers:\n - name: web-server\n image: nginx\n volumeMounts:\n - mountPath: /var/lib/www/html\n name: mypvc\n volumes:\n - name: mypvc\n persistentVolumeClaim:\n claimName: pvc-example\n readOnly: false\nEOF\n"})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"change-the-default-storage-class",children:"Change the default storage class"}),"\n",(0,r.jsxs)(s.p,{children:["The default storage class is responsible for all persistent volume claims that don't explicitly request ",(0,r.jsx)(s.code,{children:"storageClassName"}),".\nConstellation creates a storage class with encryption enabled and sets this as the default class.\nIn case you wish to change it, follow the steps below:"]}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"List the storage classes in your cluster:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"kubectl get storageclass\n"})}),"\n",(0,r.jsx)(s.p,{children:"The output is similar to this:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-shell-session",children:"NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE\nencrypted-rwo (default) {your-csp}.csi.confidential.cloud Delete Immediate true 1d\nintegrity-encrypted-rwo {your-csp}.csi.confidential.cloud Delete Immediate false 1d\n"})}),"\n",(0,r.jsxs)(s.p,{children:["The default storage class is marked by ",(0,r.jsx)(s.code,{children:"(default)"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Mark old default storage class as non default"}),"\n",(0,r.jsx)(s.p,{children:"If you previously used another storage class as the default, you will have to remove that annotation:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:'kubectl patch storageclass encrypted-rwo -p \'{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}\'\n'})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Mark new class as the default"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:'kubectl patch storageclass integrity-encrypted-rwo -p \'{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}\'\n'})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Verify that your chosen storage class is default:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"kubectl get storageclass\n"})}),"\n",(0,r.jsx)(s.p,{children:"The output is similar to this:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-shell-session",children:"NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE\nencrypted-rwo {your-csp}.csi.confidential.cloud Delete Immediate true 1d\nintegrity-encrypted-rwo (default) {your-csp}.csi.confidential.cloud Delete Immediate false 1d\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}function p(e,s){throw new Error("Expected "+(s?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/797a5fdc.4a0c0d7a.js b/pr-preview/pr-4027/assets/js/797a5fdc.4a0c0d7a.js deleted file mode 100644 index 41a50142c..000000000 --- a/pr-preview/pr-4027/assets/js/797a5fdc.4a0c0d7a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5249],{28453:(e,s,t)=>{t.d(s,{R:()=>r,x:()=>i});var n=t(96540);const o={},a=n.createContext(o);function r(e){const s=n.useContext(a);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(a.Provider,{value:s},e.children)}},81113:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"getting-started/examples/filestash-s3proxy","title":"Deploying Filestash","description":"Filestash is a web frontend for different storage backends, including S3.","source":"@site/versioned_docs/version-2.23/getting-started/examples/filestash-s3proxy.md","sourceDirName":"getting-started/examples","slug":"/getting-started/examples/filestash-s3proxy","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/filestash-s3proxy","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/getting-started/examples/filestash-s3proxy.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Horizontal Pod Autoscaling","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/horizontal-scaling"},"next":{"title":"Workflows","permalink":"/constellation/pr-preview/pr-4027/2.23/category/workflows"}}');var o=t(74848),a=t(28453);const r={},i="Deploying Filestash",c={},l=[];function d(e){const s={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.header,{children:(0,o.jsx)(s.h1,{id:"deploying-filestash",children:"Deploying Filestash"})}),"\n",(0,o.jsx)(s.p,{children:"Filestash is a web frontend for different storage backends, including S3.\nIt's a useful application to showcase s3proxy in action."}),"\n",(0,o.jsxs)(s.ol,{children:["\n",(0,o.jsxs)(s.li,{children:["Deploy s3proxy as described in ",(0,o.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/s3proxy#deployment",children:"Deployment"}),"."]}),"\n",(0,o.jsx)(s.li,{children:"Create a deployment file for Filestash with one pod:"}),"\n"]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-sh",children:'cat << EOF > "deployment-filestash.yaml"\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: filestash\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: filestash\n template:\n metadata:\n labels:\n app: filestash\n spec:\n hostAliases:\n - ip: $(kubectl get svc s3proxy-service -o=jsonpath=\'{.spec.clusterIP}\')\n hostnames:\n - "s3.us-east-1.amazonaws.com"\n - "s3.us-east-2.amazonaws.com"\n - "s3.us-west-1.amazonaws.com"\n - "s3.us-west-2.amazonaws.com"\n - "s3.eu-north-1.amazonaws.com"\n - "s3.eu-south-1.amazonaws.com"\n - "s3.eu-south-2.amazonaws.com"\n - "s3.eu-west-1.amazonaws.com"\n - "s3.eu-west-2.amazonaws.com"\n - "s3.eu-west-3.amazonaws.com"\n - "s3.eu-central-1.amazonaws.com"\n - "s3.eu-central-2.amazonaws.com"\n - "s3.ap-northeast-1.amazonaws.com"\n - "s3.ap-northeast-2.amazonaws.com"\n - "s3.ap-northeast-3.amazonaws.com"\n - "s3.ap-east-1.amazonaws.com"\n - "s3.ap-southeast-1.amazonaws.com"\n - "s3.ap-southeast-2.amazonaws.com"\n - "s3.ap-southeast-3.amazonaws.com"\n - "s3.ap-southeast-4.amazonaws.com"\n - "s3.ap-south-1.amazonaws.com"\n - "s3.ap-south-2.amazonaws.com"\n - "s3.me-south-1.amazonaws.com"\n - "s3.me-central-1.amazonaws.com"\n - "s3.il-central-1.amazonaws.com"\n - "s3.af-south-1.amazonaws.com"\n - "s3.ca-central-1.amazonaws.com"\n - "s3.sa-east-1.amazonaws.com"\n containers:\n - name: filestash\n image: machines/filestash:latest\n ports:\n - containerPort: 8334\n volumeMounts:\n - name: ca-cert\n mountPath: /etc/ssl/certs/kube-ca.crt\n subPath: kube-ca.crt\n volumes:\n - name: ca-cert\n secret:\n secretName: s3proxy-tls\n items:\n - key: ca.crt\n path: kube-ca.crt\nEOF\n'})}),"\n",(0,o.jsxs)(s.p,{children:["The pod spec includes the ",(0,o.jsx)(s.code,{children:"hostAliases"})," key, which adds an entry to the pod's ",(0,o.jsx)(s.code,{children:"/etc/hosts"}),".\nThe entry forwards all requests for any of the currently defined AWS regions to the Kubernetes service ",(0,o.jsx)(s.code,{children:"s3proxy-service"}),".\nIf you followed the s3proxy ",(0,o.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/s3proxy#deployment",children:"Deployment"})," guide, this service points to a s3proxy pod."]}),"\n",(0,o.jsxs)(s.p,{children:["The deployment specifies all regions explicitly to prevent accidental data leaks.\nIf one of your buckets were located in a region that's not part of the ",(0,o.jsx)(s.code,{children:"hostAliases"})," key, traffic towards those buckets would not be redirected to s3proxy.\nSimilarly, if you want to exclude data for specific regions from going through s3proxy you can remove those regions from the deployment."]}),"\n",(0,o.jsxs)(s.p,{children:["The spec also includes a volume mount for the TLS certificate and adds it to the pod's certificate trust store.\nThe volume is called ",(0,o.jsx)(s.code,{children:"ca-cert"}),".\nThe key ",(0,o.jsx)(s.code,{children:"ca.crt"})," of that volume is mounted to ",(0,o.jsx)(s.code,{children:"/etc/ssl/certs/kube-ca.crt"}),", which is the default certificate trust store location for that container's OpenSSL library.\nNot adding the CA certificate will result in TLS authentication errors."]}),"\n",(0,o.jsxs)(s.ol,{start:"3",children:["\n",(0,o.jsxs)(s.li,{children:["Apply the file: ",(0,o.jsx)(s.code,{children:"kubectl apply -f deployment-filestash.yaml"})]}),"\n"]}),"\n",(0,o.jsxs)(s.p,{children:["Afterward, you can use a port forward to access the Filestash pod:\n",(0,o.jsx)(s.code,{children:"kubectl port-forward pod/$(kubectl get pod --selector='app=filestash' -o=jsonpath='{.items[*].metadata.name}') 8334:8334"})]}),"\n",(0,o.jsxs)(s.ol,{start:"4",children:["\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["After browsing to ",(0,o.jsx)(s.code,{children:"localhost:8443"}),", Filestash will ask you to set an administrator password.\nAfter setting it, you can directly leave the admin area by clicking the blue cloud symbol in the top left corner.\nSubsequently, you can select S3 as storage backend and enter your credentials.\nThis will bring you to an overview of your buckets.\nIf you want to deploy Filestash in production, take a look at its ",(0,o.jsx)(s.a,{href:"https://www.filestash.app/docs/",children:"documentation"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["To see the logs of s3proxy intercepting requests made to S3, run: ",(0,o.jsx)(s.code,{children:"kubectl logs -f pod/$(kubectl get pod --selector='app=s3proxy' -o=jsonpath='{.items[*].metadata.name}')"}),"\nLook out for log messages labeled ",(0,o.jsx)(s.code,{children:"intercepting"}),".\nThere is one such log message for each message that's encrypted, decrypted, or blocked."]}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["Once you have uploaded a file with Filestash, you should be able to view the file in Filestash.\nHowever, if you go to the AWS S3 ",(0,o.jsx)(s.a,{href:"https://s3.console.aws.amazon.com/s3/home",children:"Web UI"})," and download the file you just uploaded in Filestash, you won't be able to read it.\nAnother way to spot encrypted files without downloading them is to click on a file, scroll to the Metadata section, and look for the header named ",(0,o.jsx)(s.code,{children:"x-amz-meta-constellation-encryption"}),".\nThis header holds the encrypted data encryption key of the object and is only present on objects that are encrypted by s3proxy."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/79e0c113.dcc2b313.js b/pr-preview/pr-4027/assets/js/79e0c113.dcc2b313.js deleted file mode 100644 index f232ca11f..000000000 --- a/pr-preview/pr-4027/assets/js/79e0c113.dcc2b313.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6912],{28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var s=n(96540);const i={},o=s.createContext(i);function r(e){const t=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:t},e.children)}},60420:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/concept-d3a09a16a8e7ca14a7bdf274ea7bce40.svg"},92364:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"intro","title":"Introduction","description":"Welcome to the documentation of Constellation! Constellation is a Kubernetes engine that aims to provide the best possible data security.","source":"@site/versioned_docs/version-2.22/intro.md","sourceDirName":".","slug":"/","permalink":"/constellation/pr-preview/pr-4027/2.22/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/intro.md","tags":[],"version":"2.22","frontMatter":{"slug":"/","id":"intro"},"sidebar":"docs","next":{"title":"Basics","permalink":"/constellation/pr-preview/pr-4027/2.22/category/basics"}}');var i=n(74848),o=n(28453);const r={slug:"/",id:"intro"},a="Introduction",l={},c=[{value:"Goals",id:"goals",level:2},{value:"Use cases",id:"use-cases",level:2},{value:"Next steps",id:"next-steps",level:2}];function d(e){const t={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"introduction",children:"Introduction"})}),"\n",(0,i.jsx)(t.p,{children:"Welcome to the documentation of Constellation! Constellation is a Kubernetes engine that aims to provide the best possible data security."}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Constellation concept",src:n(60420).A+"",width:"1776",height:"746"})}),"\n",(0,i.jsxs)(t.p,{children:["Constellation shields your entire Kubernetes cluster from the underlying cloud infrastructure. Everything inside is always encrypted, including at runtime in memory. For this, Constellation leverages a technology called ",(0,i.jsx)(t.em,{children:"confidential computing"})," and more specifically Confidential VMs."]}),"\n",(0,i.jsx)(t.admonition,{type:"tip",children:(0,i.jsxs)(t.p,{children:["See the \ud83d\udcc4",(0,i.jsx)(t.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"})," for more information on confidential computing."]})}),"\n",(0,i.jsx)(t.h2,{id:"goals",children:"Goals"}),"\n",(0,i.jsx)(t.p,{children:"From a security perspective, Constellation is designed to keep all data always encrypted and to prevent any access from the underlying (cloud) infrastructure. This includes access from datacenter employees, privileged cloud admins, and attackers coming through the infrastructure. Such attackers could be malicious co-tenants escalating their privileges or hackers who managed to compromise a cloud server."}),"\n",(0,i.jsx)(t.p,{children:"From a DevOps perspective, Constellation is designed to work just like what you would expect from a modern Kubernetes engine."}),"\n",(0,i.jsx)(t.h2,{id:"use-cases",children:"Use cases"}),"\n",(0,i.jsxs)(t.p,{children:["Constellation provides unique security ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/overview/confidential-kubernetes",children:"features"})," and ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/overview/security-benefits",children:"benefits"}),". The core use cases are:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Increasing the overall security of your clusters"}),"\n",(0,i.jsx)(t.li,{children:"Increasing the trustworthiness of your SaaS offerings"}),"\n",(0,i.jsx)(t.li,{children:"Moving sensitive workloads from on-prem to the cloud"}),"\n",(0,i.jsx)(t.li,{children:"Meeting regulatory requirements"}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,i.jsxs)(t.p,{children:["You can learn more about the concept of Confidential Kubernetes, features, security benefits, and performance of Constellation in the ",(0,i.jsx)(t.em,{children:"Basics"})," section. To jump right into the action head to ",(0,i.jsx)(t.em,{children:"Getting started"}),"."]})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/7ae19400.00557006.js b/pr-preview/pr-4027/assets/js/7ae19400.00557006.js deleted file mode 100644 index 37f680eba..000000000 --- a/pr-preview/pr-4027/assets/js/7ae19400.00557006.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6154],{27513:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/max_latency-ae0fad7be416fae0d31ab35bb8284234.png"},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}},41249:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/p99_latency-fd60c7ae80666133370f9b8e47404994.png"},42383:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"overview/performance/application","title":"Application benchmarks","description":"HashiCorp Vault","source":"@site/versioned_docs/version-2.22/overview/performance/application.md","sourceDirName":"overview/performance","slug":"/overview/performance/application","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/performance/application","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/overview/performance/application.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"I/O benchmarks","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/performance/io"},"next":{"title":"License","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/license"}}');var s=t(74848),i=t(28453);const r={},o="Application benchmarks",c={},l=[{value:"HashiCorp Vault",id:"hashicorp-vault",level:2},{value:"Results",id:"results",level:2},{value:"Visualization",id:"visualization",level:3}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components},{Details:a}=n;return a||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"application-benchmarks",children:"Application benchmarks"})}),"\n",(0,s.jsx)(n.h2,{id:"hashicorp-vault",children:"HashiCorp Vault"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://www.vaultproject.io/",children:"HashiCorp Vault"})," is a distributed secrets management software that can be deployed to Kubernetes.\nHashiCorp maintains a benchmarking tool for vault, ",(0,s.jsx)(n.a,{href:"https://github.com/hashicorp/vault-benchmark/",children:"vault-benchmark"}),".\nVault-benchmark generates load on a Vault deployment and measures response times."]}),"\n",(0,s.jsxs)(n.p,{children:["This article describes the results from running vault-benchmark on Constellation, AKS, and GKE.\nYou can find the setup for producing the data discussed in this article in the ",(0,s.jsx)(n.a,{href:"https://github.com/edgelesssys/vault-benchmarks",children:"vault-benchmarks"})," repository."]}),"\n",(0,s.jsxs)(n.p,{children:["The Vault API used during benchmarking is the ",(0,s.jsx)(n.a,{href:"https://developer.hashicorp.com/vault/docs/secrets/transit",children:"transits secret engine"}),".\nThis allows services to send data to Vault for encryption, decryption, signing, and verification."]}),"\n",(0,s.jsx)(n.h2,{id:"results",children:"Results"}),"\n",(0,s.jsx)(n.p,{children:"On each run, vault-benchmark sends requests and measures the latencies.\nThe measured latencies are aggregated through various statistical features.\nAfter running the benchmark n times, the arithmetic mean over a subset of the reported statistics is calculated.\nThe selected features are arithmetic mean, 99th percentile, minimum, and maximum."}),"\n",(0,s.jsx)(n.p,{children:"Arithmetic mean gives a general sense of the latency on each target.\nThe 99th percentile shows performance in (most likely) erroneous states.\nMinimum and maximum mark the range within which latency varies each run."}),"\n",(0,s.jsx)(n.p,{children:"The benchmark was configured with 1300 workers and 10 seconds per run.\nThose numbers were chosen empirically.\nThe latency was stabilizing at 10 seconds runtime, not changing with further increase.\nIncreasing the number of workers beyond 1300 leads to request failures, marking the limit Vault was able to handle in this setup.\nAll results are based on 100 runs."}),"\n",(0,s.jsx)(n.p,{children:"The following data was generated while running five replicas, one primary, and four standby nodes.\nAll numbers are in seconds if not indicated otherwise."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"========== Results AKS ==========\nMean: mean: 1.632200, variance: 0.002057\nP99: mean: 5.480679, variance: 2.263700\nMax: mean: 6.651001, variance: 2.808401\nMin: mean: 0.011415, variance: 0.000133\n========== Results GKE ==========\nMean: mean: 1.656435, variance: 0.003615\nP99: mean: 6.030807, variance: 3.955051\nMax: mean: 7.164843, variance: 3.300004\nMin: mean: 0.010233, variance: 0.000111\n========== Results C11n ==========\nMean: mean: 1.651549, variance: 0.001610\nP99: mean: 5.780422, variance: 3.016106\nMax: mean: 6.942997, variance: 3.075796\nMin: mean: 0.013774, variance: 0.000228\n========== AKS vs C11n ==========\nMean: +1.171577 % (AKS is faster)\nP99: +5.185495 % (AKS is faster)\nMax: +4.205618 % (AKS is faster)\nMin: +17.128781 % (AKS is faster)\n========== GKE vs C11n ==========\nMean: -0.295851 % (GKE is slower)\nP99: -4.331603 % (GKE is slower)\nMax: -3.195248 % (GKE is slower)\nMin: +25.710886 % (GKE is faster)\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Interpretation"}),": Latencies are all within ~5% of each other.\nAKS performs slightly better than GKE and Constellation (C11n) in all cases except minimum latency.\nMinimum latency is the lowest for GKE.\nCompared to GKE, Constellation had slightly lower peak latencies (99th percentile and maximum), indicating that Constellation could have handled slightly more concurrent accesses than GKE.\nOverall, performance is at comparable levels across all three distributions.\nBased on these numbers, you can use a similarly sized Constellation cluster to run your existing Vault deployment."]}),"\n",(0,s.jsx)(n.h3,{id:"visualization",children:"Visualization"}),"\n",(0,s.jsxs)(n.p,{children:["The following plots visualize the data presented above as ",(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Box_plot",children:"box plots"}),".\nThe whiskers denote the minimum and maximum.\nThe box stretches from the 25th to the 75th percentile, with the dividing bar marking the 50th percentile.\nThe circles outside the whiskers denote outliers."]}),"\n",(0,s.jsxs)(a,{children:[(0,s.jsx)("summary",{children:"Mean Latency"}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Mean Latency",src:t(91138).A+"",width:"576",height:"576"})})]}),"\n",(0,s.jsxs)(a,{children:[(0,s.jsx)("summary",{children:"99th Percentile Latency"}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"99th Percentile Latency",src:t(41249).A+"",width:"576",height:"576"})})]}),"\n",(0,s.jsxs)(a,{children:[(0,s.jsx)("summary",{children:"Maximum Latency"}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Maximum Latency",src:t(27513).A+"",width:"576",height:"576"})})]}),"\n",(0,s.jsxs)(a,{children:[(0,s.jsx)("summary",{children:"Minimum Latency"}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Minimum Latency",src:t(91159).A+"",width:"576",height:"576"})})]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},91138:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/mean_latency-4c041d48ebb1b521c92d464040e94031.png"},91159:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/min_latency-87ed51de18ebede26c314ff00d0e8e23.png"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/7c763686.e696c7b8.js b/pr-preview/pr-4027/assets/js/7c763686.e696c7b8.js deleted file mode 100644 index bead18151..000000000 --- a/pr-preview/pr-4027/assets/js/7c763686.e696c7b8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9075],{28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>c});var t=n(96540);const i={},r=t.createContext(i);function o(e){const s=t.useContext(r);return t.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(r.Provider,{value:s},e.children)}},93939:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"overview/license","title":"License","description":"Constellation is available under the Business Source License 1.1.","source":"@site/versioned_docs/version-2.23/overview/license.md","sourceDirName":"overview","slug":"/overview/license","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/license","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/overview/license.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Application benchmarks","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/performance/application"},"next":{"title":"Getting started","permalink":"/constellation/pr-preview/pr-4027/2.23/category/getting-started"}}');var i=n(74848),r=n(28453);const o={},c="License",a={},l=[{value:"Enterprise License",id:"enterprise-license",level:2},{value:"CSP Marketplaces",id:"csp-marketplaces",level:2}];function p(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.header,{children:(0,i.jsx)(s.h1,{id:"license",children:"License"})}),"\n",(0,i.jsxs)(s.p,{children:["Constellation is available under the ",(0,i.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/blob/main/LICENSE",children:"Business Source License 1.1"}),"."]}),"\n",(0,i.jsx)(s.p,{children:'You may use it free of charge for non-production use ("Community License").'}),"\n",(0,i.jsx)(s.h2,{id:"enterprise-license",children:"Enterprise License"}),"\n",(0,i.jsxs)(s.p,{children:["Enterprise Licenses permit production use and come with support and additional features. Find out more at the ",(0,i.jsx)(s.a,{href:"https://www.edgeless.systems/products/constellation/",children:"product website"}),"."]}),"\n",(0,i.jsxs)(s.p,{children:["Once you have received your Enterprise License file, place it in your ",(0,i.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/orchestration#workspaces",children:"Constellation workspace"})," in a file named ",(0,i.jsx)(s.code,{children:"constellation.license"}),"."]}),"\n",(0,i.jsx)(s.h2,{id:"csp-marketplaces",children:"CSP Marketplaces"}),"\n",(0,i.jsxs)(s.p,{children:["Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please ",(0,i.jsx)(s.a,{href:"https://www.edgeless.systems/enterprise-support/",children:"contact us"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(p,{...e})}):p(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/7cae3477.a2bd8629.js b/pr-preview/pr-4027/assets/js/7cae3477.a2bd8629.js deleted file mode 100644 index 8f27fbe64..000000000 --- a/pr-preview/pr-4027/assets/js/7cae3477.a2bd8629.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8784],{28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>l});var n=r(96540);const o={},s=n.createContext(o);function i(e){const t=n.useContext(s);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(s.Provider,{value:t},e.children)}},62840:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>l,default:()=>d,frontMatter:()=>i,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"workflows/create","title":"Create your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","source":"@site/versioned_docs/version-2.23/workflows/create.md","sourceDirName":"workflows","slug":"/workflows/create","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/create","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/workflows/create.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Configure your cluster","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/config"},"next":{"title":"Scale your cluster","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/scale"}}');var o=r(74848),s=r(28453);const i={},l="Create your cluster",a={},c=[{value:"Troubleshooting",id:"troubleshooting",level:3}];function u(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h3:"h3",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.R)(),...e.components},{AsciinemaWidget:r,TabItem:n,Tabs:i}=t;return r||h("AsciinemaWidget",!0),n||h("TabItem",!0),i||h("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"create-your-cluster",children:"Create your cluster"})}),"\n",(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsx)(t.p,{children:"This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details."})}),"\n",(0,o.jsx)(r,{src:"/constellation/assets/create-cluster.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,o.jsx)(t.hr,{}),"\n",(0,o.jsx)(t.p,{children:"Creating your cluster happens through multiple phases.\nThe most significant ones are:"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsx)(t.li,{children:"Creating the necessary resources in your cloud environment"}),"\n",(0,o.jsx)(t.li,{children:"Bootstrapping the Constellation cluster and setting up a connection"}),"\n",(0,o.jsx)(t.li,{children:"Installing the necessary Kubernetes components"}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.code,{children:"constellation apply"})," handles all this in a single command.\nYou can use the ",(0,o.jsx)(t.code,{children:"--skip-phases"})," flag to skip specific phases of the process.\nFor example, if you created the infrastructure manually, you can skip the cloud resource creation phase."]}),"\n",(0,o.jsxs)(t.p,{children:["See the ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/orchestration",children:"architecture"})," section for details on the inner workings of this process."]}),"\n",(0,o.jsx)(t.admonition,{type:"tip",children:(0,o.jsxs)(t.p,{children:["If you don't have a cloud subscription, you can also set up a ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps-local",children:"local Constellation cluster using virtualization"})," for testing."]})}),"\n",(0,o.jsxs)(t.p,{children:["Before you create the cluster, make sure to have a ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/config",children:"valid configuration file"}),"."]}),"\n",(0,o.jsxs)(i,{groupId:"usage",children:[(0,o.jsxs)(n,{value:"cli",label:"CLI",children:[(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation apply\n"})}),(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.code,{children:"apply"})," stores the state of your cluster's cloud resources in a ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/orchestration#cluster-creation-process",children:(0,o.jsx)(t.code,{children:"constellation-terraform"})})," directory in your workspace."]})]}),(0,o.jsxs)(n,{value:"self-managed",label:"Self-managed",children:[(0,o.jsx)(t.p,{children:"Self-managed infrastructure allows for more flexibility in the setup, by separating the infrastructure setup from the Constellation cluster management.\nThis provides flexibility in DevOps and can meet potential regulatory requirements.\nIt's recommended to use Terraform for infrastructure management, but you can use any tool of your choice."}),(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsxs)(t.p,{children:["When using Terraform, you can use the ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/terraform-provider",children:"Constellation Terraform provider"})," to manage the entire Constellation cluster lifecycle."]})}),(0,o.jsxs)(t.p,{children:["You can refer to the Terraform files for the selected CSP from the ",(0,o.jsx)(t.a,{href:"https://github.com/edgelesssys/constellation/tree/main/terraform/infrastructure",children:"Constellation GitHub repository"})," for a minimum Constellation cluster configuration. From this base, you can now add, edit, or substitute resources per your own requirements with the infrastructure\nmanagement tooling of your choice. You need to keep the essential functionality of the base configuration in order for your cluster to function correctly."]}),(0,o.jsxs)(t.admonition,{type:"info",children:[(0,o.jsxs)(t.p,{children:["On Azure, a manual update to the MAA provider's policy is necessary.\nYou can apply the update with the following command after creating the infrastructure, with ",(0,o.jsx)(t.code,{children:"<URL>"})," being the URL of the MAA provider (i.e., ",(0,o.jsx)(t.code,{children:"$(terraform output attestation_url | jq -r)"}),", when using the minimal Terraform configuration)."]}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation maa-patch <URL>\n"})})]}),(0,o.jsxs)(t.p,{children:["Make sure all necessary resources are created, e.g., through checking your CSP's portal and retrieve the necessary values, aligned with the outputs (specified in ",(0,o.jsx)(t.code,{children:"outputs.tf"}),") of the base configuration."]}),(0,o.jsxs)(t.p,{children:["Fill these outputs into the corresponding fields of the ",(0,o.jsx)(t.code,{children:"Infrastructure"})," block inside the ",(0,o.jsx)(t.code,{children:"constellation-state.yaml"})," file. For example, fill the IP or DNS name your cluster can be reached at into the ",(0,o.jsx)(t.code,{children:".Infrastructure.ClusterEndpoint"})," field."]}),(0,o.jsx)(t.p,{children:"With the required cloud resources set up, continue with initializing your cluster."}),(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"constellation apply --skip-phases=infrastructure\n"})})]})]}),"\n",(0,o.jsxs)(t.p,{children:["Finally, configure ",(0,o.jsx)(t.code,{children:"kubectl"})," for your cluster:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:'export KUBECONFIG="$PWD/constellation-admin.conf"\n'})}),"\n",(0,o.jsx)(t.p,{children:"\ud83c\udfc1 That's it. You've successfully created a Constellation cluster."}),"\n",(0,o.jsx)(t.h3,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,o.jsxs)(t.p,{children:["In case ",(0,o.jsx)(t.code,{children:"apply"})," fails, the CLI collects logs from the bootstrapping instance and stores them inside ",(0,o.jsx)(t.code,{children:"constellation-cluster.log"}),"."]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}function h(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/80697fb2.341f256e.js b/pr-preview/pr-4027/assets/js/80697fb2.341f256e.js deleted file mode 100644 index 5e6eed37a..000000000 --- a/pr-preview/pr-4027/assets/js/80697fb2.341f256e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1067],{28453:(e,t,n)=>{n.d(t,{R:()=>l,x:()=>a});var o=n(96540);const s={},i=o.createContext(s);function l(e){const t=o.useContext(i);return o.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),o.createElement(i.Provider,{value:t},e.children)}},36045:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>r,contentTitle:()=>a,default:()=>d,frontMatter:()=>l,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"getting-started/examples/online-boutique","title":"Online Boutique","description":"Online Boutique is an e-commerce demo application by Google consisting of 11 separate microservices. In this demo, Constellation automatically sets up a load balancer on your CSP, making it easy to expose services from your confidential cluster.","source":"@site/docs/getting-started/examples/online-boutique.md","sourceDirName":"getting-started/examples","slug":"/getting-started/examples/online-boutique","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/examples/online-boutique","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/getting-started/examples/online-boutique.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Emojivoto","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/examples/emojivoto"},"next":{"title":"Horizontal Pod Autoscaling","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/examples/horizontal-scaling"}}');var s=n(74848),i=n(28453);const l={},a="Online Boutique",r={},c=[];function u(e){const t={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"online-boutique",children:"Online Boutique"})}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.a,{href:"https://github.com/GoogleCloudPlatform/microservices-demo",children:"Online Boutique"})," is an e-commerce demo application by Google consisting of 11 separate microservices. In this demo, Constellation automatically sets up a load balancer on your CSP, making it easy to expose services from your confidential cluster."]}),"\n",(0,s.jsx)("img",{src:n(53661).A,alt:"Online Boutique - Web UI",width:"662"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["Create a namespace:","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"kubectl create ns boutique\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["Deploy the application:","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"kubectl apply -n boutique -f https://github.com/GoogleCloudPlatform/microservices-demo/raw/main/release/kubernetes-manifests.yaml\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["Wait for all services to become available:","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"kubectl wait --for=condition=available --timeout=300s -n boutique --all deployments\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["Get the frontend's external IP address:","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-shell-session",children:"$ kubectl get service frontend-external -n boutique | awk '{print $4}'\nEXTERNAL-IP\n<your-ip>\n"})}),"\n","(",(0,s.jsx)(t.code,{children:"<your-ip>"})," is a placeholder for the IP assigned by your CSP.)"]}),"\n",(0,s.jsx)(t.li,{children:"Enter the IP from the result in your browser to browse the online shop."}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},53661:(e,t,n)=>{n.d(t,{A:()=>o});const o=n.p+"assets/images/example-online-boutique-c89a9a15b1d4c086d3654bf75843295e.jpg"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/8142.22a8eb00.js b/pr-preview/pr-4027/assets/js/8142.22a8eb00.js deleted file mode 100644 index 8b553162b..000000000 --- a/pr-preview/pr-4027/assets/js/8142.22a8eb00.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8142],{88142:(t,e,a)=>{a.d(e,{diagram:()=>R});var i,n=a(54616),r=(a(89625),a(21152),a(10045),a(5164),a(28698),a(5894),a(63245),a(32387),a(30092),a(13226)),d=a(67633),s=a(40797),o=a(70451),g=a(62334),h=a(697),p=(0,s.K2)(t=>t.append("circle").attr("class","start-state").attr("r",(0,d.D7)().state.sizeUnit).attr("cx",(0,d.D7)().state.padding+(0,d.D7)().state.sizeUnit).attr("cy",(0,d.D7)().state.padding+(0,d.D7)().state.sizeUnit),"drawStartState"),c=(0,s.K2)(t=>t.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",(0,d.D7)().state.textHeight).attr("class","divider").attr("x2",2*(0,d.D7)().state.textHeight).attr("y1",0).attr("y2",0),"drawDivider"),l=(0,s.K2)((t,e)=>{const a=t.append("text").attr("x",2*(0,d.D7)().state.padding).attr("y",(0,d.D7)().state.textHeight+2*(0,d.D7)().state.padding).attr("font-size",(0,d.D7)().state.fontSize).attr("class","state-title").text(e.id),i=a.node().getBBox();return t.insert("rect",":first-child").attr("x",(0,d.D7)().state.padding).attr("y",(0,d.D7)().state.padding).attr("width",i.width+2*(0,d.D7)().state.padding).attr("height",i.height+2*(0,d.D7)().state.padding).attr("rx",(0,d.D7)().state.radius),a},"drawSimpleState"),x=(0,s.K2)((t,e)=>{const a=(0,s.K2)(function(t,e,a){const i=t.append("tspan").attr("x",2*(0,d.D7)().state.padding).text(e);a||i.attr("dy",(0,d.D7)().state.textHeight)},"addTspan"),i=t.append("text").attr("x",2*(0,d.D7)().state.padding).attr("y",(0,d.D7)().state.textHeight+1.3*(0,d.D7)().state.padding).attr("font-size",(0,d.D7)().state.fontSize).attr("class","state-title").text(e.descriptions[0]).node().getBBox(),n=i.height,r=t.append("text").attr("x",(0,d.D7)().state.padding).attr("y",n+.4*(0,d.D7)().state.padding+(0,d.D7)().state.dividerMargin+(0,d.D7)().state.textHeight).attr("class","state-description");let o=!0,g=!0;e.descriptions.forEach(function(t){o||(a(r,t,g),g=!1),o=!1});const h=t.append("line").attr("x1",(0,d.D7)().state.padding).attr("y1",(0,d.D7)().state.padding+n+(0,d.D7)().state.dividerMargin/2).attr("y2",(0,d.D7)().state.padding+n+(0,d.D7)().state.dividerMargin/2).attr("class","descr-divider"),p=r.node().getBBox(),c=Math.max(p.width,i.width);return h.attr("x2",c+3*(0,d.D7)().state.padding),t.insert("rect",":first-child").attr("x",(0,d.D7)().state.padding).attr("y",(0,d.D7)().state.padding).attr("width",c+2*(0,d.D7)().state.padding).attr("height",p.height+n+2*(0,d.D7)().state.padding).attr("rx",(0,d.D7)().state.radius),t},"drawDescrState"),D=(0,s.K2)((t,e,a)=>{const i=(0,d.D7)().state.padding,n=2*(0,d.D7)().state.padding,r=t.node().getBBox(),s=r.width,o=r.x,g=t.append("text").attr("x",0).attr("y",(0,d.D7)().state.titleShift).attr("font-size",(0,d.D7)().state.fontSize).attr("class","state-title").text(e.id),h=g.node().getBBox().width+n;let p,c=Math.max(h,s);c===s&&(c+=n);const l=t.node().getBBox();e.doc,p=o-i,h>s&&(p=(s-c)/2+i),Math.abs(o-l.x)<i&&h>s&&(p=o-(h-s)/2);const x=1-(0,d.D7)().state.textHeight;return t.insert("rect",":first-child").attr("x",p).attr("y",x).attr("class",a?"alt-composit":"composit").attr("width",c).attr("height",l.height+(0,d.D7)().state.textHeight+(0,d.D7)().state.titleShift+1).attr("rx","0"),g.attr("x",p+i),h<=s&&g.attr("x",o+(c-n)/2-h/2+i),t.insert("rect",":first-child").attr("x",p).attr("y",(0,d.D7)().state.titleShift-(0,d.D7)().state.textHeight-(0,d.D7)().state.padding).attr("width",c).attr("height",3*(0,d.D7)().state.textHeight).attr("rx",(0,d.D7)().state.radius),t.insert("rect",":first-child").attr("x",p).attr("y",(0,d.D7)().state.titleShift-(0,d.D7)().state.textHeight-(0,d.D7)().state.padding).attr("width",c).attr("height",l.height+3+2*(0,d.D7)().state.textHeight).attr("rx",(0,d.D7)().state.radius),t},"addTitleAndBox"),u=(0,s.K2)(t=>(t.append("circle").attr("class","end-state-outer").attr("r",(0,d.D7)().state.sizeUnit+(0,d.D7)().state.miniPadding).attr("cx",(0,d.D7)().state.padding+(0,d.D7)().state.sizeUnit+(0,d.D7)().state.miniPadding).attr("cy",(0,d.D7)().state.padding+(0,d.D7)().state.sizeUnit+(0,d.D7)().state.miniPadding),t.append("circle").attr("class","end-state-inner").attr("r",(0,d.D7)().state.sizeUnit).attr("cx",(0,d.D7)().state.padding+(0,d.D7)().state.sizeUnit+2).attr("cy",(0,d.D7)().state.padding+(0,d.D7)().state.sizeUnit+2)),"drawEndState"),f=(0,s.K2)((t,e)=>{let a=(0,d.D7)().state.forkWidth,i=(0,d.D7)().state.forkHeight;if(e.parentId){let t=a;a=i,i=t}return t.append("rect").style("stroke","black").style("fill","black").attr("width",a).attr("height",i).attr("x",(0,d.D7)().state.padding).attr("y",(0,d.D7)().state.padding)},"drawForkJoinState"),y=(0,s.K2)((t,e,a,i)=>{let n=0;const r=i.append("text");r.style("text-anchor","start"),r.attr("class","noteText");let s=t.replace(/\r\n/g,"<br/>");s=s.replace(/\n/g,"<br/>");const o=s.split(d.Y2.lineBreakRegex);let g=1.25*(0,d.D7)().state.noteMargin;for(const h of o){const t=h.trim();if(t.length>0){const i=r.append("tspan");if(i.text(t),0===g){g+=i.node().getBBox().height}n+=g,i.attr("x",e+(0,d.D7)().state.noteMargin),i.attr("y",a+n+1.25*(0,d.D7)().state.noteMargin)}}return{textWidth:r.node().getBBox().width,textHeight:n}},"_drawLongText"),w=(0,s.K2)((t,e)=>{e.attr("class","state-note");const a=e.append("rect").attr("x",0).attr("y",(0,d.D7)().state.padding),i=e.append("g"),{textWidth:n,textHeight:r}=y(t,0,0,i);return a.attr("height",r+2*(0,d.D7)().state.noteMargin),a.attr("width",n+2*(0,d.D7)().state.noteMargin),a},"drawNote"),m=(0,s.K2)(function(t,e){const a=e.id,i={id:a,label:e.id,width:0,height:0},n=t.append("g").attr("id",a).attr("class","stateGroup");"start"===e.type&&p(n),"end"===e.type&&u(n),"fork"!==e.type&&"join"!==e.type||f(n,e),"note"===e.type&&w(e.note.text,n),"divider"===e.type&&c(n),"default"===e.type&&0===e.descriptions.length&&l(n,e),"default"===e.type&&e.descriptions.length>0&&x(n,e);const r=n.node().getBBox();return i.width=r.width+2*(0,d.D7)().state.padding,i.height=r.height+2*(0,d.D7)().state.padding,i},"drawState"),b=0,B=(0,s.K2)(function(t,e,a){const i=(0,s.K2)(function(t){switch(t){case n.u4.relationType.AGGREGATION:return"aggregation";case n.u4.relationType.EXTENSION:return"extension";case n.u4.relationType.COMPOSITION:return"composition";case n.u4.relationType.DEPENDENCY:return"dependency"}},"getRelationType");e.points=e.points.filter(t=>!Number.isNaN(t.y));const g=e.points,h=(0,o.n8j)().x(function(t){return t.x}).y(function(t){return t.y}).curve(o.qrM),p=t.append("path").attr("d",h(g)).attr("id","edge"+b).attr("class","transition");let c="";if((0,d.D7)().state.arrowMarkerAbsolute&&(c=(0,d.ID)(!0)),p.attr("marker-end","url("+c+"#"+i(n.u4.relationType.DEPENDENCY)+"End)"),void 0!==a.title){const i=t.append("g").attr("class","stateLabel"),{x:n,y:o}=r._K.calcLabelPosition(e.points),g=d.Y2.getRows(a.title);let h=0;const p=[];let c=0,l=0;for(let t=0;t<=g.length;t++){const e=i.append("text").attr("text-anchor","middle").text(g[t]).attr("x",n).attr("y",o+h),a=e.node().getBBox();if(c=Math.max(c,a.width),l=Math.min(l,a.x),s.Rm.info(a.x,n,o+h),0===h){const t=e.node().getBBox();h=t.height,s.Rm.info("Title height",h,o)}p.push(e)}let x=h*g.length;if(g.length>1){const t=(g.length-1)*h*.5;p.forEach((e,a)=>e.attr("y",o+a*h-t)),x=h*g.length}const D=i.node().getBBox();i.insert("rect",":first-child").attr("class","box").attr("x",n-c/2-(0,d.D7)().state.padding/2).attr("y",o-x/2-(0,d.D7)().state.padding/2-3.5).attr("width",c+(0,d.D7)().state.padding).attr("height",x+(0,d.D7)().state.padding),s.Rm.info(D)}b++},"drawEdge"),k={},S=(0,s.K2)(function(){},"setConf"),N=(0,s.K2)(function(t){t.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},"insertMarkers"),E=(0,s.K2)(function(t,e,a,n){i=(0,d.D7)().state;const r=(0,d.D7)().securityLevel;let g;"sandbox"===r&&(g=(0,o.Ltv)("#i"+e));const h="sandbox"===r?(0,o.Ltv)(g.nodes()[0].contentDocument.body):(0,o.Ltv)("body"),p="sandbox"===r?g.nodes()[0].contentDocument:document;s.Rm.debug("Rendering diagram "+t);const c=h.select(`[id='${e}']`);N(c);const l=n.db.getRootDoc();v(l,c,void 0,!1,h,p,n);const x=i.padding,D=c.node().getBBox(),u=D.width+2*x,f=D.height+2*x,y=1.75*u;(0,d.a$)(c,f,y,i.useMaxWidth),c.attr("viewBox",`${D.x-i.padding} ${D.y-i.padding} `+u+" "+f)},"draw"),M=(0,s.K2)(t=>t?t.length*i.fontSizeFactor:1,"getLabelWidth"),v=(0,s.K2)((t,e,a,n,r,o,p)=>{const c=new h.T({compound:!0,multigraph:!0});let l,x=!0;for(l=0;l<t.length;l++)if("relation"===t[l].stmt){x=!1;break}a?c.setGraph({rankdir:"LR",multigraph:!0,compound:!0,ranker:"tight-tree",ranksep:x?1:i.edgeLengthFactor,nodeSep:x?1:50,isMultiGraph:!0}):c.setGraph({rankdir:"TB",multigraph:!0,compound:!0,ranksep:x?1:i.edgeLengthFactor,nodeSep:x?1:50,ranker:"tight-tree",isMultiGraph:!0}),c.setDefaultEdgeLabel(function(){return{}});const u=p.db.getStates(),f=p.db.getRelations(),y=Object.keys(u);for(const d of y){const t=u[d];let s;if(a&&(t.parentId=a),t.doc){let a=e.append("g").attr("id",t.id).attr("class","stateGroup");s=v(t.doc,a,t.id,!n,r,o,p);{a=D(a,t,n);let e=a.node().getBBox();s.width=e.width,s.height=e.height+i.padding/2,k[t.id]={y:i.compositTitleSize}}}else s=m(e,t,c);if(t.note){const a={descriptions:[],id:t.id+"-note",note:t.note,type:"note"},i=m(e,a,c);"left of"===t.note.position?(c.setNode(s.id+"-note",i),c.setNode(s.id,s)):(c.setNode(s.id,s),c.setNode(s.id+"-note",i)),c.setParent(s.id,s.id+"-group"),c.setParent(s.id+"-note",s.id+"-group")}else c.setNode(s.id,s)}s.Rm.debug("Count=",c.nodeCount(),c);let w=0;f.forEach(function(t){w++,s.Rm.debug("Setting edge",t),c.setEdge(t.id1,t.id2,{relation:t,width:M(t.title),height:i.labelHeight*d.Y2.getRows(t.title).length,labelpos:"c"},"id"+w)}),(0,g.Zp)(c),s.Rm.debug("Graph after layout",c.nodes());const b=e.node();c.nodes().forEach(function(t){if(void 0!==t&&void 0!==c.node(t)){s.Rm.warn("Node "+t+": "+JSON.stringify(c.node(t))),r.select("#"+b.id+" #"+t).attr("transform","translate("+(c.node(t).x-c.node(t).width/2)+","+(c.node(t).y+(k[t]?k[t].y:0)-c.node(t).height/2)+" )"),r.select("#"+b.id+" #"+t).attr("data-x-shift",c.node(t).x-c.node(t).width/2);o.querySelectorAll("#"+b.id+" #"+t+" .divider").forEach(t=>{const e=t.parentElement;let a=0,i=0;e&&(e.parentElement&&(a=e.parentElement.getBBox().width),i=parseInt(e.getAttribute("data-x-shift"),10),Number.isNaN(i)&&(i=0)),t.setAttribute("x1",0-i+8),t.setAttribute("x2",a-i-8)})}else s.Rm.debug("No Node "+t+": "+JSON.stringify(c.node(t)))});let S=b.getBBox();c.edges().forEach(function(t){void 0!==t&&void 0!==c.edge(t)&&(s.Rm.debug("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(c.edge(t))),B(e,c.edge(t),c.edge(t).relation))}),S=b.getBBox();const N={id:a||"root",label:a||"root",width:0,height:0};return N.width=S.width+2*i.padding,N.height=S.height+2*i.padding,s.Rm.debug("Doc rendered",N,c),N},"renderDoc"),K={setConf:S,draw:E},R={parser:n.Zk,get db(){return new n.u4(1)},renderer:K,styles:n.tM,init:(0,s.K2)(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/8183fba6.e63b4420.js b/pr-preview/pr-4027/assets/js/8183fba6.e63b4420.js deleted file mode 100644 index db841f00f..000000000 --- a/pr-preview/pr-4027/assets/js/8183fba6.e63b4420.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[304],{12008:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"reference/terraform","title":"Terraform usage","description":"Terraform is an Infrastructure as Code (IaC) framework to manage cloud resources. This page explains how Constellation uses it internally and how advanced users may manually use it to have more control over the resource creation.","source":"@site/versioned_docs/version-2.24/reference/terraform.md","sourceDirName":"reference","slug":"/reference/terraform","permalink":"/constellation/pr-preview/pr-4027/reference/terraform","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/reference/terraform.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Configuration migrations","permalink":"/constellation/pr-preview/pr-4027/reference/migration"},"next":{"title":"SLSA adoption","permalink":"/constellation/pr-preview/pr-4027/reference/slsa"}}');var o=t(74848),s=t(28453);const i={},a="Terraform usage",l={},c=[{value:"Terraform state files",id:"terraform-state-files",level:2},{value:"Interacting with Terraform manually",id:"interacting-with-terraform-manually",level:2},{value:"Terraform debugging",id:"terraform-debugging",level:2}];function d(e){const r={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(r.header,{children:(0,o.jsx)(r.h1,{id:"terraform-usage",children:"Terraform usage"})}),"\n",(0,o.jsxs)(r.p,{children:[(0,o.jsx)(r.a,{href:"https://www.terraform.io/",children:"Terraform"})," is an Infrastructure as Code (IaC) framework to manage cloud resources. This page explains how Constellation uses it internally and how advanced users may manually use it to have more control over the resource creation."]}),"\n",(0,o.jsx)(r.admonition,{type:"info",children:(0,o.jsxs)(r.p,{children:["Information on this page is intended for users who are familiar with Terraform.\nIt's not required for common usage of Constellation.\nSee the ",(0,o.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/docs",children:"Terraform documentation"})," if you want to learn more about it."]})}),"\n",(0,o.jsx)(r.h2,{id:"terraform-state-files",children:"Terraform state files"}),"\n",(0,o.jsx)(r.p,{children:"Constellation keeps Terraform state files in subdirectories of the workspace together with the corresponding Terraform configuration files and metadata.\nThe subdirectories are created on the first Constellation CLI action that uses Terraform internally."}),"\n",(0,o.jsx)(r.p,{children:"Currently, these subdirectories are:"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.code,{children:"constellation-terraform"})," - Terraform state files for the resources of the Constellation cluster"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.code,{children:"constellation-iam-terraform"})," - Terraform state files for IAM configuration"]}),"\n"]}),"\n",(0,o.jsxs)(r.p,{children:["As with all commands, commands that work with these files (e.g., ",(0,o.jsx)(r.code,{children:"apply"}),", ",(0,o.jsx)(r.code,{children:"terminate"}),", ",(0,o.jsx)(r.code,{children:"iam"}),") have to be executed from the root of the cluster's ",(0,o.jsx)(r.a,{href:"/constellation/pr-preview/pr-4027/architecture/orchestration#workspaces",children:"workspace directory"}),". You usually don't need and shouldn't manipulate or delete the subdirectories manually."]}),"\n",(0,o.jsx)(r.h2,{id:"interacting-with-terraform-manually",children:"Interacting with Terraform manually"}),"\n",(0,o.jsxs)(r.p,{children:["Manual interaction with Terraform state created by Constellation (i.e., via the Terraform CLI) should only be performed by experienced users. It may lead to unrecoverable loss of cloud resources. For the majority of users and use cases, the interaction done by the ",(0,o.jsx)(r.a,{href:"/constellation/pr-preview/pr-4027/reference/cli",children:"Constellation CLI"})," is sufficient."]}),"\n",(0,o.jsx)(r.h2,{id:"terraform-debugging",children:"Terraform debugging"}),"\n",(0,o.jsxs)(r.p,{children:["To debug Terraform issues, the Constellation CLI offers the ",(0,o.jsx)(r.code,{children:"tf-log"})," flag. You can set it to any of ",(0,o.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform's log levels"}),":"]}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.code,{children:"JSON"})," (JSON-formatted logs at ",(0,o.jsx)(r.code,{children:"TRACE"})," level)"]}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"TRACE"})}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"DEBUG"})}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"INFO"})}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"WARN"})}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"ERROR"})}),"\n"]}),"\n",(0,o.jsxs)(r.p,{children:["The log output is written to the ",(0,o.jsx)(r.code,{children:"terraform.log"})," file in the workspace directory. The output is appended to the file on each run."]})]})}function h(e={}){const{wrapper:r}={...(0,s.R)(),...e.components};return r?(0,o.jsx)(r,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,r,t)=>{t.d(r,{R:()=>i,x:()=>a});var n=t(96540);const o={},s=n.createContext(o);function i(e){const r=n.useContext(s);return n.useMemo(function(){return"function"==typeof e?e(r):{...r,...e}},[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(s.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/8249.7b68bdca.js b/pr-preview/pr-4027/assets/js/8249.7b68bdca.js deleted file mode 100644 index 7170027e9..000000000 --- a/pr-preview/pr-4027/assets/js/8249.7b68bdca.js +++ /dev/null @@ -1 +0,0 @@ -(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8249],{1917:function(t){var e;e=function(){return function(t){var e={};function i(n){if(e[n])return e[n].exports;var r=e[n]={i:n,l:!1,exports:{}};return t[n].call(r.exports,r,r.exports,i),r.l=!0,r.exports}return i.m=t,i.c=e,i.i=function(t){return t},i.d=function(t,e,n){i.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:n})},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=28)}([function(t,e,i){"use strict";function n(){}n.QUALITY=1,n.DEFAULT_CREATE_BENDS_AS_NEEDED=!1,n.DEFAULT_INCREMENTAL=!1,n.DEFAULT_ANIMATION_ON_LAYOUT=!0,n.DEFAULT_ANIMATION_DURING_LAYOUT=!1,n.DEFAULT_ANIMATION_PERIOD=50,n.DEFAULT_UNIFORM_LEAF_NODE_SIZES=!1,n.DEFAULT_GRAPH_MARGIN=15,n.NODE_DIMENSIONS_INCLUDE_LABELS=!1,n.SIMPLE_NODE_SIZE=40,n.SIMPLE_NODE_HALF_SIZE=n.SIMPLE_NODE_SIZE/2,n.EMPTY_COMPOUND_NODE_SIZE=40,n.MIN_EDGE_LENGTH=1,n.WORLD_BOUNDARY=1e6,n.INITIAL_WORLD_BOUNDARY=n.WORLD_BOUNDARY/1e3,n.WORLD_CENTER_X=1200,n.WORLD_CENTER_Y=900,t.exports=n},function(t,e,i){"use strict";var n=i(2),r=i(8),o=i(9);function s(t,e,i){n.call(this,i),this.isOverlapingSourceAndTarget=!1,this.vGraphObject=i,this.bendpoints=[],this.source=t,this.target=e}for(var a in s.prototype=Object.create(n.prototype),n)s[a]=n[a];s.prototype.getSource=function(){return this.source},s.prototype.getTarget=function(){return this.target},s.prototype.isInterGraph=function(){return this.isInterGraph},s.prototype.getLength=function(){return this.length},s.prototype.isOverlapingSourceAndTarget=function(){return this.isOverlapingSourceAndTarget},s.prototype.getBendpoints=function(){return this.bendpoints},s.prototype.getLca=function(){return this.lca},s.prototype.getSourceInLca=function(){return this.sourceInLca},s.prototype.getTargetInLca=function(){return this.targetInLca},s.prototype.getOtherEnd=function(t){if(this.source===t)return this.target;if(this.target===t)return this.source;throw"Node is not incident with this edge"},s.prototype.getOtherEndInGraph=function(t,e){for(var i=this.getOtherEnd(t),n=e.getGraphManager().getRoot();;){if(i.getOwner()==e)return i;if(i.getOwner()==n)break;i=i.getOwner().getParent()}return null},s.prototype.updateLength=function(){var t=new Array(4);this.isOverlapingSourceAndTarget=r.getIntersection(this.target.getRect(),this.source.getRect(),t),this.isOverlapingSourceAndTarget||(this.lengthX=t[0]-t[2],this.lengthY=t[1]-t[3],Math.abs(this.lengthX)<1&&(this.lengthX=o.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=o.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY))},s.prototype.updateLengthSimple=function(){this.lengthX=this.target.getCenterX()-this.source.getCenterX(),this.lengthY=this.target.getCenterY()-this.source.getCenterY(),Math.abs(this.lengthX)<1&&(this.lengthX=o.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=o.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY)},t.exports=s},function(t,e,i){"use strict";t.exports=function(t){this.vGraphObject=t}},function(t,e,i){"use strict";var n=i(2),r=i(10),o=i(13),s=i(0),a=i(16),h=i(5);function l(t,e,i,s){null==i&&null==s&&(s=e),n.call(this,s),null!=t.graphManager&&(t=t.graphManager),this.estimatedSize=r.MIN_VALUE,this.inclusionTreeDepth=r.MAX_VALUE,this.vGraphObject=s,this.edges=[],this.graphManager=t,this.rect=null!=i&&null!=e?new o(e.x,e.y,i.width,i.height):new o}for(var d in l.prototype=Object.create(n.prototype),n)l[d]=n[d];l.prototype.getEdges=function(){return this.edges},l.prototype.getChild=function(){return this.child},l.prototype.getOwner=function(){return this.owner},l.prototype.getWidth=function(){return this.rect.width},l.prototype.setWidth=function(t){this.rect.width=t},l.prototype.getHeight=function(){return this.rect.height},l.prototype.setHeight=function(t){this.rect.height=t},l.prototype.getCenterX=function(){return this.rect.x+this.rect.width/2},l.prototype.getCenterY=function(){return this.rect.y+this.rect.height/2},l.prototype.getCenter=function(){return new h(this.rect.x+this.rect.width/2,this.rect.y+this.rect.height/2)},l.prototype.getLocation=function(){return new h(this.rect.x,this.rect.y)},l.prototype.getRect=function(){return this.rect},l.prototype.getDiagonal=function(){return Math.sqrt(this.rect.width*this.rect.width+this.rect.height*this.rect.height)},l.prototype.getHalfTheDiagonal=function(){return Math.sqrt(this.rect.height*this.rect.height+this.rect.width*this.rect.width)/2},l.prototype.setRect=function(t,e){this.rect.x=t.x,this.rect.y=t.y,this.rect.width=e.width,this.rect.height=e.height},l.prototype.setCenter=function(t,e){this.rect.x=t-this.rect.width/2,this.rect.y=e-this.rect.height/2},l.prototype.setLocation=function(t,e){this.rect.x=t,this.rect.y=e},l.prototype.moveBy=function(t,e){this.rect.x+=t,this.rect.y+=e},l.prototype.getEdgeListToNode=function(t){var e=[],i=this;return i.edges.forEach(function(n){if(n.target==t){if(n.source!=i)throw"Incorrect edge source!";e.push(n)}}),e},l.prototype.getEdgesBetween=function(t){var e=[],i=this;return i.edges.forEach(function(n){if(n.source!=i&&n.target!=i)throw"Incorrect edge source and/or target";n.target!=t&&n.source!=t||e.push(n)}),e},l.prototype.getNeighborsList=function(){var t=new Set,e=this;return e.edges.forEach(function(i){if(i.source==e)t.add(i.target);else{if(i.target!=e)throw"Incorrect incidency!";t.add(i.source)}}),t},l.prototype.withChildren=function(){var t=new Set;if(t.add(this),null!=this.child)for(var e=this.child.getNodes(),i=0;i<e.length;i++)e[i].withChildren().forEach(function(e){t.add(e)});return t},l.prototype.getNoOfChildren=function(){var t=0;if(null==this.child)t=1;else for(var e=this.child.getNodes(),i=0;i<e.length;i++)t+=e[i].getNoOfChildren();return 0==t&&(t=1),t},l.prototype.getEstimatedSize=function(){if(this.estimatedSize==r.MIN_VALUE)throw"assert failed";return this.estimatedSize},l.prototype.calcEstimatedSize=function(){return null==this.child?this.estimatedSize=(this.rect.width+this.rect.height)/2:(this.estimatedSize=this.child.calcEstimatedSize(),this.rect.width=this.estimatedSize,this.rect.height=this.estimatedSize,this.estimatedSize)},l.prototype.scatter=function(){var t,e,i=-s.INITIAL_WORLD_BOUNDARY,n=s.INITIAL_WORLD_BOUNDARY;t=s.WORLD_CENTER_X+a.nextDouble()*(n-i)+i;var r=-s.INITIAL_WORLD_BOUNDARY,o=s.INITIAL_WORLD_BOUNDARY;e=s.WORLD_CENTER_Y+a.nextDouble()*(o-r)+r,this.rect.x=t,this.rect.y=e},l.prototype.updateBounds=function(){if(null==this.getChild())throw"assert failed";if(0!=this.getChild().getNodes().length){var t=this.getChild();if(t.updateBounds(!0),this.rect.x=t.getLeft(),this.rect.y=t.getTop(),this.setWidth(t.getRight()-t.getLeft()),this.setHeight(t.getBottom()-t.getTop()),s.NODE_DIMENSIONS_INCLUDE_LABELS){var e=t.getRight()-t.getLeft(),i=t.getBottom()-t.getTop();this.labelWidth&&("left"==this.labelPosHorizontal?(this.rect.x-=this.labelWidth,this.setWidth(e+this.labelWidth)):"center"==this.labelPosHorizontal&&this.labelWidth>e?(this.rect.x-=(this.labelWidth-e)/2,this.setWidth(this.labelWidth)):"right"==this.labelPosHorizontal&&this.setWidth(e+this.labelWidth)),this.labelHeight&&("top"==this.labelPosVertical?(this.rect.y-=this.labelHeight,this.setHeight(i+this.labelHeight)):"center"==this.labelPosVertical&&this.labelHeight>i?(this.rect.y-=(this.labelHeight-i)/2,this.setHeight(this.labelHeight)):"bottom"==this.labelPosVertical&&this.setHeight(i+this.labelHeight))}}},l.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==r.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},l.prototype.transform=function(t){var e=this.rect.x;e>s.WORLD_BOUNDARY?e=s.WORLD_BOUNDARY:e<-s.WORLD_BOUNDARY&&(e=-s.WORLD_BOUNDARY);var i=this.rect.y;i>s.WORLD_BOUNDARY?i=s.WORLD_BOUNDARY:i<-s.WORLD_BOUNDARY&&(i=-s.WORLD_BOUNDARY);var n=new h(e,i),r=t.inverseTransformPoint(n);this.setLocation(r.x,r.y)},l.prototype.getLeft=function(){return this.rect.x},l.prototype.getRight=function(){return this.rect.x+this.rect.width},l.prototype.getTop=function(){return this.rect.y},l.prototype.getBottom=function(){return this.rect.y+this.rect.height},l.prototype.getParent=function(){return null==this.owner?null:this.owner.getParent()},t.exports=l},function(t,e,i){"use strict";var n=i(0);function r(){}for(var o in n)r[o]=n[o];r.MAX_ITERATIONS=2500,r.DEFAULT_EDGE_LENGTH=50,r.DEFAULT_SPRING_STRENGTH=.45,r.DEFAULT_REPULSION_STRENGTH=4500,r.DEFAULT_GRAVITY_STRENGTH=.4,r.DEFAULT_COMPOUND_GRAVITY_STRENGTH=1,r.DEFAULT_GRAVITY_RANGE_FACTOR=3.8,r.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=1.5,r.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION=!0,r.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION=!0,r.DEFAULT_COOLING_FACTOR_INCREMENTAL=.3,r.COOLING_ADAPTATION_FACTOR=.33,r.ADAPTATION_LOWER_NODE_LIMIT=1e3,r.ADAPTATION_UPPER_NODE_LIMIT=5e3,r.MAX_NODE_DISPLACEMENT_INCREMENTAL=100,r.MAX_NODE_DISPLACEMENT=3*r.MAX_NODE_DISPLACEMENT_INCREMENTAL,r.MIN_REPULSION_DIST=r.DEFAULT_EDGE_LENGTH/10,r.CONVERGENCE_CHECK_PERIOD=100,r.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=.1,r.MIN_EDGE_LENGTH=1,r.GRID_CALCULATION_CHECK_PERIOD=10,t.exports=r},function(t,e,i){"use strict";function n(t,e){null==t&&null==e?(this.x=0,this.y=0):(this.x=t,this.y=e)}n.prototype.getX=function(){return this.x},n.prototype.getY=function(){return this.y},n.prototype.setX=function(t){this.x=t},n.prototype.setY=function(t){this.y=t},n.prototype.getDifference=function(t){return new DimensionD(this.x-t.x,this.y-t.y)},n.prototype.getCopy=function(){return new n(this.x,this.y)},n.prototype.translate=function(t){return this.x+=t.width,this.y+=t.height,this},t.exports=n},function(t,e,i){"use strict";var n=i(2),r=i(10),o=i(0),s=i(7),a=i(3),h=i(1),l=i(13),d=i(12),c=i(11);function g(t,e,i){n.call(this,i),this.estimatedSize=r.MIN_VALUE,this.margin=o.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=t,null!=e&&e instanceof s?this.graphManager=e:null!=e&&e instanceof Layout&&(this.graphManager=e.graphManager)}for(var u in g.prototype=Object.create(n.prototype),n)g[u]=n[u];g.prototype.getNodes=function(){return this.nodes},g.prototype.getEdges=function(){return this.edges},g.prototype.getGraphManager=function(){return this.graphManager},g.prototype.getParent=function(){return this.parent},g.prototype.getLeft=function(){return this.left},g.prototype.getRight=function(){return this.right},g.prototype.getTop=function(){return this.top},g.prototype.getBottom=function(){return this.bottom},g.prototype.isConnected=function(){return this.isConnected},g.prototype.add=function(t,e,i){if(null==e&&null==i){var n=t;if(null==this.graphManager)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(n)>-1)throw"Node already in graph!";return n.owner=this,this.getNodes().push(n),n}var r=t;if(!(this.getNodes().indexOf(e)>-1&&this.getNodes().indexOf(i)>-1))throw"Source or target not in graph!";if(e.owner!=i.owner||e.owner!=this)throw"Both owners must be this graph!";return e.owner!=i.owner?null:(r.source=e,r.target=i,r.isInterGraph=!1,this.getEdges().push(r),e.edges.push(r),i!=e&&i.edges.push(r),r)},g.prototype.remove=function(t){var e=t;if(t instanceof a){if(null==e)throw"Node is null!";if(null==e.owner||e.owner!=this)throw"Owner graph is invalid!";if(null==this.graphManager)throw"Owner graph manager is invalid!";for(var i=e.edges.slice(),n=i.length,r=0;r<n;r++)(o=i[r]).isInterGraph?this.graphManager.remove(o):o.source.owner.remove(o);if(-1==(s=this.nodes.indexOf(e)))throw"Node not in owner node list!";this.nodes.splice(s,1)}else if(t instanceof h){var o;if(null==(o=t))throw"Edge is null!";if(null==o.source||null==o.target)throw"Source and/or target is null!";if(null==o.source.owner||null==o.target.owner||o.source.owner!=this||o.target.owner!=this)throw"Source and/or target owner is invalid!";var s,l=o.source.edges.indexOf(o),d=o.target.edges.indexOf(o);if(!(l>-1&&d>-1))throw"Source and/or target doesn't know this edge!";if(o.source.edges.splice(l,1),o.target!=o.source&&o.target.edges.splice(d,1),-1==(s=o.source.owner.getEdges().indexOf(o)))throw"Not in owner's edge list!";o.source.owner.getEdges().splice(s,1)}},g.prototype.updateLeftTop=function(){for(var t,e,i,n=r.MAX_VALUE,o=r.MAX_VALUE,s=this.getNodes(),a=s.length,h=0;h<a;h++){var l=s[h];n>(t=l.getTop())&&(n=t),o>(e=l.getLeft())&&(o=e)}return n==r.MAX_VALUE?null:(i=null!=s[0].getParent().paddingLeft?s[0].getParent().paddingLeft:this.margin,this.left=o-i,this.top=n-i,new d(this.left,this.top))},g.prototype.updateBounds=function(t){for(var e,i,n,o,s,a=r.MAX_VALUE,h=-r.MAX_VALUE,d=r.MAX_VALUE,c=-r.MAX_VALUE,g=this.nodes,u=g.length,f=0;f<u;f++){var p=g[f];t&&null!=p.child&&p.updateBounds(),a>(e=p.getLeft())&&(a=e),h<(i=p.getRight())&&(h=i),d>(n=p.getTop())&&(d=n),c<(o=p.getBottom())&&(c=o)}var y=new l(a,d,h-a,c-d);a==r.MAX_VALUE&&(this.left=this.parent.getLeft(),this.right=this.parent.getRight(),this.top=this.parent.getTop(),this.bottom=this.parent.getBottom()),s=null!=g[0].getParent().paddingLeft?g[0].getParent().paddingLeft:this.margin,this.left=y.x-s,this.right=y.x+y.width+s,this.top=y.y-s,this.bottom=y.y+y.height+s},g.calculateBounds=function(t){for(var e,i,n,o,s=r.MAX_VALUE,a=-r.MAX_VALUE,h=r.MAX_VALUE,d=-r.MAX_VALUE,c=t.length,g=0;g<c;g++){var u=t[g];s>(e=u.getLeft())&&(s=e),a<(i=u.getRight())&&(a=i),h>(n=u.getTop())&&(h=n),d<(o=u.getBottom())&&(d=o)}return new l(s,h,a-s,d-h)},g.prototype.getInclusionTreeDepth=function(){return this==this.graphManager.getRoot()?1:this.parent.getInclusionTreeDepth()},g.prototype.getEstimatedSize=function(){if(this.estimatedSize==r.MIN_VALUE)throw"assert failed";return this.estimatedSize},g.prototype.calcEstimatedSize=function(){for(var t=0,e=this.nodes,i=e.length,n=0;n<i;n++)t+=e[n].calcEstimatedSize();return this.estimatedSize=0==t?o.EMPTY_COMPOUND_NODE_SIZE:t/Math.sqrt(this.nodes.length),this.estimatedSize},g.prototype.updateConnected=function(){var t=this;if(0!=this.nodes.length){var e,i,n=new c,r=new Set,o=this.nodes[0];for(o.withChildren().forEach(function(t){n.push(t),r.add(t)});0!==n.length;)for(var s=(e=(o=n.shift()).getEdges()).length,a=0;a<s;a++)null==(i=e[a].getOtherEndInGraph(o,this))||r.has(i)||i.withChildren().forEach(function(t){n.push(t),r.add(t)});if(this.isConnected=!1,r.size>=this.nodes.length){var h=0;r.forEach(function(e){e.owner==t&&h++}),h==this.nodes.length&&(this.isConnected=!0)}}else this.isConnected=!0},t.exports=g},function(t,e,i){"use strict";var n,r=i(1);function o(t){n=i(6),this.layout=t,this.graphs=[],this.edges=[]}o.prototype.addRoot=function(){var t=this.layout.newGraph(),e=this.layout.newNode(null),i=this.add(t,e);return this.setRootGraph(i),this.rootGraph},o.prototype.add=function(t,e,i,n,r){if(null==i&&null==n&&null==r){if(null==t)throw"Graph is null!";if(null==e)throw"Parent node is null!";if(this.graphs.indexOf(t)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(t),null!=t.parent)throw"Already has a parent!";if(null!=e.child)throw"Already has a child!";return t.parent=e,e.child=t,t}r=i,i=t;var o=(n=e).getOwner(),s=r.getOwner();if(null==o||o.getGraphManager()!=this)throw"Source not in this graph mgr!";if(null==s||s.getGraphManager()!=this)throw"Target not in this graph mgr!";if(o==s)return i.isInterGraph=!1,o.add(i,n,r);if(i.isInterGraph=!0,i.source=n,i.target=r,this.edges.indexOf(i)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(i),null==i.source||null==i.target)throw"Edge source and/or target is null!";if(-1!=i.source.edges.indexOf(i)||-1!=i.target.edges.indexOf(i))throw"Edge already in source and/or target incidency list!";return i.source.edges.push(i),i.target.edges.push(i),i},o.prototype.remove=function(t){if(t instanceof n){var e=t;if(e.getGraphManager()!=this)throw"Graph not in this graph mgr";if(e!=this.rootGraph&&(null==e.parent||e.parent.graphManager!=this))throw"Invalid parent node!";for(var i,o=[],s=(o=o.concat(e.getEdges())).length,a=0;a<s;a++)i=o[a],e.remove(i);var h,l=[];for(s=(l=l.concat(e.getNodes())).length,a=0;a<s;a++)h=l[a],e.remove(h);e==this.rootGraph&&this.setRootGraph(null);var d=this.graphs.indexOf(e);this.graphs.splice(d,1),e.parent=null}else if(t instanceof r){if(null==(i=t))throw"Edge is null!";if(!i.isInterGraph)throw"Not an inter-graph edge!";if(null==i.source||null==i.target)throw"Source and/or target is null!";if(-1==i.source.edges.indexOf(i)||-1==i.target.edges.indexOf(i))throw"Source and/or target doesn't know this edge!";if(d=i.source.edges.indexOf(i),i.source.edges.splice(d,1),d=i.target.edges.indexOf(i),i.target.edges.splice(d,1),null==i.source.owner||null==i.source.owner.getGraphManager())throw"Edge owner graph or owner graph manager is null!";if(-1==i.source.owner.getGraphManager().edges.indexOf(i))throw"Not in owner graph manager's edge list!";d=i.source.owner.getGraphManager().edges.indexOf(i),i.source.owner.getGraphManager().edges.splice(d,1)}},o.prototype.updateBounds=function(){this.rootGraph.updateBounds(!0)},o.prototype.getGraphs=function(){return this.graphs},o.prototype.getAllNodes=function(){if(null==this.allNodes){for(var t=[],e=this.getGraphs(),i=e.length,n=0;n<i;n++)t=t.concat(e[n].getNodes());this.allNodes=t}return this.allNodes},o.prototype.resetAllNodes=function(){this.allNodes=null},o.prototype.resetAllEdges=function(){this.allEdges=null},o.prototype.resetAllNodesToApplyGravitation=function(){this.allNodesToApplyGravitation=null},o.prototype.getAllEdges=function(){if(null==this.allEdges){for(var t=[],e=this.getGraphs(),i=(e.length,0);i<e.length;i++)t=t.concat(e[i].getEdges());t=t.concat(this.edges),this.allEdges=t}return this.allEdges},o.prototype.getAllNodesToApplyGravitation=function(){return this.allNodesToApplyGravitation},o.prototype.setAllNodesToApplyGravitation=function(t){if(null!=this.allNodesToApplyGravitation)throw"assert failed";this.allNodesToApplyGravitation=t},o.prototype.getRoot=function(){return this.rootGraph},o.prototype.setRootGraph=function(t){if(t.getGraphManager()!=this)throw"Root not in this graph mgr!";this.rootGraph=t,null==t.parent&&(t.parent=this.layout.newNode("Root node"))},o.prototype.getLayout=function(){return this.layout},o.prototype.isOneAncestorOfOther=function(t,e){if(null==t||null==e)throw"assert failed";if(t==e)return!0;for(var i,n=t.getOwner();null!=(i=n.getParent());){if(i==e)return!0;if(null==(n=i.getOwner()))break}for(n=e.getOwner();null!=(i=n.getParent());){if(i==t)return!0;if(null==(n=i.getOwner()))break}return!1},o.prototype.calcLowestCommonAncestors=function(){for(var t,e,i,n,r,o=this.getAllEdges(),s=o.length,a=0;a<s;a++)if(e=(t=o[a]).source,i=t.target,t.lca=null,t.sourceInLca=e,t.targetInLca=i,e!=i){for(n=e.getOwner();null==t.lca;){for(t.targetInLca=i,r=i.getOwner();null==t.lca;){if(r==n){t.lca=r;break}if(r==this.rootGraph)break;if(null!=t.lca)throw"assert failed";t.targetInLca=r.getParent(),r=t.targetInLca.getOwner()}if(n==this.rootGraph)break;null==t.lca&&(t.sourceInLca=n.getParent(),n=t.sourceInLca.getOwner())}if(null==t.lca)throw"assert failed"}else t.lca=e.getOwner()},o.prototype.calcLowestCommonAncestor=function(t,e){if(t==e)return t.getOwner();for(var i=t.getOwner();null!=i;){for(var n=e.getOwner();null!=n;){if(n==i)return n;n=n.getParent().getOwner()}i=i.getParent().getOwner()}return i},o.prototype.calcInclusionTreeDepths=function(t,e){var i;null==t&&null==e&&(t=this.rootGraph,e=1);for(var n=t.getNodes(),r=n.length,o=0;o<r;o++)(i=n[o]).inclusionTreeDepth=e,null!=i.child&&this.calcInclusionTreeDepths(i.child,e+1)},o.prototype.includesInvalidEdge=function(){for(var t,e=[],i=this.edges.length,n=0;n<i;n++)t=this.edges[n],this.isOneAncestorOfOther(t.source,t.target)&&e.push(t);for(n=0;n<e.length;n++)this.remove(e[n]);return!1},t.exports=o},function(t,e,i){"use strict";var n=i(12);function r(){}r.calcSeparationAmount=function(t,e,i,n){if(!t.intersects(e))throw"assert failed";var r=new Array(2);this.decideDirectionsForOverlappingNodes(t,e,r),i[0]=Math.min(t.getRight(),e.getRight())-Math.max(t.x,e.x),i[1]=Math.min(t.getBottom(),e.getBottom())-Math.max(t.y,e.y),t.getX()<=e.getX()&&t.getRight()>=e.getRight()?i[0]+=Math.min(e.getX()-t.getX(),t.getRight()-e.getRight()):e.getX()<=t.getX()&&e.getRight()>=t.getRight()&&(i[0]+=Math.min(t.getX()-e.getX(),e.getRight()-t.getRight())),t.getY()<=e.getY()&&t.getBottom()>=e.getBottom()?i[1]+=Math.min(e.getY()-t.getY(),t.getBottom()-e.getBottom()):e.getY()<=t.getY()&&e.getBottom()>=t.getBottom()&&(i[1]+=Math.min(t.getY()-e.getY(),e.getBottom()-t.getBottom()));var o=Math.abs((e.getCenterY()-t.getCenterY())/(e.getCenterX()-t.getCenterX()));e.getCenterY()===t.getCenterY()&&e.getCenterX()===t.getCenterX()&&(o=1);var s=o*i[0],a=i[1]/o;i[0]<a?a=i[0]:s=i[1],i[0]=-1*r[0]*(a/2+n),i[1]=-1*r[1]*(s/2+n)},r.decideDirectionsForOverlappingNodes=function(t,e,i){t.getCenterX()<e.getCenterX()?i[0]=-1:i[0]=1,t.getCenterY()<e.getCenterY()?i[1]=-1:i[1]=1},r.getIntersection2=function(t,e,i){var n=t.getCenterX(),r=t.getCenterY(),o=e.getCenterX(),s=e.getCenterY();if(t.intersects(e))return i[0]=n,i[1]=r,i[2]=o,i[3]=s,!0;var a=t.getX(),h=t.getY(),l=t.getRight(),d=t.getX(),c=t.getBottom(),g=t.getRight(),u=t.getWidthHalf(),f=t.getHeightHalf(),p=e.getX(),y=e.getY(),v=e.getRight(),m=e.getX(),E=e.getBottom(),N=e.getRight(),T=e.getWidthHalf(),A=e.getHeightHalf(),w=!1,L=!1;if(n===o){if(r>s)return i[0]=n,i[1]=h,i[2]=o,i[3]=E,!1;if(r<s)return i[0]=n,i[1]=c,i[2]=o,i[3]=y,!1}else if(r===s){if(n>o)return i[0]=a,i[1]=r,i[2]=v,i[3]=s,!1;if(n<o)return i[0]=l,i[1]=r,i[2]=p,i[3]=s,!1}else{var C=t.height/t.width,I=e.height/e.width,_=(s-r)/(o-n),M=void 0,x=void 0,O=void 0,D=void 0,R=void 0,b=void 0;if(-C===_?n>o?(i[0]=d,i[1]=c,w=!0):(i[0]=l,i[1]=h,w=!0):C===_&&(n>o?(i[0]=a,i[1]=h,w=!0):(i[0]=g,i[1]=c,w=!0)),-I===_?o>n?(i[2]=m,i[3]=E,L=!0):(i[2]=v,i[3]=y,L=!0):I===_&&(o>n?(i[2]=p,i[3]=y,L=!0):(i[2]=N,i[3]=E,L=!0)),w&&L)return!1;if(n>o?r>s?(M=this.getCardinalDirection(C,_,4),x=this.getCardinalDirection(I,_,2)):(M=this.getCardinalDirection(-C,_,3),x=this.getCardinalDirection(-I,_,1)):r>s?(M=this.getCardinalDirection(-C,_,1),x=this.getCardinalDirection(-I,_,3)):(M=this.getCardinalDirection(C,_,2),x=this.getCardinalDirection(I,_,4)),!w)switch(M){case 1:D=h,O=n+-f/_,i[0]=O,i[1]=D;break;case 2:O=g,D=r+u*_,i[0]=O,i[1]=D;break;case 3:D=c,O=n+f/_,i[0]=O,i[1]=D;break;case 4:O=d,D=r+-u*_,i[0]=O,i[1]=D}if(!L)switch(x){case 1:b=y,R=o+-A/_,i[2]=R,i[3]=b;break;case 2:R=N,b=s+T*_,i[2]=R,i[3]=b;break;case 3:b=E,R=o+A/_,i[2]=R,i[3]=b;break;case 4:R=m,b=s+-T*_,i[2]=R,i[3]=b}}return!1},r.getCardinalDirection=function(t,e,i){return t>e?i:1+i%4},r.getIntersection=function(t,e,i,r){if(null==r)return this.getIntersection2(t,e,i);var o,s,a,h,l,d,c,g=t.x,u=t.y,f=e.x,p=e.y,y=i.x,v=i.y,m=r.x,E=r.y;return 0===(c=(o=p-u)*(h=y-m)-(s=E-v)*(a=g-f))?null:new n((a*(d=m*v-y*E)-h*(l=f*u-g*p))/c,(s*l-o*d)/c)},r.angleOfVector=function(t,e,i,n){var r=void 0;return t!==i?(r=Math.atan((n-e)/(i-t)),i<t?r+=Math.PI:n<e&&(r+=this.TWO_PI)):r=n<e?this.ONE_AND_HALF_PI:this.HALF_PI,r},r.doIntersect=function(t,e,i,n){var r=t.x,o=t.y,s=e.x,a=e.y,h=i.x,l=i.y,d=n.x,c=n.y,g=(s-r)*(c-l)-(d-h)*(a-o);if(0===g)return!1;var u=((c-l)*(d-r)+(h-d)*(c-o))/g,f=((o-a)*(d-r)+(s-r)*(c-o))/g;return 0<u&&u<1&&0<f&&f<1},r.findCircleLineIntersections=function(t,e,i,n,r,o,s){var a=(i-t)*(i-t)+(n-e)*(n-e),h=2*((t-r)*(i-t)+(e-o)*(n-e)),l=(t-r)*(t-r)+(e-o)*(e-o)-s*s;if(h*h-4*a*l>=0){var d=(-h+Math.sqrt(h*h-4*a*l))/(2*a),c=(-h-Math.sqrt(h*h-4*a*l))/(2*a);return d>=0&&d<=1?[d]:c>=0&&c<=1?[c]:null}return null},r.HALF_PI=.5*Math.PI,r.ONE_AND_HALF_PI=1.5*Math.PI,r.TWO_PI=2*Math.PI,r.THREE_PI=3*Math.PI,t.exports=r},function(t,e,i){"use strict";function n(){}n.sign=function(t){return t>0?1:t<0?-1:0},n.floor=function(t){return t<0?Math.ceil(t):Math.floor(t)},n.ceil=function(t){return t<0?Math.floor(t):Math.ceil(t)},t.exports=n},function(t,e,i){"use strict";function n(){}n.MAX_VALUE=2147483647,n.MIN_VALUE=-2147483648,t.exports=n},function(t,e,i){"use strict";var n=function(){function t(t,e){for(var i=0;i<e.length;i++){var n=e[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,i,n){return i&&t(e.prototype,i),n&&t(e,n),e}}(),r=function(t){return{value:t,next:null,prev:null}},o=function(t,e,i,n){return null!==t?t.next=e:n.head=e,null!==i?i.prev=e:n.tail=e,e.prev=t,e.next=i,n.length++,e},s=function(t,e){var i=t.prev,n=t.next;return null!==i?i.next=n:e.head=n,null!==n?n.prev=i:e.tail=i,t.prev=t.next=null,e.length--,t},a=function(){function t(e){var i=this;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.length=0,this.head=null,this.tail=null,null!=e&&e.forEach(function(t){return i.push(t)})}return n(t,[{key:"size",value:function(){return this.length}},{key:"insertBefore",value:function(t,e){return o(e.prev,r(t),e,this)}},{key:"insertAfter",value:function(t,e){return o(e,r(t),e.next,this)}},{key:"insertNodeBefore",value:function(t,e){return o(e.prev,t,e,this)}},{key:"insertNodeAfter",value:function(t,e){return o(e,t,e.next,this)}},{key:"push",value:function(t){return o(this.tail,r(t),null,this)}},{key:"unshift",value:function(t){return o(null,r(t),this.head,this)}},{key:"remove",value:function(t){return s(t,this)}},{key:"pop",value:function(){return s(this.tail,this).value}},{key:"popNode",value:function(){return s(this.tail,this)}},{key:"shift",value:function(){return s(this.head,this).value}},{key:"shiftNode",value:function(){return s(this.head,this)}},{key:"get_object_at",value:function(t){if(t<=this.length()){for(var e=1,i=this.head;e<t;)i=i.next,e++;return i.value}}},{key:"set_object_at",value:function(t,e){if(t<=this.length()){for(var i=1,n=this.head;i<t;)n=n.next,i++;n.value=e}}}]),t}();t.exports=a},function(t,e,i){"use strict";function n(t,e,i){this.x=null,this.y=null,null==t&&null==e&&null==i?(this.x=0,this.y=0):"number"==typeof t&&"number"==typeof e&&null==i?(this.x=t,this.y=e):"Point"==t.constructor.name&&null==e&&null==i&&(i=t,this.x=i.x,this.y=i.y)}n.prototype.getX=function(){return this.x},n.prototype.getY=function(){return this.y},n.prototype.getLocation=function(){return new n(this.x,this.y)},n.prototype.setLocation=function(t,e,i){"Point"==t.constructor.name&&null==e&&null==i?(i=t,this.setLocation(i.x,i.y)):"number"==typeof t&&"number"==typeof e&&null==i&&(parseInt(t)==t&&parseInt(e)==e?this.move(t,e):(this.x=Math.floor(t+.5),this.y=Math.floor(e+.5)))},n.prototype.move=function(t,e){this.x=t,this.y=e},n.prototype.translate=function(t,e){this.x+=t,this.y+=e},n.prototype.equals=function(t){if("Point"==t.constructor.name){var e=t;return this.x==e.x&&this.y==e.y}return this==t},n.prototype.toString=function(){return(new n).constructor.name+"[x="+this.x+",y="+this.y+"]"},t.exports=n},function(t,e,i){"use strict";function n(t,e,i,n){this.x=0,this.y=0,this.width=0,this.height=0,null!=t&&null!=e&&null!=i&&null!=n&&(this.x=t,this.y=e,this.width=i,this.height=n)}n.prototype.getX=function(){return this.x},n.prototype.setX=function(t){this.x=t},n.prototype.getY=function(){return this.y},n.prototype.setY=function(t){this.y=t},n.prototype.getWidth=function(){return this.width},n.prototype.setWidth=function(t){this.width=t},n.prototype.getHeight=function(){return this.height},n.prototype.setHeight=function(t){this.height=t},n.prototype.getRight=function(){return this.x+this.width},n.prototype.getBottom=function(){return this.y+this.height},n.prototype.intersects=function(t){return!(this.getRight()<t.x||this.getBottom()<t.y||t.getRight()<this.x||t.getBottom()<this.y)},n.prototype.getCenterX=function(){return this.x+this.width/2},n.prototype.getMinX=function(){return this.getX()},n.prototype.getMaxX=function(){return this.getX()+this.width},n.prototype.getCenterY=function(){return this.y+this.height/2},n.prototype.getMinY=function(){return this.getY()},n.prototype.getMaxY=function(){return this.getY()+this.height},n.prototype.getWidthHalf=function(){return this.width/2},n.prototype.getHeightHalf=function(){return this.height/2},t.exports=n},function(t,e,i){"use strict";var n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};function r(){}r.lastID=0,r.createID=function(t){return r.isPrimitive(t)?t:(null!=t.uniqueID||(t.uniqueID=r.getString(),r.lastID++),t.uniqueID)},r.getString=function(t){return null==t&&(t=r.lastID),"Object#"+t},r.isPrimitive=function(t){var e=void 0===t?"undefined":n(t);return null==t||"object"!=e&&"function"!=e},t.exports=r},function(t,e,i){"use strict";function n(t){if(Array.isArray(t)){for(var e=0,i=Array(t.length);e<t.length;e++)i[e]=t[e];return i}return Array.from(t)}var r=i(0),o=i(7),s=i(3),a=i(1),h=i(6),l=i(5),d=i(17),c=i(29);function g(t){c.call(this),this.layoutQuality=r.QUALITY,this.createBendsAsNeeded=r.DEFAULT_CREATE_BENDS_AS_NEEDED,this.incremental=r.DEFAULT_INCREMENTAL,this.animationOnLayout=r.DEFAULT_ANIMATION_ON_LAYOUT,this.animationDuringLayout=r.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=r.DEFAULT_ANIMATION_PERIOD,this.uniformLeafNodeSizes=r.DEFAULT_UNIFORM_LEAF_NODE_SIZES,this.edgeToDummyNodes=new Map,this.graphManager=new o(this),this.isLayoutFinished=!1,this.isSubLayout=!1,this.isRemoteUse=!1,null!=t&&(this.isRemoteUse=t)}g.RANDOM_SEED=1,g.prototype=Object.create(c.prototype),g.prototype.getGraphManager=function(){return this.graphManager},g.prototype.getAllNodes=function(){return this.graphManager.getAllNodes()},g.prototype.getAllEdges=function(){return this.graphManager.getAllEdges()},g.prototype.getAllNodesToApplyGravitation=function(){return this.graphManager.getAllNodesToApplyGravitation()},g.prototype.newGraphManager=function(){var t=new o(this);return this.graphManager=t,t},g.prototype.newGraph=function(t){return new h(null,this.graphManager,t)},g.prototype.newNode=function(t){return new s(this.graphManager,t)},g.prototype.newEdge=function(t){return new a(null,null,t)},g.prototype.checkLayoutSuccess=function(){return null==this.graphManager.getRoot()||0==this.graphManager.getRoot().getNodes().length||this.graphManager.includesInvalidEdge()},g.prototype.runLayout=function(){var t;return this.isLayoutFinished=!1,this.tilingPreLayout&&this.tilingPreLayout(),this.initParameters(),t=!this.checkLayoutSuccess()&&this.layout(),"during"!==r.ANIMATE&&(t&&(this.isSubLayout||this.doPostLayout()),this.tilingPostLayout&&this.tilingPostLayout(),this.isLayoutFinished=!0,t)},g.prototype.doPostLayout=function(){this.incremental||this.transform(),this.update()},g.prototype.update2=function(){if(this.createBendsAsNeeded&&(this.createBendpointsFromDummyNodes(),this.graphManager.resetAllEdges()),!this.isRemoteUse){for(var t=this.graphManager.getAllEdges(),e=0;e<t.length;e++)t[e];var i=this.graphManager.getRoot().getNodes();for(e=0;e<i.length;e++)i[e];this.update(this.graphManager.getRoot())}},g.prototype.update=function(t){if(null==t)this.update2();else if(t instanceof s){var e=t;if(null!=e.getChild())for(var i=e.getChild().getNodes(),n=0;n<i.length;n++)update(i[n]);null!=e.vGraphObject&&e.vGraphObject.update(e)}else if(t instanceof a){var r=t;null!=r.vGraphObject&&r.vGraphObject.update(r)}else if(t instanceof h){var o=t;null!=o.vGraphObject&&o.vGraphObject.update(o)}},g.prototype.initParameters=function(){this.isSubLayout||(this.layoutQuality=r.QUALITY,this.animationDuringLayout=r.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=r.DEFAULT_ANIMATION_PERIOD,this.animationOnLayout=r.DEFAULT_ANIMATION_ON_LAYOUT,this.incremental=r.DEFAULT_INCREMENTAL,this.createBendsAsNeeded=r.DEFAULT_CREATE_BENDS_AS_NEEDED,this.uniformLeafNodeSizes=r.DEFAULT_UNIFORM_LEAF_NODE_SIZES),this.animationDuringLayout&&(this.animationOnLayout=!1)},g.prototype.transform=function(t){if(null==t)this.transform(new l(0,0));else{var e=new d,i=this.graphManager.getRoot().updateLeftTop();if(null!=i){e.setWorldOrgX(t.x),e.setWorldOrgY(t.y),e.setDeviceOrgX(i.x),e.setDeviceOrgY(i.y);for(var n=this.getAllNodes(),r=0;r<n.length;r++)n[r].transform(e)}}},g.prototype.positionNodesRandomly=function(t){if(null==t)this.positionNodesRandomly(this.getGraphManager().getRoot()),this.getGraphManager().getRoot().updateBounds(!0);else for(var e,i,n=t.getNodes(),r=0;r<n.length;r++)null==(i=(e=n[r]).getChild())||0==i.getNodes().length?e.scatter():(this.positionNodesRandomly(i),e.updateBounds())},g.prototype.getFlatForest=function(){for(var t=[],e=!0,i=this.graphManager.getRoot().getNodes(),r=!0,o=0;o<i.length;o++)null!=i[o].getChild()&&(r=!1);if(!r)return t;var s=new Set,a=[],h=new Map,l=[];for(l=l.concat(i);l.length>0&&e;){for(a.push(l[0]);a.length>0&&e;){var d=a[0];a.splice(0,1),s.add(d);var c=d.getEdges();for(o=0;o<c.length;o++){var g=c[o].getOtherEnd(d);if(h.get(d)!=g){if(s.has(g)){e=!1;break}a.push(g),h.set(g,d)}}}if(e){var u=[].concat(n(s));for(t.push(u),o=0;o<u.length;o++){var f=u[o],p=l.indexOf(f);p>-1&&l.splice(p,1)}s=new Set,h=new Map}else t=[]}return t},g.prototype.createDummyNodesForBendpoints=function(t){for(var e=[],i=t.source,n=this.graphManager.calcLowestCommonAncestor(t.source,t.target),r=0;r<t.bendpoints.length;r++){var o=this.newNode(null);o.setRect(new Point(0,0),new Dimension(1,1)),n.add(o);var s=this.newEdge(null);this.graphManager.add(s,i,o),e.add(o),i=o}return s=this.newEdge(null),this.graphManager.add(s,i,t.target),this.edgeToDummyNodes.set(t,e),t.isInterGraph()?this.graphManager.remove(t):n.remove(t),e},g.prototype.createBendpointsFromDummyNodes=function(){var t=[];t=t.concat(this.graphManager.getAllEdges()),t=[].concat(n(this.edgeToDummyNodes.keys())).concat(t);for(var e=0;e<t.length;e++){var i=t[e];if(i.bendpoints.length>0){for(var r=this.edgeToDummyNodes.get(i),o=0;o<r.length;o++){var s=r[o],a=new l(s.getCenterX(),s.getCenterY()),h=i.bendpoints.get(o);h.x=a.x,h.y=a.y,s.getOwner().remove(s)}this.graphManager.add(i,i.source,i.target)}}},g.transform=function(t,e,i,n){if(null!=i&&null!=n){var r=e;return t<=50?r-=(e-e/i)/50*(50-t):r+=(e*n-e)/50*(t-50),r}var o,s;return t<=50?(o=9*e/500,s=e/10):(o=9*e/50,s=-8*e),o*t+s},g.findCenterOfTree=function(t){var e=[];e=e.concat(t);var i=[],n=new Map,r=!1,o=null;1!=e.length&&2!=e.length||(r=!0,o=e[0]);for(var s=0;s<e.length;s++){var a=(d=e[s]).getNeighborsList().size;n.set(d,d.getNeighborsList().size),1==a&&i.push(d)}var h=[];for(h=h.concat(i);!r;){var l=[];for(l=l.concat(h),h=[],s=0;s<e.length;s++){var d=e[s],c=e.indexOf(d);c>=0&&e.splice(c,1),d.getNeighborsList().forEach(function(t){if(i.indexOf(t)<0){var e=n.get(t)-1;1==e&&h.push(t),n.set(t,e)}})}i=i.concat(h),1!=e.length&&2!=e.length||(r=!0,o=e[0])}return o},g.prototype.setGraphManager=function(t){this.graphManager=t},t.exports=g},function(t,e,i){"use strict";function n(){}n.seed=1,n.x=0,n.nextDouble=function(){return n.x=1e4*Math.sin(n.seed++),n.x-Math.floor(n.x)},t.exports=n},function(t,e,i){"use strict";var n=i(5);function r(t,e){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}r.prototype.getWorldOrgX=function(){return this.lworldOrgX},r.prototype.setWorldOrgX=function(t){this.lworldOrgX=t},r.prototype.getWorldOrgY=function(){return this.lworldOrgY},r.prototype.setWorldOrgY=function(t){this.lworldOrgY=t},r.prototype.getWorldExtX=function(){return this.lworldExtX},r.prototype.setWorldExtX=function(t){this.lworldExtX=t},r.prototype.getWorldExtY=function(){return this.lworldExtY},r.prototype.setWorldExtY=function(t){this.lworldExtY=t},r.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},r.prototype.setDeviceOrgX=function(t){this.ldeviceOrgX=t},r.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},r.prototype.setDeviceOrgY=function(t){this.ldeviceOrgY=t},r.prototype.getDeviceExtX=function(){return this.ldeviceExtX},r.prototype.setDeviceExtX=function(t){this.ldeviceExtX=t},r.prototype.getDeviceExtY=function(){return this.ldeviceExtY},r.prototype.setDeviceExtY=function(t){this.ldeviceExtY=t},r.prototype.transformX=function(t){var e=0,i=this.lworldExtX;return 0!=i&&(e=this.ldeviceOrgX+(t-this.lworldOrgX)*this.ldeviceExtX/i),e},r.prototype.transformY=function(t){var e=0,i=this.lworldExtY;return 0!=i&&(e=this.ldeviceOrgY+(t-this.lworldOrgY)*this.ldeviceExtY/i),e},r.prototype.inverseTransformX=function(t){var e=0,i=this.ldeviceExtX;return 0!=i&&(e=this.lworldOrgX+(t-this.ldeviceOrgX)*this.lworldExtX/i),e},r.prototype.inverseTransformY=function(t){var e=0,i=this.ldeviceExtY;return 0!=i&&(e=this.lworldOrgY+(t-this.ldeviceOrgY)*this.lworldExtY/i),e},r.prototype.inverseTransformPoint=function(t){return new n(this.inverseTransformX(t.x),this.inverseTransformY(t.y))},t.exports=r},function(t,e,i){"use strict";var n=i(15),r=i(4),o=i(0),s=i(8),a=i(9);function h(){n.call(this),this.useSmartIdealEdgeLengthCalculation=r.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.gravityConstant=r.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=r.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=r.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=r.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.displacementThresholdPerNode=3*r.DEFAULT_EDGE_LENGTH/100,this.coolingFactor=r.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.initialCoolingFactor=r.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.totalDisplacement=0,this.oldTotalDisplacement=0,this.maxIterations=r.MAX_ITERATIONS}for(var l in h.prototype=Object.create(n.prototype),n)h[l]=n[l];h.prototype.initParameters=function(){n.prototype.initParameters.call(this,arguments),this.totalIterations=0,this.notAnimatedIterations=0,this.useFRGridVariant=r.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION,this.grid=[]},h.prototype.calcIdealEdgeLengths=function(){for(var t,e,i,n,s,a,h,l=this.getGraphManager().getAllEdges(),d=0;d<l.length;d++)e=(t=l[d]).idealLength,t.isInterGraph&&(n=t.getSource(),s=t.getTarget(),a=t.getSourceInLca().getEstimatedSize(),h=t.getTargetInLca().getEstimatedSize(),this.useSmartIdealEdgeLengthCalculation&&(t.idealLength+=a+h-2*o.SIMPLE_NODE_SIZE),i=t.getLca().getInclusionTreeDepth(),t.idealLength+=e*r.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR*(n.getInclusionTreeDepth()+s.getInclusionTreeDepth()-2*i))},h.prototype.initSpringEmbedder=function(){var t=this.getAllNodes().length;this.incremental?(t>r.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*r.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(t-r.ADAPTATION_LOWER_NODE_LIMIT)/(r.ADAPTATION_UPPER_NODE_LIMIT-r.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-r.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=r.MAX_NODE_DISPLACEMENT_INCREMENTAL):(t>r.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(r.COOLING_ADAPTATION_FACTOR,1-(t-r.ADAPTATION_LOWER_NODE_LIMIT)/(r.ADAPTATION_UPPER_NODE_LIMIT-r.ADAPTATION_LOWER_NODE_LIMIT)*(1-r.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=r.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(5*this.getAllNodes().length,this.maxIterations),this.displacementThresholdPerNode=3*r.DEFAULT_EDGE_LENGTH/100,this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},h.prototype.calcSpringForces=function(){for(var t,e=this.getAllEdges(),i=0;i<e.length;i++)t=e[i],this.calcSpringForce(t,t.idealLength)},h.prototype.calcRepulsionForces=function(){var t,e,i,n,o,s=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],a=arguments.length>1&&void 0!==arguments[1]&&arguments[1],h=this.getAllNodes();if(this.useFRGridVariant)for(this.totalIterations%r.GRID_CALCULATION_CHECK_PERIOD==1&&s&&this.updateGrid(),o=new Set,t=0;t<h.length;t++)i=h[t],this.calculateRepulsionForceOfANode(i,o,s,a),o.add(i);else for(t=0;t<h.length;t++)for(i=h[t],e=t+1;e<h.length;e++)n=h[e],i.getOwner()==n.getOwner()&&this.calcRepulsionForce(i,n)},h.prototype.calcGravitationalForces=function(){for(var t,e=this.getAllNodesToApplyGravitation(),i=0;i<e.length;i++)t=e[i],this.calcGravitationalForce(t)},h.prototype.moveNodes=function(){for(var t=this.getAllNodes(),e=0;e<t.length;e++)t[e].move()},h.prototype.calcSpringForce=function(t,e){var i,n,r,o,s=t.getSource(),a=t.getTarget();if(this.uniformLeafNodeSizes&&null==s.getChild()&&null==a.getChild())t.updateLengthSimple();else if(t.updateLength(),t.isOverlapingSourceAndTarget)return;0!=(i=t.getLength())&&(r=(n=t.edgeElasticity*(i-e))*(t.lengthX/i),o=n*(t.lengthY/i),s.springForceX+=r,s.springForceY+=o,a.springForceX-=r,a.springForceY-=o)},h.prototype.calcRepulsionForce=function(t,e){var i,n,o,h,l,d,c,g=t.getRect(),u=e.getRect(),f=new Array(2),p=new Array(4);if(g.intersects(u)){s.calcSeparationAmount(g,u,f,r.DEFAULT_EDGE_LENGTH/2),d=2*f[0],c=2*f[1];var y=t.noOfChildren*e.noOfChildren/(t.noOfChildren+e.noOfChildren);t.repulsionForceX-=y*d,t.repulsionForceY-=y*c,e.repulsionForceX+=y*d,e.repulsionForceY+=y*c}else this.uniformLeafNodeSizes&&null==t.getChild()&&null==e.getChild()?(i=u.getCenterX()-g.getCenterX(),n=u.getCenterY()-g.getCenterY()):(s.getIntersection(g,u,p),i=p[2]-p[0],n=p[3]-p[1]),Math.abs(i)<r.MIN_REPULSION_DIST&&(i=a.sign(i)*r.MIN_REPULSION_DIST),Math.abs(n)<r.MIN_REPULSION_DIST&&(n=a.sign(n)*r.MIN_REPULSION_DIST),o=i*i+n*n,h=Math.sqrt(o),d=(l=(t.nodeRepulsion/2+e.nodeRepulsion/2)*t.noOfChildren*e.noOfChildren/o)*i/h,c=l*n/h,t.repulsionForceX-=d,t.repulsionForceY-=c,e.repulsionForceX+=d,e.repulsionForceY+=c},h.prototype.calcGravitationalForce=function(t){var e,i,n,r,o,s,a,h;i=((e=t.getOwner()).getRight()+e.getLeft())/2,n=(e.getTop()+e.getBottom())/2,r=t.getCenterX()-i,o=t.getCenterY()-n,s=Math.abs(r)+t.getWidth()/2,a=Math.abs(o)+t.getHeight()/2,t.getOwner()==this.graphManager.getRoot()?(s>(h=e.getEstimatedSize()*this.gravityRangeFactor)||a>h)&&(t.gravitationForceX=-this.gravityConstant*r,t.gravitationForceY=-this.gravityConstant*o):(s>(h=e.getEstimatedSize()*this.compoundGravityRangeFactor)||a>h)&&(t.gravitationForceX=-this.gravityConstant*r*this.compoundGravityConstant,t.gravitationForceY=-this.gravityConstant*o*this.compoundGravityConstant)},h.prototype.isConverged=function(){var t,e=!1;return this.totalIterations>this.maxIterations/3&&(e=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),t=this.totalDisplacement<this.totalDisplacementThreshold,this.oldTotalDisplacement=this.totalDisplacement,t||e},h.prototype.animate=function(){this.animationDuringLayout&&!this.isSubLayout&&(this.notAnimatedIterations==this.animationPeriod?(this.update(),this.notAnimatedIterations=0):this.notAnimatedIterations++)},h.prototype.calcNoOfChildrenForAllNodes=function(){for(var t,e=this.graphManager.getAllNodes(),i=0;i<e.length;i++)(t=e[i]).noOfChildren=t.getNoOfChildren()},h.prototype.calcGrid=function(t){var e,i;e=parseInt(Math.ceil((t.getRight()-t.getLeft())/this.repulsionRange)),i=parseInt(Math.ceil((t.getBottom()-t.getTop())/this.repulsionRange));for(var n=new Array(e),r=0;r<e;r++)n[r]=new Array(i);for(r=0;r<e;r++)for(var o=0;o<i;o++)n[r][o]=new Array;return n},h.prototype.addNodeToGrid=function(t,e,i){var n,r,o,s;n=parseInt(Math.floor((t.getRect().x-e)/this.repulsionRange)),r=parseInt(Math.floor((t.getRect().width+t.getRect().x-e)/this.repulsionRange)),o=parseInt(Math.floor((t.getRect().y-i)/this.repulsionRange)),s=parseInt(Math.floor((t.getRect().height+t.getRect().y-i)/this.repulsionRange));for(var a=n;a<=r;a++)for(var h=o;h<=s;h++)this.grid[a][h].push(t),t.setGridCoordinates(n,r,o,s)},h.prototype.updateGrid=function(){var t,e,i=this.getAllNodes();for(this.grid=this.calcGrid(this.graphManager.getRoot()),t=0;t<i.length;t++)e=i[t],this.addNodeToGrid(e,this.graphManager.getRoot().getLeft(),this.graphManager.getRoot().getTop())},h.prototype.calculateRepulsionForceOfANode=function(t,e,i,n){if(this.totalIterations%r.GRID_CALCULATION_CHECK_PERIOD==1&&i||n){var o,s=new Set;t.surrounding=new Array;for(var a=this.grid,h=t.startX-1;h<t.finishX+2;h++)for(var l=t.startY-1;l<t.finishY+2;l++)if(!(h<0||l<0||h>=a.length||l>=a[0].length))for(var d=0;d<a[h][l].length;d++)if(o=a[h][l][d],t.getOwner()==o.getOwner()&&t!=o&&!e.has(o)&&!s.has(o)){var c=Math.abs(t.getCenterX()-o.getCenterX())-(t.getWidth()/2+o.getWidth()/2),g=Math.abs(t.getCenterY()-o.getCenterY())-(t.getHeight()/2+o.getHeight()/2);c<=this.repulsionRange&&g<=this.repulsionRange&&s.add(o)}t.surrounding=[].concat(function(t){if(Array.isArray(t)){for(var e=0,i=Array(t.length);e<t.length;e++)i[e]=t[e];return i}return Array.from(t)}(s))}for(h=0;h<t.surrounding.length;h++)this.calcRepulsionForce(t,t.surrounding[h])},h.prototype.calcRepulsionRange=function(){return 0},t.exports=h},function(t,e,i){"use strict";var n=i(1),r=i(4);function o(t,e,i){n.call(this,t,e,i),this.idealLength=r.DEFAULT_EDGE_LENGTH,this.edgeElasticity=r.DEFAULT_SPRING_STRENGTH}for(var s in o.prototype=Object.create(n.prototype),n)o[s]=n[s];t.exports=o},function(t,e,i){"use strict";var n=i(3),r=i(4);function o(t,e,i,o){n.call(this,t,e,i,o),this.nodeRepulsion=r.DEFAULT_REPULSION_STRENGTH,this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0,this.startX=0,this.finishX=0,this.startY=0,this.finishY=0,this.surrounding=[]}for(var s in o.prototype=Object.create(n.prototype),n)o[s]=n[s];o.prototype.setGridCoordinates=function(t,e,i,n){this.startX=t,this.finishX=e,this.startY=i,this.finishY=n},t.exports=o},function(t,e,i){"use strict";function n(t,e){this.width=0,this.height=0,null!==t&&null!==e&&(this.height=e,this.width=t)}n.prototype.getWidth=function(){return this.width},n.prototype.setWidth=function(t){this.width=t},n.prototype.getHeight=function(){return this.height},n.prototype.setHeight=function(t){this.height=t},t.exports=n},function(t,e,i){"use strict";var n=i(14);function r(){this.map={},this.keys=[]}r.prototype.put=function(t,e){var i=n.createID(t);this.contains(i)||(this.map[i]=e,this.keys.push(t))},r.prototype.contains=function(t){return n.createID(t),null!=this.map[t]},r.prototype.get=function(t){var e=n.createID(t);return this.map[e]},r.prototype.keySet=function(){return this.keys},t.exports=r},function(t,e,i){"use strict";var n=i(14);function r(){this.set={}}r.prototype.add=function(t){var e=n.createID(t);this.contains(e)||(this.set[e]=t)},r.prototype.remove=function(t){delete this.set[n.createID(t)]},r.prototype.clear=function(){this.set={}},r.prototype.contains=function(t){return this.set[n.createID(t)]==t},r.prototype.isEmpty=function(){return 0===this.size()},r.prototype.size=function(){return Object.keys(this.set).length},r.prototype.addAllTo=function(t){for(var e=Object.keys(this.set),i=e.length,n=0;n<i;n++)t.push(this.set[e[n]])},r.prototype.size=function(){return Object.keys(this.set).length},r.prototype.addAll=function(t){for(var e=t.length,i=0;i<e;i++){var n=t[i];this.add(n)}},t.exports=r},function(t,e,i){"use strict";function n(){}n.multMat=function(t,e){for(var i=[],n=0;n<t.length;n++){i[n]=[];for(var r=0;r<e[0].length;r++){i[n][r]=0;for(var o=0;o<t[0].length;o++)i[n][r]+=t[n][o]*e[o][r]}}return i},n.transpose=function(t){for(var e=[],i=0;i<t[0].length;i++){e[i]=[];for(var n=0;n<t.length;n++)e[i][n]=t[n][i]}return e},n.multCons=function(t,e){for(var i=[],n=0;n<t.length;n++)i[n]=t[n]*e;return i},n.minusOp=function(t,e){for(var i=[],n=0;n<t.length;n++)i[n]=t[n]-e[n];return i},n.dotProduct=function(t,e){for(var i=0,n=0;n<t.length;n++)i+=t[n]*e[n];return i},n.mag=function(t){return Math.sqrt(this.dotProduct(t,t))},n.normalize=function(t){for(var e=[],i=this.mag(t),n=0;n<t.length;n++)e[n]=t[n]/i;return e},n.multGamma=function(t){for(var e=[],i=0,n=0;n<t.length;n++)i+=t[n];i*=-1/t.length;for(var r=0;r<t.length;r++)e[r]=i+t[r];return e},n.multL=function(t,e,i){for(var n=[],r=[],o=[],s=0;s<e[0].length;s++){for(var a=0,h=0;h<e.length;h++)a+=-.5*e[h][s]*t[h];r[s]=a}for(var l=0;l<i.length;l++){for(var d=0,c=0;c<i.length;c++)d+=i[l][c]*r[c];o[l]=d}for(var g=0;g<e.length;g++){for(var u=0,f=0;f<e[0].length;f++)u+=e[g][f]*o[f];n[g]=u}return n},t.exports=n},function(t,e,i){"use strict";var n=function(){function t(t,e){for(var i=0;i<e.length;i++){var n=e[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,i,n){return i&&t(e.prototype,i),n&&t(e,n),e}}(),r=i(11),o=function(){function t(e,i){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),null===i&&void 0===i||(this.compareFunction=this._defaultCompareFunction);var n=void 0;n=e instanceof r?e.size():e.length,this._quicksort(e,0,n-1)}return n(t,[{key:"_quicksort",value:function(t,e,i){if(e<i){var n=this._partition(t,e,i);this._quicksort(t,e,n),this._quicksort(t,n+1,i)}}},{key:"_partition",value:function(t,e,i){for(var n=this._get(t,e),r=e,o=i;;){for(;this.compareFunction(n,this._get(t,o));)o--;for(;this.compareFunction(this._get(t,r),n);)r++;if(!(r<o))return o;this._swap(t,r,o),r++,o--}}},{key:"_get",value:function(t,e){return t instanceof r?t.get_object_at(e):t[e]}},{key:"_set",value:function(t,e,i){t instanceof r?t.set_object_at(e,i):t[e]=i}},{key:"_swap",value:function(t,e,i){var n=this._get(t,e);this._set(t,e,this._get(t,i)),this._set(t,i,n)}},{key:"_defaultCompareFunction",value:function(t,e){return e>t}}]),t}();t.exports=o},function(t,e,i){"use strict";function n(){}n.svd=function(t){this.U=null,this.V=null,this.s=null,this.m=0,this.n=0,this.m=t.length,this.n=t[0].length;var e=Math.min(this.m,this.n);this.s=function(t){for(var e=[];t-- >0;)e.push(0);return e}(Math.min(this.m+1,this.n)),this.U=function t(e){if(0==e.length)return 0;for(var i=[],n=0;n<e[0];n++)i.push(t(e.slice(1)));return i}([this.m,e]),this.V=function(t){return function t(e){if(0==e.length)return 0;for(var i=[],n=0;n<e[0];n++)i.push(t(e.slice(1)));return i}(t)}([this.n,this.n]);for(var i=function(t){for(var e=[];t-- >0;)e.push(0);return e}(this.n),r=function(t){for(var e=[];t-- >0;)e.push(0);return e}(this.m),o=Math.min(this.m-1,this.n),s=Math.max(0,Math.min(this.n-2,this.m)),a=0;a<Math.max(o,s);a++){if(a<o){this.s[a]=0;for(var h=a;h<this.m;h++)this.s[a]=n.hypot(this.s[a],t[h][a]);if(0!==this.s[a]){t[a][a]<0&&(this.s[a]=-this.s[a]);for(var l=a;l<this.m;l++)t[l][a]/=this.s[a];t[a][a]+=1}this.s[a]=-this.s[a]}for(var d=a+1;d<this.n;d++){if(function(t,e){return t&&e}(a<o,0!==this.s[a])){for(var c=0,g=a;g<this.m;g++)c+=t[g][a]*t[g][d];c=-c/t[a][a];for(var u=a;u<this.m;u++)t[u][d]+=c*t[u][a]}i[d]=t[a][d]}if(function(t,e){return e}(0,a<o))for(var f=a;f<this.m;f++)this.U[f][a]=t[f][a];if(a<s){i[a]=0;for(var p=a+1;p<this.n;p++)i[a]=n.hypot(i[a],i[p]);if(0!==i[a]){i[a+1]<0&&(i[a]=-i[a]);for(var y=a+1;y<this.n;y++)i[y]/=i[a];i[a+1]+=1}if(i[a]=-i[a],function(t,e){return t&&e}(a+1<this.m,0!==i[a])){for(var v=a+1;v<this.m;v++)r[v]=0;for(var m=a+1;m<this.n;m++)for(var E=a+1;E<this.m;E++)r[E]+=i[m]*t[E][m];for(var N=a+1;N<this.n;N++)for(var T=-i[N]/i[a+1],A=a+1;A<this.m;A++)t[A][N]+=T*r[A]}for(var w=a+1;w<this.n;w++)this.V[w][a]=i[w]}}var L=Math.min(this.n,this.m+1);o<this.n&&(this.s[o]=t[o][o]),this.m<L&&(this.s[L-1]=0),s+1<L&&(i[s]=t[s][L-1]),i[L-1]=0;for(var C=o;C<e;C++){for(var I=0;I<this.m;I++)this.U[I][C]=0;this.U[C][C]=1}for(var _=o-1;_>=0;_--)if(0!==this.s[_]){for(var M=_+1;M<e;M++){for(var x=0,O=_;O<this.m;O++)x+=this.U[O][_]*this.U[O][M];x=-x/this.U[_][_];for(var D=_;D<this.m;D++)this.U[D][M]+=x*this.U[D][_]}for(var R=_;R<this.m;R++)this.U[R][_]=-this.U[R][_];this.U[_][_]=1+this.U[_][_];for(var b=0;b<_-1;b++)this.U[b][_]=0}else{for(var F=0;F<this.m;F++)this.U[F][_]=0;this.U[_][_]=1}for(var G=this.n-1;G>=0;G--){if(function(t,e){return t&&e}(G<s,0!==i[G]))for(var S=G+1;S<e;S++){for(var P=0,U=G+1;U<this.n;U++)P+=this.V[U][G]*this.V[U][S];P=-P/this.V[G+1][G];for(var Y=G+1;Y<this.n;Y++)this.V[Y][S]+=P*this.V[Y][G]}for(var k=0;k<this.n;k++)this.V[k][G]=0;this.V[G][G]=1}for(var H=L-1,X=Math.pow(2,-52),z=Math.pow(2,-966);L>0;){var B=void 0,V=void 0;for(B=L-2;B>=-1&&-1!==B;B--)if(Math.abs(i[B])<=z+X*(Math.abs(this.s[B])+Math.abs(this.s[B+1]))){i[B]=0;break}if(B===L-2)V=4;else{var W=void 0;for(W=L-1;W>=B&&W!==B;W--){var j=(W!==L?Math.abs(i[W]):0)+(W!==B+1?Math.abs(i[W-1]):0);if(Math.abs(this.s[W])<=z+X*j){this.s[W]=0;break}}W===B?V=3:W===L-1?V=1:(V=2,B=W)}switch(B++,V){case 1:var $=i[L-2];i[L-2]=0;for(var q=L-2;q>=B;q--){var K=n.hypot(this.s[q],$),Z=this.s[q]/K,Q=$/K;this.s[q]=K,q!==B&&($=-Q*i[q-1],i[q-1]=Z*i[q-1]);for(var J=0;J<this.n;J++)K=Z*this.V[J][q]+Q*this.V[J][L-1],this.V[J][L-1]=-Q*this.V[J][q]+Z*this.V[J][L-1],this.V[J][q]=K}break;case 2:var tt=i[B-1];i[B-1]=0;for(var et=B;et<L;et++){var it=n.hypot(this.s[et],tt),nt=this.s[et]/it,rt=tt/it;this.s[et]=it,tt=-rt*i[et],i[et]=nt*i[et];for(var ot=0;ot<this.m;ot++)it=nt*this.U[ot][et]+rt*this.U[ot][B-1],this.U[ot][B-1]=-rt*this.U[ot][et]+nt*this.U[ot][B-1],this.U[ot][et]=it}break;case 3:var st=Math.max(Math.max(Math.max(Math.max(Math.abs(this.s[L-1]),Math.abs(this.s[L-2])),Math.abs(i[L-2])),Math.abs(this.s[B])),Math.abs(i[B])),at=this.s[L-1]/st,ht=this.s[L-2]/st,lt=i[L-2]/st,dt=this.s[B]/st,ct=i[B]/st,gt=((ht+at)*(ht-at)+lt*lt)/2,ut=at*lt*(at*lt),ft=0;(function(t,e){return t||e})(0!==gt,0!==ut)&&(ft=Math.sqrt(gt*gt+ut),gt<0&&(ft=-ft),ft=ut/(gt+ft));for(var pt=(dt+at)*(dt-at)+ft,yt=dt*ct,vt=B;vt<L-1;vt++){var mt=n.hypot(pt,yt),Et=pt/mt,Nt=yt/mt;vt!==B&&(i[vt-1]=mt),pt=Et*this.s[vt]+Nt*i[vt],i[vt]=Et*i[vt]-Nt*this.s[vt],yt=Nt*this.s[vt+1],this.s[vt+1]=Et*this.s[vt+1];for(var Tt=0;Tt<this.n;Tt++)mt=Et*this.V[Tt][vt]+Nt*this.V[Tt][vt+1],this.V[Tt][vt+1]=-Nt*this.V[Tt][vt]+Et*this.V[Tt][vt+1],this.V[Tt][vt]=mt;if(Et=pt/(mt=n.hypot(pt,yt)),Nt=yt/mt,this.s[vt]=mt,pt=Et*i[vt]+Nt*this.s[vt+1],this.s[vt+1]=-Nt*i[vt]+Et*this.s[vt+1],yt=Nt*i[vt+1],i[vt+1]=Et*i[vt+1],vt<this.m-1)for(var At=0;At<this.m;At++)mt=Et*this.U[At][vt]+Nt*this.U[At][vt+1],this.U[At][vt+1]=-Nt*this.U[At][vt]+Et*this.U[At][vt+1],this.U[At][vt]=mt}i[L-2]=pt;break;case 4:if(this.s[B]<=0){this.s[B]=this.s[B]<0?-this.s[B]:0;for(var wt=0;wt<=H;wt++)this.V[wt][B]=-this.V[wt][B]}for(;B<H&&!(this.s[B]>=this.s[B+1]);){var Lt=this.s[B];if(this.s[B]=this.s[B+1],this.s[B+1]=Lt,B<this.n-1)for(var Ct=0;Ct<this.n;Ct++)Lt=this.V[Ct][B+1],this.V[Ct][B+1]=this.V[Ct][B],this.V[Ct][B]=Lt;if(B<this.m-1)for(var It=0;It<this.m;It++)Lt=this.U[It][B+1],this.U[It][B+1]=this.U[It][B],this.U[It][B]=Lt;B++}L--}}return{U:this.U,V:this.V,S:this.s}},n.hypot=function(t,e){var i=void 0;return Math.abs(t)>Math.abs(e)?(i=e/t,i=Math.abs(t)*Math.sqrt(1+i*i)):0!=e?(i=t/e,i=Math.abs(e)*Math.sqrt(1+i*i)):i=0,i},t.exports=n},function(t,e,i){"use strict";var n=function(){function t(t,e){for(var i=0;i<e.length;i++){var n=e[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,i,n){return i&&t(e.prototype,i),n&&t(e,n),e}}(),r=function(){function t(e,i){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:-1,o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:-1;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.sequence1=e,this.sequence2=i,this.match_score=n,this.mismatch_penalty=r,this.gap_penalty=o,this.iMax=e.length+1,this.jMax=i.length+1,this.grid=new Array(this.iMax);for(var s=0;s<this.iMax;s++){this.grid[s]=new Array(this.jMax);for(var a=0;a<this.jMax;a++)this.grid[s][a]=0}this.tracebackGrid=new Array(this.iMax);for(var h=0;h<this.iMax;h++){this.tracebackGrid[h]=new Array(this.jMax);for(var l=0;l<this.jMax;l++)this.tracebackGrid[h][l]=[null,null,null]}this.alignments=[],this.score=-1,this.computeGrids()}return n(t,[{key:"getScore",value:function(){return this.score}},{key:"getAlignments",value:function(){return this.alignments}},{key:"computeGrids",value:function(){for(var t=1;t<this.jMax;t++)this.grid[0][t]=this.grid[0][t-1]+this.gap_penalty,this.tracebackGrid[0][t]=[!1,!1,!0];for(var e=1;e<this.iMax;e++)this.grid[e][0]=this.grid[e-1][0]+this.gap_penalty,this.tracebackGrid[e][0]=[!1,!0,!1];for(var i=1;i<this.iMax;i++)for(var n=1;n<this.jMax;n++){var r=[this.sequence1[i-1]===this.sequence2[n-1]?this.grid[i-1][n-1]+this.match_score:this.grid[i-1][n-1]+this.mismatch_penalty,this.grid[i-1][n]+this.gap_penalty,this.grid[i][n-1]+this.gap_penalty],o=this.arrayAllMaxIndexes(r);this.grid[i][n]=r[o[0]],this.tracebackGrid[i][n]=[o.includes(0),o.includes(1),o.includes(2)]}this.score=this.grid[this.iMax-1][this.jMax-1]}},{key:"alignmentTraceback",value:function(){var t=[];for(t.push({pos:[this.sequence1.length,this.sequence2.length],seq1:"",seq2:""});t[0];){var e=t[0],i=this.tracebackGrid[e.pos[0]][e.pos[1]];i[0]&&t.push({pos:[e.pos[0]-1,e.pos[1]-1],seq1:this.sequence1[e.pos[0]-1]+e.seq1,seq2:this.sequence2[e.pos[1]-1]+e.seq2}),i[1]&&t.push({pos:[e.pos[0]-1,e.pos[1]],seq1:this.sequence1[e.pos[0]-1]+e.seq1,seq2:"-"+e.seq2}),i[2]&&t.push({pos:[e.pos[0],e.pos[1]-1],seq1:"-"+e.seq1,seq2:this.sequence2[e.pos[1]-1]+e.seq2}),0===e.pos[0]&&0===e.pos[1]&&this.alignments.push({sequence1:e.seq1,sequence2:e.seq2}),t.shift()}return this.alignments}},{key:"getAllIndexes",value:function(t,e){for(var i=[],n=-1;-1!==(n=t.indexOf(e,n+1));)i.push(n);return i}},{key:"arrayAllMaxIndexes",value:function(t){return this.getAllIndexes(t,Math.max.apply(null,t))}}]),t}();t.exports=r},function(t,e,i){"use strict";var n=function(){};n.FDLayout=i(18),n.FDLayoutConstants=i(4),n.FDLayoutEdge=i(19),n.FDLayoutNode=i(20),n.DimensionD=i(21),n.HashMap=i(22),n.HashSet=i(23),n.IGeometry=i(8),n.IMath=i(9),n.Integer=i(10),n.Point=i(12),n.PointD=i(5),n.RandomSeed=i(16),n.RectangleD=i(13),n.Transform=i(17),n.UniqueIDGeneretor=i(14),n.Quicksort=i(25),n.LinkedList=i(11),n.LGraphObject=i(2),n.LGraph=i(6),n.LEdge=i(1),n.LGraphManager=i(7),n.LNode=i(3),n.Layout=i(15),n.LayoutConstants=i(0),n.NeedlemanWunsch=i(27),n.Matrix=i(24),n.SVD=i(26),t.exports=n},function(t,e,i){"use strict";function n(){this.listeners=[]}var r=n.prototype;r.addListener=function(t,e){this.listeners.push({event:t,callback:e})},r.removeListener=function(t,e){for(var i=this.listeners.length;i>=0;i--){var n=this.listeners[i];n.event===t&&n.callback===e&&this.listeners.splice(i,1)}},r.emit=function(t,e){for(var i=0;i<this.listeners.length;i++){var n=this.listeners[i];t===n.event&&n.callback(e)}},t.exports=n}])},t.exports=e()},8249:(t,e,i)=>{"use strict";i.d(e,{diagram:()=>Z});var n=i(73590),r=i(30092),o=i(25871),s=i(13226),a=i(67633),h=i(40797),l=i(78731),d=i(90165),c=i(26527),g=i(70451),u={L:"left",R:"right",T:"top",B:"bottom"},f={L:(0,h.K2)(t=>`${t},${t/2} 0,${t} 0,0`,"L"),R:(0,h.K2)(t=>`0,${t/2} ${t},0 ${t},${t}`,"R"),T:(0,h.K2)(t=>`0,0 ${t},0 ${t/2},${t}`,"T"),B:(0,h.K2)(t=>`${t/2},0 ${t},${t} 0,${t}`,"B")},p={L:(0,h.K2)((t,e)=>t-e+2,"L"),R:(0,h.K2)((t,e)=>t-2,"R"),T:(0,h.K2)((t,e)=>t-e+2,"T"),B:(0,h.K2)((t,e)=>t-2,"B")},y=(0,h.K2)(function(t){return m(t)?"L"===t?"R":"L":"T"===t?"B":"T"},"getOppositeArchitectureDirection"),v=(0,h.K2)(function(t){return"L"===t||"R"===t||"T"===t||"B"===t},"isArchitectureDirection"),m=(0,h.K2)(function(t){return"L"===t||"R"===t},"isArchitectureDirectionX"),E=(0,h.K2)(function(t){return"T"===t||"B"===t},"isArchitectureDirectionY"),N=(0,h.K2)(function(t,e){const i=m(t)&&E(e),n=E(t)&&m(e);return i||n},"isArchitectureDirectionXY"),T=(0,h.K2)(function(t){const e=t[0],i=t[1],n=m(e)&&E(i),r=E(e)&&m(i);return n||r},"isArchitecturePairXY"),A=(0,h.K2)(function(t){return"LL"!==t&&"RR"!==t&&"TT"!==t&&"BB"!==t},"isValidArchitectureDirectionPair"),w=(0,h.K2)(function(t,e){const i=`${t}${e}`;return A(i)?i:void 0},"getArchitectureDirectionPair"),L=(0,h.K2)(function([t,e],i){const n=i[0],r=i[1];return m(n)?E(r)?[t+("L"===n?-1:1),e+("T"===r?1:-1)]:[t+("L"===n?-1:1),e]:m(r)?[t+("L"===r?1:-1),e+("T"===n?1:-1)]:[t,e+("T"===n?1:-1)]},"shiftPositionByArchitectureDirectionPair"),C=(0,h.K2)(function(t){return"LT"===t||"TL"===t?[1,1]:"BL"===t||"LB"===t?[1,-1]:"BR"===t||"RB"===t?[-1,-1]:[-1,1]},"getArchitectureDirectionXYFactors"),I=(0,h.K2)(function(t,e){return N(t,e)?"bend":m(t)?"horizontal":"vertical"},"getArchitectureDirectionAlignment"),_=(0,h.K2)(function(t){return"service"===t.type},"isArchitectureService"),M=(0,h.K2)(function(t){return"junction"===t.type},"isArchitectureJunction"),x=(0,h.K2)(t=>t.data(),"edgeData"),O=(0,h.K2)(t=>t.data(),"nodeData"),D=a.UI.architecture,R=class{constructor(){this.nodes={},this.groups={},this.edges=[],this.registeredIds={},this.elements={},this.setAccTitle=a.SV,this.getAccTitle=a.iN,this.setDiagramTitle=a.ke,this.getDiagramTitle=a.ab,this.getAccDescription=a.m7,this.setAccDescription=a.EI,this.clear()}static{(0,h.K2)(this,"ArchitectureDB")}clear(){this.nodes={},this.groups={},this.edges=[],this.registeredIds={},this.dataStructures=void 0,this.elements={},(0,a.IU)()}addService({id:t,icon:e,in:i,title:n,iconText:r}){if(void 0!==this.registeredIds[t])throw new Error(`The service id [${t}] is already in use by another ${this.registeredIds[t]}`);if(void 0!==i){if(t===i)throw new Error(`The service [${t}] cannot be placed within itself`);if(void 0===this.registeredIds[i])throw new Error(`The service [${t}]'s parent does not exist. Please make sure the parent is created before this service`);if("node"===this.registeredIds[i])throw new Error(`The service [${t}]'s parent is not a group`)}this.registeredIds[t]="node",this.nodes[t]={id:t,type:"service",icon:e,iconText:r,title:n,edges:[],in:i}}getServices(){return Object.values(this.nodes).filter(_)}addJunction({id:t,in:e}){this.registeredIds[t]="node",this.nodes[t]={id:t,type:"junction",edges:[],in:e}}getJunctions(){return Object.values(this.nodes).filter(M)}getNodes(){return Object.values(this.nodes)}getNode(t){return this.nodes[t]??null}addGroup({id:t,icon:e,in:i,title:n}){if(void 0!==this.registeredIds?.[t])throw new Error(`The group id [${t}] is already in use by another ${this.registeredIds[t]}`);if(void 0!==i){if(t===i)throw new Error(`The group [${t}] cannot be placed within itself`);if(void 0===this.registeredIds?.[i])throw new Error(`The group [${t}]'s parent does not exist. Please make sure the parent is created before this group`);if("node"===this.registeredIds?.[i])throw new Error(`The group [${t}]'s parent is not a group`)}this.registeredIds[t]="group",this.groups[t]={id:t,icon:e,title:n,in:i}}getGroups(){return Object.values(this.groups)}addEdge({lhsId:t,rhsId:e,lhsDir:i,rhsDir:n,lhsInto:r,rhsInto:o,lhsGroup:s,rhsGroup:a,title:h}){if(!v(i))throw new Error(`Invalid direction given for left hand side of edge ${t}--${e}. Expected (L,R,T,B) got ${String(i)}`);if(!v(n))throw new Error(`Invalid direction given for right hand side of edge ${t}--${e}. Expected (L,R,T,B) got ${String(n)}`);if(void 0===this.nodes[t]&&void 0===this.groups[t])throw new Error(`The left-hand id [${t}] does not yet exist. Please create the service/group before declaring an edge to it.`);if(void 0===this.nodes[e]&&void 0===this.groups[e])throw new Error(`The right-hand id [${e}] does not yet exist. Please create the service/group before declaring an edge to it.`);const l=this.nodes[t].in,d=this.nodes[e].in;if(s&&l&&d&&l==d)throw new Error(`The left-hand id [${t}] is modified to traverse the group boundary, but the edge does not pass through two groups.`);if(a&&l&&d&&l==d)throw new Error(`The right-hand id [${e}] is modified to traverse the group boundary, but the edge does not pass through two groups.`);const c={lhsId:t,lhsDir:i,lhsInto:r,lhsGroup:s,rhsId:e,rhsDir:n,rhsInto:o,rhsGroup:a,title:h};this.edges.push(c),this.nodes[t]&&this.nodes[e]&&(this.nodes[t].edges.push(this.edges[this.edges.length-1]),this.nodes[e].edges.push(this.edges[this.edges.length-1]))}getEdges(){return this.edges}getDataStructures(){if(void 0===this.dataStructures){const t={},e=Object.entries(this.nodes).reduce((e,[i,n])=>(e[i]=n.edges.reduce((e,n)=>{const r=this.getNode(n.lhsId)?.in,o=this.getNode(n.rhsId)?.in;if(r&&o&&r!==o){const e=I(n.lhsDir,n.rhsDir);"bend"!==e&&(t[r]??={},t[r][o]=e,t[o]??={},t[o][r]=e)}if(n.lhsId===i){const t=w(n.lhsDir,n.rhsDir);t&&(e[t]=n.rhsId)}else{const t=w(n.rhsDir,n.lhsDir);t&&(e[t]=n.lhsId)}return e},{}),e),{}),i=Object.keys(e)[0],n={[i]:1},r=Object.keys(e).reduce((t,e)=>e===i?t:{...t,[e]:1},{}),o=(0,h.K2)(t=>{const i={[t]:[0,0]},o=[t];for(;o.length>0;){const t=o.shift();if(t){n[t]=1,delete r[t];const s=e[t],[a,h]=i[t];Object.entries(s).forEach(([t,e])=>{n[e]||(i[e]=L([a,h],t),o.push(e))})}}return i},"BFS"),s=[o(i)];for(;Object.keys(r).length>0;)s.push(o(Object.keys(r)[0]));this.dataStructures={adjList:e,spatialMaps:s,groupAlignments:t}}return this.dataStructures}setElementForId(t,e){this.elements[t]=e}getElementById(t){return this.elements[t]}getConfig(){return(0,s.$t)({...D,...(0,a.zj)().architecture})}getConfigField(t){return this.getConfig()[t]}},b=(0,h.K2)((t,e)=>{(0,o.S)(t,e),t.groups.map(t=>e.addGroup(t)),t.services.map(t=>e.addService({...t,type:"service"})),t.junctions.map(t=>e.addJunction({...t,type:"junction"})),t.edges.map(t=>e.addEdge(t))},"populateDb"),F={parser:{yy:void 0},parse:(0,h.K2)(async t=>{const e=await(0,l.qg)("architecture",t);h.Rm.debug(e);const i=F.parser?.yy;if(!(i instanceof R))throw new Error("parser.parser?.yy was not a ArchitectureDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.");b(e,i)},"parse")},G=(0,h.K2)(t=>`\n .edge {\n stroke-width: ${t.archEdgeWidth};\n stroke: ${t.archEdgeColor};\n fill: none;\n }\n\n .arrow {\n fill: ${t.archEdgeArrowColor};\n }\n\n .node-bkg {\n fill: none;\n stroke: ${t.archGroupBorderColor};\n stroke-width: ${t.archGroupBorderWidth};\n stroke-dasharray: 8;\n }\n .node-icon-text {\n display: flex; \n align-items: center;\n }\n \n .node-icon-text > div {\n color: #fff;\n margin: 1px;\n height: fit-content;\n text-align: center;\n overflow: hidden;\n display: -webkit-box;\n -webkit-box-orient: vertical;\n }\n`,"getStyles"),S=(0,h.K2)(t=>`<g><rect width="80" height="80" style="fill: #087ebf; stroke-width: 0px;"/>${t}</g>`,"wrapIcon"),P={prefix:"mermaid-architecture",height:80,width:80,icons:{database:{body:S('<path id="b" data-name="4" d="m20,57.86c0,3.94,8.95,7.14,20,7.14s20-3.2,20-7.14" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><path id="c" data-name="3" d="m20,45.95c0,3.94,8.95,7.14,20,7.14s20-3.2,20-7.14" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><path id="d" data-name="2" d="m20,34.05c0,3.94,8.95,7.14,20,7.14s20-3.2,20-7.14" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><ellipse id="e" data-name="1" cx="40" cy="22.14" rx="20" ry="7.14" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><line x1="20" y1="57.86" x2="20" y2="22.14" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><line x1="60" y1="57.86" x2="60" y2="22.14" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/>')},server:{body:S('<rect x="17.5" y="17.5" width="45" height="45" rx="2" ry="2" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><line x1="17.5" y1="32.5" x2="62.5" y2="32.5" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><line x1="17.5" y1="47.5" x2="62.5" y2="47.5" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><g><path d="m56.25,25c0,.27-.45.5-1,.5h-10.5c-.55,0-1-.23-1-.5s.45-.5,1-.5h10.5c.55,0,1,.23,1,.5Z" style="fill: #fff; stroke-width: 0px;"/><path d="m56.25,25c0,.27-.45.5-1,.5h-10.5c-.55,0-1-.23-1-.5s.45-.5,1-.5h10.5c.55,0,1,.23,1,.5Z" style="fill: none; stroke: #fff; stroke-miterlimit: 10;"/></g><g><path d="m56.25,40c0,.27-.45.5-1,.5h-10.5c-.55,0-1-.23-1-.5s.45-.5,1-.5h10.5c.55,0,1,.23,1,.5Z" style="fill: #fff; stroke-width: 0px;"/><path d="m56.25,40c0,.27-.45.5-1,.5h-10.5c-.55,0-1-.23-1-.5s.45-.5,1-.5h10.5c.55,0,1,.23,1,.5Z" style="fill: none; stroke: #fff; stroke-miterlimit: 10;"/></g><g><path d="m56.25,55c0,.27-.45.5-1,.5h-10.5c-.55,0-1-.23-1-.5s.45-.5,1-.5h10.5c.55,0,1,.23,1,.5Z" style="fill: #fff; stroke-width: 0px;"/><path d="m56.25,55c0,.27-.45.5-1,.5h-10.5c-.55,0-1-.23-1-.5s.45-.5,1-.5h10.5c.55,0,1,.23,1,.5Z" style="fill: none; stroke: #fff; stroke-miterlimit: 10;"/></g><g><circle cx="32.5" cy="25" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/><circle cx="27.5" cy="25" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/><circle cx="22.5" cy="25" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/></g><g><circle cx="32.5" cy="40" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/><circle cx="27.5" cy="40" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/><circle cx="22.5" cy="40" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/></g><g><circle cx="32.5" cy="55" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/><circle cx="27.5" cy="55" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/><circle cx="22.5" cy="55" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/></g>')},disk:{body:S('<rect x="20" y="15" width="40" height="50" rx="1" ry="1" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><ellipse cx="24" cy="19.17" rx=".8" ry=".83" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><ellipse cx="56" cy="19.17" rx=".8" ry=".83" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><ellipse cx="24" cy="60.83" rx=".8" ry=".83" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><ellipse cx="56" cy="60.83" rx=".8" ry=".83" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><ellipse cx="40" cy="33.75" rx="14" ry="14.58" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><ellipse cx="40" cy="33.75" rx="4" ry="4.17" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><path d="m37.51,42.52l-4.83,13.22c-.26.71-1.1,1.02-1.76.64l-4.18-2.42c-.66-.38-.81-1.26-.33-1.84l9.01-10.8c.88-1.05,2.56-.08,2.09,1.2Z" style="fill: #fff; stroke-width: 0px;"/>')},internet:{body:S('<circle cx="40" cy="40" r="22.5" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><line x1="40" y1="17.5" x2="40" y2="62.5" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><line x1="17.5" y1="40" x2="62.5" y2="40" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><path d="m39.99,17.51c-15.28,11.1-15.28,33.88,0,44.98" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><path d="m40.01,17.51c15.28,11.1,15.28,33.88,0,44.98" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><line x1="19.75" y1="30.1" x2="60.25" y2="30.1" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><line x1="19.75" y1="49.9" x2="60.25" y2="49.9" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/>')},cloud:{body:S('<path d="m65,47.5c0,2.76-2.24,5-5,5H20c-2.76,0-5-2.24-5-5,0-1.87,1.03-3.51,2.56-4.36-.04-.21-.06-.42-.06-.64,0-2.6,2.48-4.74,5.65-4.97,1.65-4.51,6.34-7.76,11.85-7.76.86,0,1.69.08,2.5.23,2.09-1.57,4.69-2.5,7.5-2.5,6.1,0,11.19,4.38,12.28,10.17,2.14.56,3.72,2.51,3.72,4.83,0,.03,0,.07-.01.1,2.29.46,4.01,2.48,4.01,4.9Z" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/>')},unknown:r.Gc,blank:{body:S("")}}},U=(0,h.K2)(async function(t,e,i){const n=i.getConfigField("padding"),o=i.getConfigField("iconSize"),h=o/2,l=o/6,d=l/2;await Promise.all(e.edges().map(async e=>{const{source:o,sourceDir:c,sourceArrow:g,sourceGroup:u,target:y,targetDir:v,targetArrow:A,targetGroup:L,label:I}=x(e);let{x:_,y:M}=e[0].sourceEndpoint();const{x:O,y:D}=e[0].midpoint();let{x:R,y:b}=e[0].targetEndpoint();const F=n+4;if(u&&(m(c)?_+="L"===c?-F:F:M+="T"===c?-F:F+18),L&&(m(v)?R+="L"===v?-F:F:b+="T"===v?-F:F+18),u||"junction"!==i.getNode(o)?.type||(m(c)?_+="L"===c?h:-h:M+="T"===c?h:-h),L||"junction"!==i.getNode(y)?.type||(m(v)?R+="L"===v?h:-h:b+="T"===v?h:-h),e[0]._private.rscratch){const e=t.insert("g");if(e.insert("path").attr("d",`M ${_},${M} L ${O},${D} L${R},${b} `).attr("class","edge").attr("id",(0,s.rY)(o,y,{prefix:"L"})),g){const t=m(c)?p[c](_,l):_-d,i=E(c)?p[c](M,l):M-d;e.insert("polygon").attr("points",f[c](l)).attr("transform",`translate(${t},${i})`).attr("class","arrow")}if(A){const t=m(v)?p[v](R,l):R-d,i=E(v)?p[v](b,l):b-d;e.insert("polygon").attr("points",f[v](l)).attr("transform",`translate(${t},${i})`).attr("class","arrow")}if(I){const t=N(c,v)?"XY":m(c)?"X":"Y";let i=0;i="X"===t?Math.abs(_-R):"Y"===t?Math.abs(M-b)/1.5:Math.abs(_-R)/2;const n=e.append("g");if(await(0,r.GZ)(n,I,{useHtmlLabels:!1,width:i,classes:"architecture-service-label"},(0,a.D7)()),n.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle"),"X"===t)n.attr("transform","translate("+O+", "+D+")");else if("Y"===t)n.attr("transform","translate("+O+", "+D+") rotate(-90)");else if("XY"===t){const t=w(c,v);if(t&&T(t)){const e=n.node().getBoundingClientRect(),[i,r]=C(t);n.attr("dominant-baseline","auto").attr("transform",`rotate(${-1*i*r*45})`);const o=n.node().getBoundingClientRect();n.attr("transform",`\n translate(${O}, ${D-e.height/2})\n translate(${i*o.width/2}, ${r*o.height/2})\n rotate(${-1*i*r*45}, 0, ${e.height/2})\n `)}}}}}))},"drawEdges"),Y=(0,h.K2)(async function(t,e,i){const n=.75*i.getConfigField("padding"),o=i.getConfigField("fontSize"),s=i.getConfigField("iconSize")/2;await Promise.all(e.nodes().map(async e=>{const h=O(e);if("group"===h.type){const{h:l,w:d,x1:c,y1:g}=e.boundingBox(),u=t.append("rect");u.attr("id",`group-${h.id}`).attr("x",c+s).attr("y",g+s).attr("width",d).attr("height",l).attr("class","node-bkg");const f=t.append("g");let p=c,y=g;if(h.icon){const t=f.append("g");t.html(`<g>${await(0,r.WY)(h.icon,{height:n,width:n,fallbackPrefix:P.prefix})}</g>`),t.attr("transform","translate("+(p+s+1)+", "+(y+s+1)+")"),p+=n,y+=o/2-1-2}if(h.label){const t=f.append("g");await(0,r.GZ)(t,h.label,{useHtmlLabels:!1,width:d,classes:"architecture-service-label"},(0,a.D7)()),t.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","start").attr("text-anchor","start"),t.attr("transform","translate("+(p+s+4)+", "+(y+s+2)+")")}i.setElementForId(h.id,u)}}))},"drawGroups"),k=(0,h.K2)(async function(t,e,i){const n=(0,a.D7)();for(const o of i){const i=e.append("g"),s=t.getConfigField("iconSize");if(o.title){const t=i.append("g");await(0,r.GZ)(t,o.title,{useHtmlLabels:!1,width:1.5*s,classes:"architecture-service-label"},n),t.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle"),t.attr("transform","translate("+s/2+", "+s+")")}const h=i.append("g");if(o.icon)h.html(`<g>${await(0,r.WY)(o.icon,{height:s,width:s,fallbackPrefix:P.prefix})}</g>`);else if(o.iconText){h.html(`<g>${await(0,r.WY)("blank",{height:s,width:s,fallbackPrefix:P.prefix})}</g>`);const t=h.append("g").append("foreignObject").attr("width",s).attr("height",s).append("div").attr("class","node-icon-text").attr("style",`height: ${s}px;`).append("div").html((0,a.jZ)(o.iconText,n)),e=parseInt(window.getComputedStyle(t.node(),null).getPropertyValue("font-size").replace(/\D/g,""))??16;t.attr("style",`-webkit-line-clamp: ${Math.floor((s-2)/e)};`)}else h.append("path").attr("class","node-bkg").attr("id","node-"+o.id).attr("d",`M0 ${s} v${-s} q0,-5 5,-5 h${s} q5,0 5,5 v${s} H0 Z`);i.attr("id",`service-${o.id}`).attr("class","architecture-service");const{width:l,height:d}=i.node().getBBox();o.width=l,o.height=d,t.setElementForId(o.id,i)}return 0},"drawServices"),H=(0,h.K2)(function(t,e,i){i.forEach(i=>{const n=e.append("g"),r=t.getConfigField("iconSize");n.append("g").append("rect").attr("id","node-"+i.id).attr("fill-opacity","0").attr("width",r).attr("height",r),n.attr("class","architecture-junction");const{width:o,height:s}=n._groups[0][0].getBBox();n.width=o,n.height=s,t.setElementForId(i.id,n)})},"drawJunctions");function X(t,e,i){t.forEach(t=>{e.add({group:"nodes",data:{type:"service",id:t.id,icon:t.icon,label:t.title,parent:t.in,width:i.getConfigField("iconSize"),height:i.getConfigField("iconSize")},classes:"node-service"})})}function z(t,e,i){t.forEach(t=>{e.add({group:"nodes",data:{type:"junction",id:t.id,parent:t.in,width:i.getConfigField("iconSize"),height:i.getConfigField("iconSize")},classes:"node-junction"})})}function B(t,e){e.nodes().map(e=>{const i=O(e);if("group"===i.type)return;i.x=e.position().x,i.y=e.position().y;t.getElementById(i.id).attr("transform","translate("+(i.x||0)+","+(i.y||0)+")")})}function V(t,e){t.forEach(t=>{e.add({group:"nodes",data:{type:"group",id:t.id,icon:t.icon,label:t.title,parent:t.in},classes:"node-group"})})}function W(t,e){t.forEach(t=>{const{lhsId:i,rhsId:n,lhsInto:r,lhsGroup:o,rhsInto:s,lhsDir:a,rhsDir:h,rhsGroup:l,title:d}=t,c=N(t.lhsDir,t.rhsDir)?"segments":"straight",g={id:`${i}-${n}`,label:d,source:i,sourceDir:a,sourceArrow:r,sourceGroup:o,sourceEndpoint:"L"===a?"0 50%":"R"===a?"100% 50%":"T"===a?"50% 0":"50% 100%",target:n,targetDir:h,targetArrow:s,targetGroup:l,targetEndpoint:"L"===h?"0 50%":"R"===h?"100% 50%":"T"===h?"50% 0":"50% 100%"};e.add({group:"edges",data:g,classes:c})})}function j(t,e,i){const n=(0,h.K2)((t,e)=>Object.entries(t).reduce((t,[n,r])=>{let o=0;const s=Object.entries(r);if(1===s.length)return t[n]=s[0][1],t;for(let a=0;a<s.length-1;a++)for(let r=a+1;r<s.length;r++){const[h,l]=s[a],[d,c]=s[r],g=i[h]?.[d];if(g===e)t[n]??=[],t[n]=[...t[n],...l,...c];else if("default"===h||"default"===d)t[n]??=[],t[n]=[...t[n],...l,...c];else{t[`${n}-${o++}`]=l;t[`${n}-${o++}`]=c}}return t},{}),"flattenAlignments"),r=e.map(e=>{const i={},r={};return Object.entries(e).forEach(([e,[n,o]])=>{const s=t.getNode(e)?.in??"default";i[o]??={},i[o][s]??=[],i[o][s].push(e),r[n]??={},r[n][s]??=[],r[n][s].push(e)}),{horiz:Object.values(n(i,"horizontal")).filter(t=>t.length>1),vert:Object.values(n(r,"vertical")).filter(t=>t.length>1)}}),[o,s]=r.reduce(([t,e],{horiz:i,vert:n})=>[[...t,...i],[...e,...n]],[[],[]]);return{horizontal:o,vertical:s}}function $(t,e){const i=[],n=(0,h.K2)(t=>`${t[0]},${t[1]}`,"posToStr"),r=(0,h.K2)(t=>t.split(",").map(t=>parseInt(t)),"strToPos");return t.forEach(t=>{const o=Object.fromEntries(Object.entries(t).map(([t,e])=>[n(e),t])),s=[n([0,0])],a={},h={L:[-1,0],R:[1,0],T:[0,1],B:[0,-1]};for(;s.length>0;){const t=s.shift();if(t){a[t]=1;const l=o[t];if(l){const d=r(t);Object.entries(h).forEach(([t,r])=>{const h=n([d[0]+r[0],d[1]+r[1]]),c=o[h];c&&!a[h]&&(s.push(h),i.push({[u[t]]:c,[u[y(t)]]:l,gap:1.5*e.getConfigField("iconSize")}))})}}}}),i}function q(t,e,i,n,r,{spatialMaps:o,groupAlignments:s}){return new Promise(a=>{const l=(0,g.Ltv)("body").append("div").attr("id","cy").attr("style","display:none"),c=(0,d.A)({container:document.getElementById("cy"),style:[{selector:"edge",style:{"curve-style":"straight",label:"data(label)","source-endpoint":"data(sourceEndpoint)","target-endpoint":"data(targetEndpoint)"}},{selector:"edge.segments",style:{"curve-style":"segments","segment-weights":"0","segment-distances":[.5],"edge-distances":"endpoints","source-endpoint":"data(sourceEndpoint)","target-endpoint":"data(targetEndpoint)"}},{selector:"node",style:{"compound-sizing-wrt-labels":"include"}},{selector:"node[label]",style:{"text-valign":"bottom","text-halign":"center","font-size":`${r.getConfigField("fontSize")}px`}},{selector:".node-service",style:{label:"data(label)",width:"data(width)",height:"data(height)"}},{selector:".node-junction",style:{width:"data(width)",height:"data(height)"}},{selector:".node-group",style:{padding:`${r.getConfigField("padding")}px`}}],layout:{name:"grid",boundingBox:{x1:0,x2:100,y1:0,y2:100}}});l.remove(),V(i,c),X(t,c,r),z(e,c,r),W(n,c);const u=j(r,o,s),f=$(o,r),p=c.layout({name:"fcose",quality:"proof",styleEnabled:!1,animate:!1,nodeDimensionsIncludeLabels:!1,idealEdgeLength(t){const[e,i]=t.connectedNodes(),{parent:n}=O(e),{parent:o}=O(i);return n===o?1.5*r.getConfigField("iconSize"):.5*r.getConfigField("iconSize")},edgeElasticity(t){const[e,i]=t.connectedNodes(),{parent:n}=O(e),{parent:r}=O(i);return n===r?.45:.001},alignmentConstraint:u,relativePlacementConstraint:f});p.one("layoutstop",()=>{function t(t,e,i,n){let r,o;const{x:s,y:a}=t,{x:h,y:l}=e;o=(n-a+(s-i)*(a-l)/(s-h))/Math.sqrt(1+Math.pow((a-l)/(s-h),2)),r=Math.sqrt(Math.pow(n-a,2)+Math.pow(i-s,2)-Math.pow(o,2));r/=Math.sqrt(Math.pow(h-s,2)+Math.pow(l-a,2));let d=(h-s)*(n-a)-(l-a)*(i-s);switch(!0){case d>=0:d=1;break;case d<0:d=-1}let c=(h-s)*(i-s)+(l-a)*(n-a);switch(!0){case c>=0:c=1;break;case c<0:c=-1}return o=Math.abs(o)*d,r*=c,{distances:o,weights:r}}(0,h.K2)(t,"getSegmentWeights"),c.startBatch();for(const e of Object.values(c.edges()))if(e.data?.()){const{x:i,y:n}=e.source().position(),{x:r,y:o}=e.target().position();if(i!==r&&n!==o){const i=e.sourceEndpoint(),n=e.targetEndpoint(),{sourceDir:r}=x(e),[o,s]=E(r)?[i.x,n.y]:[n.x,i.y],{weights:a,distances:h}=t(i,n,o,s);e.style("segment-distances",h),e.style("segment-weights",a)}}c.endBatch(),p.run()}),p.run(),c.ready(t=>{h.Rm.info("Ready",t),a(c)})})}(0,r.pC)([{name:P.prefix,icons:P}]),d.A.use(c),(0,h.K2)(X,"addServices"),(0,h.K2)(z,"addJunctions"),(0,h.K2)(B,"positionNodes"),(0,h.K2)(V,"addGroups"),(0,h.K2)(W,"addEdges"),(0,h.K2)(j,"getAlignments"),(0,h.K2)($,"getRelativeConstraints"),(0,h.K2)(q,"layoutArchitecture");var K={draw:(0,h.K2)(async(t,e,i,r)=>{const o=r.db,s=o.getServices(),h=o.getJunctions(),l=o.getGroups(),d=o.getEdges(),c=o.getDataStructures(),g=(0,n.D)(e),u=g.append("g");u.attr("class","architecture-edges");const f=g.append("g");f.attr("class","architecture-services");const p=g.append("g");p.attr("class","architecture-groups"),await k(o,f,s),H(o,f,h);const y=await q(s,h,l,d,o,c);await U(u,y,o),await Y(p,y,o),B(o,y),(0,a.ot)(void 0,g,o.getConfigField("padding"),o.getConfigField("useMaxWidth"))},"draw")},Z={parser:F,get db(){return new R},renderer:K,styles:G}},25871:(t,e,i)=>{"use strict";function n(t,e){t.accDescr&&e.setAccDescription?.(t.accDescr),t.accTitle&&e.setAccTitle?.(t.accTitle),t.title&&e.setDiagramTitle?.(t.title)}i.d(e,{S:()=>n}),(0,i(40797).K2)(n,"populateCommonDb")},26527:function(t,e,i){var n;n=function(t){return(()=>{"use strict";var e={658:t=>{t.exports=null!=Object.assign?Object.assign.bind(Object):function(t){for(var e=arguments.length,i=Array(e>1?e-1:0),n=1;n<e;n++)i[n-1]=arguments[n];return i.forEach(function(e){Object.keys(e).forEach(function(i){return t[i]=e[i]})}),t}},548:(t,e,i)=>{var n=function(t,e){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t))return function(t,e){var i=[],n=!0,r=!1,o=void 0;try{for(var s,a=t[Symbol.iterator]();!(n=(s=a.next()).done)&&(i.push(s.value),!e||i.length!==e);n=!0);}catch(h){r=!0,o=h}finally{try{!n&&a.return&&a.return()}finally{if(r)throw o}}return i}(t,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")},r=i(140).layoutBase.LinkedList,o={getTopMostNodes:function(t){for(var e={},i=0;i<t.length;i++)e[t[i].id()]=!0;var n=t.filter(function(t,i){"number"==typeof t&&(t=i);for(var n=t.parent()[0];null!=n;){if(e[n.id()])return!1;n=n.parent()[0]}return!0});return n},connectComponents:function(t,e,i,n){var o=new r,s=new Set,a=[],h=void 0,l=void 0,d=void 0,c=!1,g=1,u=[],f=[],p=function(){var n=t.collection();f.push(n);var r=i[0],p=t.collection();p.merge(r).merge(r.descendants().intersection(e)),a.push(r),p.forEach(function(t){o.push(t),s.add(t),n.merge(t)});for(var y=function(){r=o.shift();var l=t.collection();r.neighborhood().nodes().forEach(function(t){e.intersection(r.edgesWith(t)).length>0&&l.merge(t)});for(var d=0;d<l.length;d++){var c=l[d];null==(h=i.intersection(c.union(c.ancestors())))||s.has(h[0])||h.union(h.descendants()).forEach(function(t){o.push(t),s.add(t),n.merge(t),i.has(t)&&a.push(t)})}};0!=o.length;)y();if(n.forEach(function(t){e.intersection(t.connectedEdges()).forEach(function(t){n.has(t.source())&&n.has(t.target())&&n.merge(t)})}),a.length==i.length&&(c=!0),!c||c&&g>1){l=a[0],d=l.connectedEdges().length,a.forEach(function(t){t.connectedEdges().length<d&&(d=t.connectedEdges().length,l=t)}),u.push(l.id());var v=t.collection();v.merge(a[0]),a.forEach(function(t){v.merge(t)}),a=[],i=i.difference(v),g++}};do{p()}while(!c);return n&&u.length>0&&n.set("dummy"+(n.size+1),u),f},relocateComponent:function(t,e,i){if(!i.fixedNodeConstraint){var r=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,s=Number.POSITIVE_INFINITY,a=Number.NEGATIVE_INFINITY;if("draft"==i.quality){var h=!0,l=!1,d=void 0;try{for(var c,g=e.nodeIndexes[Symbol.iterator]();!(h=(c=g.next()).done);h=!0){var u=c.value,f=n(u,2),p=f[0],y=f[1],v=i.cy.getElementById(p);if(v){var m=v.boundingBox(),E=e.xCoords[y]-m.w/2,N=e.xCoords[y]+m.w/2,T=e.yCoords[y]-m.h/2,A=e.yCoords[y]+m.h/2;E<r&&(r=E),N>o&&(o=N),T<s&&(s=T),A>a&&(a=A)}}}catch(_){l=!0,d=_}finally{try{!h&&g.return&&g.return()}finally{if(l)throw d}}var w=t.x-(o+r)/2,L=t.y-(a+s)/2;e.xCoords=e.xCoords.map(function(t){return t+w}),e.yCoords=e.yCoords.map(function(t){return t+L})}else{Object.keys(e).forEach(function(t){var i=e[t],n=i.getRect().x,h=i.getRect().x+i.getRect().width,l=i.getRect().y,d=i.getRect().y+i.getRect().height;n<r&&(r=n),h>o&&(o=h),l<s&&(s=l),d>a&&(a=d)});var C=t.x-(o+r)/2,I=t.y-(a+s)/2;Object.keys(e).forEach(function(t){var i=e[t];i.setCenter(i.getCenterX()+C,i.getCenterY()+I)})}}},calcBoundingBox:function(t,e,i,n){for(var r=Number.MAX_SAFE_INTEGER,o=Number.MIN_SAFE_INTEGER,s=Number.MAX_SAFE_INTEGER,a=Number.MIN_SAFE_INTEGER,h=void 0,l=void 0,d=void 0,c=void 0,g=t.descendants().not(":parent"),u=g.length,f=0;f<u;f++){var p=g[f];r>(h=e[n.get(p.id())]-p.width()/2)&&(r=h),o<(l=e[n.get(p.id())]+p.width()/2)&&(o=l),s>(d=i[n.get(p.id())]-p.height()/2)&&(s=d),a<(c=i[n.get(p.id())]+p.height()/2)&&(a=c)}var y={};return y.topLeftX=r,y.topLeftY=s,y.width=o-r,y.height=a-s,y},calcParentsWithoutChildren:function(t,e){var i=t.collection();return e.nodes(":parent").forEach(function(t){var e=!1;t.children().forEach(function(t){"none"!=t.css("display")&&(e=!0)}),e||i.merge(t)}),i}};t.exports=o},816:(t,e,i)=>{var n=i(548),r=i(140).CoSELayout,o=i(140).CoSENode,s=i(140).layoutBase.PointD,a=i(140).layoutBase.DimensionD,h=i(140).layoutBase.LayoutConstants,l=i(140).layoutBase.FDLayoutConstants,d=i(140).CoSEConstants;t.exports={coseLayout:function(t,e){var i=t.cy,c=t.eles,g=c.nodes(),u=c.edges(),f=void 0,p=void 0,y=void 0,v={};t.randomize&&(f=e.nodeIndexes,p=e.xCoords,y=e.yCoords);var m=function(t){return"function"==typeof t},E=function(t,e){return m(t)?t(e):t},N=n.calcParentsWithoutChildren(i,c);null!=t.nestingFactor&&(d.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=l.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=t.nestingFactor),null!=t.gravity&&(d.DEFAULT_GRAVITY_STRENGTH=l.DEFAULT_GRAVITY_STRENGTH=t.gravity),null!=t.numIter&&(d.MAX_ITERATIONS=l.MAX_ITERATIONS=t.numIter),null!=t.gravityRange&&(d.DEFAULT_GRAVITY_RANGE_FACTOR=l.DEFAULT_GRAVITY_RANGE_FACTOR=t.gravityRange),null!=t.gravityCompound&&(d.DEFAULT_COMPOUND_GRAVITY_STRENGTH=l.DEFAULT_COMPOUND_GRAVITY_STRENGTH=t.gravityCompound),null!=t.gravityRangeCompound&&(d.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=l.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=t.gravityRangeCompound),null!=t.initialEnergyOnIncremental&&(d.DEFAULT_COOLING_FACTOR_INCREMENTAL=l.DEFAULT_COOLING_FACTOR_INCREMENTAL=t.initialEnergyOnIncremental),null!=t.tilingCompareBy&&(d.TILING_COMPARE_BY=t.tilingCompareBy),"proof"==t.quality?h.QUALITY=2:h.QUALITY=0,d.NODE_DIMENSIONS_INCLUDE_LABELS=l.NODE_DIMENSIONS_INCLUDE_LABELS=h.NODE_DIMENSIONS_INCLUDE_LABELS=t.nodeDimensionsIncludeLabels,d.DEFAULT_INCREMENTAL=l.DEFAULT_INCREMENTAL=h.DEFAULT_INCREMENTAL=!t.randomize,d.ANIMATE=l.ANIMATE=h.ANIMATE=t.animate,d.TILE=t.tile,d.TILING_PADDING_VERTICAL="function"==typeof t.tilingPaddingVertical?t.tilingPaddingVertical.call():t.tilingPaddingVertical,d.TILING_PADDING_HORIZONTAL="function"==typeof t.tilingPaddingHorizontal?t.tilingPaddingHorizontal.call():t.tilingPaddingHorizontal,d.DEFAULT_INCREMENTAL=l.DEFAULT_INCREMENTAL=h.DEFAULT_INCREMENTAL=!0,d.PURE_INCREMENTAL=!t.randomize,h.DEFAULT_UNIFORM_LEAF_NODE_SIZES=t.uniformNodeDimensions,"transformed"==t.step&&(d.TRANSFORM_ON_CONSTRAINT_HANDLING=!0,d.ENFORCE_CONSTRAINTS=!1,d.APPLY_LAYOUT=!1),"enforced"==t.step&&(d.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,d.ENFORCE_CONSTRAINTS=!0,d.APPLY_LAYOUT=!1),"cose"==t.step&&(d.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,d.ENFORCE_CONSTRAINTS=!1,d.APPLY_LAYOUT=!0),"all"==t.step&&(t.randomize?d.TRANSFORM_ON_CONSTRAINT_HANDLING=!0:d.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,d.ENFORCE_CONSTRAINTS=!0,d.APPLY_LAYOUT=!0),t.fixedNodeConstraint||t.alignmentConstraint||t.relativePlacementConstraint?d.TREE_REDUCTION_ON_INCREMENTAL=!1:d.TREE_REDUCTION_ON_INCREMENTAL=!0;var T=new r,A=T.newGraphManager();return function t(e,i,r,h){for(var l=i.length,d=0;d<l;d++){var c=i[d],g=null;0==c.intersection(N).length&&(g=c.children());var u=void 0,m=c.layoutDimensions({nodeDimensionsIncludeLabels:h.nodeDimensionsIncludeLabels});if(null!=c.outerWidth()&&null!=c.outerHeight())if(h.randomize)if(c.isParent()){var T=n.calcBoundingBox(c,p,y,f);u=0==c.intersection(N).length?e.add(new o(r.graphManager,new s(T.topLeftX,T.topLeftY),new a(T.width,T.height))):e.add(new o(r.graphManager,new s(T.topLeftX,T.topLeftY),new a(parseFloat(m.w),parseFloat(m.h))))}else u=e.add(new o(r.graphManager,new s(p[f.get(c.id())]-m.w/2,y[f.get(c.id())]-m.h/2),new a(parseFloat(m.w),parseFloat(m.h))));else u=e.add(new o(r.graphManager,new s(c.position("x")-m.w/2,c.position("y")-m.h/2),new a(parseFloat(m.w),parseFloat(m.h))));else u=e.add(new o(this.graphManager));u.id=c.data("id"),u.nodeRepulsion=E(h.nodeRepulsion,c),u.paddingLeft=parseInt(c.css("padding")),u.paddingTop=parseInt(c.css("padding")),u.paddingRight=parseInt(c.css("padding")),u.paddingBottom=parseInt(c.css("padding")),h.nodeDimensionsIncludeLabels&&(u.labelWidth=c.boundingBox({includeLabels:!0,includeNodes:!1,includeOverlays:!1}).w,u.labelHeight=c.boundingBox({includeLabels:!0,includeNodes:!1,includeOverlays:!1}).h,u.labelPosVertical=c.css("text-valign"),u.labelPosHorizontal=c.css("text-halign")),v[c.data("id")]=u,isNaN(u.rect.x)&&(u.rect.x=0),isNaN(u.rect.y)&&(u.rect.y=0),null!=g&&g.length>0&&t(r.getGraphManager().add(r.newGraph(),u),g,r,h)}}(A.addRoot(),n.getTopMostNodes(g),T,t),function(e,i,n){for(var r=0,o=0,s=0;s<n.length;s++){var a=n[s],h=v[a.data("source")],c=v[a.data("target")];if(h&&c&&h!==c&&0==h.getEdgesBetween(c).length){var g=i.add(e.newEdge(),h,c);g.id=a.id(),g.idealLength=E(t.idealEdgeLength,a),g.edgeElasticity=E(t.edgeElasticity,a),r+=g.idealLength,o++}}null!=t.idealEdgeLength&&(o>0?d.DEFAULT_EDGE_LENGTH=l.DEFAULT_EDGE_LENGTH=r/o:m(t.idealEdgeLength)?d.DEFAULT_EDGE_LENGTH=l.DEFAULT_EDGE_LENGTH=50:d.DEFAULT_EDGE_LENGTH=l.DEFAULT_EDGE_LENGTH=t.idealEdgeLength,d.MIN_REPULSION_DIST=l.MIN_REPULSION_DIST=l.DEFAULT_EDGE_LENGTH/10,d.DEFAULT_RADIAL_SEPARATION=l.DEFAULT_EDGE_LENGTH)}(T,A,u),function(t,e){e.fixedNodeConstraint&&(t.constraints.fixedNodeConstraint=e.fixedNodeConstraint),e.alignmentConstraint&&(t.constraints.alignmentConstraint=e.alignmentConstraint),e.relativePlacementConstraint&&(t.constraints.relativePlacementConstraint=e.relativePlacementConstraint)}(T,t),T.runLayout(),v}}},212:(t,e,i)=>{var n=function(){function t(t,e){for(var i=0;i<e.length;i++){var n=e[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,i,n){return i&&t(e.prototype,i),n&&t(e,n),e}}(),r=i(658),o=i(548),s=i(657).spectralLayout,a=i(816).coseLayout,h=Object.freeze({quality:"default",randomize:!0,animate:!0,animationDuration:1e3,animationEasing:void 0,fit:!0,padding:30,nodeDimensionsIncludeLabels:!1,uniformNodeDimensions:!1,packComponents:!0,step:"all",samplingType:!0,sampleSize:25,nodeSeparation:75,piTol:1e-7,nodeRepulsion:function(t){return 4500},idealEdgeLength:function(t){return 50},edgeElasticity:function(t){return.45},nestingFactor:.1,gravity:.25,numIter:2500,tile:!0,tilingCompareBy:void 0,tilingPaddingVertical:10,tilingPaddingHorizontal:10,gravityRangeCompound:1.5,gravityCompound:1,gravityRange:3.8,initialEnergyOnIncremental:.3,fixedNodeConstraint:void 0,alignmentConstraint:void 0,relativePlacementConstraint:void 0,ready:function(){},stop:function(){}}),l=function(){function t(e){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.options=r({},h,e)}return n(t,[{key:"run",value:function(){var t=this.options,e=t.cy,i=t.eles,n=[],r=[],h=void 0,l=[];!t.fixedNodeConstraint||Array.isArray(t.fixedNodeConstraint)&&0!=t.fixedNodeConstraint.length||(t.fixedNodeConstraint=void 0),t.alignmentConstraint&&(!t.alignmentConstraint.vertical||Array.isArray(t.alignmentConstraint.vertical)&&0!=t.alignmentConstraint.vertical.length||(t.alignmentConstraint.vertical=void 0),!t.alignmentConstraint.horizontal||Array.isArray(t.alignmentConstraint.horizontal)&&0!=t.alignmentConstraint.horizontal.length||(t.alignmentConstraint.horizontal=void 0)),!t.relativePlacementConstraint||Array.isArray(t.relativePlacementConstraint)&&0!=t.relativePlacementConstraint.length||(t.relativePlacementConstraint=void 0),(t.fixedNodeConstraint||t.alignmentConstraint||t.relativePlacementConstraint)&&(t.tile=!1,t.packComponents=!1);var d=void 0,c=!1;if(e.layoutUtilities&&t.packComponents&&((d=e.layoutUtilities("get"))||(d=e.layoutUtilities()),c=!0),i.nodes().length>0)if(c){var g=o.getTopMostNodes(t.eles.nodes());if((h=o.connectComponents(e,t.eles,g)).forEach(function(t){var e=t.boundingBox();l.push({x:e.x1+e.w/2,y:e.y1+e.h/2})}),t.randomize&&h.forEach(function(e){t.eles=e,n.push(s(t))}),"default"==t.quality||"proof"==t.quality){var u=e.collection();if(t.tile){var f=new Map,p=0,y={nodeIndexes:f,xCoords:[],yCoords:[]},v=[];if(h.forEach(function(t,e){0==t.edges().length&&(t.nodes().forEach(function(e,i){u.merge(t.nodes()[i]),e.isParent()||(y.nodeIndexes.set(t.nodes()[i].id(),p++),y.xCoords.push(t.nodes()[0].position().x),y.yCoords.push(t.nodes()[0].position().y))}),v.push(e))}),u.length>1){var m=u.boundingBox();l.push({x:m.x1+m.w/2,y:m.y1+m.h/2}),h.push(u),n.push(y);for(var E=v.length-1;E>=0;E--)h.splice(v[E],1),n.splice(v[E],1),l.splice(v[E],1)}}h.forEach(function(e,i){t.eles=e,r.push(a(t,n[i])),o.relocateComponent(l[i],r[i],t)})}else h.forEach(function(e,i){o.relocateComponent(l[i],n[i],t)});var N=new Set;if(h.length>1){var T=[],A=i.filter(function(t){return"none"==t.css("display")});h.forEach(function(e,i){var s=void 0;if("draft"==t.quality&&(s=n[i].nodeIndexes),e.nodes().not(A).length>0){var a={edges:[],nodes:[]},h=void 0;e.nodes().not(A).forEach(function(e){if("draft"==t.quality)if(e.isParent()){var l=o.calcBoundingBox(e,n[i].xCoords,n[i].yCoords,s);a.nodes.push({x:l.topLeftX,y:l.topLeftY,width:l.width,height:l.height})}else h=s.get(e.id()),a.nodes.push({x:n[i].xCoords[h]-e.boundingbox().w/2,y:n[i].yCoords[h]-e.boundingbox().h/2,width:e.boundingbox().w,height:e.boundingbox().h});else r[i][e.id()]&&a.nodes.push({x:r[i][e.id()].getLeft(),y:r[i][e.id()].getTop(),width:r[i][e.id()].getWidth(),height:r[i][e.id()].getHeight()})}),e.edges().forEach(function(e){var h=e.source(),l=e.target();if("none"!=h.css("display")&&"none"!=l.css("display"))if("draft"==t.quality){var d=s.get(h.id()),c=s.get(l.id()),g=[],u=[];if(h.isParent()){var f=o.calcBoundingBox(h,n[i].xCoords,n[i].yCoords,s);g.push(f.topLeftX+f.width/2),g.push(f.topLeftY+f.height/2)}else g.push(n[i].xCoords[d]),g.push(n[i].yCoords[d]);if(l.isParent()){var p=o.calcBoundingBox(l,n[i].xCoords,n[i].yCoords,s);u.push(p.topLeftX+p.width/2),u.push(p.topLeftY+p.height/2)}else u.push(n[i].xCoords[c]),u.push(n[i].yCoords[c]);a.edges.push({startX:g[0],startY:g[1],endX:u[0],endY:u[1]})}else r[i][h.id()]&&r[i][l.id()]&&a.edges.push({startX:r[i][h.id()].getCenterX(),startY:r[i][h.id()].getCenterY(),endX:r[i][l.id()].getCenterX(),endY:r[i][l.id()].getCenterY()})}),a.nodes.length>0&&(T.push(a),N.add(i))}});var w=d.packComponents(T,t.randomize).shifts;if("draft"==t.quality)n.forEach(function(t,e){var i=t.xCoords.map(function(t){return t+w[e].dx}),n=t.yCoords.map(function(t){return t+w[e].dy});t.xCoords=i,t.yCoords=n});else{var L=0;N.forEach(function(t){Object.keys(r[t]).forEach(function(e){var i=r[t][e];i.setCenter(i.getCenterX()+w[L].dx,i.getCenterY()+w[L].dy)}),L++})}}}else{var C=t.eles.boundingBox();if(l.push({x:C.x1+C.w/2,y:C.y1+C.h/2}),t.randomize){var I=s(t);n.push(I)}"default"==t.quality||"proof"==t.quality?(r.push(a(t,n[0])),o.relocateComponent(l[0],r[0],t)):o.relocateComponent(l[0],n[0],t)}var _=function(e,i){if("default"==t.quality||"proof"==t.quality){"number"==typeof e&&(e=i);var o=void 0,s=void 0,a=e.data("id");return r.forEach(function(t){a in t&&(o={x:t[a].getRect().getCenterX(),y:t[a].getRect().getCenterY()},s=t[a])}),t.nodeDimensionsIncludeLabels&&(s.labelWidth&&("left"==s.labelPosHorizontal?o.x+=s.labelWidth/2:"right"==s.labelPosHorizontal&&(o.x-=s.labelWidth/2)),s.labelHeight&&("top"==s.labelPosVertical?o.y+=s.labelHeight/2:"bottom"==s.labelPosVertical&&(o.y-=s.labelHeight/2))),null==o&&(o={x:e.position("x"),y:e.position("y")}),{x:o.x,y:o.y}}var h=void 0;return n.forEach(function(t){var i=t.nodeIndexes.get(e.id());null!=i&&(h={x:t.xCoords[i],y:t.yCoords[i]})}),null==h&&(h={x:e.position("x"),y:e.position("y")}),{x:h.x,y:h.y}};if("default"==t.quality||"proof"==t.quality||t.randomize){var M=o.calcParentsWithoutChildren(e,i),x=i.filter(function(t){return"none"==t.css("display")});t.eles=i.not(x),i.nodes().not(":parent").not(x).layoutPositions(this,t,_),M.length>0&&M.forEach(function(t){t.position(_(t))})}else console.log("If randomize option is set to false, then quality option must be 'default' or 'proof'.")}}]),t}();t.exports=l},657:(t,e,i)=>{var n=i(548),r=i(140).layoutBase.Matrix,o=i(140).layoutBase.SVD;t.exports={spectralLayout:function(t){var e=t.cy,i=t.eles,s=i.nodes(),a=i.nodes(":parent"),h=new Map,l=new Map,d=new Map,c=[],g=[],u=[],f=[],p=[],y=[],v=[],m=[],E=void 0,N=1e8,T=1e-9,A=t.piTol,w=t.samplingType,L=t.nodeSeparation,C=void 0,I=function(t,e,i){for(var n=[],r=0,o=0,s=0,a=void 0,h=[],d=0,g=1,u=0;u<E;u++)h[u]=N;for(n[o]=t,h[t]=0;o>=r;){s=n[r++];for(var f=c[s],v=0;v<f.length;v++)h[a=l.get(f[v])]==N&&(h[a]=h[s]+1,n[++o]=a);y[s][e]=h[s]*L}if(i){for(var m=0;m<E;m++)y[m][e]<p[m]&&(p[m]=y[m][e]);for(var T=0;T<E;T++)p[T]>d&&(d=p[T],g=T)}return g};n.connectComponents(e,i,n.getTopMostNodes(s),h),a.forEach(function(t){n.connectComponents(e,i,n.getTopMostNodes(t.descendants().intersection(i)),h)});for(var _=0,M=0;M<s.length;M++)s[M].isParent()||l.set(s[M].id(),_++);var x=!0,O=!1,D=void 0;try{for(var R,b=h.keys()[Symbol.iterator]();!(x=(R=b.next()).done);x=!0){var F=R.value;l.set(F,_++)}}catch(K){O=!0,D=K}finally{try{!x&&b.return&&b.return()}finally{if(O)throw D}}for(var G=0;G<l.size;G++)c[G]=[];a.forEach(function(t){for(var e=t.children().intersection(i);0==e.nodes(":childless").length;)e=e.nodes()[0].children().intersection(i);var n=0,r=e.nodes(":childless")[0].connectedEdges().length;e.nodes(":childless").forEach(function(t,e){t.connectedEdges().length<r&&(r=t.connectedEdges().length,n=e)}),d.set(t.id(),e.nodes(":childless")[n].id())}),s.forEach(function(t){var e=void 0;e=t.isParent()?l.get(d.get(t.id())):l.get(t.id()),t.neighborhood().nodes().forEach(function(n){i.intersection(t.edgesWith(n)).length>0&&(n.isParent()?c[e].push(d.get(n.id())):c[e].push(n.id()))})});var S=function(t){var i=l.get(t),n=void 0;h.get(t).forEach(function(r){n=e.getElementById(r).isParent()?d.get(r):r,c[i].push(n),c[l.get(n)].push(t)})},P=!0,U=!1,Y=void 0;try{for(var k,H=h.keys()[Symbol.iterator]();!(P=(k=H.next()).done);P=!0)S(k.value)}catch(K){U=!0,Y=K}finally{try{!P&&H.return&&H.return()}finally{if(U)throw Y}}var X=void 0;if((E=l.size)>2){C=E<t.sampleSize?E:t.sampleSize;for(var z=0;z<E;z++)y[z]=[];for(var B=0;B<C;B++)m[B]=[];return"draft"==t.quality||"all"==t.step?(function(t){var e=void 0;if(t){e=Math.floor(Math.random()*E);for(var i=0;i<E;i++)p[i]=N;for(var n=0;n<C;n++)f[n]=e,e=I(e,n,t)}else{!function(){for(var t=0,e=0,i=!1;e<C;){t=Math.floor(Math.random()*E),i=!1;for(var n=0;n<e;n++)if(f[n]==t){i=!0;break}i||(f[e]=t,e++)}}();for(var r=0;r<C;r++)I(f[r],r,t)}for(var o=0;o<E;o++)for(var s=0;s<C;s++)y[o][s]*=y[o][s];for(var a=0;a<C;a++)v[a]=[];for(var h=0;h<C;h++)for(var l=0;l<C;l++)v[h][l]=y[f[l]][h]}(w),function(){for(var t=o.svd(v),e=t.S,i=t.U,n=t.V,s=e[0]*e[0]*e[0],a=[],h=0;h<C;h++){a[h]=[];for(var l=0;l<C;l++)a[h][l]=0,h==l&&(a[h][l]=e[h]/(e[h]*e[h]+s/(e[h]*e[h])))}m=r.multMat(r.multMat(n,a),r.transpose(i))}(),function(){for(var t=void 0,e=void 0,i=[],n=[],o=[],s=[],a=0;a<E;a++)i[a]=Math.random(),n[a]=Math.random();i=r.normalize(i),n=r.normalize(n);for(var h=T,l=T,d=void 0;;){for(var c=0;c<E;c++)o[c]=i[c];if(i=r.multGamma(r.multL(r.multGamma(o),y,m)),t=r.dotProduct(o,i),i=r.normalize(i),h=r.dotProduct(o,i),(d=Math.abs(h/l))<=1+A&&d>=1)break;l=h}for(var f=0;f<E;f++)o[f]=i[f];for(l=T;;){for(var p=0;p<E;p++)s[p]=n[p];if(s=r.minusOp(s,r.multCons(o,r.dotProduct(o,s))),n=r.multGamma(r.multL(r.multGamma(s),y,m)),e=r.dotProduct(s,n),n=r.normalize(n),h=r.dotProduct(s,n),(d=Math.abs(h/l))<=1+A&&d>=1)break;l=h}for(var v=0;v<E;v++)s[v]=n[v];g=r.multCons(o,Math.sqrt(Math.abs(t))),u=r.multCons(s,Math.sqrt(Math.abs(e)))}(),X={nodeIndexes:l,xCoords:g,yCoords:u}):(l.forEach(function(t,i){g.push(e.getElementById(i).position("x")),u.push(e.getElementById(i).position("y"))}),X={nodeIndexes:l,xCoords:g,yCoords:u}),X}var V=l.keys(),W=e.getElementById(V.next().value),j=W.position(),$=W.outerWidth();if(g.push(j.x),u.push(j.y),2==E){var q=e.getElementById(V.next().value).outerWidth();g.push(j.x+$/2+q/2+t.idealEdgeLength),u.push(j.y)}return X={nodeIndexes:l,xCoords:g,yCoords:u}}}},579:(t,e,i)=>{var n=i(212),r=function(t){t&&t("layout","fcose",n)};"undefined"!=typeof cytoscape&&r(cytoscape),t.exports=r},140:e=>{e.exports=t}},i={},n=function t(n){var r=i[n];if(void 0!==r)return r.exports;var o=i[n]={exports:{}};return e[n](o,o.exports,t),o.exports}(579);return n})()},t.exports=n(i(41709))},41709:function(t,e,i){var n;n=function(t){return(()=>{"use strict";var e={45:(t,e,i)=>{var n={};n.layoutBase=i(551),n.CoSEConstants=i(806),n.CoSEEdge=i(767),n.CoSEGraph=i(880),n.CoSEGraphManager=i(578),n.CoSELayout=i(765),n.CoSENode=i(991),n.ConstraintHandler=i(902),t.exports=n},806:(t,e,i)=>{var n=i(551).FDLayoutConstants;function r(){}for(var o in n)r[o]=n[o];r.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,r.DEFAULT_RADIAL_SEPARATION=n.DEFAULT_EDGE_LENGTH,r.DEFAULT_COMPONENT_SEPERATION=60,r.TILE=!0,r.TILING_PADDING_VERTICAL=10,r.TILING_PADDING_HORIZONTAL=10,r.TRANSFORM_ON_CONSTRAINT_HANDLING=!0,r.ENFORCE_CONSTRAINTS=!0,r.APPLY_LAYOUT=!0,r.RELAX_MOVEMENT_ON_CONSTRAINTS=!0,r.TREE_REDUCTION_ON_INCREMENTAL=!0,r.PURE_INCREMENTAL=r.DEFAULT_INCREMENTAL,t.exports=r},767:(t,e,i)=>{var n=i(551).FDLayoutEdge;function r(t,e,i){n.call(this,t,e,i)}for(var o in r.prototype=Object.create(n.prototype),n)r[o]=n[o];t.exports=r},880:(t,e,i)=>{var n=i(551).LGraph;function r(t,e,i){n.call(this,t,e,i)}for(var o in r.prototype=Object.create(n.prototype),n)r[o]=n[o];t.exports=r},578:(t,e,i)=>{var n=i(551).LGraphManager;function r(t){n.call(this,t)}for(var o in r.prototype=Object.create(n.prototype),n)r[o]=n[o];t.exports=r},765:(t,e,i)=>{var n=i(551).FDLayout,r=i(578),o=i(880),s=i(991),a=i(767),h=i(806),l=i(902),d=i(551).FDLayoutConstants,c=i(551).LayoutConstants,g=i(551).Point,u=i(551).PointD,f=i(551).DimensionD,p=i(551).Layout,y=i(551).Integer,v=i(551).IGeometry,m=i(551).LGraph,E=i(551).Transform,N=i(551).LinkedList;function T(){n.call(this),this.toBeTiled={},this.constraints={}}for(var A in T.prototype=Object.create(n.prototype),n)T[A]=n[A];T.prototype.newGraphManager=function(){var t=new r(this);return this.graphManager=t,t},T.prototype.newGraph=function(t){return new o(null,this.graphManager,t)},T.prototype.newNode=function(t){return new s(this.graphManager,t)},T.prototype.newEdge=function(t){return new a(null,null,t)},T.prototype.initParameters=function(){n.prototype.initParameters.call(this,arguments),this.isSubLayout||(h.DEFAULT_EDGE_LENGTH<10?this.idealEdgeLength=10:this.idealEdgeLength=h.DEFAULT_EDGE_LENGTH,this.useSmartIdealEdgeLengthCalculation=h.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.gravityConstant=d.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=d.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=d.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=d.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.prunedNodesAll=[],this.growTreeIterations=0,this.afterGrowthIterations=0,this.isTreeGrowing=!1,this.isGrowthFinished=!1)},T.prototype.initSpringEmbedder=function(){n.prototype.initSpringEmbedder.call(this),this.coolingCycle=0,this.maxCoolingCycle=this.maxIterations/d.CONVERGENCE_CHECK_PERIOD,this.finalTemperature=.04,this.coolingAdjuster=1},T.prototype.layout=function(){return c.DEFAULT_CREATE_BENDS_AS_NEEDED&&(this.createBendpoints(),this.graphManager.resetAllEdges()),this.level=0,this.classicLayout()},T.prototype.classicLayout=function(){if(this.nodesWithGravity=this.calculateNodesToApplyGravitationTo(),this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity),this.calcNoOfChildrenForAllNodes(),this.graphManager.calcLowestCommonAncestors(),this.graphManager.calcInclusionTreeDepths(),this.graphManager.getRoot().calcEstimatedSize(),this.calcIdealEdgeLengths(),this.incremental)h.TREE_REDUCTION_ON_INCREMENTAL&&(this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation(),e=new Set(this.getAllNodes()),i=this.nodesWithGravity.filter(function(t){return e.has(t)}),this.graphManager.setAllNodesToApplyGravitation(i));else{var t=this.getFlatForest();if(t.length>0)this.positionNodesRadially(t);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var e=new Set(this.getAllNodes()),i=this.nodesWithGravity.filter(function(t){return e.has(t)});this.graphManager.setAllNodesToApplyGravitation(i),this.positionNodesRandomly()}}return Object.keys(this.constraints).length>0&&(l.handleConstraints(this),this.initConstraintVariables()),this.initSpringEmbedder(),h.APPLY_LAYOUT&&this.runSpringEmbedder(),!0},T.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished){if(!(this.prunedNodesAll.length>0))return!0;this.isTreeGrowing=!0}if(this.totalIterations%d.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged()){if(!(this.prunedNodesAll.length>0))return!0;this.isTreeGrowing=!0}this.coolingCycle++,0==this.layoutQuality?this.coolingAdjuster=this.coolingCycle:1==this.layoutQuality&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var t=new Set(this.getAllNodes()),e=this.nodesWithGravity.filter(function(e){return t.has(e)});this.graphManager.setAllNodesToApplyGravitation(e),this.graphManager.updateBounds(),this.updateGrid(),h.PURE_INCREMENTAL?this.coolingFactor=d.DEFAULT_COOLING_FACTOR_INCREMENTAL/2:this.coolingFactor=d.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),h.PURE_INCREMENTAL?this.coolingFactor=d.DEFAULT_COOLING_FACTOR_INCREMENTAL/2*((100-this.afterGrowthIterations)/100):this.coolingFactor=d.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var i=!this.isTreeGrowing&&!this.isGrowthFinished,n=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(i,n),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},T.prototype.getPositionsData=function(){for(var t=this.graphManager.getAllNodes(),e={},i=0;i<t.length;i++){var n=t[i].rect,r=t[i].id;e[r]={id:r,x:n.getCenterX(),y:n.getCenterY(),w:n.width,h:n.height}}return e},T.prototype.runSpringEmbedder=function(){this.initialAnimationPeriod=25,this.animationPeriod=this.initialAnimationPeriod;var t=!1;if("during"===d.ANIMATE)this.emit("layoutstarted");else{for(;!t;)t=this.tick();this.graphManager.updateBounds()}},T.prototype.moveNodes=function(){for(var t=this.getAllNodes(),e=0;e<t.length;e++)t[e].calculateDisplacement();for(Object.keys(this.constraints).length>0&&this.updateDisplacements(),e=0;e<t.length;e++)t[e].move()},T.prototype.initConstraintVariables=function(){var t=this;this.idToNodeMap=new Map,this.fixedNodeSet=new Set;for(var e=this.graphManager.getAllNodes(),i=0;i<e.length;i++){var n=e[i];this.idToNodeMap.set(n.id,n)}var r=function e(i){for(var n,r=i.getChild().getNodes(),o=0,s=0;s<r.length;s++)null==(n=r[s]).getChild()?t.fixedNodeSet.has(n.id)&&(o+=100):o+=e(n);return o};if(this.constraints.fixedNodeConstraint)for(this.constraints.fixedNodeConstraint.forEach(function(e){t.fixedNodeSet.add(e.nodeId)}),e=this.graphManager.getAllNodes(),i=0;i<e.length;i++)if(null!=(n=e[i]).getChild()){var o=r(n);o>0&&(n.fixedNodeWeight=o)}if(this.constraints.relativePlacementConstraint){var s=new Map,a=new Map;if(this.dummyToNodeForVerticalAlignment=new Map,this.dummyToNodeForHorizontalAlignment=new Map,this.fixedNodesOnHorizontal=new Set,this.fixedNodesOnVertical=new Set,this.fixedNodeSet.forEach(function(e){t.fixedNodesOnHorizontal.add(e),t.fixedNodesOnVertical.add(e)}),this.constraints.alignmentConstraint){if(this.constraints.alignmentConstraint.vertical){var l=this.constraints.alignmentConstraint.vertical;for(i=0;i<l.length;i++)this.dummyToNodeForVerticalAlignment.set("dummy"+i,[]),l[i].forEach(function(e){s.set(e,"dummy"+i),t.dummyToNodeForVerticalAlignment.get("dummy"+i).push(e),t.fixedNodeSet.has(e)&&t.fixedNodesOnHorizontal.add("dummy"+i)})}if(this.constraints.alignmentConstraint.horizontal){var d=this.constraints.alignmentConstraint.horizontal;for(i=0;i<d.length;i++)this.dummyToNodeForHorizontalAlignment.set("dummy"+i,[]),d[i].forEach(function(e){a.set(e,"dummy"+i),t.dummyToNodeForHorizontalAlignment.get("dummy"+i).push(e),t.fixedNodeSet.has(e)&&t.fixedNodesOnVertical.add("dummy"+i)})}}if(h.RELAX_MOVEMENT_ON_CONSTRAINTS)this.shuffle=function(t){var e,i,n;for(n=t.length-1;n>=2*t.length/3;n--)e=Math.floor(Math.random()*(n+1)),i=t[n],t[n]=t[e],t[e]=i;return t},this.nodesInRelativeHorizontal=[],this.nodesInRelativeVertical=[],this.nodeToRelativeConstraintMapHorizontal=new Map,this.nodeToRelativeConstraintMapVertical=new Map,this.nodeToTempPositionMapHorizontal=new Map,this.nodeToTempPositionMapVertical=new Map,this.constraints.relativePlacementConstraint.forEach(function(e){if(e.left){var i=s.has(e.left)?s.get(e.left):e.left,n=s.has(e.right)?s.get(e.right):e.right;t.nodesInRelativeHorizontal.includes(i)||(t.nodesInRelativeHorizontal.push(i),t.nodeToRelativeConstraintMapHorizontal.set(i,[]),t.dummyToNodeForVerticalAlignment.has(i)?t.nodeToTempPositionMapHorizontal.set(i,t.idToNodeMap.get(t.dummyToNodeForVerticalAlignment.get(i)[0]).getCenterX()):t.nodeToTempPositionMapHorizontal.set(i,t.idToNodeMap.get(i).getCenterX())),t.nodesInRelativeHorizontal.includes(n)||(t.nodesInRelativeHorizontal.push(n),t.nodeToRelativeConstraintMapHorizontal.set(n,[]),t.dummyToNodeForVerticalAlignment.has(n)?t.nodeToTempPositionMapHorizontal.set(n,t.idToNodeMap.get(t.dummyToNodeForVerticalAlignment.get(n)[0]).getCenterX()):t.nodeToTempPositionMapHorizontal.set(n,t.idToNodeMap.get(n).getCenterX())),t.nodeToRelativeConstraintMapHorizontal.get(i).push({right:n,gap:e.gap}),t.nodeToRelativeConstraintMapHorizontal.get(n).push({left:i,gap:e.gap})}else{var r=a.has(e.top)?a.get(e.top):e.top,o=a.has(e.bottom)?a.get(e.bottom):e.bottom;t.nodesInRelativeVertical.includes(r)||(t.nodesInRelativeVertical.push(r),t.nodeToRelativeConstraintMapVertical.set(r,[]),t.dummyToNodeForHorizontalAlignment.has(r)?t.nodeToTempPositionMapVertical.set(r,t.idToNodeMap.get(t.dummyToNodeForHorizontalAlignment.get(r)[0]).getCenterY()):t.nodeToTempPositionMapVertical.set(r,t.idToNodeMap.get(r).getCenterY())),t.nodesInRelativeVertical.includes(o)||(t.nodesInRelativeVertical.push(o),t.nodeToRelativeConstraintMapVertical.set(o,[]),t.dummyToNodeForHorizontalAlignment.has(o)?t.nodeToTempPositionMapVertical.set(o,t.idToNodeMap.get(t.dummyToNodeForHorizontalAlignment.get(o)[0]).getCenterY()):t.nodeToTempPositionMapVertical.set(o,t.idToNodeMap.get(o).getCenterY())),t.nodeToRelativeConstraintMapVertical.get(r).push({bottom:o,gap:e.gap}),t.nodeToRelativeConstraintMapVertical.get(o).push({top:r,gap:e.gap})}});else{var c=new Map,g=new Map;this.constraints.relativePlacementConstraint.forEach(function(t){if(t.left){var e=s.has(t.left)?s.get(t.left):t.left,i=s.has(t.right)?s.get(t.right):t.right;c.has(e)?c.get(e).push(i):c.set(e,[i]),c.has(i)?c.get(i).push(e):c.set(i,[e])}else{var n=a.has(t.top)?a.get(t.top):t.top,r=a.has(t.bottom)?a.get(t.bottom):t.bottom;g.has(n)?g.get(n).push(r):g.set(n,[r]),g.has(r)?g.get(r).push(n):g.set(r,[n])}});var u=function(t,e){var i=[],n=[],r=new N,o=new Set,s=0;return t.forEach(function(a,h){if(!o.has(h)){i[s]=[],n[s]=!1;var l=h;for(r.push(l),o.add(l),i[s].push(l);0!=r.length;)l=r.shift(),e.has(l)&&(n[s]=!0),t.get(l).forEach(function(t){o.has(t)||(r.push(t),o.add(t),i[s].push(t))});s++}}),{components:i,isFixed:n}},f=u(c,t.fixedNodesOnHorizontal);this.componentsOnHorizontal=f.components,this.fixedComponentsOnHorizontal=f.isFixed;var p=u(g,t.fixedNodesOnVertical);this.componentsOnVertical=p.components,this.fixedComponentsOnVertical=p.isFixed}}},T.prototype.updateDisplacements=function(){var t=this;if(this.constraints.fixedNodeConstraint&&this.constraints.fixedNodeConstraint.forEach(function(e){var i=t.idToNodeMap.get(e.nodeId);i.displacementX=0,i.displacementY=0}),this.constraints.alignmentConstraint){if(this.constraints.alignmentConstraint.vertical)for(var e=this.constraints.alignmentConstraint.vertical,i=0;i<e.length;i++){for(var n=0,r=0;r<e[i].length;r++){if(this.fixedNodeSet.has(e[i][r])){n=0;break}n+=this.idToNodeMap.get(e[i][r]).displacementX}var o=n/e[i].length;for(r=0;r<e[i].length;r++)this.idToNodeMap.get(e[i][r]).displacementX=o}if(this.constraints.alignmentConstraint.horizontal){var s=this.constraints.alignmentConstraint.horizontal;for(i=0;i<s.length;i++){var a=0;for(r=0;r<s[i].length;r++){if(this.fixedNodeSet.has(s[i][r])){a=0;break}a+=this.idToNodeMap.get(s[i][r]).displacementY}var l=a/s[i].length;for(r=0;r<s[i].length;r++)this.idToNodeMap.get(s[i][r]).displacementY=l}}}if(this.constraints.relativePlacementConstraint)if(h.RELAX_MOVEMENT_ON_CONSTRAINTS)this.totalIterations%10==0&&(this.shuffle(this.nodesInRelativeHorizontal),this.shuffle(this.nodesInRelativeVertical)),this.nodesInRelativeHorizontal.forEach(function(e){if(!t.fixedNodesOnHorizontal.has(e)){var i=0;i=t.dummyToNodeForVerticalAlignment.has(e)?t.idToNodeMap.get(t.dummyToNodeForVerticalAlignment.get(e)[0]).displacementX:t.idToNodeMap.get(e).displacementX,t.nodeToRelativeConstraintMapHorizontal.get(e).forEach(function(n){var r;n.right?(r=t.nodeToTempPositionMapHorizontal.get(n.right)-t.nodeToTempPositionMapHorizontal.get(e)-i)<n.gap&&(i-=n.gap-r):(r=t.nodeToTempPositionMapHorizontal.get(e)-t.nodeToTempPositionMapHorizontal.get(n.left)+i)<n.gap&&(i+=n.gap-r)}),t.nodeToTempPositionMapHorizontal.set(e,t.nodeToTempPositionMapHorizontal.get(e)+i),t.dummyToNodeForVerticalAlignment.has(e)?t.dummyToNodeForVerticalAlignment.get(e).forEach(function(e){t.idToNodeMap.get(e).displacementX=i}):t.idToNodeMap.get(e).displacementX=i}}),this.nodesInRelativeVertical.forEach(function(e){if(!t.fixedNodesOnHorizontal.has(e)){var i=0;i=t.dummyToNodeForHorizontalAlignment.has(e)?t.idToNodeMap.get(t.dummyToNodeForHorizontalAlignment.get(e)[0]).displacementY:t.idToNodeMap.get(e).displacementY,t.nodeToRelativeConstraintMapVertical.get(e).forEach(function(n){var r;n.bottom?(r=t.nodeToTempPositionMapVertical.get(n.bottom)-t.nodeToTempPositionMapVertical.get(e)-i)<n.gap&&(i-=n.gap-r):(r=t.nodeToTempPositionMapVertical.get(e)-t.nodeToTempPositionMapVertical.get(n.top)+i)<n.gap&&(i+=n.gap-r)}),t.nodeToTempPositionMapVertical.set(e,t.nodeToTempPositionMapVertical.get(e)+i),t.dummyToNodeForHorizontalAlignment.has(e)?t.dummyToNodeForHorizontalAlignment.get(e).forEach(function(e){t.idToNodeMap.get(e).displacementY=i}):t.idToNodeMap.get(e).displacementY=i}});else{for(i=0;i<this.componentsOnHorizontal.length;i++){var d=this.componentsOnHorizontal[i];if(this.fixedComponentsOnHorizontal[i])for(r=0;r<d.length;r++)this.dummyToNodeForVerticalAlignment.has(d[r])?this.dummyToNodeForVerticalAlignment.get(d[r]).forEach(function(e){t.idToNodeMap.get(e).displacementX=0}):this.idToNodeMap.get(d[r]).displacementX=0;else{var c=0,g=0;for(r=0;r<d.length;r++)this.dummyToNodeForVerticalAlignment.has(d[r])?(c+=(f=this.dummyToNodeForVerticalAlignment.get(d[r])).length*this.idToNodeMap.get(f[0]).displacementX,g+=f.length):(c+=this.idToNodeMap.get(d[r]).displacementX,g++);var u=c/g;for(r=0;r<d.length;r++)this.dummyToNodeForVerticalAlignment.has(d[r])?this.dummyToNodeForVerticalAlignment.get(d[r]).forEach(function(e){t.idToNodeMap.get(e).displacementX=u}):this.idToNodeMap.get(d[r]).displacementX=u}}for(i=0;i<this.componentsOnVertical.length;i++)if(d=this.componentsOnVertical[i],this.fixedComponentsOnVertical[i])for(r=0;r<d.length;r++)this.dummyToNodeForHorizontalAlignment.has(d[r])?this.dummyToNodeForHorizontalAlignment.get(d[r]).forEach(function(e){t.idToNodeMap.get(e).displacementY=0}):this.idToNodeMap.get(d[r]).displacementY=0;else{for(c=0,g=0,r=0;r<d.length;r++){var f;this.dummyToNodeForHorizontalAlignment.has(d[r])?(c+=(f=this.dummyToNodeForHorizontalAlignment.get(d[r])).length*this.idToNodeMap.get(f[0]).displacementY,g+=f.length):(c+=this.idToNodeMap.get(d[r]).displacementY,g++)}for(u=c/g,r=0;r<d.length;r++)this.dummyToNodeForHorizontalAlignment.has(d[r])?this.dummyToNodeForHorizontalAlignment.get(d[r]).forEach(function(e){t.idToNodeMap.get(e).displacementY=u}):this.idToNodeMap.get(d[r]).displacementY=u}}},T.prototype.calculateNodesToApplyGravitationTo=function(){var t,e,i=[],n=this.graphManager.getGraphs(),r=n.length;for(e=0;e<r;e++)(t=n[e]).updateConnected(),t.isConnected||(i=i.concat(t.getNodes()));return i},T.prototype.createBendpoints=function(){var t=[];t=t.concat(this.graphManager.getAllEdges());var e,i=new Set;for(e=0;e<t.length;e++){var n=t[e];if(!i.has(n)){var r=n.getSource(),o=n.getTarget();if(r==o)n.getBendpoints().push(new u),n.getBendpoints().push(new u),this.createDummyNodesForBendpoints(n),i.add(n);else{var s=[];if(s=(s=s.concat(r.getEdgeListToNode(o))).concat(o.getEdgeListToNode(r)),!i.has(s[0])){var a;if(s.length>1)for(a=0;a<s.length;a++){var h=s[a];h.getBendpoints().push(new u),this.createDummyNodesForBendpoints(h)}s.forEach(function(t){i.add(t)})}}}if(i.size==t.length)break}},T.prototype.positionNodesRadially=function(t){for(var e=new g(0,0),i=Math.ceil(Math.sqrt(t.length)),n=0,r=0,o=0,s=new u(0,0),a=0;a<t.length;a++){a%i==0&&(o=0,r=n,0!=a&&(r+=h.DEFAULT_COMPONENT_SEPERATION),n=0);var l=t[a],d=p.findCenterOfTree(l);e.x=o,e.y=r,(s=T.radialLayout(l,d,e)).y>n&&(n=Math.floor(s.y)),o=Math.floor(s.x+h.DEFAULT_COMPONENT_SEPERATION)}this.transform(new u(c.WORLD_CENTER_X-s.x/2,c.WORLD_CENTER_Y-s.y/2))},T.radialLayout=function(t,e,i){var n=Math.max(this.maxDiagonalInTree(t),h.DEFAULT_RADIAL_SEPARATION);T.branchRadialLayout(e,null,0,359,0,n);var r=m.calculateBounds(t),o=new E;o.setDeviceOrgX(r.getMinX()),o.setDeviceOrgY(r.getMinY()),o.setWorldOrgX(i.x),o.setWorldOrgY(i.y);for(var s=0;s<t.length;s++)t[s].transform(o);var a=new u(r.getMaxX(),r.getMaxY());return o.inverseTransformPoint(a)},T.branchRadialLayout=function(t,e,i,n,r,o){var s=(n-i+1)/2;s<0&&(s+=180);var a=(s+i)%360*v.TWO_PI/360,h=(Math.cos(a),r*Math.cos(a)),l=r*Math.sin(a);t.setCenter(h,l);var d=[],c=(d=d.concat(t.getEdges())).length;null!=e&&c--;for(var g,u=0,f=d.length,p=t.getEdgesBetween(e);p.length>1;){var y=p[0];p.splice(0,1);var m=d.indexOf(y);m>=0&&d.splice(m,1),f--,c--}g=null!=e?(d.indexOf(p[0])+1)%f:0;for(var E=Math.abs(n-i)/c,N=g;u!=c;N=++N%f){var A=d[N].getOtherEnd(t);if(A!=e){var w=(i+u*E)%360,L=(w+E)%360;T.branchRadialLayout(A,t,w,L,r+o,o),u++}}},T.maxDiagonalInTree=function(t){for(var e=y.MIN_VALUE,i=0;i<t.length;i++){var n=t[i].getDiagonal();n>e&&(e=n)}return e},T.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},T.prototype.groupZeroDegreeMembers=function(){var t=this,e={};this.memberGroups={},this.idToDummyNode={};for(var i=[],n=this.graphManager.getAllNodes(),r=0;r<n.length;r++){var o=(a=n[r]).getParent();0!==this.getNodeDegreeWithChildren(a)||null!=o.id&&this.getToBeTiled(o)||i.push(a)}for(r=0;r<i.length;r++){var a,h=(a=i[r]).getParent().id;void 0===e[h]&&(e[h]=[]),e[h]=e[h].concat(a)}Object.keys(e).forEach(function(i){if(e[i].length>1){var n="DummyCompound_"+i;t.memberGroups[n]=e[i];var r=e[i][0].getParent(),o=new s(t.graphManager);o.id=n,o.paddingLeft=r.paddingLeft||0,o.paddingRight=r.paddingRight||0,o.paddingBottom=r.paddingBottom||0,o.paddingTop=r.paddingTop||0,t.idToDummyNode[n]=o;var a=t.getGraphManager().add(t.newGraph(),o),h=r.getChild();h.add(o);for(var l=0;l<e[i].length;l++){var d=e[i][l];h.remove(d),a.add(d)}}})},T.prototype.clearCompounds=function(){var t={},e={};this.performDFSOnCompounds();for(var i=0;i<this.compoundOrder.length;i++)e[this.compoundOrder[i].id]=this.compoundOrder[i],t[this.compoundOrder[i].id]=[].concat(this.compoundOrder[i].getChild().getNodes()),this.graphManager.remove(this.compoundOrder[i].getChild()),this.compoundOrder[i].child=null;this.graphManager.resetAllNodes(),this.tileCompoundMembers(t,e)},T.prototype.clearZeroDegreeMembers=function(){var t=this,e=this.tiledZeroDegreePack=[];Object.keys(this.memberGroups).forEach(function(i){var n=t.idToDummyNode[i];if(e[i]=t.tileNodes(t.memberGroups[i],n.paddingLeft+n.paddingRight),n.rect.width=e[i].width,n.rect.height=e[i].height,n.setCenter(e[i].centerX,e[i].centerY),n.labelMarginLeft=0,n.labelMarginTop=0,h.NODE_DIMENSIONS_INCLUDE_LABELS){var r=n.rect.width,o=n.rect.height;n.labelWidth&&("left"==n.labelPosHorizontal?(n.rect.x-=n.labelWidth,n.setWidth(r+n.labelWidth),n.labelMarginLeft=n.labelWidth):"center"==n.labelPosHorizontal&&n.labelWidth>r?(n.rect.x-=(n.labelWidth-r)/2,n.setWidth(n.labelWidth),n.labelMarginLeft=(n.labelWidth-r)/2):"right"==n.labelPosHorizontal&&n.setWidth(r+n.labelWidth)),n.labelHeight&&("top"==n.labelPosVertical?(n.rect.y-=n.labelHeight,n.setHeight(o+n.labelHeight),n.labelMarginTop=n.labelHeight):"center"==n.labelPosVertical&&n.labelHeight>o?(n.rect.y-=(n.labelHeight-o)/2,n.setHeight(n.labelHeight),n.labelMarginTop=(n.labelHeight-o)/2):"bottom"==n.labelPosVertical&&n.setHeight(o+n.labelHeight))}})},T.prototype.repopulateCompounds=function(){for(var t=this.compoundOrder.length-1;t>=0;t--){var e=this.compoundOrder[t],i=e.id,n=e.paddingLeft,r=e.paddingTop,o=e.labelMarginLeft,s=e.labelMarginTop;this.adjustLocations(this.tiledMemberPack[i],e.rect.x,e.rect.y,n,r,o,s)}},T.prototype.repopulateZeroDegreeMembers=function(){var t=this,e=this.tiledZeroDegreePack;Object.keys(e).forEach(function(i){var n=t.idToDummyNode[i],r=n.paddingLeft,o=n.paddingTop,s=n.labelMarginLeft,a=n.labelMarginTop;t.adjustLocations(e[i],n.rect.x,n.rect.y,r,o,s,a)})},T.prototype.getToBeTiled=function(t){var e=t.id;if(null!=this.toBeTiled[e])return this.toBeTiled[e];var i=t.getChild();if(null==i)return this.toBeTiled[e]=!1,!1;for(var n=i.getNodes(),r=0;r<n.length;r++){var o=n[r];if(this.getNodeDegree(o)>0)return this.toBeTiled[e]=!1,!1;if(null!=o.getChild()){if(!this.getToBeTiled(o))return this.toBeTiled[e]=!1,!1}else this.toBeTiled[o.id]=!1}return this.toBeTiled[e]=!0,!0},T.prototype.getNodeDegree=function(t){t.id;for(var e=t.getEdges(),i=0,n=0;n<e.length;n++){var r=e[n];r.getSource().id!==r.getTarget().id&&(i+=1)}return i},T.prototype.getNodeDegreeWithChildren=function(t){var e=this.getNodeDegree(t);if(null==t.getChild())return e;for(var i=t.getChild().getNodes(),n=0;n<i.length;n++){var r=i[n];e+=this.getNodeDegreeWithChildren(r)}return e},T.prototype.performDFSOnCompounds=function(){this.compoundOrder=[],this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes())},T.prototype.fillCompexOrderByDFS=function(t){for(var e=0;e<t.length;e++){var i=t[e];null!=i.getChild()&&this.fillCompexOrderByDFS(i.getChild().getNodes()),this.getToBeTiled(i)&&this.compoundOrder.push(i)}},T.prototype.adjustLocations=function(t,e,i,n,r,o,s){i+=r+s;for(var a=e+=n+o,h=0;h<t.rows.length;h++){var l=t.rows[h];e=a;for(var d=0,c=0;c<l.length;c++){var g=l[c];g.rect.x=e,g.rect.y=i,e+=g.rect.width+t.horizontalPadding,g.rect.height>d&&(d=g.rect.height)}i+=d+t.verticalPadding}},T.prototype.tileCompoundMembers=function(t,e){var i=this;this.tiledMemberPack=[],Object.keys(t).forEach(function(n){var r=e[n];if(i.tiledMemberPack[n]=i.tileNodes(t[n],r.paddingLeft+r.paddingRight),r.rect.width=i.tiledMemberPack[n].width,r.rect.height=i.tiledMemberPack[n].height,r.setCenter(i.tiledMemberPack[n].centerX,i.tiledMemberPack[n].centerY),r.labelMarginLeft=0,r.labelMarginTop=0,h.NODE_DIMENSIONS_INCLUDE_LABELS){var o=r.rect.width,s=r.rect.height;r.labelWidth&&("left"==r.labelPosHorizontal?(r.rect.x-=r.labelWidth,r.setWidth(o+r.labelWidth),r.labelMarginLeft=r.labelWidth):"center"==r.labelPosHorizontal&&r.labelWidth>o?(r.rect.x-=(r.labelWidth-o)/2,r.setWidth(r.labelWidth),r.labelMarginLeft=(r.labelWidth-o)/2):"right"==r.labelPosHorizontal&&r.setWidth(o+r.labelWidth)),r.labelHeight&&("top"==r.labelPosVertical?(r.rect.y-=r.labelHeight,r.setHeight(s+r.labelHeight),r.labelMarginTop=r.labelHeight):"center"==r.labelPosVertical&&r.labelHeight>s?(r.rect.y-=(r.labelHeight-s)/2,r.setHeight(r.labelHeight),r.labelMarginTop=(r.labelHeight-s)/2):"bottom"==r.labelPosVertical&&r.setHeight(s+r.labelHeight))}})},T.prototype.tileNodes=function(t,e){var i=this.tileNodesByFavoringDim(t,e,!0),n=this.tileNodesByFavoringDim(t,e,!1),r=this.getOrgRatio(i);return this.getOrgRatio(n)<r?n:i},T.prototype.getOrgRatio=function(t){var e=t.width/t.height;return e<1&&(e=1/e),e},T.prototype.calcIdealRowWidth=function(t,e){var i=h.TILING_PADDING_VERTICAL,n=h.TILING_PADDING_HORIZONTAL,r=t.length,o=0,s=0,a=0;t.forEach(function(t){o+=t.getWidth(),s+=t.getHeight(),t.getWidth()>a&&(a=t.getWidth())});var l,d=o/r,c=s/r,g=Math.pow(i-n,2)+4*(d+n)*(c+i)*r,u=(n-i+Math.sqrt(g))/(2*(d+n));e?(l=Math.ceil(u))==u&&l++:l=Math.floor(u);var f=l*(d+n)-n;return a>f&&(f=a),f+=2*n},T.prototype.tileNodesByFavoringDim=function(t,e,i){var n=h.TILING_PADDING_VERTICAL,r=h.TILING_PADDING_HORIZONTAL,o=h.TILING_COMPARE_BY,s={rows:[],rowWidth:[],rowHeight:[],width:0,height:e,verticalPadding:n,horizontalPadding:r,centerX:0,centerY:0};o&&(s.idealRowWidth=this.calcIdealRowWidth(t,i));var a=function(t){return t.rect.width*t.rect.height},l=function(t,e){return a(e)-a(t)};t.sort(function(t,e){var i=l;return s.idealRowWidth?(i=o)(t.id,e.id):i(t,e)});for(var d=0,c=0,g=0;g<t.length;g++)d+=(u=t[g]).getCenterX(),c+=u.getCenterY();for(s.centerX=d/t.length,s.centerY=c/t.length,g=0;g<t.length;g++){var u=t[g];if(0==s.rows.length)this.insertNodeToRow(s,u,0,e);else if(this.canAddHorizontal(s,u.rect.width,u.rect.height)){var f=s.rows.length-1;s.idealRowWidth||(f=this.getShortestRowIndex(s)),this.insertNodeToRow(s,u,f,e)}else this.insertNodeToRow(s,u,s.rows.length,e);this.shiftToLastRow(s)}return s},T.prototype.insertNodeToRow=function(t,e,i,n){var r=n;i==t.rows.length&&(t.rows.push([]),t.rowWidth.push(r),t.rowHeight.push(0));var o=t.rowWidth[i]+e.rect.width;t.rows[i].length>0&&(o+=t.horizontalPadding),t.rowWidth[i]=o,t.width<o&&(t.width=o);var s=e.rect.height;i>0&&(s+=t.verticalPadding);var a=0;s>t.rowHeight[i]&&(a=t.rowHeight[i],t.rowHeight[i]=s,a=t.rowHeight[i]-a),t.height+=a,t.rows[i].push(e)},T.prototype.getShortestRowIndex=function(t){for(var e=-1,i=Number.MAX_VALUE,n=0;n<t.rows.length;n++)t.rowWidth[n]<i&&(e=n,i=t.rowWidth[n]);return e},T.prototype.getLongestRowIndex=function(t){for(var e=-1,i=Number.MIN_VALUE,n=0;n<t.rows.length;n++)t.rowWidth[n]>i&&(e=n,i=t.rowWidth[n]);return e},T.prototype.canAddHorizontal=function(t,e,i){if(t.idealRowWidth){var n=t.rows.length-1;return t.rowWidth[n]+e+t.horizontalPadding<=t.idealRowWidth}var r=this.getShortestRowIndex(t);if(r<0)return!0;var o=t.rowWidth[r];if(o+t.horizontalPadding+e<=t.width)return!0;var s,a,h=0;return t.rowHeight[r]<i&&r>0&&(h=i+t.verticalPadding-t.rowHeight[r]),s=t.width-o>=e+t.horizontalPadding?(t.height+h)/(o+e+t.horizontalPadding):(t.height+h)/t.width,h=i+t.verticalPadding,(a=t.width<e?(t.height+h)/e:(t.height+h)/t.width)<1&&(a=1/a),s<1&&(s=1/s),s<a},T.prototype.shiftToLastRow=function(t){var e=this.getLongestRowIndex(t),i=t.rowWidth.length-1,n=t.rows[e],r=n[n.length-1],o=r.width+t.horizontalPadding;if(t.width-t.rowWidth[i]>o&&e!=i){n.splice(-1,1),t.rows[i].push(r),t.rowWidth[e]=t.rowWidth[e]-o,t.rowWidth[i]=t.rowWidth[i]+o,t.width=t.rowWidth[instance.getLongestRowIndex(t)];for(var s=Number.MIN_VALUE,a=0;a<n.length;a++)n[a].height>s&&(s=n[a].height);e>0&&(s+=t.verticalPadding);var h=t.rowHeight[e]+t.rowHeight[i];t.rowHeight[e]=s,t.rowHeight[i]<r.height+t.verticalPadding&&(t.rowHeight[i]=r.height+t.verticalPadding);var l=t.rowHeight[e]+t.rowHeight[i];t.height+=l-h,this.shiftToLastRow(t)}},T.prototype.tilingPreLayout=function(){h.TILE&&(this.groupZeroDegreeMembers(),this.clearCompounds(),this.clearZeroDegreeMembers())},T.prototype.tilingPostLayout=function(){h.TILE&&(this.repopulateZeroDegreeMembers(),this.repopulateCompounds())},T.prototype.reduceTrees=function(){for(var t,e=[],i=!0;i;){var n=this.graphManager.getAllNodes(),r=[];i=!1;for(var o=0;o<n.length;o++)if(1==(t=n[o]).getEdges().length&&!t.getEdges()[0].isInterGraph&&null==t.getChild()){if(h.PURE_INCREMENTAL){var s=t.getEdges()[0].getOtherEnd(t),a=new f(t.getCenterX()-s.getCenterX(),t.getCenterY()-s.getCenterY());r.push([t,t.getEdges()[0],t.getOwner(),a])}else r.push([t,t.getEdges()[0],t.getOwner()]);i=!0}if(1==i){for(var l=[],d=0;d<r.length;d++)1==r[d][0].getEdges().length&&(l.push(r[d]),r[d][0].getOwner().remove(r[d][0]));e.push(l),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()}}this.prunedNodesAll=e},T.prototype.growTree=function(t){for(var e,i=t[t.length-1],n=0;n<i.length;n++)e=i[n],this.findPlaceforPrunedNode(e),e[2].add(e[0]),e[2].add(e[1],e[1].source,e[1].target);t.splice(t.length-1,1),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()},T.prototype.findPlaceforPrunedNode=function(t){var e,i,n=t[0];if(i=n==t[1].source?t[1].target:t[1].source,h.PURE_INCREMENTAL)n.setCenter(i.getCenterX()+t[3].getWidth(),i.getCenterY()+t[3].getHeight());else{var r=i.startX,o=i.finishX,s=i.startY,a=i.finishY,l=[0,0,0,0];if(s>0)for(var c=r;c<=o;c++)l[0]+=this.grid[c][s-1].length+this.grid[c][s].length-1;if(o<this.grid.length-1)for(c=s;c<=a;c++)l[1]+=this.grid[o+1][c].length+this.grid[o][c].length-1;if(a<this.grid[0].length-1)for(c=r;c<=o;c++)l[2]+=this.grid[c][a+1].length+this.grid[c][a].length-1;if(r>0)for(c=s;c<=a;c++)l[3]+=this.grid[r-1][c].length+this.grid[r][c].length-1;for(var g,u,f=y.MAX_VALUE,p=0;p<l.length;p++)l[p]<f?(f=l[p],g=1,u=p):l[p]==f&&g++;if(3==g&&0==f)0==l[0]&&0==l[1]&&0==l[2]?e=1:0==l[0]&&0==l[1]&&0==l[3]?e=0:0==l[0]&&0==l[2]&&0==l[3]?e=3:0==l[1]&&0==l[2]&&0==l[3]&&(e=2);else if(2==g&&0==f){var v=Math.floor(2*Math.random());e=0==l[0]&&0==l[1]?0==v?0:1:0==l[0]&&0==l[2]?0==v?0:2:0==l[0]&&0==l[3]?0==v?0:3:0==l[1]&&0==l[2]?0==v?1:2:0==l[1]&&0==l[3]?0==v?1:3:0==v?2:3}else e=4==g&&0==f?v=Math.floor(4*Math.random()):u;0==e?n.setCenter(i.getCenterX(),i.getCenterY()-i.getHeight()/2-d.DEFAULT_EDGE_LENGTH-n.getHeight()/2):1==e?n.setCenter(i.getCenterX()+i.getWidth()/2+d.DEFAULT_EDGE_LENGTH+n.getWidth()/2,i.getCenterY()):2==e?n.setCenter(i.getCenterX(),i.getCenterY()+i.getHeight()/2+d.DEFAULT_EDGE_LENGTH+n.getHeight()/2):n.setCenter(i.getCenterX()-i.getWidth()/2-d.DEFAULT_EDGE_LENGTH-n.getWidth()/2,i.getCenterY())}},t.exports=T},991:(t,e,i)=>{var n=i(551).FDLayoutNode,r=i(551).IMath;function o(t,e,i,r){n.call(this,t,e,i,r)}for(var s in o.prototype=Object.create(n.prototype),n)o[s]=n[s];o.prototype.calculateDisplacement=function(){var t=this.graphManager.getLayout();null!=this.getChild()&&this.fixedNodeWeight?(this.displacementX+=t.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.fixedNodeWeight,this.displacementY+=t.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.fixedNodeWeight):(this.displacementX+=t.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY+=t.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren),Math.abs(this.displacementX)>t.coolingFactor*t.maxNodeDisplacement&&(this.displacementX=t.coolingFactor*t.maxNodeDisplacement*r.sign(this.displacementX)),Math.abs(this.displacementY)>t.coolingFactor*t.maxNodeDisplacement&&(this.displacementY=t.coolingFactor*t.maxNodeDisplacement*r.sign(this.displacementY)),this.child&&this.child.getNodes().length>0&&this.propogateDisplacementToChildren(this.displacementX,this.displacementY)},o.prototype.propogateDisplacementToChildren=function(t,e){for(var i,n=this.getChild().getNodes(),r=0;r<n.length;r++)null==(i=n[r]).getChild()?(i.displacementX+=t,i.displacementY+=e):i.propogateDisplacementToChildren(t,e)},o.prototype.move=function(){var t=this.graphManager.getLayout();null!=this.child&&0!=this.child.getNodes().length||(this.moveBy(this.displacementX,this.displacementY),t.totalDisplacement+=Math.abs(this.displacementX)+Math.abs(this.displacementY)),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0},o.prototype.setPred1=function(t){this.pred1=t},o.prototype.getPred1=function(){return pred1},o.prototype.getPred2=function(){return pred2},o.prototype.setNext=function(t){this.next=t},o.prototype.getNext=function(){return next},o.prototype.setProcessed=function(t){this.processed=t},o.prototype.isProcessed=function(){return processed},t.exports=o},902:(t,e,i)=>{function n(t){if(Array.isArray(t)){for(var e=0,i=Array(t.length);e<t.length;e++)i[e]=t[e];return i}return Array.from(t)}var r=i(806),o=i(551).LinkedList,s=i(551).Matrix,a=i(551).SVD;function h(){}h.handleConstraints=function(t){var e={};e.fixedNodeConstraint=t.constraints.fixedNodeConstraint,e.alignmentConstraint=t.constraints.alignmentConstraint,e.relativePlacementConstraint=t.constraints.relativePlacementConstraint;for(var i=new Map,h=new Map,l=[],d=[],c=t.getAllNodes(),g=0,u=0;u<c.length;u++){var f=c[u];null==f.getChild()&&(h.set(f.id,g++),l.push(f.getCenterX()),d.push(f.getCenterY()),i.set(f.id,f))}e.relativePlacementConstraint&&e.relativePlacementConstraint.forEach(function(t){t.gap||0==t.gap||(t.left?t.gap=r.DEFAULT_EDGE_LENGTH+i.get(t.left).getWidth()/2+i.get(t.right).getWidth()/2:t.gap=r.DEFAULT_EDGE_LENGTH+i.get(t.top).getHeight()/2+i.get(t.bottom).getHeight()/2)});var p=function(t){var e=0,i=0;return t.forEach(function(t){e+=l[h.get(t)],i+=d[h.get(t)]}),{x:e/t.size,y:i/t.size}},y=function(t,e,i,r,s){var a=new Map;t.forEach(function(t,e){a.set(e,0)}),t.forEach(function(t,e){t.forEach(function(t){a.set(t.id,a.get(t.id)+1)})});var c=new Map,g=new Map,u=new o;a.forEach(function(t,n){0==t?(u.push(n),i||("horizontal"==e?c.set(n,h.has(n)?l[h.get(n)]:r.get(n)):c.set(n,h.has(n)?d[h.get(n)]:r.get(n)))):c.set(n,Number.NEGATIVE_INFINITY),i&&g.set(n,new Set([n]))}),i&&s.forEach(function(t){var n=[];if(t.forEach(function(t){i.has(t)&&n.push(t)}),n.length>0){var o=0;n.forEach(function(t){"horizontal"==e?(c.set(t,h.has(t)?l[h.get(t)]:r.get(t)),o+=c.get(t)):(c.set(t,h.has(t)?d[h.get(t)]:r.get(t)),o+=c.get(t))}),o/=n.length,t.forEach(function(t){i.has(t)||c.set(t,o)})}else{var s=0;t.forEach(function(t){s+="horizontal"==e?h.has(t)?l[h.get(t)]:r.get(t):h.has(t)?d[h.get(t)]:r.get(t)}),s/=t.length,t.forEach(function(t){c.set(t,s)})}});for(var f=function(){var n=u.shift();t.get(n).forEach(function(t){if(c.get(t.id)<c.get(n)+t.gap)if(i&&i.has(t.id)){var o=void 0;if(o="horizontal"==e?h.has(t.id)?l[h.get(t.id)]:r.get(t.id):h.has(t.id)?d[h.get(t.id)]:r.get(t.id),c.set(t.id,o),o<c.get(n)+t.gap){var s=c.get(n)+t.gap-o;g.get(n).forEach(function(t){c.set(t,c.get(t)-s)})}}else c.set(t.id,c.get(n)+t.gap);a.set(t.id,a.get(t.id)-1),0==a.get(t.id)&&u.push(t.id),i&&g.set(t.id,function(t,e){var i=new Set(t),n=!0,r=!1,o=void 0;try{for(var s,a=e[Symbol.iterator]();!(n=(s=a.next()).done);n=!0){var h=s.value;i.add(h)}}catch(l){r=!0,o=l}finally{try{!n&&a.return&&a.return()}finally{if(r)throw o}}return i}(g.get(n),g.get(t.id)))})};0!=u.length;)f();if(i){var p=new Set;t.forEach(function(t,e){0==t.length&&p.add(e)});var y=[];g.forEach(function(t,e){if(p.has(e)){var r=!1,o=!0,s=!1,a=void 0;try{for(var h,l=t[Symbol.iterator]();!(o=(h=l.next()).done);o=!0){var d=h.value;i.has(d)&&(r=!0)}}catch(u){s=!0,a=u}finally{try{!o&&l.return&&l.return()}finally{if(s)throw a}}if(!r){var c=!1,g=void 0;y.forEach(function(e,i){e.has([].concat(n(t))[0])&&(c=!0,g=i)}),c?t.forEach(function(t){y[g].add(t)}):y.push(new Set(t))}}}),y.forEach(function(t,i){var n=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,a=Number.NEGATIVE_INFINITY,g=!0,u=!1,f=void 0;try{for(var p,y=t[Symbol.iterator]();!(g=(p=y.next()).done);g=!0){var v=p.value,m=void 0;m="horizontal"==e?h.has(v)?l[h.get(v)]:r.get(v):h.has(v)?d[h.get(v)]:r.get(v);var E=c.get(v);m<n&&(n=m),m>s&&(s=m),E<o&&(o=E),E>a&&(a=E)}}catch(_){u=!0,f=_}finally{try{!g&&y.return&&y.return()}finally{if(u)throw f}}var N=(n+s)/2-(o+a)/2,T=!0,A=!1,w=void 0;try{for(var L,C=t[Symbol.iterator]();!(T=(L=C.next()).done);T=!0){var I=L.value;c.set(I,c.get(I)+N)}}catch(_){A=!0,w=_}finally{try{!T&&C.return&&C.return()}finally{if(A)throw w}}})}return c},v=function(t){var e=0,i=0,n=0,r=0;if(t.forEach(function(t){t.left?l[h.get(t.left)]-l[h.get(t.right)]>=0?e++:i++:d[h.get(t.top)]-d[h.get(t.bottom)]>=0?n++:r++}),e>i&&n>r)for(var o=0;o<h.size;o++)l[o]=-1*l[o],d[o]=-1*d[o];else if(e>i)for(var s=0;s<h.size;s++)l[s]=-1*l[s];else if(n>r)for(var a=0;a<h.size;a++)d[a]=-1*d[a]},m=function(t){var e=[],i=new o,n=new Set,r=0;return t.forEach(function(o,s){if(!n.has(s)){e[r]=[];var a=s;for(i.push(a),n.add(a),e[r].push(a);0!=i.length;)a=i.shift(),t.get(a).forEach(function(t){n.has(t.id)||(i.push(t.id),n.add(t.id),e[r].push(t.id))});r++}}),e},E=function(t){var e=new Map;return t.forEach(function(t,i){e.set(i,[])}),t.forEach(function(t,i){t.forEach(function(t){e.get(i).push(t),e.get(t.id).push({id:i,gap:t.gap,direction:t.direction})})}),e},N=function(t){var e=new Map;return t.forEach(function(t,i){e.set(i,[])}),t.forEach(function(t,i){t.forEach(function(t){e.get(t.id).push({id:i,gap:t.gap,direction:t.direction})})}),e},T=[],A=[],w=!1,L=!1,C=new Set,I=new Map,_=new Map,M=[];if(e.fixedNodeConstraint&&e.fixedNodeConstraint.forEach(function(t){C.add(t.nodeId)}),e.relativePlacementConstraint&&(e.relativePlacementConstraint.forEach(function(t){t.left?(I.has(t.left)?I.get(t.left).push({id:t.right,gap:t.gap,direction:"horizontal"}):I.set(t.left,[{id:t.right,gap:t.gap,direction:"horizontal"}]),I.has(t.right)||I.set(t.right,[])):(I.has(t.top)?I.get(t.top).push({id:t.bottom,gap:t.gap,direction:"vertical"}):I.set(t.top,[{id:t.bottom,gap:t.gap,direction:"vertical"}]),I.has(t.bottom)||I.set(t.bottom,[]))}),_=E(I),M=m(_)),r.TRANSFORM_ON_CONSTRAINT_HANDLING){if(e.fixedNodeConstraint&&e.fixedNodeConstraint.length>1)e.fixedNodeConstraint.forEach(function(t,e){T[e]=[t.position.x,t.position.y],A[e]=[l[h.get(t.nodeId)],d[h.get(t.nodeId)]]}),w=!0;else if(e.alignmentConstraint)!function(){var t=0;if(e.alignmentConstraint.vertical){for(var i=e.alignmentConstraint.vertical,r=function(e){var r=new Set;i[e].forEach(function(t){r.add(t)});var o=new Set([].concat(n(r)).filter(function(t){return C.has(t)})),s=void 0;s=o.size>0?l[h.get(o.values().next().value)]:p(r).x,i[e].forEach(function(e){T[t]=[s,d[h.get(e)]],A[t]=[l[h.get(e)],d[h.get(e)]],t++})},o=0;o<i.length;o++)r(o);w=!0}if(e.alignmentConstraint.horizontal){for(var s=e.alignmentConstraint.horizontal,a=function(e){var i=new Set;s[e].forEach(function(t){i.add(t)});var r=new Set([].concat(n(i)).filter(function(t){return C.has(t)})),o=void 0;o=r.size>0?l[h.get(r.values().next().value)]:p(i).y,s[e].forEach(function(e){T[t]=[l[h.get(e)],o],A[t]=[l[h.get(e)],d[h.get(e)]],t++})},c=0;c<s.length;c++)a(c);w=!0}e.relativePlacementConstraint&&(L=!0)}();else if(e.relativePlacementConstraint){for(var x=0,O=0,D=0;D<M.length;D++)M[D].length>x&&(x=M[D].length,O=D);if(x<_.size/2)v(e.relativePlacementConstraint),w=!1,L=!1;else{var R=new Map,b=new Map,F=[];M[O].forEach(function(t){I.get(t).forEach(function(e){"horizontal"==e.direction?(R.has(t)?R.get(t).push(e):R.set(t,[e]),R.has(e.id)||R.set(e.id,[]),F.push({left:t,right:e.id})):(b.has(t)?b.get(t).push(e):b.set(t,[e]),b.has(e.id)||b.set(e.id,[]),F.push({top:t,bottom:e.id}))})}),v(F),L=!1;var G=y(R,"horizontal"),S=y(b,"vertical");M[O].forEach(function(t,e){A[e]=[l[h.get(t)],d[h.get(t)]],T[e]=[],G.has(t)?T[e][0]=G.get(t):T[e][0]=l[h.get(t)],S.has(t)?T[e][1]=S.get(t):T[e][1]=d[h.get(t)]}),w=!0}}if(w){for(var P,U=s.transpose(T),Y=s.transpose(A),k=0;k<U.length;k++)U[k]=s.multGamma(U[k]),Y[k]=s.multGamma(Y[k]);var H=s.multMat(U,s.transpose(Y)),X=a.svd(H);P=s.multMat(X.V,s.transpose(X.U));for(var z=0;z<h.size;z++){var B=[l[z],d[z]],V=[P[0][0],P[1][0]],W=[P[0][1],P[1][1]];l[z]=s.dotProduct(B,V),d[z]=s.dotProduct(B,W)}L&&v(e.relativePlacementConstraint)}}if(r.ENFORCE_CONSTRAINTS){if(e.fixedNodeConstraint&&e.fixedNodeConstraint.length>0){var j={x:0,y:0};e.fixedNodeConstraint.forEach(function(t,e){var i,n,r={x:l[h.get(t.nodeId)],y:d[h.get(t.nodeId)]},o=t.position,s=(n=r,{x:(i=o).x-n.x,y:i.y-n.y});j.x+=s.x,j.y+=s.y}),j.x/=e.fixedNodeConstraint.length,j.y/=e.fixedNodeConstraint.length,l.forEach(function(t,e){l[e]+=j.x}),d.forEach(function(t,e){d[e]+=j.y}),e.fixedNodeConstraint.forEach(function(t){l[h.get(t.nodeId)]=t.position.x,d[h.get(t.nodeId)]=t.position.y})}if(e.alignmentConstraint){if(e.alignmentConstraint.vertical)for(var $=e.alignmentConstraint.vertical,q=function(t){var e=new Set;$[t].forEach(function(t){e.add(t)});var i=new Set([].concat(n(e)).filter(function(t){return C.has(t)})),r=void 0;r=i.size>0?l[h.get(i.values().next().value)]:p(e).x,e.forEach(function(t){C.has(t)||(l[h.get(t)]=r)})},K=0;K<$.length;K++)q(K);if(e.alignmentConstraint.horizontal)for(var Z=e.alignmentConstraint.horizontal,Q=function(t){var e=new Set;Z[t].forEach(function(t){e.add(t)});var i=new Set([].concat(n(e)).filter(function(t){return C.has(t)})),r=void 0;r=i.size>0?d[h.get(i.values().next().value)]:p(e).y,e.forEach(function(t){C.has(t)||(d[h.get(t)]=r)})},J=0;J<Z.length;J++)Q(J)}e.relativePlacementConstraint&&function(){var t=new Map,i=new Map,n=new Map,r=new Map,o=new Map,s=new Map,a=new Set,c=new Set;if(C.forEach(function(t){a.add(t),c.add(t)}),e.alignmentConstraint){if(e.alignmentConstraint.vertical)for(var g=e.alignmentConstraint.vertical,u=function(e){n.set("dummy"+e,[]),g[e].forEach(function(i){t.set(i,"dummy"+e),n.get("dummy"+e).push(i),C.has(i)&&a.add("dummy"+e)}),o.set("dummy"+e,l[h.get(g[e][0])])},f=0;f<g.length;f++)u(f);if(e.alignmentConstraint.horizontal)for(var p=e.alignmentConstraint.horizontal,v=function(t){r.set("dummy"+t,[]),p[t].forEach(function(e){i.set(e,"dummy"+t),r.get("dummy"+t).push(e),C.has(e)&&c.add("dummy"+t)}),s.set("dummy"+t,d[h.get(p[t][0])])},T=0;T<p.length;T++)v(T)}var A=new Map,w=new Map,L=function(e){I.get(e).forEach(function(n){var r=void 0,o=void 0;"horizontal"==n.direction?(r=t.get(e)?t.get(e):e,o=t.get(n.id)?{id:t.get(n.id),gap:n.gap,direction:n.direction}:n,A.has(r)?A.get(r).push(o):A.set(r,[o]),A.has(o.id)||A.set(o.id,[])):(r=i.get(e)?i.get(e):e,o=i.get(n.id)?{id:i.get(n.id),gap:n.gap,direction:n.direction}:n,w.has(r)?w.get(r).push(o):w.set(r,[o]),w.has(o.id)||w.set(o.id,[]))})},_=!0,M=!1,x=void 0;try{for(var O,D=I.keys()[Symbol.iterator]();!(_=(O=D.next()).done);_=!0)L(O.value)}catch(tt){M=!0,x=tt}finally{try{!_&&D.return&&D.return()}finally{if(M)throw x}}var R=E(A),b=E(w),F=m(R),G=m(b),S=N(A),P=N(w),U=[],Y=[];F.forEach(function(t,e){U[e]=[],t.forEach(function(t){0==S.get(t).length&&U[e].push(t)})}),G.forEach(function(t,e){Y[e]=[],t.forEach(function(t){0==P.get(t).length&&Y[e].push(t)})});var k=y(A,"horizontal",a,o,U),H=y(w,"vertical",c,s,Y),X=function(t){n.get(t)?n.get(t).forEach(function(e){l[h.get(e)]=k.get(t)}):l[h.get(t)]=k.get(t)},z=!0,B=!1,V=void 0;try{for(var W,j=k.keys()[Symbol.iterator]();!(z=(W=j.next()).done);z=!0)X(W.value)}catch(tt){B=!0,V=tt}finally{try{!z&&j.return&&j.return()}finally{if(B)throw V}}var $=function(t){r.get(t)?r.get(t).forEach(function(e){d[h.get(e)]=H.get(t)}):d[h.get(t)]=H.get(t)},q=!0,K=!1,Z=void 0;try{for(var Q,J=H.keys()[Symbol.iterator]();!(q=(Q=J.next()).done);q=!0)$(Q.value)}catch(tt){K=!0,Z=tt}finally{try{!q&&J.return&&J.return()}finally{if(K)throw Z}}}()}for(var tt=0;tt<c.length;tt++){var et=c[tt];null==et.getChild()&&et.setCenter(l[h.get(et.id)],d[h.get(et.id)])}},t.exports=h},551:e=>{e.exports=t}},i={},n=function t(n){var r=i[n];if(void 0!==r)return r.exports;var o=i[n]={exports:{}};return e[n](o,o.exports,t),o.exports}(45);return n})()},t.exports=n(i(1917))}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/836c9f98.fba690cd.js b/pr-preview/pr-4027/assets/js/836c9f98.fba690cd.js deleted file mode 100644 index 95038cdba..000000000 --- a/pr-preview/pr-4027/assets/js/836c9f98.fba690cd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6407],{28453:(e,t,r)=>{r.d(t,{R:()=>a,x:()=>s});var i=r(96540);const n={},o=i.createContext(n);function a(e){const t=i.useContext(o);return i.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),i.createElement(o.Provider,{value:t},e.children)}},59519:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"architecture/overview","title":"Overview","description":"Constellation is a cloud-based confidential orchestration platform.","source":"@site/versioned_docs/version-2.24/architecture/overview.md","sourceDirName":"architecture","slug":"/architecture/overview","permalink":"/constellation/pr-preview/pr-4027/architecture/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/architecture/overview.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Architecture","permalink":"/constellation/pr-preview/pr-4027/category/architecture"},"next":{"title":"Cluster orchestration","permalink":"/constellation/pr-preview/pr-4027/architecture/orchestration"}}');var n=r(74848),o=r(28453);const a={},s="Overview",c={},l=[{value:"About orchestration and updates",id:"about-orchestration-and-updates",level:2},{value:"About microservices and attestation",id:"about-microservices-and-attestation",level:2},{value:"About node images and verified boot",id:"about-node-images-and-verified-boot",level:2},{value:"About key management and cryptographic primitives",id:"about-key-management-and-cryptographic-primitives",level:2},{value:"About observability",id:"about-observability",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,n.jsxs)(t.p,{children:["Constellation is a cloud-based confidential orchestration platform.\nThe foundation of Constellation is Kubernetes and therefore shares the same technology stack and architecture principles.\nTo learn more about Constellation and Kubernetes, see ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/overview/product",children:"product overview"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"about-orchestration-and-updates",children:"About orchestration and updates"}),"\n",(0,n.jsxs)(t.p,{children:["As a cluster administrator, you can use the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/orchestration",children:"Constellation CLI"})," to install and deploy a cluster.\nUpdates are provided in accordance with the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/versions",children:"support policy"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"about-microservices-and-attestation",children:"About microservices and attestation"}),"\n",(0,n.jsxs)(t.p,{children:["Constellation manages the nodes and network in your cluster. All nodes are bootstrapped by the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#bootstrapper",children:(0,n.jsx)(t.em,{children:"Bootstrapper"})}),". They're verified and authenticated by the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#joinservice",children:(0,n.jsx)(t.em,{children:"JoinService"})})," before being added to the cluster and the network. Finally, the entire cluster can be verified via the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#verificationservice",children:(0,n.jsx)(t.em,{children:"VerificationService"})})," using ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/attestation",children:"remote attestation"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"about-node-images-and-verified-boot",children:"About node images and verified boot"}),"\n",(0,n.jsxs)(t.p,{children:["Constellation comes with operating system images for Kubernetes control-plane and worker nodes.\nThey're highly optimized for running containerized workloads and specifically prepared for running inside confidential VMs.\nYou can learn more about ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/images",children:"the images"})," and how verified boot ensures their integrity during boot and beyond."]}),"\n",(0,n.jsx)(t.h2,{id:"about-key-management-and-cryptographic-primitives",children:"About key management and cryptographic primitives"}),"\n",(0,n.jsxs)(t.p,{children:["Encryption of data at-rest, in-transit, and in-use is the fundamental building block for confidential computing and Constellation. Learn more about the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys",children:"keys and cryptographic primitives"})," used in Constellation, ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/encrypted-storage",children:"encrypted persistent storage"}),", and ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/networking",children:"network encryption"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"about-observability",children:"About observability"}),"\n",(0,n.jsxs)(t.p,{children:["Observability in Kubernetes refers to the capability to troubleshoot issues using telemetry signals such as logs, metrics, and traces.\nIn the realm of Confidential Computing, it's crucial that observability aligns with confidentiality, necessitating careful implementation.\nLearn more about the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/observability",children:"observability capabilities in Constellation"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/837f4190.ddddc1c3.js b/pr-preview/pr-4027/assets/js/837f4190.ddddc1c3.js deleted file mode 100644 index e2049971b..000000000 --- a/pr-preview/pr-4027/assets/js/837f4190.ddddc1c3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4613],{28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>a});var t=s(96540);const o={},i=t.createContext(o);function r(e){const n=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),t.createElement(i.Provider,{value:n},e.children)}},71800:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"workflows/trusted-launch","title":"Use Azure trusted launch VMs","description":"Constellation also supports trusted launch VMs on Microsoft Azure. Trusted launch VMs don\'t offer the same level of security as Confidential VMs, but are available in more regions and in larger quantities. The main difference between trusted launch VMs and normal VMs is that the former offer vTPM-based remote attestation. When used with trusted launch VMs, Constellation relies on vTPM-based remote attestation to verify nodes.","source":"@site/versioned_docs/version-2.24/workflows/trusted-launch.md","sourceDirName":"workflows","slug":"/workflows/trusted-launch","permalink":"/constellation/pr-preview/pr-4027/workflows/trusted-launch","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/workflows/trusted-launch.md","tags":[],"version":"2.24","frontMatter":{}}');var o=s(74848),i=s(28453);const r={},a="Use Azure trusted launch VMs",l={},c=[{value:"VM images",id:"vm-images",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"use-azure-trusted-launch-vms",children:"Use Azure trusted launch VMs"})}),"\n",(0,o.jsxs)(n.p,{children:["Constellation also supports ",(0,o.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/trusted-launch",children:"trusted launch VMs"})," on Microsoft Azure. Trusted launch VMs don't offer the same level of security as Confidential VMs, but are available in more regions and in larger quantities. The main difference between trusted launch VMs and normal VMs is that the former offer vTPM-based remote attestation. When used with trusted launch VMs, Constellation relies on vTPM-based remote attestation to verify nodes."]}),"\n",(0,o.jsx)(n.admonition,{type:"caution",children:(0,o.jsx)(n.p,{children:"Trusted launch VMs don't provide runtime encryption and don't keep the cloud service provider (CSP) out of your trusted computing base."})}),"\n",(0,o.jsxs)(n.p,{children:["Constellation supports trusted launch VMs with instance types ",(0,o.jsx)(n.code,{children:"Standard_D*_v4"})," and ",(0,o.jsx)(n.code,{children:"Standard_E*_v4"}),". Run ",(0,o.jsx)(n.code,{children:"constellation config instance-types"})," for a list of all supported instance types."]}),"\n",(0,o.jsx)(n.h2,{id:"vm-images",children:"VM images"}),"\n",(0,o.jsxs)(n.p,{children:["Azure currently doesn't support ",(0,o.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/share-gallery-community",children:"community galleries for trusted launch VMs"}),". Thus, you need to manually import the Constellation node image into your cloud subscription."]}),"\n",(0,o.jsxs)(n.p,{children:["The latest image is available at ",(0,o.jsx)(n.code,{children:"https://cdn.confidential.cloud/constellation/images/azure/trusted-launch/v2.2.0/constellation.img"}),". Simply adjust the version number to download a newer version."]}),"\n",(0,o.jsxs)(n.p,{children:["After you've downloaded the image, create a resource group ",(0,o.jsx)(n.code,{children:"constellation-images"})," in your Azure subscription and import the image.\nYou can use a script to do this:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"wget https://raw.githubusercontent.com/edgelesssys/constellation/main/hack/importAzure.sh\nchmod +x importAzure.sh\nAZURE_IMAGE_VERSION=2.2.0 AZURE_RESOURCE_GROUP_NAME=constellation-images AZURE_IMAGE_FILE=./constellation.img ./importAzure.sh\n"})}),"\n",(0,o.jsx)(n.p,{children:"The script creates the following resources:"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["A new image gallery with the default name ",(0,o.jsx)(n.code,{children:"constellation-import"})]}),"\n",(0,o.jsxs)(n.li,{children:["A new image definition with the default name ",(0,o.jsx)(n.code,{children:"constellation"})]}),"\n",(0,o.jsxs)(n.li,{children:["The actual image with the provided version. In this case ",(0,o.jsx)(n.code,{children:"2.2.0"})]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Once the import is completed, use the ",(0,o.jsx)(n.code,{children:"ID"})," of the image version in your ",(0,o.jsx)(n.code,{children:"constellation-conf.yaml"})," for the ",(0,o.jsx)(n.code,{children:"image"})," field. Set ",(0,o.jsx)(n.code,{children:"confidentialVM"})," to ",(0,o.jsx)(n.code,{children:"false"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"Fetch the image measurements:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"IMAGE_VERSION=2.2.0\nURL=https://public-edgeless-constellation.s3.us-east-2.amazonaws.com//communitygalleries/constellationcvm-b3782fa0-0df7-4f2f-963e-fc7fc42663df/images/constellation/versions/$IMAGE_VERSION/measurements.yaml\nconstellation config fetch-measurements -u$URL -s$URL.sig\n"})}),"\n",(0,o.jsxs)(n.admonition,{type:"info",children:[(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/create",children:(0,o.jsx)(n.code,{children:"constellation apply"})})," command will issue a warning because manually imported images aren't recognized as production grade images:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-shell-session",children:"Configured image doesn't look like a released production image. Double check image before deploying to production.\n"})}),(0,o.jsx)(n.p,{children:"Please ignore this warning."})]})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/84353103.8406d97f.js b/pr-preview/pr-4027/assets/js/84353103.8406d97f.js deleted file mode 100644 index 8a7443f7a..000000000 --- a/pr-preview/pr-4027/assets/js/84353103.8406d97f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2908],{28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var r=n(96540);const i={},s=r.createContext(i);function o(e){const t=r.useContext(s);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(s.Provider,{value:t},e.children)}},96428:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"architecture/microservices","title":"Microservices","description":"Constellation takes care of bootstrapping and initializing a Confidential Kubernetes cluster.","source":"@site/versioned_docs/version-2.22/architecture/microservices.md","sourceDirName":"architecture","slug":"/architecture/microservices","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/microservices","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/architecture/microservices.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Versions and support","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/versions"},"next":{"title":"Attestation","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation"}}');var i=n(74848),s=n(28453);const o={},a="Microservices",c={},l=[{value:"Bootstrapper",id:"bootstrapper",level:2},{value:"JoinService",id:"joinservice",level:2},{value:"VerificationService",id:"verificationservice",level:2},{value:"KeyService",id:"keyservice",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",mermaid:"mermaid",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"microservices",children:"Microservices"})}),"\n",(0,i.jsx)(t.p,{children:"Constellation takes care of bootstrapping and initializing a Confidential Kubernetes cluster.\nDuring the lifetime of the cluster, it handles day 2 operations such as key management, remote attestation, and updates.\nThese features are provided by several microservices:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#bootstrapper",children:"Bootstrapper"})," initializes a Constellation node and bootstraps the cluster"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#joinservice",children:"JoinService"})," joins new nodes to an existing cluster"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#verificationservice",children:"VerificationService"})," provides remote attestation functionality"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#keyservice",children:"KeyService"})," manages Constellation-internal keys"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"The relations between microservices are shown in the following diagram:"}),"\n",(0,i.jsx)(t.mermaid,{value:"flowchart LR\n subgraph admin [Admin's machine]\n A[Constellation CLI]\n end\n subgraph img [Constellation OS image]\n B[Constellation OS]\n C[Bootstrapper]\n end\n subgraph Kubernetes\n D[JoinService]\n E[KeyService]\n F[VerificationService]\n end\n A -- deploys --\x3e\n B -- starts --\x3e C\n C -- deploys --\x3e D\n C -- deploys --\x3e E\n C -- deploys --\x3e F"}),"\n",(0,i.jsx)(t.h2,{id:"bootstrapper",children:"Bootstrapper"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"Bootstrapper"})," is the first microservice launched after booting a Constellation node image.\nIt sets up that machine as a Kubernetes node and integrates that node into the Kubernetes cluster.\nTo this end, the ",(0,i.jsx)(t.em,{children:"Bootstrapper"})," first downloads and verifies the ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/overview/components/",children:"Kubernetes components"})," at the configured versions.\nThe ",(0,i.jsx)(t.em,{children:"Bootstrapper"})," tries to find an existing cluster and if successful, communicates with the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#joinservice",children:"JoinService"})," to join the node.\nOtherwise, it waits for an initialization request to create a new Kubernetes cluster."]}),"\n",(0,i.jsx)(t.h2,{id:"joinservice",children:"JoinService"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"JoinService"})," runs as ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/",children:"DaemonSet"})," on each control-plane node.\nNew nodes (at cluster start, or later through autoscaling) send a request to the service over ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#attested-tls-atls",children:"attested TLS (aTLS)"}),".\nThe ",(0,i.jsx)(t.em,{children:"JoinService"})," verifies the new node's certificate and attestation statement.\nIf attestation is successful, the new node is supplied with an encryption key from the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#keyservice",children:(0,i.jsx)(t.em,{children:"KeyService"})})," for its state disk, and a Kubernetes bootstrap token."]}),"\n",(0,i.jsx)(t.mermaid,{value:"sequenceDiagram\n participant New node\n participant JoinService\n New node->>JoinService: aTLS handshake (server side verification)\n JoinService--\x3e>New node: #\n New node->>+JoinService: IssueJoinTicket(DiskUUID, NodeName, IsControlPlane)\n JoinService->>+KeyService: GetDataKey(DiskUUID)\n KeyService--\x3e>-JoinService: DiskEncryptionKey\n JoinService--\x3e>-New node: DiskEncryptionKey, KubernetesJoinToken, ..."}),"\n",(0,i.jsx)(t.h2,{id:"verificationservice",children:"VerificationService"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"VerificationService"})," runs as DaemonSet on each node.\nIt provides user-facing functionality for remote attestation during the cluster's lifetime via an endpoint for ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#cluster-attestation",children:"verifying the cluster"}),".\nRead more about the hardware-based ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation",children:"attestation feature"})," of Constellation and how to ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cluster",children:"verify"})," a cluster on the client side."]}),"\n",(0,i.jsx)(t.h2,{id:"keyservice",children:"KeyService"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"KeyService"})," runs as DaemonSet on each control-plane node.\nIt implements the key management for the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys#storage-encryption",children:"storage encryption keys"})," in Constellation. These keys are used for the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/images#state-disk",children:"state disk"})," of each node and the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage",children:"transparently encrypted storage"})," for Kubernetes.\nDepending on wether the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys#constellation-managed-key-management",children:"constellation-managed"})," or ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys#user-managed-key-management",children:"user-managed"})," mode is used, the ",(0,i.jsx)(t.em,{children:"KeyService"})," holds the key encryption key (KEK) directly or calls an external key management service (KMS) for key derivation respectively."]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/8452cbfd.5b138794.js b/pr-preview/pr-4027/assets/js/8452cbfd.5b138794.js deleted file mode 100644 index eab9bd5c3..000000000 --- a/pr-preview/pr-4027/assets/js/8452cbfd.5b138794.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6851],{11476:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"getting-started/examples","title":"Examples","description":"After you installed the CLI and created your first cluster, you\'re ready to deploy applications. Why not start with one of the following examples?","source":"@site/versioned_docs/version-2.22/getting-started/examples.md","sourceDirName":"getting-started","slug":"/getting-started/examples","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/getting-started/examples.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Cloud Marketplaces","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/marketplaces"},"next":{"title":"Emojivoto","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/emojivoto"}}');var o=n(74848),i=n(28453);const r={},a="Examples",l={},c=[];function p(e){const t={a:"a",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"examples",children:"Examples"})}),"\n",(0,o.jsxs)(t.p,{children:["After you ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/install",children:"installed the CLI"})," and ",(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps",children:"created your first cluster"}),", you're ready to deploy applications. Why not start with one of the following examples?"]}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/emojivoto",children:"Emojivoto"}),": a simple but fun web application"]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/online-boutique",children:"Online Boutique"}),": an e-commerce demo application by Google consisting of 11 separate microservices"]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scaling",children:"Horizontal Pod Autoscaling"}),": an example demonstrating Constellation's autoscaling capabilities"]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var s=n(96540);const o={},i=s.createContext(o);function r(e){const t=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/84de5ccf.ae4c6c22.js b/pr-preview/pr-4027/assets/js/84de5ccf.ae4c6c22.js deleted file mode 100644 index 5ed213e8f..000000000 --- a/pr-preview/pr-4027/assets/js/84de5ccf.ae4c6c22.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1897],{28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>t});var i=s(96540);const l={},r=i.createContext(l);function c(e){const n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:c(e.components),i.createElement(r.Provider,{value:n},e.children)}},91810:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>t,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"getting-started/install","title":"Installation and setup","description":"Constellation runs entirely in your cloud environment and can be controlled via a dedicated command-line interface (CLI) or a Terraform provider.","source":"@site/versioned_docs/version-2.24/getting-started/install.md","sourceDirName":"getting-started","slug":"/getting-started/install","permalink":"/constellation/pr-preview/pr-4027/getting-started/install","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/getting-started/install.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Getting started","permalink":"/constellation/pr-preview/pr-4027/category/getting-started"},"next":{"title":"First steps (cloud)","permalink":"/constellation/pr-preview/pr-4027/getting-started/first-steps"}}');var l=s(74848),r=s(28453);const c={},t="Installation and setup",o={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install the Constellation CLI",id:"install-the-constellation-cli",level:2},{value:"Set up cloud credentials",id:"set-up-cloud-credentials",level:2},{value:"Required permissions",id:"required-permissions",level:3},{value:"Authentication",id:"authentication",level:3},{value:"Next steps",id:"next-steps",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components},{TabItem:s,Tabs:i}=n;return s||u("TabItem",!0),i||u("Tabs",!0),(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"installation-and-setup",children:"Installation and setup"})}),"\n",(0,l.jsxs)(n.p,{children:["Constellation runs entirely in your cloud environment and can be controlled via a dedicated ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/reference/cli",children:"command-line interface (CLI)"})," or a ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/terraform-provider",children:"Terraform provider"}),"."]}),"\n",(0,l.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,l.jsx)(n.p,{children:"Make sure the following requirements are met:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Your machine is running Linux, macOS, or Windows"}),"\n",(0,l.jsx)(n.li,{children:"You have admin rights on your machine"}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/tools/",children:"kubectl"})," is installed"]}),"\n",(0,l.jsx)(n.li,{children:"Your CSP is Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), or STACKIT"}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"install-the-constellation-cli",children:"Install the Constellation CLI"}),"\n",(0,l.jsx)(n.admonition,{type:"tip",children:(0,l.jsxs)(n.p,{children:["If you prefer to use Terraform, you can alternatively use the ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/terraform-provider",children:"Terraform provider"})," to manage the cluster's lifecycle."]})}),"\n",(0,l.jsxs)(n.p,{children:["The CLI executable is available at ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub"}),".\nInstall it with the following commands:"]}),"\n",(0,l.jsxs)(i,{children:[(0,l.jsxs)(s,{value:"linux-amd64",label:"Linux (amd64)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-amd64\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Install the CLI to your PATH:"}),"\n"]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo install constellation-linux-amd64 /usr/local/bin/constellation\n"})})]}),(0,l.jsxs)(s,{value:"linux-arm64",label:"Linux (arm64)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-arm64\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Install the CLI to your PATH:"}),"\n"]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo install constellation-linux-arm64 /usr/local/bin/constellation\n"})})]}),(0,l.jsxs)(s,{value:"darwin-arm64",label:"macOS (Apple Silicon)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-darwin-arm64\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Install the CLI to your PATH:"}),"\n"]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo install constellation-darwin-arm64 /usr/local/bin/constellation\n"})})]}),(0,l.jsxs)(s,{value:"darwin-amd64",label:"macOS (Intel)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-darwin-amd64\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Install the CLI to your PATH:"}),"\n"]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo install constellation-darwin-amd64 /usr/local/bin/constellation\n"})})]}),(0,l.jsxs)(s,{value:"windows-amd64",label:"Windows (amd64)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"Invoke-WebRequest -OutFile ./constellation.exe -Uri 'https://github.com/edgelesssys/constellation/releases/latest/download/constellation-windows-amd64.exe'\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Install the CLI under ",(0,l.jsx)(n.code,{children:"C:\\Program Files\\Constellation\\bin\\constellation.exe"})]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Add the CLI to your PATH:"}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["Open ",(0,l.jsx)(n.code,{children:"Advanced system settings"})," by searching for the App in the Windows search"]}),"\n",(0,l.jsxs)(n.li,{children:["Go to the ",(0,l.jsx)(n.code,{children:"Advanced"})," tab"]}),"\n",(0,l.jsxs)(n.li,{children:["Click ",(0,l.jsx)(n.code,{children:"Environment Variables\u2026"})]}),"\n",(0,l.jsxs)(n.li,{children:["Click variable called ",(0,l.jsx)(n.code,{children:"Path"})," and click ",(0,l.jsx)(n.code,{children:"Edit\u2026"})]}),"\n",(0,l.jsxs)(n.li,{children:["Click ",(0,l.jsx)(n.code,{children:"New"})]}),"\n",(0,l.jsxs)(n.li,{children:["Enter the path to the folder containing the binary you want on your PATH: ",(0,l.jsx)(n.code,{children:"C:\\Program Files\\Constellation\\bin"})]}),"\n"]}),"\n"]}),"\n"]})]})]}),"\n",(0,l.jsx)(n.admonition,{type:"tip",children:(0,l.jsxs)(n.p,{children:["The CLI supports autocompletion for various shells. To set it up, run ",(0,l.jsx)(n.code,{children:"constellation completion"})," and follow the given steps."]})}),"\n",(0,l.jsx)(n.h2,{id:"set-up-cloud-credentials",children:"Set up cloud credentials"}),"\n",(0,l.jsx)(n.p,{children:"Constellation makes authenticated calls to the CSP API. Therefore, you need to set up Constellation with the credentials for your CSP."}),"\n",(0,l.jsx)(n.admonition,{type:"tip",children:(0,l.jsxs)(n.p,{children:["If you don't have a cloud subscription, you can also set up a ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/getting-started/first-steps-local",children:"local Constellation cluster using virtualization"})," for testing."]})}),"\n",(0,l.jsx)(n.h3,{id:"required-permissions",children:"Required permissions"}),"\n",(0,l.jsxs)(i,{groupId:"csp",children:[(0,l.jsxs)(s,{value:"aws",label:"AWS",children:[(0,l.jsx)(n.p,{children:"To set up a Constellation cluster, you need to perform two tasks that require permissions: create the infrastructure and create roles for cluster nodes. Both of these actions can be performed by different users, e.g., an administrator to create roles and a DevOps engineer to create the infrastructure."}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/config#creating-an-iam-configuration",children:"create the IAM configuration"})," for Constellation, you need the following permissions:"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-json",children:'{\n "Version": "2012-10-17",\n "Statement": [\n {\n "Effect": "Allow",\n "Action": [\n "ec2:DescribeAccountAttributes",\n "iam:AddRoleToInstanceProfile",\n "iam:AttachRolePolicy",\n "iam:CreateInstanceProfile",\n "iam:CreatePolicy",\n "iam:CreateRole",\n "iam:DeleteInstanceProfile",\n "iam:DeletePolicy",\n "iam:DeletePolicyVersion",\n "iam:DeleteRole",\n "iam:DetachRolePolicy",\n "iam:GetInstanceProfile",\n "iam:GetPolicy",\n "iam:GetPolicyVersion",\n "iam:GetRole",\n "iam:ListAttachedRolePolicies",\n "iam:ListInstanceProfilesForRole",\n "iam:ListPolicyVersions",\n "iam:ListRolePolicies",\n "iam:PassRole",\n "iam:RemoveRoleFromInstanceProfile",\n "sts:GetCallerIdentity"\n ],\n "Resource": "*"\n }\n ]\n}\n'})}),(0,l.jsxs)(n.p,{children:["The built-in ",(0,l.jsx)(n.code,{children:"AdministratorAccess"})," policy is a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/create",children:"create a Constellation cluster"}),", see the permissions of ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/blob/main/terraform/infrastructure/iam/aws/main.tf",children:"main.tf"}),"."]}),(0,l.jsxs)(n.p,{children:["The built-in ",(0,l.jsx)(n.code,{children:"PowerUserAccess"})," policy is a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["Follow Amazon's guide on ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html",children:"understanding"})," and ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html",children:"managing policies"}),"."]})]}),(0,l.jsxs)(s,{value:"azure",label:"Azure",children:[(0,l.jsxs)(n.p,{children:["The following ",(0,l.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/resource-providers-and-types#register-resource-provider",children:"resource providers need to be registered"})," in your subscription:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Attestation"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Compute"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Insights"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.ManagedIdentity"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network"})}),"\n"]}),(0,l.jsx)(n.p,{children:"By default, Constellation tries to register these automatically if they haven't been registered before."}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/config#creating-an-iam-configuration",children:"create the IAM configuration"})," for Constellation, you need the following permissions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"*/register/action"})," [1]"]}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Authorization/roleAssignments/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Authorization/roleDefinitions/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.ManagedIdentity/userAssignedIdentities/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Resources/subscriptions/resourcegroups/*"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["The built-in ",(0,l.jsx)(n.code,{children:"Owner"})," role is a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/create",children:"create a Constellation cluster"}),", you need the following permissions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Attestation/attestationProviders/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Compute/virtualMachineScaleSets/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Insights/components/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.ManagedIdentity/userAssignedIdentities/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/loadBalancers/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/loadBalancers/backendAddressPools/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/networkSecurityGroups/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/publicIPAddresses/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/virtualNetworks/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/virtualNetworks/subnets/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/natGateways/*"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["The built-in ",(0,l.jsx)(n.code,{children:"Contributor"})," role is a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["Follow Microsoft's guide on ",(0,l.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/role-based-access-control/role-definitions",children:"understanding"})," and ",(0,l.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments",children:"assigning roles"}),"."]}),(0,l.jsxs)(n.p,{children:["1: You can omit ",(0,l.jsx)(n.code,{children:"*/register/Action"})," if the resource providers mentioned above are already registered and the ",(0,l.jsx)(n.code,{children:"ARM_SKIP_PROVIDER_REGISTRATION"})," environment variable is set to ",(0,l.jsx)(n.code,{children:"true"})," when creating the IAM configuration."]})]}),(0,l.jsxs)(s,{value:"gcp",label:"GCP",children:[(0,l.jsxs)(n.p,{children:["Create a new project for Constellation or use an existing one.\nEnable the ",(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/apis/library/compute.googleapis.com",children:"Compute Engine API"})," on it."]}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/config#creating-an-iam-configuration",children:"create the IAM configuration"})," for Constellation, you need the following permissions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.roles.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.roles.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.roles.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccountKeys.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccountKeys.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccountKeys.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccounts.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccounts.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccounts.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"resourcemanager.projects.getIamPolicy"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"resourcemanager.projects.setIamPolicy"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["Together, the built-in roles ",(0,l.jsx)(n.code,{children:"roles/editor"})," and ",(0,l.jsx)(n.code,{children:"roles/resourcemanager.projectIamAdmin"})," form a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/create",children:"create a Constellation cluster"}),", you need the following permissions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.addresses.createInternal"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.addresses.deleteInternal"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.addresses.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.addresses.useInternal"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.backendServices.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.backendServices.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.backendServices.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.backendServices.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.disks.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.firewalls.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.firewalls.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.firewalls.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.firewalls.update"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.forwardingRules.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.forwardingRules.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.forwardingRules.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.forwardingRules.setLabels"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.forwardingRules.list"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalAddresses.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalAddresses.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalAddresses.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalAddresses.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalForwardingRules.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalForwardingRules.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalForwardingRules.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalForwardingRules.setLabels"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalOperations.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.healthChecks.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.healthChecks.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.healthChecks.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.healthChecks.useReadOnly"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroupManagers.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroupManagers.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroupManagers.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroupManagers.update"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.update"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instances.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instances.setLabels"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instances.setMetadata"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instances.setTags"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceTemplates.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceTemplates.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceTemplates.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceTemplates.useReadOnly"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.networks.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.networks.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.networks.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.networks.updatePolicy"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.routers.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.routers.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.routers.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.routers.update"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.subnetworks.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.subnetworks.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.subnetworks.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.subnetworks.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.targetTcpProxies.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.targetTcpProxies.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.targetTcpProxies.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.targetTcpProxies.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccounts.actAs"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["Together, the built-in roles ",(0,l.jsx)(n.code,{children:"roles/editor"}),", ",(0,l.jsx)(n.code,{children:"roles/compute.instanceAdmin"})," and ",(0,l.jsx)(n.code,{children:"roles/resourcemanager.projectIamAdmin"})," form a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["Follow Google's guide on ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/iam/docs/understanding-roles",children:"understanding"})," and ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/iam/docs/granting-changing-revoking-access",children:"assigning roles"}),"."]})]}),(0,l.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,l.jsxs)(n.p,{children:["Constellation on STACKIT requires a User Access Token (UAT) for the OpenStack API and a STACKIT service account.\nThe UAT already has all required permissions by default.\nThe STACKIT service account needs the ",(0,l.jsx)(n.code,{children:"editor"})," role to create STACKIT LoadBalancers.\nLook at the ",(0,l.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/getting-started-in-service-accounts-134415831.html",children:"STACKIT documentation"})," on how to create the service account and assign the role."]})})]}),"\n",(0,l.jsx)(n.h3,{id:"authentication",children:"Authentication"}),"\n",(0,l.jsxs)(n.p,{children:["You need to authenticate with your CSP. The following lists the required steps for ",(0,l.jsx)(n.em,{children:"testing"})," and ",(0,l.jsx)(n.em,{children:"production"})," environments."]}),"\n",(0,l.jsx)(n.admonition,{type:"note",children:(0,l.jsxs)(n.p,{children:["The steps for a ",(0,l.jsx)(n.em,{children:"testing"})," environment are simpler. However, they may expose secrets to the CSP. If in doubt, follow the ",(0,l.jsx)(n.em,{children:"production"})," steps."]})}),"\n",(0,l.jsxs)(i,{groupId:"csp",children:[(0,l.jsxs)(s,{value:"aws",label:"AWS",children:[(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Testing"})}),(0,l.jsxs)(n.p,{children:["You can use the ",(0,l.jsx)(n.a,{href:"https://console.aws.amazon.com/cloudshell/home",children:"AWS CloudShell"}),". Make sure you are ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/cloudshell/latest/userguide/sec-auth-with-identities.html",children:"authorized to use it"}),"."]}),(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Production"})}),(0,l.jsxs)(n.p,{children:["Use the latest version of the ",(0,l.jsx)(n.a,{href:"https://aws.amazon.com/cli/",children:"AWS CLI"})," on a trusted machine:"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"aws configure\n"})}),(0,l.jsxs)(n.p,{children:["Options and first steps are described in the ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/cli/index.html",children:"AWS CLI documentation"}),"."]})]}),(0,l.jsxs)(s,{value:"azure",label:"Azure",children:[(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Testing"})}),(0,l.jsxs)(n.p,{children:["Simply open the ",(0,l.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/cloud-shell/overview",children:"Azure Cloud Shell"}),"."]}),(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Production"})}),(0,l.jsxs)(n.p,{children:["Use the latest version of the ",(0,l.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/",children:"Azure CLI"})," on a trusted machine:"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"az login\n"})}),(0,l.jsxs)(n.p,{children:["Other options are described in Azure's ",(0,l.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli",children:"authentication guide"}),"."]})]}),(0,l.jsxs)(s,{value:"gcp",label:"GCP",children:[(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Testing"})}),(0,l.jsxs)(n.p,{children:["You can use the ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/shell",children:"Google Cloud Shell"}),". Make sure your ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/shell/docs/auth",children:"session is authorized"}),". For example, execute ",(0,l.jsx)(n.code,{children:"gsutil"})," and accept the authorization prompt."]}),(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Production"})}),(0,l.jsx)(n.p,{children:"Use one of the following options on a trusted machine:"}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Use the ",(0,l.jsxs)(n.a,{href:"https://cloud.google.com/sdk/gcloud",children:[(0,l.jsx)(n.code,{children:"gcloud"})," CLI"]})]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"gcloud auth application-default login\n"})}),"\n",(0,l.jsx)(n.p,{children:"This will ask you to log-in to your Google account and create your credentials.\nThe Constellation CLI will automatically load these credentials when needed."}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Set up a service account and pass the credentials manually"}),"\n",(0,l.jsxs)(n.p,{children:["Follow ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/docs/authentication/production#manually",children:"Google's guide"})," for setting up your credentials."]}),"\n"]}),"\n"]})]}),(0,l.jsxs)(s,{value:"stackit",label:"STACKIT",children:[(0,l.jsx)(n.p,{children:"You need to authenticate with the infrastructure API (OpenStack) and create a service account (STACKIT API)."}),(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/step-1-generating-of-user-access-token-11763726.html",children:"Follow the STACKIT documentation"})," for obtaining a User Access Token (UAT) to use the infrastructure API"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Create a configuration file with the credentials from the User Access Token under:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Linux: ",(0,l.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})]}),"\n",(0,l.jsxs)(n.li,{children:["macOS: ",(0,l.jsx)(n.code,{children:"/Users/<user>/Library/Application Support/openstack/clouds.yaml"})," or ",(0,l.jsx)(n.code,{children:"/etc/openstack/clouds.yaml"})]}),"\n",(0,l.jsxs)(n.li,{children:["Windows: ",(0,l.jsx)(n.code,{children:"%AppData%\\openstack\\clouds.yaml"})]}),"\n"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",children:"clouds:\n stackit:\n auth:\n auth_url: https://keystone.api.iaas.eu01.stackit.cloud/v3\n username: REPLACE_WITH_UAT_USERNAME\n password: REPLACE_WITH_UAT_PASSWORD\n project_id: REPLACE_WITH_OPENSTACK_PROJECT_ID\n project_name: REPLACE_WITH_STACKIT_PROJECT_NAME\n user_domain_name: portal_mvp\n project_domain_name: portal_mvp\n region_name: RegionOne\n identity_api_version: 3\n"})}),"\n"]}),"\n"]}),(0,l.jsx)(n.admonition,{type:"caution",children:(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:"project_id"})," refers to the ID of your OpenStack project. The STACKIT portal also shows the STACKIT ID that's associated with your project in some places. Make sure you insert the OpenStack project ID in the ",(0,l.jsx)(n.code,{children:"clouds.yaml"})," file."]})}),(0,l.jsxs)(n.ol,{start:"3",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/getting-started-in-service-accounts-134415831.html",children:"Follow the STACKIT documentation"})," for creating a service account and an access token"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Assign the ",(0,l.jsx)(n.code,{children:"editor"})," role to the service account by ",(0,l.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/getting-started-in-service-accounts-134415831.html",children:"following the documentation"})]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Create a configuration file under ",(0,l.jsx)(n.code,{children:"~/.stackit/credentials.json"})," (",(0,l.jsx)(n.code,{children:"%USERPROFILE%\\.stackit\\credentials.json"})," on Windows)"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-json",children:'{"STACKIT_SERVICE_ACCOUNT_TOKEN":"REPLACE_WITH_TOKEN"}\n'})}),"\n"]}),"\n"]})]})]}),"\n",(0,l.jsx)(n.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,l.jsxs)(n.p,{children:["You are now ready to ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/getting-started/first-steps",children:"deploy your first confidential Kubernetes cluster and application"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(a,{...e})}):a(e)}function u(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/8565.6b3d8208.js b/pr-preview/pr-4027/assets/js/8565.6b3d8208.js deleted file mode 100644 index e40931949..000000000 --- a/pr-preview/pr-4027/assets/js/8565.6b3d8208.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8565],{21152:(t,e,n)=>{n.d(e,{P:()=>o});var i=n(67633),s=n(40797),o=(0,s.K2)((t,e,n,o)=>{t.attr("class",n);const{width:c,height:h,x:l,y:d}=r(t,e);(0,i.a$)(t,h,c,o);const g=a(l,d,c,h,e);t.attr("viewBox",g),s.Rm.debug(`viewBox configured: ${g} with padding: ${e}`)},"setupViewPortForSVG"),r=(0,s.K2)((t,e)=>{const n=t.node()?.getBBox()||{width:0,height:0,x:0,y:0};return{width:n.width+2*e,height:n.height+2*e,x:n.x,y:n.y}},"calculateDimensionsWithPadding"),a=(0,s.K2)((t,e,n,i,s)=>`${t-s} ${e-s} ${n} ${i}`,"createViewBox")},78565:(t,e,n)=>{n.d(e,{diagram:()=>D});var i=n(89625),s=n(21152),o=n(10045),r=(n(5164),n(28698),n(5894),n(63245),n(32387),n(30092),n(13226),n(67633)),a=n(40797);const c={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};let h;const l=new Uint8Array(16);const d=[];for(let L=0;L<256;++L)d.push((L+256).toString(16).slice(1));function g(t,e=0){return(d[t[e+0]]+d[t[e+1]]+d[t[e+2]]+d[t[e+3]]+"-"+d[t[e+4]]+d[t[e+5]]+"-"+d[t[e+6]]+d[t[e+7]]+"-"+d[t[e+8]]+d[t[e+9]]+"-"+d[t[e+10]]+d[t[e+11]]+d[t[e+12]]+d[t[e+13]]+d[t[e+14]]+d[t[e+15]]).toLowerCase()}const u=function(t,e,n){if(c.randomUUID&&!e&&!t)return c.randomUUID();const i=(t=t||{}).random??t.rng?.()??function(){if(!h){if("undefined"==typeof crypto||!crypto.getRandomValues)throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");h=crypto.getRandomValues.bind(crypto)}return h(l)}();if(i.length<16)throw new Error("Random bytes length must be >= 16");if(i[6]=15&i[6]|64,i[8]=63&i[8]|128,e){if((n=n||0)<0||n+16>e.length)throw new RangeError(`UUID byte range ${n}:${n+15} is out of buffer bounds`);for(let t=0;t<16;++t)e[n+t]=i[t];return e}return g(i)};var p=n(3219),y=n(78041),m=n(75263),f=function(){var t=(0,a.K2)(function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},"o"),e=[1,4],n=[1,13],i=[1,12],s=[1,15],o=[1,16],r=[1,20],c=[1,19],h=[6,7,8],l=[1,26],d=[1,24],g=[1,25],u=[6,7,11],p=[1,6,13,15,16,19,22],y=[1,33],m=[1,34],f=[1,6,7,11,13,15,16,19,22],b={trace:(0,a.K2)(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,MINDMAP:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,ICON:15,CLASS:16,nodeWithId:17,nodeWithoutId:18,NODE_DSTART:19,NODE_DESCR:20,NODE_DEND:21,NODE_ID:22,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"MINDMAP",11:"EOF",13:"SPACELIST",15:"ICON",16:"CLASS",19:"NODE_DSTART",20:"NODE_DESCR",21:"NODE_DEND",22:"NODE_ID"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,2],[12,2],[12,2],[12,1],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[18,3],[17,1],[17,4]],performAction:(0,a.K2)(function(t,e,n,i,s,o,r){var a=o.length-1;switch(s){case 6:case 7:return i;case 8:i.getLogger().trace("Stop NL ");break;case 9:i.getLogger().trace("Stop EOF ");break;case 11:i.getLogger().trace("Stop NL2 ");break;case 12:i.getLogger().trace("Stop EOF2 ");break;case 15:i.getLogger().info("Node: ",o[a].id),i.addNode(o[a-1].length,o[a].id,o[a].descr,o[a].type);break;case 16:i.getLogger().trace("Icon: ",o[a]),i.decorateNode({icon:o[a]});break;case 17:case 21:i.decorateNode({class:o[a]});break;case 18:i.getLogger().trace("SPACELIST");break;case 19:i.getLogger().trace("Node: ",o[a].id),i.addNode(0,o[a].id,o[a].descr,o[a].type);break;case 20:i.decorateNode({icon:o[a]});break;case 25:i.getLogger().trace("node found ..",o[a-2]),this.$={id:o[a-1],descr:o[a-1],type:i.getType(o[a-2],o[a])};break;case 26:this.$={id:o[a],descr:o[a],type:i.nodeType.DEFAULT};break;case 27:i.getLogger().trace("node found ..",o[a-3]),this.$={id:o[a-3],descr:o[a-1],type:i.getType(o[a-2],o[a])}}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:e},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:e},{6:n,7:[1,10],9:9,12:11,13:i,14:14,15:s,16:o,17:17,18:18,19:r,22:c},t(h,[2,3]),{1:[2,2]},t(h,[2,4]),t(h,[2,5]),{1:[2,6],6:n,12:21,13:i,14:14,15:s,16:o,17:17,18:18,19:r,22:c},{6:n,9:22,12:11,13:i,14:14,15:s,16:o,17:17,18:18,19:r,22:c},{6:l,7:d,10:23,11:g},t(u,[2,22],{17:17,18:18,14:27,15:[1,28],16:[1,29],19:r,22:c}),t(u,[2,18]),t(u,[2,19]),t(u,[2,20]),t(u,[2,21]),t(u,[2,23]),t(u,[2,24]),t(u,[2,26],{19:[1,30]}),{20:[1,31]},{6:l,7:d,10:32,11:g},{1:[2,7],6:n,12:21,13:i,14:14,15:s,16:o,17:17,18:18,19:r,22:c},t(p,[2,14],{7:y,11:m}),t(f,[2,8]),t(f,[2,9]),t(f,[2,10]),t(u,[2,15]),t(u,[2,16]),t(u,[2,17]),{20:[1,35]},{21:[1,36]},t(p,[2,13],{7:y,11:m}),t(f,[2,11]),t(f,[2,12]),{21:[1,37]},t(u,[2,25]),t(u,[2,27])],defaultActions:{2:[2,1],6:[2,2]},parseError:(0,a.K2)(function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},"parseError"),parse:(0,a.K2)(function(t){var e=this,n=[0],i=[],s=[null],o=[],r=this.table,c="",h=0,l=0,d=0,g=o.slice.call(arguments,1),u=Object.create(this.lexer),p={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(p.yy[y]=this.yy[y]);u.setInput(t,p.yy),p.yy.lexer=u,p.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var m=u.yylloc;o.push(m);var f=u.options&&u.options.ranges;function b(){var t;return"number"!=typeof(t=i.pop()||u.lex()||1)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,a.K2)(function(t){n.length=n.length-2*t,s.length=s.length-t,o.length=o.length-t},"popStack"),(0,a.K2)(b,"lex");for(var _,E,S,N,k,D,L,x,I,v={};;){if(S=n[n.length-1],this.defaultActions[S]?N=this.defaultActions[S]:(null==_&&(_=b()),N=r[S]&&r[S][_]),void 0===N||!N.length||!N[0]){var T="";for(D in I=[],r[S])this.terminals_[D]&&D>2&&I.push("'"+this.terminals_[D]+"'");T=u.showPosition?"Parse error on line "+(h+1)+":\n"+u.showPosition()+"\nExpecting "+I.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(h+1)+": Unexpected "+(1==_?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(T,{text:u.match,token:this.terminals_[_]||_,line:u.yylineno,loc:m,expected:I})}if(N[0]instanceof Array&&N.length>1)throw new Error("Parse Error: multiple actions possible at state: "+S+", token: "+_);switch(N[0]){case 1:n.push(_),s.push(u.yytext),o.push(u.yylloc),n.push(N[1]),_=null,E?(_=E,E=null):(l=u.yyleng,c=u.yytext,h=u.yylineno,m=u.yylloc,d>0&&d--);break;case 2:if(L=this.productions_[N[1]][1],v.$=s[s.length-L],v._$={first_line:o[o.length-(L||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(L||1)].first_column,last_column:o[o.length-1].last_column},f&&(v._$.range=[o[o.length-(L||1)].range[0],o[o.length-1].range[1]]),void 0!==(k=this.performAction.apply(v,[c,l,h,p.yy,N[1],s,o].concat(g))))return k;L&&(n=n.slice(0,-1*L*2),s=s.slice(0,-1*L),o=o.slice(0,-1*L)),n.push(this.productions_[N[1]][0]),s.push(v.$),o.push(v._$),x=r[n[n.length-2]][n[n.length-1]],n.push(x);break;case 3:return!0}}return!0},"parse")},_=function(){return{EOF:1,parseError:(0,a.K2)(function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},"parseError"),setInput:(0,a.K2)(function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:(0,a.K2)(function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},"input"),unput:(0,a.K2)(function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},"unput"),more:(0,a.K2)(function(){return this._more=!0,this},"more"),reject:(0,a.K2)(function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"reject"),less:(0,a.K2)(function(t){this.unput(this.match.slice(t))},"less"),pastInput:(0,a.K2)(function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:(0,a.K2)(function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:(0,a.K2)(function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},"showPosition"),test_match:(0,a.K2)(function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var o in s)this[o]=s[o];return!1}return!1},"test_match"),next:(0,a.K2)(function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),o=0;o<s.length;o++)if((n=this._input.match(this.rules[s[o]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=o,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[o])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:(0,a.K2)(function(){var t=this.next();return t||this.lex()},"lex"),begin:(0,a.K2)(function(t){this.conditionStack.push(t)},"begin"),popState:(0,a.K2)(function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:(0,a.K2)(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:(0,a.K2)(function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},"topState"),pushState:(0,a.K2)(function(t){this.begin(t)},"pushState"),stateStackSize:(0,a.K2)(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,a.K2)(function(t,e,n,i){switch(n){case 0:return t.getLogger().trace("Found comment",e.yytext),6;case 1:return 8;case 2:this.begin("CLASS");break;case 3:return this.popState(),16;case 4:case 23:case 26:this.popState();break;case 5:t.getLogger().trace("Begin icon"),this.begin("ICON");break;case 6:return t.getLogger().trace("SPACELINE"),6;case 7:return 7;case 8:return 15;case 9:t.getLogger().trace("end icon"),this.popState();break;case 10:return t.getLogger().trace("Exploding node"),this.begin("NODE"),19;case 11:return t.getLogger().trace("Cloud"),this.begin("NODE"),19;case 12:return t.getLogger().trace("Explosion Bang"),this.begin("NODE"),19;case 13:return t.getLogger().trace("Cloud Bang"),this.begin("NODE"),19;case 14:case 15:case 16:case 17:return this.begin("NODE"),19;case 18:return 13;case 19:return 22;case 20:return 11;case 21:this.begin("NSTR2");break;case 22:return"NODE_DESCR";case 24:t.getLogger().trace("Starting NSTR"),this.begin("NSTR");break;case 25:return t.getLogger().trace("description:",e.yytext),"NODE_DESCR";case 27:return this.popState(),t.getLogger().trace("node end ))"),"NODE_DEND";case 28:return this.popState(),t.getLogger().trace("node end )"),"NODE_DEND";case 29:return this.popState(),t.getLogger().trace("node end ...",e.yytext),"NODE_DEND";case 30:case 33:case 34:return this.popState(),t.getLogger().trace("node end (("),"NODE_DEND";case 31:case 32:return this.popState(),t.getLogger().trace("node end (-"),"NODE_DEND";case 35:case 36:return t.getLogger().trace("Long description:",e.yytext),20}},"anonymous"),rules:[/^(?:\s*%%.*)/i,/^(?:mindmap\b)/i,/^(?::::)/i,/^(?:.+)/i,/^(?:\n)/i,/^(?:::icon\()/i,/^(?:[\s]+[\n])/i,/^(?:[\n]+)/i,/^(?:[^\)]+)/i,/^(?:\))/i,/^(?:-\))/i,/^(?:\(-)/i,/^(?:\)\))/i,/^(?:\))/i,/^(?:\(\()/i,/^(?:\{\{)/i,/^(?:\()/i,/^(?:\[)/i,/^(?:[\s]+)/i,/^(?:[^\(\[\n\)\{\}]+)/i,/^(?:$)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:[^"]+)/i,/^(?:["])/i,/^(?:[\)]\))/i,/^(?:[\)])/i,/^(?:[\]])/i,/^(?:\}\})/i,/^(?:\(-)/i,/^(?:-\))/i,/^(?:\(\()/i,/^(?:\()/i,/^(?:[^\)\]\(\}]+)/i,/^(?:.+(?!\(\())/i],conditions:{CLASS:{rules:[3,4],inclusive:!1},ICON:{rules:[8,9],inclusive:!1},NSTR2:{rules:[22,23],inclusive:!1},NSTR:{rules:[25,26],inclusive:!1},NODE:{rules:[21,24,27,28,29,30,31,32,33,34,35,36],inclusive:!1},INITIAL:{rules:[0,1,2,5,6,7,10,11,12,13,14,15,16,17,18,19,20],inclusive:!0}}}}();function E(){this.yy={}}return b.lexer=_,(0,a.K2)(E,"Parser"),E.prototype=b,b.Parser=E,new E}();f.parser=f;var b=f,_={DEFAULT:0,NO_BORDER:0,ROUNDED_RECT:1,RECT:2,CIRCLE:3,CLOUD:4,BANG:5,HEXAGON:6},E=class{constructor(){this.nodes=[],this.count=0,this.elements={},this.getLogger=this.getLogger.bind(this),this.nodeType=_,this.clear(),this.getType=this.getType.bind(this),this.getElementById=this.getElementById.bind(this),this.getParent=this.getParent.bind(this),this.getMindmap=this.getMindmap.bind(this),this.addNode=this.addNode.bind(this),this.decorateNode=this.decorateNode.bind(this)}static{(0,a.K2)(this,"MindmapDB")}clear(){this.nodes=[],this.count=0,this.elements={},this.baseLevel=void 0}getParent(t){for(let e=this.nodes.length-1;e>=0;e--)if(this.nodes[e].level<t)return this.nodes[e];return null}getMindmap(){return this.nodes.length>0?this.nodes[0]:null}addNode(t,e,n,i){a.Rm.info("addNode",t,e,n,i);let s=!1;0===this.nodes.length?(this.baseLevel=t,t=0,s=!0):void 0!==this.baseLevel&&(t-=this.baseLevel,s=!1);const o=(0,r.D7)();let c=o.mindmap?.padding??r.UI.mindmap.padding;switch(i){case this.nodeType.ROUNDED_RECT:case this.nodeType.RECT:case this.nodeType.HEXAGON:c*=2}const h={id:this.count++,nodeId:(0,r.jZ)(e,o),level:t,descr:(0,r.jZ)(n,o),type:i,children:[],width:o.mindmap?.maxNodeWidth??r.UI.mindmap.maxNodeWidth,padding:c,isRoot:s},l=this.getParent(t);if(l)l.children.push(h),this.nodes.push(h);else{if(!s)throw new Error(`There can be only one root. No parent could be found for ("${h.descr}")`);this.nodes.push(h)}}getType(t,e){switch(a.Rm.debug("In get type",t,e),t){case"[":return this.nodeType.RECT;case"(":return")"===e?this.nodeType.ROUNDED_RECT:this.nodeType.CLOUD;case"((":return this.nodeType.CIRCLE;case")":return this.nodeType.CLOUD;case"))":return this.nodeType.BANG;case"{{":return this.nodeType.HEXAGON;default:return this.nodeType.DEFAULT}}setElementForId(t,e){this.elements[t]=e}getElementById(t){return this.elements[t]}decorateNode(t){if(!t)return;const e=(0,r.D7)(),n=this.nodes[this.nodes.length-1];t.icon&&(n.icon=(0,r.jZ)(t.icon,e)),t.class&&(n.class=(0,r.jZ)(t.class,e))}type2Str(t){switch(t){case this.nodeType.DEFAULT:return"no-border";case this.nodeType.RECT:return"rect";case this.nodeType.ROUNDED_RECT:return"rounded-rect";case this.nodeType.CIRCLE:return"circle";case this.nodeType.CLOUD:return"cloud";case this.nodeType.BANG:return"bang";case this.nodeType.HEXAGON:return"hexgon";default:return"no-border"}}assignSections(t,e){if(0===t.level?t.section=void 0:t.section=e,t.children)for(const[n,i]of t.children.entries()){const s=0===t.level?n:e;this.assignSections(i,s)}}flattenNodes(t,e){const n=["mindmap-node"];!0===t.isRoot?n.push("section-root","section--1"):void 0!==t.section&&n.push(`section-${t.section}`),t.class&&n.push(t.class);const i=n.join(" "),s=(0,a.K2)(t=>{switch(t){case _.CIRCLE:return"mindmapCircle";case _.RECT:return"rect";case _.ROUNDED_RECT:return"rounded";case _.CLOUD:return"cloud";case _.BANG:return"bang";case _.HEXAGON:return"hexagon";case _.DEFAULT:return"defaultMindmapNode";default:return"rect"}},"getShapeFromType"),o={id:t.id.toString(),domId:"node_"+t.id.toString(),label:t.descr,isGroup:!1,shape:s(t.type),width:t.width,height:t.height??0,padding:t.padding,cssClasses:i,cssStyles:[],look:"default",icon:t.icon,x:t.x,y:t.y,level:t.level,nodeId:t.nodeId,type:t.type,section:t.section};if(e.push(o),t.children)for(const r of t.children)this.flattenNodes(r,e)}generateEdges(t,e){if(t.children)for(const n of t.children){let i="edge";void 0!==n.section&&(i+=` section-edge-${n.section}`);i+=` edge-depth-${t.level+1}`;const s={id:`edge_${t.id}_${n.id}`,start:t.id.toString(),end:n.id.toString(),type:"normal",curve:"basis",thickness:"normal",look:"default",classes:i,depth:t.level,section:n.section};e.push(s),this.generateEdges(n,e)}}getData(){const t=this.getMindmap(),e=(0,r.D7)(),n=e;if(void 0!==(0,r.TM)().layout||(n.layout="cose-bilkent"),!t)return{nodes:[],edges:[],config:n};a.Rm.debug("getData: mindmapRoot",t,e),this.assignSections(t);const i=[],s=[];this.flattenNodes(t,i),this.generateEdges(t,s),a.Rm.debug(`getData: processed ${i.length} nodes and ${s.length} edges`);const o=new Map;for(const r of i)o.set(r.id,{shape:r.shape,width:r.width,height:r.height,padding:r.padding});return{nodes:i,edges:s,config:n,rootNode:t,markers:["point"],direction:"TB",nodeSpacing:50,rankSpacing:50,shapes:Object.fromEntries(o),type:"mindmap",diagramId:"mindmap-"+u()}}getLogger(){return a.Rm}},S={draw:(0,a.K2)(async(t,e,n,c)=>{a.Rm.debug("Rendering mindmap diagram\n"+t);const h=c.db,l=h.getData(),d=(0,i.A)(e,l.config.securityLevel);l.type=c.type,l.layoutAlgorithm=(0,o.q7)(l.config.layout,{fallback:"cose-bilkent"}),l.diagramId=e;h.getMindmap()&&(l.nodes.forEach(t=>{"rounded"===t.shape?(t.radius=15,t.taper=15,t.stroke="none",t.width=0,t.padding=15):"circle"===t.shape?t.padding=10:"rect"===t.shape&&(t.width=0,t.padding=10)}),await(0,o.XX)(l,d),(0,s.P)(d,l.config.mindmap?.padding??r.UI.mindmap.padding,"mindmapDiagram",l.config.mindmap?.useMaxWidth??r.UI.mindmap.useMaxWidth))},"draw")},N=(0,a.K2)(t=>{let e="";for(let n=0;n<t.THEME_COLOR_LIMIT;n++)t["lineColor"+n]=t["lineColor"+n]||t["cScaleInv"+n],(0,p.A)(t["lineColor"+n])?t["lineColor"+n]=(0,y.A)(t["lineColor"+n],20):t["lineColor"+n]=(0,m.A)(t["lineColor"+n],20);for(let n=0;n<t.THEME_COLOR_LIMIT;n++){const i=""+(17-3*n);e+=`\n .section-${n-1} rect, .section-${n-1} path, .section-${n-1} circle, .section-${n-1} polygon, .section-${n-1} path {\n fill: ${t["cScale"+n]};\n }\n .section-${n-1} text {\n fill: ${t["cScaleLabel"+n]};\n }\n .node-icon-${n-1} {\n font-size: 40px;\n color: ${t["cScaleLabel"+n]};\n }\n .section-edge-${n-1}{\n stroke: ${t["cScale"+n]};\n }\n .edge-depth-${n-1}{\n stroke-width: ${i};\n }\n .section-${n-1} line {\n stroke: ${t["cScaleInv"+n]} ;\n stroke-width: 3;\n }\n\n .disabled, .disabled circle, .disabled text {\n fill: lightgray;\n }\n .disabled text {\n fill: #efefef;\n }\n `}return e},"genSections"),k=(0,a.K2)(t=>`\n .edge {\n stroke-width: 3;\n }\n ${N(t)}\n .section-root rect, .section-root path, .section-root circle, .section-root polygon {\n fill: ${t.git0};\n }\n .section-root text {\n fill: ${t.gitBranchLabel0};\n }\n .section-root span {\n color: ${t.gitBranchLabel0};\n }\n .section-2 span {\n color: ${t.gitBranchLabel0};\n }\n .icon-container {\n height:100%;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .edge {\n fill: none;\n }\n .mindmap-node-label {\n dy: 1em;\n alignment-baseline: middle;\n text-anchor: middle;\n dominant-baseline: middle;\n text-align: center;\n }\n`,"getStyles"),D={get db(){return new E},renderer:S,parser:b,styles:k}},89625:(t,e,n)=>{n.d(e,{A:()=>o});var i=n(40797),s=n(70451),o=(0,i.K2)((t,e)=>{let n;"sandbox"===e&&(n=(0,s.Ltv)("#i"+t));return("sandbox"===e?(0,s.Ltv)(n.nodes()[0].contentDocument.body):(0,s.Ltv)("body")).select(`[id="${t}"]`)},"getDiagramElement")}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/856c1b4a.b9ee9d40.js b/pr-preview/pr-4027/assets/js/856c1b4a.b9ee9d40.js deleted file mode 100644 index e07d55883..000000000 --- a/pr-preview/pr-4027/assets/js/856c1b4a.b9ee9d40.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4263],{28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>a});var t=s(96540);const o={},i=t.createContext(o);function r(e){const n=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),t.createElement(i.Provider,{value:n},e.children)}},45577:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"workflows/trusted-launch","title":"Use Azure trusted launch VMs","description":"Constellation also supports trusted launch VMs on Microsoft Azure. Trusted launch VMs don\'t offer the same level of security as Confidential VMs, but are available in more regions and in larger quantities. The main difference between trusted launch VMs and normal VMs is that the former offer vTPM-based remote attestation. When used with trusted launch VMs, Constellation relies on vTPM-based remote attestation to verify nodes.","source":"@site/versioned_docs/version-2.22/workflows/trusted-launch.md","sourceDirName":"workflows","slug":"/workflows/trusted-launch","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/trusted-launch","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/workflows/trusted-launch.md","tags":[],"version":"2.22","frontMatter":{}}');var o=s(74848),i=s(28453);const r={},a="Use Azure trusted launch VMs",l={},c=[{value:"VM images",id:"vm-images",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"use-azure-trusted-launch-vms",children:"Use Azure trusted launch VMs"})}),"\n",(0,o.jsxs)(n.p,{children:["Constellation also supports ",(0,o.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/trusted-launch",children:"trusted launch VMs"})," on Microsoft Azure. Trusted launch VMs don't offer the same level of security as Confidential VMs, but are available in more regions and in larger quantities. The main difference between trusted launch VMs and normal VMs is that the former offer vTPM-based remote attestation. When used with trusted launch VMs, Constellation relies on vTPM-based remote attestation to verify nodes."]}),"\n",(0,o.jsx)(n.admonition,{type:"caution",children:(0,o.jsx)(n.p,{children:"Trusted launch VMs don't provide runtime encryption and don't keep the cloud service provider (CSP) out of your trusted computing base."})}),"\n",(0,o.jsxs)(n.p,{children:["Constellation supports trusted launch VMs with instance types ",(0,o.jsx)(n.code,{children:"Standard_D*_v4"})," and ",(0,o.jsx)(n.code,{children:"Standard_E*_v4"}),". Run ",(0,o.jsx)(n.code,{children:"constellation config instance-types"})," for a list of all supported instance types."]}),"\n",(0,o.jsx)(n.h2,{id:"vm-images",children:"VM images"}),"\n",(0,o.jsxs)(n.p,{children:["Azure currently doesn't support ",(0,o.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/share-gallery-community",children:"community galleries for trusted launch VMs"}),". Thus, you need to manually import the Constellation node image into your cloud subscription."]}),"\n",(0,o.jsxs)(n.p,{children:["The latest image is available at ",(0,o.jsx)(n.code,{children:"https://cdn.confidential.cloud/constellation/images/azure/trusted-launch/v2.2.0/constellation.img"}),". Simply adjust the version number to download a newer version."]}),"\n",(0,o.jsxs)(n.p,{children:["After you've downloaded the image, create a resource group ",(0,o.jsx)(n.code,{children:"constellation-images"})," in your Azure subscription and import the image.\nYou can use a script to do this:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"wget https://raw.githubusercontent.com/edgelesssys/constellation/main/hack/importAzure.sh\nchmod +x importAzure.sh\nAZURE_IMAGE_VERSION=2.2.0 AZURE_RESOURCE_GROUP_NAME=constellation-images AZURE_IMAGE_FILE=./constellation.img ./importAzure.sh\n"})}),"\n",(0,o.jsx)(n.p,{children:"The script creates the following resources:"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["A new image gallery with the default name ",(0,o.jsx)(n.code,{children:"constellation-import"})]}),"\n",(0,o.jsxs)(n.li,{children:["A new image definition with the default name ",(0,o.jsx)(n.code,{children:"constellation"})]}),"\n",(0,o.jsxs)(n.li,{children:["The actual image with the provided version. In this case ",(0,o.jsx)(n.code,{children:"2.2.0"})]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Once the import is completed, use the ",(0,o.jsx)(n.code,{children:"ID"})," of the image version in your ",(0,o.jsx)(n.code,{children:"constellation-conf.yaml"})," for the ",(0,o.jsx)(n.code,{children:"image"})," field. Set ",(0,o.jsx)(n.code,{children:"confidentialVM"})," to ",(0,o.jsx)(n.code,{children:"false"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"Fetch the image measurements:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"IMAGE_VERSION=2.2.0\nURL=https://public-edgeless-constellation.s3.us-east-2.amazonaws.com//communitygalleries/constellationcvm-b3782fa0-0df7-4f2f-963e-fc7fc42663df/images/constellation/versions/$IMAGE_VERSION/measurements.yaml\nconstellation config fetch-measurements -u$URL -s$URL.sig\n"})}),"\n",(0,o.jsxs)(n.admonition,{type:"info",children:[(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/create",children:(0,o.jsx)(n.code,{children:"constellation apply"})})," command will issue a warning because manually imported images aren't recognized as production grade images:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-shell-session",children:"Configured image doesn't look like a released production image. Double check image before deploying to production.\n"})}),(0,o.jsx)(n.p,{children:"Please ignore this warning."})]})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/86470a9a.ad9a737e.js b/pr-preview/pr-4027/assets/js/86470a9a.ad9a737e.js deleted file mode 100644 index cd8953867..000000000 --- a/pr-preview/pr-4027/assets/js/86470a9a.ad9a737e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8569],{28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>l});var i=s(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}},72601:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>a});const i=JSON.parse('{"id":"workflows/config","title":"Configure your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","source":"@site/docs/workflows/config.md","sourceDirName":"workflows","slug":"/workflows/config","permalink":"/constellation/pr-preview/pr-4027/next/workflows/config","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/workflows/config.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Verify the CLI","permalink":"/constellation/pr-preview/pr-4027/next/workflows/verify-cli"},"next":{"title":"Create your cluster","permalink":"/constellation/pr-preview/pr-4027/next/workflows/create"}}');var t=s(74848),r=s(28453);const o={},l="Configure your cluster",c={},a=[{value:"Creating the configuration file",id:"creating-the-configuration-file",level:2},{value:"Choosing a VM type",id:"choosing-a-vm-type",level:2},{value:"Creating additional node groups",id:"creating-additional-node-groups",level:2},{value:"Choosing a Kubernetes version",id:"choosing-a-kubernetes-version",level:2},{value:"Creating an IAM configuration",id:"creating-an-iam-configuration",level:2},{value:"Deleting an IAM configuration",id:"deleting-an-iam-configuration",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components},{AsciinemaWidget:s,Details:i,TabItem:o,Tabs:l}=n;return s||u("AsciinemaWidget",!0),i||u("Details",!0),o||u("TabItem",!0),l||u("Tabs",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"configure-your-cluster",children:"Configure your cluster"})}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsx)(n.p,{children:"This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details."})}),"\n",(0,t.jsx)(s,{src:"/constellation/assets/configure-cluster.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.p,{children:"Before you can create your cluster, you need to configure the identity and access management (IAM) for your cloud service provider (CSP) and choose machine types for the nodes."}),"\n",(0,t.jsx)(n.h2,{id:"creating-the-configuration-file",children:"Creating the configuration file"}),"\n",(0,t.jsx)(n.p,{children:"You can generate a configuration file for your CSP by using the following CLI command:"}),"\n",(0,t.jsxs)(l,{groupId:"csp",children:[(0,t.jsx)(o,{value:"aws",label:"AWS",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation config generate aws\n"})})}),(0,t.jsx)(o,{value:"azure",label:"Azure",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation config generate azure\n"})})}),(0,t.jsx)(o,{value:"gcp",label:"GCP",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation config generate gcp\n"})})}),(0,t.jsx)(o,{value:"stackit",label:"STACKIT",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation config generate stackit\n"})})})]}),"\n",(0,t.jsxs)(n.p,{children:["This creates the file ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," in the current directory."]}),"\n",(0,t.jsx)(n.h2,{id:"choosing-a-vm-type",children:"Choosing a VM type"}),"\n",(0,t.jsx)(n.p,{children:"Constellation supports the following VM types:"}),"\n",(0,t.jsxs)(l,{groupId:"csp",children:[(0,t.jsxs)(o,{value:"aws",label:"AWS",children:[(0,t.jsxs)(n.p,{children:["By default, Constellation uses ",(0,t.jsx)(n.code,{children:"m6a.xlarge"})," VMs (4 vCPUs, 16 GB RAM) to create your cluster.\nOptionally, you can switch to a different VM type by modifying ",(0,t.jsx)(n.code,{children:"instanceType"})," in the configuration file.\nIf you are using the default attestation variant ",(0,t.jsx)(n.code,{children:"awsSEVSNP"}),", you can use the instance types described in ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/snp-requirements.html",children:"AWS's AMD SEV-SNP docs"}),".\nPlease mind the region restrictions mentioned in the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/first-steps#create-a-cluster",children:"Getting started"})," section."]}),(0,t.jsxs)(n.p,{children:["If you are using the attestation variant ",(0,t.jsx)(n.code,{children:"awsNitroTPM"}),", you can choose any of the ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enable-nitrotpm-prerequisites.html",children:"nitroTPM-enabled instance types"}),"."]}),(0,t.jsxs)(n.p,{children:["The Constellation CLI can also print the supported instance types with: ",(0,t.jsx)(n.code,{children:"constellation config instance-types"}),"."]})]}),(0,t.jsxs)(o,{value:"azure",label:"Azure",children:[(0,t.jsxs)(n.p,{children:["By default, Constellation uses ",(0,t.jsx)(n.code,{children:"Standard_DC4as_v5"})," CVMs (4 vCPUs, 16 GB RAM) to create your cluster. Optionally, you can switch to a different VM type by modifying ",(0,t.jsx)(n.code,{children:"instanceType"})," in the configuration file. For CVMs, any VM type with a minimum of 4 vCPUs from the ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/dcasv5-dcadsv5-series",children:"DCasv5 & DCadsv5"})," or ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/virtual-machines/ecasv5-ecadsv5-series",children:"ECasv5 & ECadsv5"})," families is supported."]}),(0,t.jsxs)(n.p,{children:["You can also run ",(0,t.jsx)(n.code,{children:"constellation config instance-types"})," to get the list of all supported options."]})]}),(0,t.jsx)(o,{value:"gcp",label:"GCP",children:(0,t.jsxs)(n.p,{children:["By default, Constellation uses ",(0,t.jsx)(n.code,{children:"n2d-standard-4"})," VMs (4 vCPUs, 16 GB RAM) to create your cluster. Optionally, you can switch to a different VM type by modifying ",(0,t.jsx)(n.code,{children:"instanceType"})," in the configuration file. Supported are all machines with a minimum of 4 vCPUs from the ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/compute-optimized-machines#c2d_machine_types",children:"C2D"})," or ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/general-purpose-machines#n2d_machines",children:"N2D"})," family. You can run ",(0,t.jsx)(n.code,{children:"constellation config instance-types"})," to get the list of all supported options."]})}),(0,t.jsxs)(o,{value:"stackit",label:"STACKIT",children:[(0,t.jsxs)(n.p,{children:["By default, Constellation uses ",(0,t.jsx)(n.code,{children:"m1a.4cd"})," VMs (4 vCPUs, 30 GB RAM) to create your cluster.\nOptionally, you can switch to a different VM type by modifying ",(0,t.jsx)(n.code,{children:"instanceType"})," in the configuration file."]}),(0,t.jsx)(n.p,{children:"The following instance types are known to be supported:"}),(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"name"}),(0,t.jsx)(n.th,{children:"vCPUs"}),(0,t.jsx)(n.th,{children:"GB RAM"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"m1a.4cd"}),(0,t.jsx)(n.td,{children:"4"}),(0,t.jsx)(n.td,{children:"30"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"m1a.8cd"}),(0,t.jsx)(n.td,{children:"8"}),(0,t.jsx)(n.td,{children:"60"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"m1a.16cd"}),(0,t.jsx)(n.td,{children:"16"}),(0,t.jsx)(n.td,{children:"120"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"m1a.30cd"}),(0,t.jsx)(n.td,{children:"30"}),(0,t.jsx)(n.td,{children:"230"})]})]})]}),(0,t.jsxs)(n.p,{children:["You can choose any of the SEV-enabled instance types. You can find a list of all supported instance types in the ",(0,t.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/virtual-machine-flavors-75137231.html",children:"STACKIT documentation"}),"."]}),(0,t.jsxs)(n.p,{children:["The Constellation CLI can also print the supported instance types with: ",(0,t.jsx)(n.code,{children:"constellation config instance-types"}),"."]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Fill the desired VM type into the ",(0,t.jsx)(n.code,{children:"instanceType"})," fields in the ",(0,t.jsx)(n.code,{children:"constellation-conf.yml"})," file."]}),"\n",(0,t.jsx)(n.h2,{id:"creating-additional-node-groups",children:"Creating additional node groups"}),"\n",(0,t.jsxs)(n.p,{children:["By default, Constellation creates the node groups ",(0,t.jsx)(n.code,{children:"control_plane_default"})," and ",(0,t.jsx)(n.code,{children:"worker_default"})," for control-plane nodes and workers, respectively.\nIf you require additional control-plane or worker groups with different instance types, zone placements, or disk sizes, you can add additional node groups to the ",(0,t.jsx)(n.code,{children:"constellation-conf.yml"})," file.\nEach node group can be scaled individually."]}),"\n",(0,t.jsx)(n.p,{children:"Consider the following example for AWS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"nodeGroups:\n control_plane_default:\n role: control-plane\n instanceType: c6a.xlarge\n stateDiskSizeGB: 30\n stateDiskType: gp3\n zone: eu-west-1c\n initialCount: 3\n worker_default:\n role: worker\n instanceType: c6a.xlarge\n stateDiskSizeGB: 30\n stateDiskType: gp3\n zone: eu-west-1c\n initialCount: 2\n high_cpu:\n role: worker\n instanceType: c6a.24xlarge\n stateDiskSizeGB: 128\n stateDiskType: gp3\n zone: eu-west-1c\n initialCount: 1\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This configuration creates an additional node group ",(0,t.jsx)(n.code,{children:"high_cpu"})," with a larger instance type and disk."]}),"\n",(0,t.jsxs)(n.p,{children:["You can use the field ",(0,t.jsx)(n.code,{children:"zone"})," to specify what availability zone nodes of the group are placed in.\nOn Azure, this field is empty by default and nodes are automatically spread across availability zones.\nSTACKIT currently offers SEV-enabled CPUs in the ",(0,t.jsx)(n.code,{children:"eu01-1"}),", ",(0,t.jsx)(n.code,{children:"eu01-2"}),", and ",(0,t.jsx)(n.code,{children:"eu01-3"})," zones.\nConsult the documentation of your cloud provider for more information:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://aws.amazon.com/about-aws/global-infrastructure/regions_az/",children:"AWS"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/explore/global-infrastructure/availability-zones",children:"Azure"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones",children:"GCP"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/regions-and-availability-zones-75137212.html",children:"STACKIT"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"choosing-a-kubernetes-version",children:"Choosing a Kubernetes version"}),"\n",(0,t.jsxs)(n.p,{children:["To learn which Kubernetes versions can be installed with your current CLI, you can run ",(0,t.jsx)(n.code,{children:"constellation config kubernetes-versions"}),".\nSee also Constellation's ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/versions#kubernetes-support-policy",children:"Kubernetes support policy"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"creating-an-iam-configuration",children:"Creating an IAM configuration"}),"\n",(0,t.jsxs)(n.p,{children:["You can create an IAM configuration for your cluster automatically using the ",(0,t.jsx)(n.code,{children:"constellation iam create"})," command.\nIf you already have a Constellation configuration file, you can add the ",(0,t.jsx)(n.code,{children:"--update-config"})," flag to the command. This writes the needed IAM fields into your configuration. Furthermore, the flag updates the zone/region of the configuration if it hasn't been set yet."]}),"\n",(0,t.jsxs)(l,{groupId:"csp",children:[(0,t.jsxs)(o,{value:"aws",label:"AWS",children:[(0,t.jsxs)(n.p,{children:["You must be authenticated with the ",(0,t.jsx)(n.a,{href:"https://aws.amazon.com/en/cli/",children:"AWS CLI"})," in the shell session with a user that has the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/install#set-up-cloud-credentials",children:"required permissions for IAM creation"}),"."]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation iam create aws --zone=us-east-2a --prefix=constellTest\n"})}),(0,t.jsxs)(n.p,{children:["This command creates IAM configuration for the AWS zone ",(0,t.jsx)(n.code,{children:"us-east-2a"})," using the prefix ",(0,t.jsx)(n.code,{children:"constellTest"})," for all named resources being created."]}),(0,t.jsx)(n.p,{children:"Constellation OS images are currently replicated to the following regions:"}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-central-1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-west-1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-west-3"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"us-east-2"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"ap-south-1"})}),"\n"]}),(0,t.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+AWS+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),(0,t.jsxs)(n.p,{children:["You can find a list of all ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions",children:"regions in AWS's documentation"}),"."]}),(0,t.jsxs)(n.p,{children:["Paste the output into the corresponding fields of the ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," file."]})]}),(0,t.jsxs)(o,{value:"azure",label:"Azure",children:[(0,t.jsxs)(n.p,{children:["You must be authenticated with the ",(0,t.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/cli/azure/install-azure-cli",children:"Azure CLI"})," in the shell session with a user that has the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/install#set-up-cloud-credentials",children:"required permissions for IAM creation"}),"."]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation iam create azure --subscriptionID 00000000-0000-0000-0000-000000000000 --region=westus --resourceGroup=constellTest --servicePrincipal=spTest\n"})}),(0,t.jsxs)(n.p,{children:["This command creates IAM configuration on the Azure region ",(0,t.jsx)(n.code,{children:"westus"})," creating a new resource group ",(0,t.jsx)(n.code,{children:"constellTest"})," and a new service principal ",(0,t.jsx)(n.code,{children:"spTest"}),"."]}),(0,t.jsx)(n.p,{children:"CVMs are available in several Azure regions. Constellation OS images are currently replicated to the following:"}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"germanywestcentral"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"westus"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eastus"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"northeurope"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"westeurope"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"southeastasia"})}),"\n"]}),(0,t.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+Azure+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),(0,t.jsxs)(n.p,{children:["You can find a list of all ",(0,t.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/global-infrastructure/services/?products=virtual-machines®ions=all",children:"regions in Azure's documentation"}),"."]}),(0,t.jsxs)(n.p,{children:["Paste the output into the corresponding fields of the ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," file."]})]}),(0,t.jsxs)(o,{value:"gcp",label:"GCP",children:[(0,t.jsxs)(n.p,{children:["You must be authenticated with the ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/sdk/gcloud",children:"GCP CLI"})," in the shell session with a user that has the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/install#set-up-cloud-credentials",children:"required permissions for IAM creation"}),"."]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation iam create gcp --projectID=yourproject-12345 --zone=europe-west3-a --prefix=constell-test\n"})}),(0,t.jsxs)(n.p,{children:["This command creates IAM configuration in the GCP project ",(0,t.jsx)(n.code,{children:"yourproject-12345"})," on the GCP zone ",(0,t.jsx)(n.code,{children:"europe-west3-a"})," creating a new service account ",(0,t.jsx)(n.code,{children:"constell-test"}),"."]}),(0,t.jsxs)(n.p,{children:["Note that only regions offering CVMs of the ",(0,t.jsx)(n.code,{children:"C2D"})," or ",(0,t.jsx)(n.code,{children:"N2D"})," series are supported. You can find a ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones#available",children:"list of all regions in Google's documentation"}),", which you can filter by machine type ",(0,t.jsx)(n.code,{children:"N2D"}),"."]}),(0,t.jsxs)(n.p,{children:["Paste the output into the corresponding fields of the ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," file."]})]}),(0,t.jsx)(o,{value:"stackit",label:"STACKIT",children:(0,t.jsxs)(n.p,{children:["STACKIT requires manual creation and configuration of service accounts. Look at the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/first-steps",children:"first steps"})," for more information."]})})]}),"\n",(0,t.jsxs)(i,{children:[(0,t.jsx)("summary",{children:"Alternatively, you can manually create the IAM configuration on your CSP."}),(0,t.jsx)(n.p,{children:"The following describes the configuration fields and how you obtain the required information or create the required resources."}),(0,t.jsxs)(l,{groupId:"csp",children:[(0,t.jsx)(o,{value:"aws",label:"AWS",children:(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"region"}),": The name of your chosen AWS data center region, e.g., ",(0,t.jsx)(n.code,{children:"us-east-2"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Constellation OS images are currently replicated to the following regions:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-central-1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-west-1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eu-west-3"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"us-east-2"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"ap-south-1"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+AWS+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find a list of all ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions",children:"regions in AWS's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"zone"}),": The name of your chosen AWS data center availability zone, e.g., ",(0,t.jsx)(n.code,{children:"us-east-2a"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Learn more about ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-availability-zones",children:"availability zones in AWS's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"iamProfileControlPlane"}),": The name of an IAM instance profile attached to all control-plane nodes."]}),"\n",(0,t.jsxs)(n.p,{children:["You can create the resource with ",(0,t.jsx)(n.a,{href:"https://www.terraform.io/",children:"Terraform"}),". For that, use the ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/tree/release/v2.2/hack/terraform/aws/iam",children:"provided Terraform script"})," to generate the necessary profile. The profile name will be provided as Terraform output value: ",(0,t.jsx)(n.code,{children:"control_plane_instance_profile_name"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Alternatively, you can create the AWS profile with a tool of your choice. Use the JSON policy in ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/tree/release/v2.2/hack/terraform/aws/iam/main.tf",children:"main.tf"})," in the resource ",(0,t.jsx)(n.code,{children:"aws_iam_policy.control_plane_policy"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"iamProfileWorkerNodes"}),": The name of an IAM instance profile attached to all worker nodes."]}),"\n",(0,t.jsxs)(n.p,{children:["You can create the resource with ",(0,t.jsx)(n.a,{href:"https://www.terraform.io/",children:"Terraform"}),". For that, use the ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/tree/release/v2.2/hack/terraform/aws/iam",children:"provided Terraform script"})," to generate the necessary profile. The profile name will be provided as Terraform output value: ",(0,t.jsx)(n.code,{children:"worker_nodes_instance_profile_name"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Alternatively, you can create the AWS profile with a tool of your choice. Use the JSON policy in ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/tree/release/v2.2/hack/terraform/aws/iam/main.tf",children:"main.tf"})," in the resource ",(0,t.jsx)(n.code,{children:"aws_iam_policy.worker_node_policy"}),"."]}),"\n"]}),"\n"]})}),(0,t.jsx)(o,{value:"azure",label:"Azure",children:(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"subscription"}),": The UUID of your Azure subscription, e.g., ",(0,t.jsx)(n.code,{children:"8b8bd01f-efd9-4113-9bd1-c82137c32da7"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can view your subscription UUID via ",(0,t.jsx)(n.code,{children:"az account show"})," and read the ",(0,t.jsx)(n.code,{children:"id"})," field. For more information refer to ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id#find-your-azure-subscription",children:"Azure's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"tenant"}),": The UUID of your Azure tenant, e.g., ",(0,t.jsx)(n.code,{children:"3400e5a2-8fe2-492a-886c-38cb66170f25"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can view your tenant UUID via ",(0,t.jsx)(n.code,{children:"az account show"})," and read the ",(0,t.jsx)(n.code,{children:"tenant"})," field. For more information refer to ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id#find-your-azure-ad-tenant",children:"Azure's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"location"}),": The Azure datacenter location you want to deploy your cluster in, e.g., ",(0,t.jsx)(n.code,{children:"westus"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"CVMs are available in several Azure regions. Constellation OS images are currently replicated to the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"germanywestcentral"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"westus"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"eastus"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"northeurope"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"westeurope"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"southeastasia"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,t.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+Azure+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find a list of all ",(0,t.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/global-infrastructure/services/?products=virtual-machines®ions=all",children:"regions in Azure's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"resourceGroup"}),": ",(0,t.jsx)(n.a,{href:"https://learn.microsoft.com/azure/azure-resource-manager/management/manage-resource-groups-portal",children:"Create a new resource group in Azure"})," for your Constellation cluster. Set this configuration field to the name of the created resource group."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"userAssignedIdentity"}),": ",(0,t.jsx)(n.a,{href:"https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/how-manage-user-assigned-managed-identities",children:"Create a new managed identity in Azure"}),". You should create the identity in a different resource group as all resources within the cluster resource group will be deleted on cluster termination."]}),"\n",(0,t.jsxs)(n.p,{children:["Add three role assignments to the identity: ",(0,t.jsx)(n.code,{children:"Owner"}),", ",(0,t.jsx)(n.code,{children:"Virtual Machine Contributor"}),", and ",(0,t.jsx)(n.code,{children:"Application Insights Component Contributor"}),". The ",(0,t.jsx)(n.code,{children:"scope"})," of all three should refer to the previously created cluster resource group."]}),"\n",(0,t.jsxs)(n.p,{children:["Set the configuration value to the full ID of the created identity, e.g., ",(0,t.jsx)(n.code,{children:"/subscriptions/8b8bd01f-efd9-4113-9bd1-c82137c32da7/resourcegroups/constellation-identity/providers/Microsoft.ManagedIdentity/userAssignedIdentities/constellation-identity"}),". You can get it by opening the ",(0,t.jsx)(n.code,{children:"JSON View"})," from the ",(0,t.jsx)(n.code,{children:"Overview"})," section of the identity."]}),"\n",(0,t.jsxs)(n.p,{children:["The user-assigned identity is used by instances of the cluster to access other cloud resources.\nFor more information about managed identities refer to ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-manage-user-assigned-managed-identities",children:"Azure's documentation"}),"."]}),"\n"]}),"\n"]})}),(0,t.jsx)(o,{value:"gcp",label:"GCP",children:(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"project"}),": The ID of your GCP project, e.g., ",(0,t.jsx)(n.code,{children:"constellation-129857"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find it on the ",(0,t.jsx)(n.a,{href:"https://console.cloud.google.com/welcome",children:"welcome screen of your GCP project"}),". For more information refer to ",(0,t.jsx)(n.a,{href:"https://support.google.com/googleapi/answer/7014113",children:"Google's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"region"}),": The GCP region you want to deploy your cluster in, e.g., ",(0,t.jsx)(n.code,{children:"us-central1"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find a ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones#available",children:"list of all regions in Google's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"zone"}),": The GCP zone you want to deploy your cluster in, e.g., ",(0,t.jsx)(n.code,{children:"us-central1-a"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["You can find a ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones#available",children:"list of all zones in Google's documentation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"serviceAccountKeyPath"}),": To configure this, you need to create a GCP ",(0,t.jsx)(n.a,{href:"https://cloud.google.com/iam/docs/service-accounts",children:"service account"})," with the following permissions:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Compute Instance Admin (v1) (roles/compute.instanceAdmin.v1)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Compute Network Admin (roles/compute.networkAdmin)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Compute Security Admin (roles/compute.securityAdmin)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Compute Storage Admin (roles/compute.storageAdmin)"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"Service Account User (roles/iam.serviceAccountUser)"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Afterward, create and download a new JSON key for this service account. Place the downloaded file in your Constellation workspace, and set the config parameter to the filename, e.g., ",(0,t.jsx)(n.code,{children:"constellation-129857-15343dba46cb.json"}),"."]}),"\n"]}),"\n"]})}),(0,t.jsx)(o,{value:"stackit",label:"STACKIT",children:(0,t.jsxs)(n.p,{children:["STACKIT requires manual creation and configuration of service accounts. Look at the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/first-steps",children:"first steps"})," for more information."]})})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Now that you've configured your CSP, you can ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/create",children:"create your cluster"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"deleting-an-iam-configuration",children:"Deleting an IAM configuration"}),"\n",(0,t.jsx)(n.p,{children:"You can keep a created IAM configuration and reuse it for new clusters. Alternatively, you can also delete it if you don't want to use it anymore."}),"\n",(0,t.jsxs)(n.p,{children:["Delete the IAM configuration by executing the following command in the same directory where you executed ",(0,t.jsx)(n.code,{children:"constellation iam create"})," (the directory that contains ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/reference/terraform",children:(0,t.jsx)(n.code,{children:"constellation-iam-terraform"})})," as a subdirectory):"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation iam destroy\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsxs)(n.p,{children:["For Azure, deleting the IAM configuration by executing ",(0,t.jsx)(n.code,{children:"constellation iam destroy"})," will delete the whole resource group created by ",(0,t.jsx)(n.code,{children:"constellation iam create"}),".\nThis also includes any additional resources in the resource group that weren't created by Constellation."]})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}function u(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/8713d71c.e522f149.js b/pr-preview/pr-4027/assets/js/8713d71c.e522f149.js deleted file mode 100644 index a2d19e834..000000000 --- a/pr-preview/pr-4027/assets/js/8713d71c.e522f149.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7083],{28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>t});var i=s(96540);const l={},r=i.createContext(l);function c(e){const n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:c(e.components),i.createElement(r.Provider,{value:n},e.children)}},91974:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>t,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"getting-started/install","title":"Installation and setup","description":"Constellation runs entirely in your cloud environment and can be controlled via a dedicated command-line interface (CLI) or a Terraform provider.","source":"@site/versioned_docs/version-2.23/getting-started/install.md","sourceDirName":"getting-started","slug":"/getting-started/install","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/install","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/getting-started/install.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Getting started","permalink":"/constellation/pr-preview/pr-4027/2.23/category/getting-started"},"next":{"title":"First steps (cloud)","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps"}}');var l=s(74848),r=s(28453);const c={},t="Installation and setup",o={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install the Constellation CLI",id:"install-the-constellation-cli",level:2},{value:"Set up cloud credentials",id:"set-up-cloud-credentials",level:2},{value:"Required permissions",id:"required-permissions",level:3},{value:"Authentication",id:"authentication",level:3},{value:"Next steps",id:"next-steps",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components},{TabItem:s,Tabs:i}=n;return s||u("TabItem",!0),i||u("Tabs",!0),(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"installation-and-setup",children:"Installation and setup"})}),"\n",(0,l.jsxs)(n.p,{children:["Constellation runs entirely in your cloud environment and can be controlled via a dedicated ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/reference/cli",children:"command-line interface (CLI)"})," or a ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/terraform-provider",children:"Terraform provider"}),"."]}),"\n",(0,l.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,l.jsx)(n.p,{children:"Make sure the following requirements are met:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Your machine is running Linux, macOS, or Windows"}),"\n",(0,l.jsx)(n.li,{children:"You have admin rights on your machine"}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/tools/",children:"kubectl"})," is installed"]}),"\n",(0,l.jsx)(n.li,{children:"Your CSP is Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), or STACKIT"}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"install-the-constellation-cli",children:"Install the Constellation CLI"}),"\n",(0,l.jsx)(n.admonition,{type:"tip",children:(0,l.jsxs)(n.p,{children:["If you prefer to use Terraform, you can alternatively use the ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/terraform-provider",children:"Terraform provider"})," to manage the cluster's lifecycle."]})}),"\n",(0,l.jsxs)(n.p,{children:["The CLI executable is available at ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub"}),".\nInstall it with the following commands:"]}),"\n",(0,l.jsxs)(i,{children:[(0,l.jsxs)(s,{value:"linux-amd64",label:"Linux (amd64)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-amd64\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Install the CLI to your PATH:"}),"\n"]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo install constellation-linux-amd64 /usr/local/bin/constellation\n"})})]}),(0,l.jsxs)(s,{value:"linux-arm64",label:"Linux (arm64)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-arm64\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Install the CLI to your PATH:"}),"\n"]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo install constellation-linux-arm64 /usr/local/bin/constellation\n"})})]}),(0,l.jsxs)(s,{value:"darwin-arm64",label:"macOS (Apple Silicon)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-darwin-arm64\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Install the CLI to your PATH:"}),"\n"]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo install constellation-darwin-arm64 /usr/local/bin/constellation\n"})})]}),(0,l.jsxs)(s,{value:"darwin-amd64",label:"macOS (Intel)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-darwin-amd64\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Install the CLI to your PATH:"}),"\n"]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo install constellation-darwin-amd64 /usr/local/bin/constellation\n"})})]}),(0,l.jsxs)(s,{value:"windows-amd64",label:"Windows (amd64)",children:[(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Download the CLI:"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"Invoke-WebRequest -OutFile ./constellation.exe -Uri 'https://github.com/edgelesssys/constellation/releases/latest/download/constellation-windows-amd64.exe'\n"})}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cli",children:"Verify the signature"})," (optional)"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Install the CLI under ",(0,l.jsx)(n.code,{children:"C:\\Program Files\\Constellation\\bin\\constellation.exe"})]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Add the CLI to your PATH:"}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["Open ",(0,l.jsx)(n.code,{children:"Advanced system settings"})," by searching for the App in the Windows search"]}),"\n",(0,l.jsxs)(n.li,{children:["Go to the ",(0,l.jsx)(n.code,{children:"Advanced"})," tab"]}),"\n",(0,l.jsxs)(n.li,{children:["Click ",(0,l.jsx)(n.code,{children:"Environment Variables\u2026"})]}),"\n",(0,l.jsxs)(n.li,{children:["Click variable called ",(0,l.jsx)(n.code,{children:"Path"})," and click ",(0,l.jsx)(n.code,{children:"Edit\u2026"})]}),"\n",(0,l.jsxs)(n.li,{children:["Click ",(0,l.jsx)(n.code,{children:"New"})]}),"\n",(0,l.jsxs)(n.li,{children:["Enter the path to the folder containing the binary you want on your PATH: ",(0,l.jsx)(n.code,{children:"C:\\Program Files\\Constellation\\bin"})]}),"\n"]}),"\n"]}),"\n"]})]})]}),"\n",(0,l.jsx)(n.admonition,{type:"tip",children:(0,l.jsxs)(n.p,{children:["The CLI supports autocompletion for various shells. To set it up, run ",(0,l.jsx)(n.code,{children:"constellation completion"})," and follow the given steps."]})}),"\n",(0,l.jsx)(n.h2,{id:"set-up-cloud-credentials",children:"Set up cloud credentials"}),"\n",(0,l.jsx)(n.p,{children:"Constellation makes authenticated calls to the CSP API. Therefore, you need to set up Constellation with the credentials for your CSP."}),"\n",(0,l.jsx)(n.admonition,{type:"tip",children:(0,l.jsxs)(n.p,{children:["If you don't have a cloud subscription, you can also set up a ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps-local",children:"local Constellation cluster using virtualization"})," for testing."]})}),"\n",(0,l.jsx)(n.h3,{id:"required-permissions",children:"Required permissions"}),"\n",(0,l.jsxs)(i,{groupId:"csp",children:[(0,l.jsxs)(s,{value:"aws",label:"AWS",children:[(0,l.jsx)(n.p,{children:"To set up a Constellation cluster, you need to perform two tasks that require permissions: create the infrastructure and create roles for cluster nodes. Both of these actions can be performed by different users, e.g., an administrator to create roles and a DevOps engineer to create the infrastructure."}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/config#creating-an-iam-configuration",children:"create the IAM configuration"})," for Constellation, you need the following permissions:"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-json",children:'{\n "Version": "2012-10-17",\n "Statement": [\n {\n "Effect": "Allow",\n "Action": [\n "ec2:DescribeAccountAttributes",\n "iam:AddRoleToInstanceProfile",\n "iam:AttachRolePolicy",\n "iam:CreateInstanceProfile",\n "iam:CreatePolicy",\n "iam:CreateRole",\n "iam:DeleteInstanceProfile",\n "iam:DeletePolicy",\n "iam:DeletePolicyVersion",\n "iam:DeleteRole",\n "iam:DetachRolePolicy",\n "iam:GetInstanceProfile",\n "iam:GetPolicy",\n "iam:GetPolicyVersion",\n "iam:GetRole",\n "iam:ListAttachedRolePolicies",\n "iam:ListInstanceProfilesForRole",\n "iam:ListPolicyVersions",\n "iam:ListRolePolicies",\n "iam:PassRole",\n "iam:RemoveRoleFromInstanceProfile",\n "sts:GetCallerIdentity"\n ],\n "Resource": "*"\n }\n ]\n}\n'})}),(0,l.jsxs)(n.p,{children:["The built-in ",(0,l.jsx)(n.code,{children:"AdministratorAccess"})," policy is a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/create",children:"create a Constellation cluster"}),", see the permissions of ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/blob/main/terraform/infrastructure/iam/aws/main.tf",children:"main.tf"}),"."]}),(0,l.jsxs)(n.p,{children:["The built-in ",(0,l.jsx)(n.code,{children:"PowerUserAccess"})," policy is a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["Follow Amazon's guide on ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html",children:"understanding"})," and ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html",children:"managing policies"}),"."]})]}),(0,l.jsxs)(s,{value:"azure",label:"Azure",children:[(0,l.jsxs)(n.p,{children:["The following ",(0,l.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/resource-providers-and-types#register-resource-provider",children:"resource providers need to be registered"})," in your subscription:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Attestation"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Compute"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Insights"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.ManagedIdentity"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network"})}),"\n"]}),(0,l.jsx)(n.p,{children:"By default, Constellation tries to register these automatically if they haven't been registered before."}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/config#creating-an-iam-configuration",children:"create the IAM configuration"})," for Constellation, you need the following permissions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"*/register/action"})," [1]"]}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Authorization/roleAssignments/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Authorization/roleDefinitions/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.ManagedIdentity/userAssignedIdentities/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Resources/subscriptions/resourcegroups/*"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["The built-in ",(0,l.jsx)(n.code,{children:"Owner"})," role is a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/create",children:"create a Constellation cluster"}),", you need the following permissions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Attestation/attestationProviders/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Compute/virtualMachineScaleSets/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Insights/components/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.ManagedIdentity/userAssignedIdentities/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/loadBalancers/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/loadBalancers/backendAddressPools/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/networkSecurityGroups/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/publicIPAddresses/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/virtualNetworks/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/virtualNetworks/subnets/*"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"Microsoft.Network/natGateways/*"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["The built-in ",(0,l.jsx)(n.code,{children:"Contributor"})," role is a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["Follow Microsoft's guide on ",(0,l.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/role-based-access-control/role-definitions",children:"understanding"})," and ",(0,l.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments",children:"assigning roles"}),"."]}),(0,l.jsxs)(n.p,{children:["1: You can omit ",(0,l.jsx)(n.code,{children:"*/register/Action"})," if the resource providers mentioned above are already registered and the ",(0,l.jsx)(n.code,{children:"ARM_SKIP_PROVIDER_REGISTRATION"})," environment variable is set to ",(0,l.jsx)(n.code,{children:"true"})," when creating the IAM configuration."]})]}),(0,l.jsxs)(s,{value:"gcp",label:"GCP",children:[(0,l.jsxs)(n.p,{children:["Create a new project for Constellation or use an existing one.\nEnable the ",(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/apis/library/compute.googleapis.com",children:"Compute Engine API"})," on it."]}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/config#creating-an-iam-configuration",children:"create the IAM configuration"})," for Constellation, you need the following permissions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.roles.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.roles.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.roles.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccountKeys.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccountKeys.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccountKeys.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccounts.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccounts.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccounts.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"resourcemanager.projects.getIamPolicy"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"resourcemanager.projects.setIamPolicy"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["Together, the built-in roles ",(0,l.jsx)(n.code,{children:"roles/editor"})," and ",(0,l.jsx)(n.code,{children:"roles/resourcemanager.projectIamAdmin"})," form a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["To ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/create",children:"create a Constellation cluster"}),", you need the following permissions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.addresses.createInternal"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.addresses.deleteInternal"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.addresses.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.addresses.useInternal"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.backendServices.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.backendServices.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.backendServices.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.backendServices.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.disks.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.firewalls.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.firewalls.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.firewalls.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.firewalls.update"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.forwardingRules.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.forwardingRules.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.forwardingRules.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.forwardingRules.setLabels"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.forwardingRules.list"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalAddresses.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalAddresses.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalAddresses.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalAddresses.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalForwardingRules.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalForwardingRules.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalForwardingRules.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalForwardingRules.setLabels"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.globalOperations.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.healthChecks.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.healthChecks.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.healthChecks.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.healthChecks.useReadOnly"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroupManagers.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroupManagers.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroupManagers.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroupManagers.update"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.update"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceGroups.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instances.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instances.setLabels"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instances.setMetadata"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instances.setTags"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceTemplates.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceTemplates.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceTemplates.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.instanceTemplates.useReadOnly"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.networks.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.networks.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.networks.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.networks.updatePolicy"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.routers.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.routers.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.routers.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.routers.update"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.subnetworks.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.subnetworks.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.subnetworks.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.subnetworks.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.targetTcpProxies.create"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.targetTcpProxies.delete"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.targetTcpProxies.get"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"compute.targetTcpProxies.use"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"iam.serviceAccounts.actAs"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["Together, the built-in roles ",(0,l.jsx)(n.code,{children:"roles/editor"}),", ",(0,l.jsx)(n.code,{children:"roles/compute.instanceAdmin"})," and ",(0,l.jsx)(n.code,{children:"roles/resourcemanager.projectIamAdmin"})," form a superset of these permissions."]}),(0,l.jsxs)(n.p,{children:["Follow Google's guide on ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/iam/docs/understanding-roles",children:"understanding"})," and ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/iam/docs/granting-changing-revoking-access",children:"assigning roles"}),"."]})]}),(0,l.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,l.jsxs)(n.p,{children:["Constellation on STACKIT requires a User Access Token (UAT) for the OpenStack API and a STACKIT service account.\nThe UAT already has all required permissions by default.\nThe STACKIT service account needs the ",(0,l.jsx)(n.code,{children:"editor"})," role to create STACKIT LoadBalancers.\nLook at the ",(0,l.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/getting-started-in-service-accounts-134415831.html",children:"STACKIT documentation"})," on how to create the service account and assign the role."]})})]}),"\n",(0,l.jsx)(n.h3,{id:"authentication",children:"Authentication"}),"\n",(0,l.jsxs)(n.p,{children:["You need to authenticate with your CSP. The following lists the required steps for ",(0,l.jsx)(n.em,{children:"testing"})," and ",(0,l.jsx)(n.em,{children:"production"})," environments."]}),"\n",(0,l.jsx)(n.admonition,{type:"note",children:(0,l.jsxs)(n.p,{children:["The steps for a ",(0,l.jsx)(n.em,{children:"testing"})," environment are simpler. However, they may expose secrets to the CSP. If in doubt, follow the ",(0,l.jsx)(n.em,{children:"production"})," steps."]})}),"\n",(0,l.jsxs)(i,{groupId:"csp",children:[(0,l.jsxs)(s,{value:"aws",label:"AWS",children:[(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Testing"})}),(0,l.jsxs)(n.p,{children:["You can use the ",(0,l.jsx)(n.a,{href:"https://console.aws.amazon.com/cloudshell/home",children:"AWS CloudShell"}),". Make sure you are ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/cloudshell/latest/userguide/sec-auth-with-identities.html",children:"authorized to use it"}),"."]}),(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Production"})}),(0,l.jsxs)(n.p,{children:["Use the latest version of the ",(0,l.jsx)(n.a,{href:"https://aws.amazon.com/cli/",children:"AWS CLI"})," on a trusted machine:"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"aws configure\n"})}),(0,l.jsxs)(n.p,{children:["Options and first steps are described in the ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/cli/index.html",children:"AWS CLI documentation"}),"."]})]}),(0,l.jsxs)(s,{value:"azure",label:"Azure",children:[(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Testing"})}),(0,l.jsxs)(n.p,{children:["Simply open the ",(0,l.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/azure/cloud-shell/overview",children:"Azure Cloud Shell"}),"."]}),(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Production"})}),(0,l.jsxs)(n.p,{children:["Use the latest version of the ",(0,l.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/",children:"Azure CLI"})," on a trusted machine:"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"az login\n"})}),(0,l.jsxs)(n.p,{children:["Other options are described in Azure's ",(0,l.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli",children:"authentication guide"}),"."]})]}),(0,l.jsxs)(s,{value:"gcp",label:"GCP",children:[(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Testing"})}),(0,l.jsxs)(n.p,{children:["You can use the ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/shell",children:"Google Cloud Shell"}),". Make sure your ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/shell/docs/auth",children:"session is authorized"}),". For example, execute ",(0,l.jsx)(n.code,{children:"gsutil"})," and accept the authorization prompt."]}),(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Production"})}),(0,l.jsx)(n.p,{children:"Use one of the following options on a trusted machine:"}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Use the ",(0,l.jsxs)(n.a,{href:"https://cloud.google.com/sdk/gcloud",children:[(0,l.jsx)(n.code,{children:"gcloud"})," CLI"]})]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"gcloud auth application-default login\n"})}),"\n",(0,l.jsx)(n.p,{children:"This will ask you to log-in to your Google account and create your credentials.\nThe Constellation CLI will automatically load these credentials when needed."}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Set up a service account and pass the credentials manually"}),"\n",(0,l.jsxs)(n.p,{children:["Follow ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/docs/authentication/production#manually",children:"Google's guide"})," for setting up your credentials."]}),"\n"]}),"\n"]})]}),(0,l.jsxs)(s,{value:"stackit",label:"STACKIT",children:[(0,l.jsx)(n.p,{children:"You need to authenticate with the infrastructure API (OpenStack) and create a service account (STACKIT API)."}),(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/step-1-generating-of-user-access-token-11763726.html",children:"Follow the STACKIT documentation"})," for obtaining a User Access Token (UAT) to use the infrastructure API"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Create a configuration file with the credentials from the User Access Token under:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Linux: ",(0,l.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})]}),"\n",(0,l.jsxs)(n.li,{children:["macOS: ",(0,l.jsx)(n.code,{children:"/Users/<user>/Library/Application Support/openstack/clouds.yaml"})," or ",(0,l.jsx)(n.code,{children:"/etc/openstack/clouds.yaml"})]}),"\n",(0,l.jsxs)(n.li,{children:["Windows: ",(0,l.jsx)(n.code,{children:"%AppData%\\openstack\\clouds.yaml"})]}),"\n"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",children:"clouds:\n stackit:\n auth:\n auth_url: https://keystone.api.iaas.eu01.stackit.cloud/v3\n username: REPLACE_WITH_UAT_USERNAME\n password: REPLACE_WITH_UAT_PASSWORD\n project_id: REPLACE_WITH_OPENSTACK_PROJECT_ID\n project_name: REPLACE_WITH_STACKIT_PROJECT_NAME\n user_domain_name: portal_mvp\n project_domain_name: portal_mvp\n region_name: RegionOne\n identity_api_version: 3\n"})}),"\n"]}),"\n"]}),(0,l.jsx)(n.admonition,{type:"caution",children:(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:"project_id"})," refers to the ID of your OpenStack project. The STACKIT portal also shows the STACKIT ID that's associated with your project in some places. Make sure you insert the OpenStack project ID in the ",(0,l.jsx)(n.code,{children:"clouds.yaml"})," file."]})}),(0,l.jsxs)(n.ol,{start:"3",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/getting-started-in-service-accounts-134415831.html",children:"Follow the STACKIT documentation"})," for creating a service account and an access token"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Assign the ",(0,l.jsx)(n.code,{children:"editor"})," role to the service account by ",(0,l.jsx)(n.a,{href:"https://docs.stackit.cloud/stackit/en/getting-started-in-service-accounts-134415831.html",children:"following the documentation"})]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Create a configuration file under ",(0,l.jsx)(n.code,{children:"~/.stackit/credentials.json"})," (",(0,l.jsx)(n.code,{children:"%USERPROFILE%\\.stackit\\credentials.json"})," on Windows)"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-json",children:'{"STACKIT_SERVICE_ACCOUNT_TOKEN":"REPLACE_WITH_TOKEN"}\n'})}),"\n"]}),"\n"]})]})]}),"\n",(0,l.jsx)(n.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,l.jsxs)(n.p,{children:["You are now ready to ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps",children:"deploy your first confidential Kubernetes cluster and application"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(a,{...e})}):a(e)}function u(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/8731.ae3eb0c0.js b/pr-preview/pr-4027/assets/js/8731.ae3eb0c0.js deleted file mode 100644 index f8cd41146..000000000 --- a/pr-preview/pr-4027/assets/js/8731.ae3eb0c0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8731],{9703:(e,t,n)=>{n.d(t,{A:()=>a});var r=n(88496),i=n(92049),s=n(53098);const a=function(e){return"string"==typeof e||!(0,i.A)(e)&&(0,s.A)(e)&&"[object String]"==(0,r.A)(e)}},16145:(e,t,n)=>{n.d(t,{A:()=>u});var r=n(23958),i=n(38446),s=n(27422);const a=function(e){return function(t,n,a){var o=Object(t);if(!(0,i.A)(t)){var l=(0,r.A)(n,3);t=(0,s.A)(t),n=function(e){return l(o[e],e,o)}}var c=e(t,n,a);return c>-1?o[l?t[c]:c]:void 0}};var o=n(25707),l=n(18593),c=Math.max;const u=a(function(e,t,n){var i=null==e?0:e.length;if(!i)return-1;var s=null==n?0:(0,l.A)(n);return s<0&&(s=c(i+s,0)),(0,o.A)(e,(0,r.A)(t,3),s)})},18139:(e,t,n)=>{n.d(t,{A:()=>s});var r=n(13588),i=n(74722);const s=function(e,t){return(0,r.A)((0,i.A)(e,t),1)}},18593:(e,t,n)=>{n.d(t,{A:()=>i});var r=n(74342);const i=function(e){var t=(0,r.A)(e),n=t%1;return t==t?n?t-n:t:0}},23068:(e,t,n)=>{n.d(t,{A:()=>c});var r=n(24326),i=n(66984),s=n(6832),a=n(55615),o=Object.prototype,l=o.hasOwnProperty;const c=(0,r.A)(function(e,t){e=Object(e);var n=-1,r=t.length,c=r>2?t[2]:void 0;for(c&&(0,s.A)(t[0],t[1],c)&&(r=1);++n<r;)for(var u=t[n],d=(0,a.A)(u),h=-1,f=d.length;++h<f;){var p=d[h],m=e[p];(void 0===m||(0,i.A)(m,o[p])&&!l.call(e,p))&&(e[p]=u[p])}return e})},26666:(e,t,n)=>{n.d(t,{A:()=>r});const r=function(e){var t=null==e?0:e.length;return t?e[t-1]:void 0}},32151:(e,t,n)=>{n.d(t,{$g:()=>fe,Bg:()=>J,Ct:()=>S,Cz:()=>p,D8:()=>U,FO:()=>re,Fy:()=>me,GL:()=>ce,IZ:()=>se,Mz:()=>Ee,O4:()=>ye,QX:()=>Ie,RP:()=>T,S2:()=>k,SP:()=>$,TF:()=>L,Tu:()=>g,Xj:()=>j,_c:()=>te,cY:()=>Re,fG:()=>M,jp:()=>X,lF:()=>Ae,r1:()=>u,rE:()=>K,s7:()=>O,vd:()=>de,ve:()=>z,wb:()=>oe,wh:()=>Q,z2:()=>xe});var r=n(32479);const i="AbstractRule";const s="AbstractType";const a="Condition";const o="TypeDefinition";const l="ValueLiteral";const c="AbstractElement";function u(e){return Se.isInstance(e,c)}const d="ArrayLiteral";const h="ArrayType";const f="BooleanLiteral";function p(e){return Se.isInstance(e,f)}const m="Conjunction";function g(e){return Se.isInstance(e,m)}const y="Disjunction";function T(e){return Se.isInstance(e,y)}const A="Grammar";const v="GrammarImport";const R="InferredType";function $(e){return Se.isInstance(e,R)}const E="Interface";function k(e){return Se.isInstance(e,E)}const x="NamedArgument";const I="Negation";function S(e){return Se.isInstance(e,I)}const N="NumberLiteral";const C="Parameter";const w="ParameterReference";function L(e){return Se.isInstance(e,w)}const b="ParserRule";function O(e){return Se.isInstance(e,b)}const _="ReferenceType";const P="ReturnType";function M(e){return Se.isInstance(e,P)}const D="SimpleType";function U(e){return Se.isInstance(e,D)}const F="StringLiteral";const G="TerminalRule";function K(e){return Se.isInstance(e,G)}const B="Type";function j(e){return Se.isInstance(e,B)}const V="TypeAttribute";const H="UnionType";const W="Action";function z(e){return Se.isInstance(e,W)}const Y="Alternatives";function X(e){return Se.isInstance(e,Y)}const q="Assignment";function Q(e){return Se.isInstance(e,q)}const Z="CharacterRange";function J(e){return Se.isInstance(e,Z)}const ee="CrossReference";function te(e){return Se.isInstance(e,ee)}const ne="EndOfFile";function re(e){return Se.isInstance(e,ne)}const ie="Group";function se(e){return Se.isInstance(e,ie)}const ae="Keyword";function oe(e){return Se.isInstance(e,ae)}const le="NegatedToken";function ce(e){return Se.isInstance(e,le)}const ue="RegexToken";function de(e){return Se.isInstance(e,ue)}const he="RuleCall";function fe(e){return Se.isInstance(e,he)}const pe="TerminalAlternatives";function me(e){return Se.isInstance(e,pe)}const ge="TerminalGroup";function ye(e){return Se.isInstance(e,ge)}const Te="TerminalRuleCall";function Ae(e){return Se.isInstance(e,Te)}const ve="UnorderedGroup";function Re(e){return Se.isInstance(e,ve)}const $e="UntilToken";function Ee(e){return Se.isInstance(e,$e)}const ke="Wildcard";function xe(e){return Se.isInstance(e,ke)}class Ie extends r.kD{getAllTypes(){return[c,i,s,W,Y,d,h,q,f,Z,a,m,ee,y,ne,A,v,ie,R,E,ae,x,le,I,N,C,w,b,_,ue,P,he,D,F,pe,ge,G,Te,B,V,o,H,ve,$e,l,ke]}computeIsSubtype(e,t){switch(e){case W:case Y:case q:case Z:case ee:case ne:case ie:case ae:case le:case ue:case he:case pe:case ge:case Te:case ve:case $e:case ke:return this.isSubtype(c,t);case d:case N:case F:return this.isSubtype(l,t);case h:case _:case D:case H:return this.isSubtype(o,t);case f:return this.isSubtype(a,t)||this.isSubtype(l,t);case m:case y:case I:case w:return this.isSubtype(a,t);case R:case E:case B:return this.isSubtype(s,t);case b:return this.isSubtype(i,t)||this.isSubtype(s,t);case G:return this.isSubtype(i,t);default:return!1}}getReferenceType(e){const t=`${e.container.$type}:${e.property}`;switch(t){case"Action:type":case"CrossReference:type":case"Interface:superTypes":case"ParserRule:returnType":case"SimpleType:typeRef":return s;case"Grammar:hiddenTokens":case"ParserRule:hiddenTokens":case"RuleCall:rule":return i;case"Grammar:usedGrammars":return A;case"NamedArgument:parameter":case"ParameterReference:parameter":return C;case"TerminalRuleCall:rule":return G;default:throw new Error(`${t} is not a valid reference id.`)}}getTypeMetaData(e){switch(e){case c:return{name:c,properties:[{name:"cardinality"},{name:"lookahead"}]};case d:return{name:d,properties:[{name:"elements",defaultValue:[]}]};case h:return{name:h,properties:[{name:"elementType"}]};case f:return{name:f,properties:[{name:"true",defaultValue:!1}]};case m:return{name:m,properties:[{name:"left"},{name:"right"}]};case y:return{name:y,properties:[{name:"left"},{name:"right"}]};case A:return{name:A,properties:[{name:"definesHiddenTokens",defaultValue:!1},{name:"hiddenTokens",defaultValue:[]},{name:"imports",defaultValue:[]},{name:"interfaces",defaultValue:[]},{name:"isDeclared",defaultValue:!1},{name:"name"},{name:"rules",defaultValue:[]},{name:"types",defaultValue:[]},{name:"usedGrammars",defaultValue:[]}]};case v:return{name:v,properties:[{name:"path"}]};case R:return{name:R,properties:[{name:"name"}]};case E:return{name:E,properties:[{name:"attributes",defaultValue:[]},{name:"name"},{name:"superTypes",defaultValue:[]}]};case x:return{name:x,properties:[{name:"calledByName",defaultValue:!1},{name:"parameter"},{name:"value"}]};case I:return{name:I,properties:[{name:"value"}]};case N:return{name:N,properties:[{name:"value"}]};case C:return{name:C,properties:[{name:"name"}]};case w:return{name:w,properties:[{name:"parameter"}]};case b:return{name:b,properties:[{name:"dataType"},{name:"definesHiddenTokens",defaultValue:!1},{name:"definition"},{name:"entry",defaultValue:!1},{name:"fragment",defaultValue:!1},{name:"hiddenTokens",defaultValue:[]},{name:"inferredType"},{name:"name"},{name:"parameters",defaultValue:[]},{name:"returnType"},{name:"wildcard",defaultValue:!1}]};case _:return{name:_,properties:[{name:"referenceType"}]};case P:return{name:P,properties:[{name:"name"}]};case D:return{name:D,properties:[{name:"primitiveType"},{name:"stringType"},{name:"typeRef"}]};case F:return{name:F,properties:[{name:"value"}]};case G:return{name:G,properties:[{name:"definition"},{name:"fragment",defaultValue:!1},{name:"hidden",defaultValue:!1},{name:"name"},{name:"type"}]};case B:return{name:B,properties:[{name:"name"},{name:"type"}]};case V:return{name:V,properties:[{name:"defaultValue"},{name:"isOptional",defaultValue:!1},{name:"name"},{name:"type"}]};case H:return{name:H,properties:[{name:"types",defaultValue:[]}]};case W:return{name:W,properties:[{name:"cardinality"},{name:"feature"},{name:"inferredType"},{name:"lookahead"},{name:"operator"},{name:"type"}]};case Y:return{name:Y,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case q:return{name:q,properties:[{name:"cardinality"},{name:"feature"},{name:"lookahead"},{name:"operator"},{name:"terminal"}]};case Z:return{name:Z,properties:[{name:"cardinality"},{name:"left"},{name:"lookahead"},{name:"right"}]};case ee:return{name:ee,properties:[{name:"cardinality"},{name:"deprecatedSyntax",defaultValue:!1},{name:"lookahead"},{name:"terminal"},{name:"type"}]};case ne:return{name:ne,properties:[{name:"cardinality"},{name:"lookahead"}]};case ie:return{name:ie,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"guardCondition"},{name:"lookahead"}]};case ae:return{name:ae,properties:[{name:"cardinality"},{name:"lookahead"},{name:"value"}]};case le:return{name:le,properties:[{name:"cardinality"},{name:"lookahead"},{name:"terminal"}]};case ue:return{name:ue,properties:[{name:"cardinality"},{name:"lookahead"},{name:"regex"}]};case he:return{name:he,properties:[{name:"arguments",defaultValue:[]},{name:"cardinality"},{name:"lookahead"},{name:"rule"}]};case pe:return{name:pe,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case ge:return{name:ge,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case Te:return{name:Te,properties:[{name:"cardinality"},{name:"lookahead"},{name:"rule"}]};case ve:return{name:ve,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case $e:return{name:$e,properties:[{name:"cardinality"},{name:"lookahead"},{name:"terminal"}]};case ke:return{name:ke,properties:[{name:"cardinality"},{name:"lookahead"}]};default:return{name:e,properties:[]}}}}const Se=new Ie},32479:(e,t,n)=>{function r(e){return"object"==typeof e&&null!==e&&"string"==typeof e.$type}function i(e){return"object"==typeof e&&null!==e&&"string"==typeof e.$refText}function s(e){return"object"==typeof e&&null!==e&&"string"==typeof e.name&&"string"==typeof e.type&&"string"==typeof e.path}function a(e){return"object"==typeof e&&null!==e&&r(e.container)&&i(e.reference)&&"string"==typeof e.message}n.d(t,{A_:()=>i,FC:()=>c,Nr:()=>s,Zl:()=>a,br:()=>u,kD:()=>o,mD:()=>l,ng:()=>r});class o{constructor(){this.subtypes={},this.allSubtypes={}}isInstance(e,t){return r(e)&&this.isSubtype(e.$type,t)}isSubtype(e,t){if(e===t)return!0;let n=this.subtypes[e];n||(n=this.subtypes[e]={});const r=n[t];if(void 0!==r)return r;{const r=this.computeIsSubtype(e,t);return n[t]=r,r}}getAllSubTypes(e){const t=this.allSubtypes[e];if(t)return t;{const t=this.getAllTypes(),n=[];for(const r of t)this.isSubtype(r,e)&&n.push(r);return this.allSubtypes[e]=n,n}}}function l(e){return"object"==typeof e&&null!==e&&Array.isArray(e.content)}function c(e){return"object"==typeof e&&null!==e&&"object"==typeof e.tokenType}function u(e){return l(e)&&"string"==typeof e.fullText}},34098:(e,t,n)=>{n.d(t,{A:()=>i});var r=n(13588);const i=function(e){return(null==e?0:e.length)?(0,r.A)(e,1):[]}},36224:(e,t,n)=>{n.d(t,{A:()=>r});const r=function(e,t){return e<t}},37608:(e,t,n)=>{var r;n.d(t,{A:()=>s,r:()=>i}),(()=>{var e={470:e=>{function t(e){if("string"!=typeof e)throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}function n(e,t){for(var n,r="",i=0,s=-1,a=0,o=0;o<=e.length;++o){if(o<e.length)n=e.charCodeAt(o);else{if(47===n)break;n=47}if(47===n){if(s===o-1||1===a);else if(s!==o-1&&2===a){if(r.length<2||2!==i||46!==r.charCodeAt(r.length-1)||46!==r.charCodeAt(r.length-2))if(r.length>2){var l=r.lastIndexOf("/");if(l!==r.length-1){-1===l?(r="",i=0):i=(r=r.slice(0,l)).length-1-r.lastIndexOf("/"),s=o,a=0;continue}}else if(2===r.length||1===r.length){r="",i=0,s=o,a=0;continue}t&&(r.length>0?r+="/..":r="..",i=2)}else r.length>0?r+="/"+e.slice(s+1,o):r=e.slice(s+1,o),i=o-s-1;s=o,a=0}else 46===n&&-1!==a?++a:a=-1}return r}var r={resolve:function(){for(var e,r="",i=!1,s=arguments.length-1;s>=-1&&!i;s--){var a;s>=0?a=arguments[s]:(void 0===e&&(e=process.cwd()),a=e),t(a),0!==a.length&&(r=a+"/"+r,i=47===a.charCodeAt(0))}return r=n(r,!i),i?r.length>0?"/"+r:"/":r.length>0?r:"."},normalize:function(e){if(t(e),0===e.length)return".";var r=47===e.charCodeAt(0),i=47===e.charCodeAt(e.length-1);return 0!==(e=n(e,!r)).length||r||(e="."),e.length>0&&i&&(e+="/"),r?"/"+e:e},isAbsolute:function(e){return t(e),e.length>0&&47===e.charCodeAt(0)},join:function(){if(0===arguments.length)return".";for(var e,n=0;n<arguments.length;++n){var i=arguments[n];t(i),i.length>0&&(void 0===e?e=i:e+="/"+i)}return void 0===e?".":r.normalize(e)},relative:function(e,n){if(t(e),t(n),e===n)return"";if((e=r.resolve(e))===(n=r.resolve(n)))return"";for(var i=1;i<e.length&&47===e.charCodeAt(i);++i);for(var s=e.length,a=s-i,o=1;o<n.length&&47===n.charCodeAt(o);++o);for(var l=n.length-o,c=a<l?a:l,u=-1,d=0;d<=c;++d){if(d===c){if(l>c){if(47===n.charCodeAt(o+d))return n.slice(o+d+1);if(0===d)return n.slice(o+d)}else a>c&&(47===e.charCodeAt(i+d)?u=d:0===d&&(u=0));break}var h=e.charCodeAt(i+d);if(h!==n.charCodeAt(o+d))break;47===h&&(u=d)}var f="";for(d=i+u+1;d<=s;++d)d!==s&&47!==e.charCodeAt(d)||(0===f.length?f+="..":f+="/..");return f.length>0?f+n.slice(o+u):(o+=u,47===n.charCodeAt(o)&&++o,n.slice(o))},_makeLong:function(e){return e},dirname:function(e){if(t(e),0===e.length)return".";for(var n=e.charCodeAt(0),r=47===n,i=-1,s=!0,a=e.length-1;a>=1;--a)if(47===(n=e.charCodeAt(a))){if(!s){i=a;break}}else s=!1;return-1===i?r?"/":".":r&&1===i?"//":e.slice(0,i)},basename:function(e,n){if(void 0!==n&&"string"!=typeof n)throw new TypeError('"ext" argument must be a string');t(e);var r,i=0,s=-1,a=!0;if(void 0!==n&&n.length>0&&n.length<=e.length){if(n.length===e.length&&n===e)return"";var o=n.length-1,l=-1;for(r=e.length-1;r>=0;--r){var c=e.charCodeAt(r);if(47===c){if(!a){i=r+1;break}}else-1===l&&(a=!1,l=r+1),o>=0&&(c===n.charCodeAt(o)?-1==--o&&(s=r):(o=-1,s=l))}return i===s?s=l:-1===s&&(s=e.length),e.slice(i,s)}for(r=e.length-1;r>=0;--r)if(47===e.charCodeAt(r)){if(!a){i=r+1;break}}else-1===s&&(a=!1,s=r+1);return-1===s?"":e.slice(i,s)},extname:function(e){t(e);for(var n=-1,r=0,i=-1,s=!0,a=0,o=e.length-1;o>=0;--o){var l=e.charCodeAt(o);if(47!==l)-1===i&&(s=!1,i=o+1),46===l?-1===n?n=o:1!==a&&(a=1):-1!==n&&(a=-1);else if(!s){r=o+1;break}}return-1===n||-1===i||0===a||1===a&&n===i-1&&n===r+1?"":e.slice(n,i)},format:function(e){if(null===e||"object"!=typeof e)throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof e);return function(e,t){var n=t.dir||t.root,r=t.base||(t.name||"")+(t.ext||"");return n?n===t.root?n+r:n+"/"+r:r}(0,e)},parse:function(e){t(e);var n={root:"",dir:"",base:"",ext:"",name:""};if(0===e.length)return n;var r,i=e.charCodeAt(0),s=47===i;s?(n.root="/",r=1):r=0;for(var a=-1,o=0,l=-1,c=!0,u=e.length-1,d=0;u>=r;--u)if(47!==(i=e.charCodeAt(u)))-1===l&&(c=!1,l=u+1),46===i?-1===a?a=u:1!==d&&(d=1):-1!==a&&(d=-1);else if(!c){o=u+1;break}return-1===a||-1===l||0===d||1===d&&a===l-1&&a===o+1?-1!==l&&(n.base=n.name=0===o&&s?e.slice(1,l):e.slice(o,l)):(0===o&&s?(n.name=e.slice(1,a),n.base=e.slice(1,l)):(n.name=e.slice(o,a),n.base=e.slice(o,l)),n.ext=e.slice(a,l)),o>0?n.dir=e.slice(0,o-1):s&&(n.dir="/"),n},sep:"/",delimiter:":",win32:null,posix:null};r.posix=r,e.exports=r}},t={};function n(r){var i=t[r];if(void 0!==i)return i.exports;var s=t[r]={exports:{}};return e[r](s,s.exports,n),s.exports}n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var i={};(()=>{let e;if(n.r(i),n.d(i,{URI:()=>u,Utils:()=>k}),"object"==typeof process)e="win32"===process.platform;else if("object"==typeof navigator){let t=navigator.userAgent;e=t.indexOf("Windows")>=0}const t=/^\w[\w\d+.-]*$/,r=/^\//,s=/^\/\//;function a(e,n){if(!e.scheme&&n)throw new Error(`[UriError]: Scheme is missing: {scheme: "", authority: "${e.authority}", path: "${e.path}", query: "${e.query}", fragment: "${e.fragment}"}`);if(e.scheme&&!t.test(e.scheme))throw new Error("[UriError]: Scheme contains illegal characters.");if(e.path)if(e.authority){if(!r.test(e.path))throw new Error('[UriError]: If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character')}else if(s.test(e.path))throw new Error('[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//")')}const o="",l="/",c=/^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;class u{static isUri(e){return e instanceof u||!!e&&"string"==typeof e.authority&&"string"==typeof e.fragment&&"string"==typeof e.path&&"string"==typeof e.query&&"string"==typeof e.scheme&&"string"==typeof e.fsPath&&"function"==typeof e.with&&"function"==typeof e.toString}scheme;authority;path;query;fragment;constructor(e,t,n,r,i,s=!1){"object"==typeof e?(this.scheme=e.scheme||o,this.authority=e.authority||o,this.path=e.path||o,this.query=e.query||o,this.fragment=e.fragment||o):(this.scheme=function(e,t){return e||t?e:"file"}(e,s),this.authority=t||o,this.path=function(e,t){switch(e){case"https":case"http":case"file":t?t[0]!==l&&(t=l+t):t=l}return t}(this.scheme,n||o),this.query=r||o,this.fragment=i||o,a(this,s))}get fsPath(){return g(this,!1)}with(e){if(!e)return this;let{scheme:t,authority:n,path:r,query:i,fragment:s}=e;return void 0===t?t=this.scheme:null===t&&(t=o),void 0===n?n=this.authority:null===n&&(n=o),void 0===r?r=this.path:null===r&&(r=o),void 0===i?i=this.query:null===i&&(i=o),void 0===s?s=this.fragment:null===s&&(s=o),t===this.scheme&&n===this.authority&&r===this.path&&i===this.query&&s===this.fragment?this:new h(t,n,r,i,s)}static parse(e,t=!1){const n=c.exec(e);return n?new h(n[2]||o,v(n[4]||o),v(n[5]||o),v(n[7]||o),v(n[9]||o),t):new h(o,o,o,o,o)}static file(t){let n=o;if(e&&(t=t.replace(/\\/g,l)),t[0]===l&&t[1]===l){const e=t.indexOf(l,2);-1===e?(n=t.substring(2),t=l):(n=t.substring(2,e),t=t.substring(e)||l)}return new h("file",n,t,o,o)}static from(e){const t=new h(e.scheme,e.authority,e.path,e.query,e.fragment);return a(t,!0),t}toString(e=!1){return y(this,e)}toJSON(){return this}static revive(e){if(e){if(e instanceof u)return e;{const t=new h(e);return t._formatted=e.external,t._fsPath=e._sep===d?e.fsPath:null,t}}return e}}const d=e?1:void 0;class h extends u{_formatted=null;_fsPath=null;get fsPath(){return this._fsPath||(this._fsPath=g(this,!1)),this._fsPath}toString(e=!1){return e?y(this,!0):(this._formatted||(this._formatted=y(this,!1)),this._formatted)}toJSON(){const e={$mid:1};return this._fsPath&&(e.fsPath=this._fsPath,e._sep=d),this._formatted&&(e.external=this._formatted),this.path&&(e.path=this.path),this.scheme&&(e.scheme=this.scheme),this.authority&&(e.authority=this.authority),this.query&&(e.query=this.query),this.fragment&&(e.fragment=this.fragment),e}}const f={58:"%3A",47:"%2F",63:"%3F",35:"%23",91:"%5B",93:"%5D",64:"%40",33:"%21",36:"%24",38:"%26",39:"%27",40:"%28",41:"%29",42:"%2A",43:"%2B",44:"%2C",59:"%3B",61:"%3D",32:"%20"};function p(e,t,n){let r,i=-1;for(let s=0;s<e.length;s++){const a=e.charCodeAt(s);if(a>=97&&a<=122||a>=65&&a<=90||a>=48&&a<=57||45===a||46===a||95===a||126===a||t&&47===a||n&&91===a||n&&93===a||n&&58===a)-1!==i&&(r+=encodeURIComponent(e.substring(i,s)),i=-1),void 0!==r&&(r+=e.charAt(s));else{void 0===r&&(r=e.substr(0,s));const t=f[a];void 0!==t?(-1!==i&&(r+=encodeURIComponent(e.substring(i,s)),i=-1),r+=t):-1===i&&(i=s)}}return-1!==i&&(r+=encodeURIComponent(e.substring(i))),void 0!==r?r:e}function m(e){let t;for(let n=0;n<e.length;n++){const r=e.charCodeAt(n);35===r||63===r?(void 0===t&&(t=e.substr(0,n)),t+=f[r]):void 0!==t&&(t+=e[n])}return void 0!==t?t:e}function g(t,n){let r;return r=t.authority&&t.path.length>1&&"file"===t.scheme?`//${t.authority}${t.path}`:47===t.path.charCodeAt(0)&&(t.path.charCodeAt(1)>=65&&t.path.charCodeAt(1)<=90||t.path.charCodeAt(1)>=97&&t.path.charCodeAt(1)<=122)&&58===t.path.charCodeAt(2)?n?t.path.substr(1):t.path[1].toLowerCase()+t.path.substr(2):t.path,e&&(r=r.replace(/\//g,"\\")),r}function y(e,t){const n=t?m:p;let r="",{scheme:i,authority:s,path:a,query:o,fragment:c}=e;if(i&&(r+=i,r+=":"),(s||"file"===i)&&(r+=l,r+=l),s){let e=s.indexOf("@");if(-1!==e){const t=s.substr(0,e);s=s.substr(e+1),e=t.lastIndexOf(":"),-1===e?r+=n(t,!1,!1):(r+=n(t.substr(0,e),!1,!1),r+=":",r+=n(t.substr(e+1),!1,!0)),r+="@"}s=s.toLowerCase(),e=s.lastIndexOf(":"),-1===e?r+=n(s,!1,!0):(r+=n(s.substr(0,e),!1,!0),r+=s.substr(e))}if(a){if(a.length>=3&&47===a.charCodeAt(0)&&58===a.charCodeAt(2)){const e=a.charCodeAt(1);e>=65&&e<=90&&(a=`/${String.fromCharCode(e+32)}:${a.substr(3)}`)}else if(a.length>=2&&58===a.charCodeAt(1)){const e=a.charCodeAt(0);e>=65&&e<=90&&(a=`${String.fromCharCode(e+32)}:${a.substr(2)}`)}r+=n(a,!0,!1)}return o&&(r+="?",r+=n(o,!1,!1)),c&&(r+="#",r+=t?c:p(c,!1,!1)),r}function T(e){try{return decodeURIComponent(e)}catch{return e.length>3?e.substr(0,3)+T(e.substr(3)):e}}const A=/(%[0-9A-Za-z][0-9A-Za-z])+/g;function v(e){return e.match(A)?e.replace(A,e=>T(e)):e}var R=n(470);const $=R.posix||R,E="/";var k;!function(e){e.joinPath=function(e,...t){return e.with({path:$.join(e.path,...t)})},e.resolvePath=function(e,...t){let n=e.path,r=!1;n[0]!==E&&(n=E+n,r=!0);let i=$.resolve(n,...t);return r&&i[0]===E&&!e.authority&&(i=i.substring(1)),e.with({path:i})},e.dirname=function(e){if(0===e.path.length||e.path===E)return e;let t=$.dirname(e.path);return 1===t.length&&46===t.charCodeAt(0)&&(t=""),e.with({path:t})},e.basename=function(e){return $.basename(e.path)},e.extname=function(e){return $.extname(e.path)}}(k||(k={}))})(),r=i})();const{URI:i,Utils:s}=r},38980:(e,t,n)=>{n.d(t,{S:()=>u});var r=n(87960),i=n(98913),s=n(39364),a=n(51917),o=class extends r.mR{static{(0,r.K2)(this,"ArchitectureTokenBuilder")}constructor(){super(["architecture"])}},l=class extends r.dg{static{(0,r.K2)(this,"ArchitectureValueConverter")}runCustomConverter(e,t,n){return"ARCH_ICON"===e.name?t.replace(/[()]/g,"").trim():"ARCH_TEXT_ICON"===e.name?t.replace(/["()]/g,""):"ARCH_TITLE"===e.name?t.replace(/[[\]]/g,"").trim():void 0}},c={parser:{TokenBuilder:(0,r.K2)(()=>new o,"TokenBuilder"),ValueConverter:(0,r.K2)(()=>new l,"ValueConverter")}};function u(e=a.D){const t=(0,s.WQ)((0,i.u)(e),r.sr),n=(0,s.WQ)((0,i.t)({shared:t}),r.jE,c);return t.ServiceRegistry.register(n),{shared:t,Architecture:n}}(0,r.K2)(u,"createArchitectureServices")},39364:(e,t,n)=>{var r;function i(e,t,n,r,i,s,o,l,u){return a([e,t,n,r,i,s,o,l,u].reduce(c,{}))}n.d(t,{WQ:()=>i}),function(e){e.merge=(e,t)=>c(c({},e),t)}(r||(r={}));const s=Symbol("isProxy");function a(e,t){const n=new Proxy({},{deleteProperty:()=>!1,set:()=>{throw new Error("Cannot set property on injected service container")},get:(r,i)=>i===s||l(r,i,e,t||n),getOwnPropertyDescriptor:(r,i)=>(l(r,i,e,t||n),Object.getOwnPropertyDescriptor(r,i)),has:(t,n)=>n in e,ownKeys:()=>[...Object.getOwnPropertyNames(e)]});return n}const o=Symbol();function l(e,t,n,r){if(t in e){if(e[t]instanceof Error)throw new Error("Construction failure. Please make sure that your dependencies are constructable.",{cause:e[t]});if(e[t]===o)throw new Error('Cycle detected. Please make "'+String(t)+'" lazy. Visit https://langium.org/docs/reference/configuration-services/#resolving-cyclic-dependencies');return e[t]}if(t in n){const s=n[t];e[t]=o;try{e[t]="function"==typeof s?s(r):a(s,r)}catch(i){throw e[t]=i instanceof Error?i:void 0,i}return e[t]}}function c(e,t){if(t)for(const[n,r]of Object.entries(t))if(void 0!==r){const t=e[n];e[n]=null!==t&&null!==r&&"object"==typeof t&&"object"==typeof r?c(t,r):r}return e}},44326:(e,t,n)=>{n.d(t,{Q:()=>c});var r=n(69637),i=n(32151),s=n(49683),a=n(90418),o=n(82806),l=n(91719);class c{constructor(){this.diagnostics=[]}buildTokens(e,t){const n=(0,l.Td)((0,a.YV)(e,!1)),r=this.buildTerminalTokens(n),i=this.buildKeywordTokens(n,r,t);return r.forEach(e=>{const t=e.PATTERN;"object"==typeof t&&t&&"test"in t&&(0,o.Yv)(t)?i.unshift(e):i.push(e)}),i}flushLexingReport(e){return{diagnostics:this.popDiagnostics()}}popDiagnostics(){const e=[...this.diagnostics];return this.diagnostics=[],e}buildTerminalTokens(e){return e.filter(i.rE).filter(e=>!e.fragment).map(e=>this.buildTerminalToken(e)).toArray()}buildTerminalToken(e){const t=(0,a.S)(e),n=this.requiresCustomPattern(t)?this.regexPatternFunction(t):t,i={name:e.name,PATTERN:n};return"function"==typeof n&&(i.LINE_BREAKS=!0),e.hidden&&(i.GROUP=(0,o.Yv)(t)?r.JG.SKIPPED:"hidden"),i}requiresCustomPattern(e){return!(!e.flags.includes("u")&&!e.flags.includes("s"))||!(!e.source.includes("?<=")&&!e.source.includes("?<!"))}regexPatternFunction(e){const t=new RegExp(e,e.flags+"y");return(e,n)=>{t.lastIndex=n;return t.exec(e)}}buildKeywordTokens(e,t,n){return e.filter(i.s7).flatMap(e=>(0,s.Uo)(e).filter(i.wb)).distinct(e=>e.value).toArray().sort((e,t)=>t.value.length-e.value.length).map(e=>this.buildKeywordToken(e,t,Boolean(null==n?void 0:n.caseInsensitive)))}buildKeywordToken(e,t,n){const r=this.buildKeywordPattern(e,n),i={name:e.value,PATTERN:r,LONGER_ALT:this.findLongerAlt(e,t)};return"function"==typeof r&&(i.LINE_BREAKS=!0),i}buildKeywordPattern(e,t){return t?new RegExp((0,o.Ao)(e.value)):e.value}findLongerAlt(e,t){return t.reduce((t,n)=>{const r=null==n?void 0:n.PATTERN;return(null==r?void 0:r.source)&&(0,o.PC)("^"+r.source+"$",e.value)&&t.push(n),t},[])}}},48585:(e,t,n)=>{n.d(t,{A:()=>a});var r=Object.prototype.hasOwnProperty;const i=function(e,t){return null!=e&&r.call(e,t)};var s=n(85054);const a=function(e,t){return null!=e&&(0,s.A)(e,t,i)}},49683:(e,t,n)=>{n.d(t,{DM:()=>p,OP:()=>m,SD:()=>a,Uo:()=>d,VN:()=>u,XG:()=>o,YE:()=>l,cQ:()=>c,jm:()=>h});var r=n(32479),i=n(91719),s=n(76373);function a(e){for(const[t,n]of Object.entries(e))t.startsWith("$")||(Array.isArray(n)?n.forEach((n,i)=>{(0,r.ng)(n)&&(n.$container=e,n.$containerProperty=t,n.$containerIndex=i)}):(0,r.ng)(n)&&(n.$container=e,n.$containerProperty=t))}function o(e,t){let n=e;for(;n;){if(t(n))return n;n=n.$container}}function l(e){const t=c(e).$document;if(!t)throw new Error("AST node has no document.");return t}function c(e){for(;e.$container;)e=e.$container;return e}function u(e,t){if(!e)throw new Error("Node must be an AstNode.");const n=null==t?void 0:t.range;return new i.fq(()=>({keys:Object.keys(e),keyIndex:0,arrayIndex:0}),t=>{for(;t.keyIndex<t.keys.length;){const i=t.keys[t.keyIndex];if(!i.startsWith("$")){const s=e[i];if((0,r.ng)(s)){if(t.keyIndex++,f(s,n))return{done:!1,value:s}}else if(Array.isArray(s)){for(;t.arrayIndex<s.length;){const e=s[t.arrayIndex++];if((0,r.ng)(e)&&f(e,n))return{done:!1,value:e}}t.arrayIndex=0}}t.keyIndex++}return i.Rf})}function d(e,t){if(!e)throw new Error("Root node must be an AstNode.");return new i.Vj(e,e=>u(e,t))}function h(e,t){if(!e)throw new Error("Root node must be an AstNode.");return(null==t?void 0:t.range)&&!f(e,t.range)?new i.Vj(e,()=>[]):new i.Vj(e,e=>u(e,t),{includeRoot:!0})}function f(e,t){var n;if(!t)return!0;const r=null===(n=e.$cstNode)||void 0===n?void 0:n.range;return!!r&&(0,s.r4)(r,t)}function p(e){return new i.fq(()=>({keys:Object.keys(e),keyIndex:0,arrayIndex:0}),t=>{for(;t.keyIndex<t.keys.length;){const n=t.keys[t.keyIndex];if(!n.startsWith("$")){const i=e[n];if((0,r.A_)(i))return t.keyIndex++,{done:!1,value:{reference:i,container:e,property:n}};if(Array.isArray(i)){for(;t.arrayIndex<i.length;){const s=t.arrayIndex++,a=i[s];if((0,r.A_)(a))return{done:!1,value:{reference:a,container:e,property:n,index:s}}}t.arrayIndex=0}}t.keyIndex++}return i.Rf})}function m(e,t){const n=e.getTypeMetaData(t.$type),r=t;for(const i of n.properties)void 0!==i.defaultValue&&void 0===r[i.name]&&(r[i.name]=g(i.defaultValue))}function g(e){return Array.isArray(e)?[...e.map(g)]:e}},50053:(e,t,n)=>{n.d(t,{A:()=>i});var r=n(68675);const i=function(e){return(0,r.A)(e,4)}},51633:(e,t,n)=>{n.d(t,{d:()=>f});var r=n(87960),i=n(98913),s=n(39364),a=n(51917),o=class extends r.mR{static{(0,r.K2)(this,"TreemapTokenBuilder")}constructor(){super(["treemap"])}},l=/classDef\s+([A-Z_a-z]\w+)(?:\s+([^\n\r;]*))?;?/,c=class extends r.dg{static{(0,r.K2)(this,"TreemapValueConverter")}runCustomConverter(e,t,n){if("NUMBER2"===e.name)return parseFloat(t.replace(/,/g,""));if("SEPARATOR"===e.name)return t.substring(1,t.length-1);if("STRING2"===e.name)return t.substring(1,t.length-1);if("INDENTATION"===e.name)return t.length;if("ClassDef"===e.name){if("string"!=typeof t)return t;const e=l.exec(t);if(e)return{$type:"ClassDefStatement",className:e[1],styleText:e[2]||void 0}}}};function u(e){const t=e.validation.TreemapValidator,n=e.validation.ValidationRegistry;if(n){const e={Treemap:t.checkSingleRoot.bind(t)};n.register(e,t)}}(0,r.K2)(u,"registerValidationChecks");var d=class{static{(0,r.K2)(this,"TreemapValidator")}checkSingleRoot(e,t){let n;for(const r of e.TreemapRows)r.item&&(void 0===n&&void 0===r.indent?n=0:(void 0===r.indent||void 0!==n&&n>=parseInt(r.indent,10))&&t("error","Multiple root nodes are not allowed in a treemap.",{node:r,property:"item"}))}},h={parser:{TokenBuilder:(0,r.K2)(()=>new o,"TokenBuilder"),ValueConverter:(0,r.K2)(()=>new c,"ValueConverter")},validation:{TreemapValidator:(0,r.K2)(()=>new d,"TreemapValidator")}};function f(e=a.D){const t=(0,s.WQ)((0,i.u)(e),r.sr),n=(0,s.WQ)((0,i.t)({shared:t}),r.eV,h);return t.ServiceRegistry.register(n),u(n),{shared:t,Treemap:n}}(0,r.K2)(f,"createTreemapServices")},51917:(e,t,n)=>{n.d(t,{D:()=>i});class r{readFile(){throw new Error("No file system is available.")}async readDirectory(){return[]}}const i={fileSystemProvider:()=>new r}},52568:(e,t,n)=>{n.d(t,{A:()=>s});var r=n(6240),i=n(38446);const s=function(e,t){var n=-1,s=(0,i.A)(e)?Array(e.length):[];return(0,r.A)(e,function(e,r,i){s[++n]=t(e,r,i)}),s}},59850:(e,t,n)=>{t.Qi=t.XO=void 0;const r=n(69590),i=n(78585),s=n(62676);var a;!function(e){e.None=Object.freeze({isCancellationRequested:!1,onCancellationRequested:s.Event.None}),e.Cancelled=Object.freeze({isCancellationRequested:!0,onCancellationRequested:s.Event.None}),e.is=function(t){const n=t;return n&&(n===e.None||n===e.Cancelled||i.boolean(n.isCancellationRequested)&&!!n.onCancellationRequested)}}(a||(t.XO=a={}));const o=Object.freeze(function(e,t){const n=(0,r.default)().timer.setTimeout(e.bind(t),0);return{dispose(){n.dispose()}}});class l{constructor(){this._isCancelled=!1}cancel(){this._isCancelled||(this._isCancelled=!0,this._emitter&&(this._emitter.fire(void 0),this.dispose()))}get isCancellationRequested(){return this._isCancelled}get onCancellationRequested(){return this._isCancelled?o:(this._emitter||(this._emitter=new s.Emitter),this._emitter.event)}dispose(){this._emitter&&(this._emitter.dispose(),this._emitter=void 0)}}t.Qi=class{get token(){return this._token||(this._token=new l),this._token}cancel(){this._token?this._token.cancel():this._token=a.Cancelled}dispose(){this._token?this._token instanceof l&&this._token.dispose():this._token=a.None}}},62676:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Emitter=t.Event=void 0;const r=n(69590);var i;!function(e){const t={dispose(){}};e.None=function(){return t}}(i||(t.Event=i={}));class s{add(e,t=null,n){this._callbacks||(this._callbacks=[],this._contexts=[]),this._callbacks.push(e),this._contexts.push(t),Array.isArray(n)&&n.push({dispose:()=>this.remove(e,t)})}remove(e,t=null){if(!this._callbacks)return;let n=!1;for(let r=0,i=this._callbacks.length;r<i;r++)if(this._callbacks[r]===e){if(this._contexts[r]===t)return this._callbacks.splice(r,1),void this._contexts.splice(r,1);n=!0}if(n)throw new Error("When adding a listener with a context, you should remove it with the same context")}invoke(...e){if(!this._callbacks)return[];const t=[],n=this._callbacks.slice(0),i=this._contexts.slice(0);for(let a=0,o=n.length;a<o;a++)try{t.push(n[a].apply(i[a],e))}catch(s){(0,r.default)().console.error(s)}return t}isEmpty(){return!this._callbacks||0===this._callbacks.length}dispose(){this._callbacks=void 0,this._contexts=void 0}}class a{constructor(e){this._options=e}get event(){return this._event||(this._event=(e,t,n)=>{this._callbacks||(this._callbacks=new s),this._options&&this._options.onFirstListenerAdd&&this._callbacks.isEmpty()&&this._options.onFirstListenerAdd(this),this._callbacks.add(e,t);const r={dispose:()=>{this._callbacks&&(this._callbacks.remove(e,t),r.dispose=a._noop,this._options&&this._options.onLastListenerRemove&&this._callbacks.isEmpty()&&this._options.onLastListenerRemove(this))}};return Array.isArray(n)&&n.push(r),r}),this._event}fire(e){this._callbacks&&this._callbacks.invoke.call(this._callbacks,e)}dispose(){this._callbacks&&(this._callbacks.dispose(),this._callbacks=void 0)}}t.Emitter=a,a._noop=function(){}},65033:(e,t,n)=>{n.d(t,{d:()=>a});var r,i=n(32151),s=n(90418);class a{convert(e,t){let n=t.grammarSource;if((0,i._c)(n)&&(n=(0,s.g4)(n)),(0,i.$g)(n)){const r=n.rule.ref;if(!r)throw new Error("This cst node was not parsed by a rule.");return this.runConverter(r,e,t)}return e}runConverter(e,t,n){var i;switch(e.name.toUpperCase()){case"INT":return r.convertInt(t);case"STRING":return r.convertString(t);case"ID":return r.convertID(t)}switch(null===(i=(0,s.P3)(e))||void 0===i?void 0:i.toLowerCase()){case"number":return r.convertNumber(t);case"boolean":return r.convertBoolean(t);case"bigint":return r.convertBigint(t);case"date":return r.convertDate(t);default:return t}}}!function(e){function t(e){switch(e){case"b":return"\b";case"f":return"\f";case"n":return"\n";case"r":return"\r";case"t":return"\t";case"v":return"\v";case"0":return"\0";default:return e}}e.convertString=function(e){let n="";for(let r=1;r<e.length-1;r++){const i=e.charAt(r);if("\\"===i){n+=t(e.charAt(++r))}else n+=i}return n},e.convertID=function(e){return"^"===e.charAt(0)?e.substring(1):e},e.convertInt=function(e){return parseInt(e)},e.convertBigint=function(e){return BigInt(e)},e.convertDate=function(e){return new Date(e)},e.convertNumber=function(e){return Number(e)},e.convertBoolean=function(e){return"true"===e.toLowerCase()}}(r||(r={}))},67539:(e,t,n)=>{n.d(t,{b:()=>c});var r=n(87960),i=n(98913),s=n(39364),a=n(51917),o=class extends r.mR{static{(0,r.K2)(this,"GitGraphTokenBuilder")}constructor(){super(["gitGraph"])}},l={parser:{TokenBuilder:(0,r.K2)(()=>new o,"TokenBuilder"),ValueConverter:(0,r.K2)(()=>new r.Tm,"ValueConverter")}};function c(e=a.D){const t=(0,s.WQ)((0,i.u)(e),r.sr),n=(0,s.WQ)((0,i.t)({shared:t}),r.eZ,l);return t.ServiceRegistry.register(n),{shared:t,GitGraph:n}}(0,r.K2)(c,"createGitGraphServices")},69150:(e,t,n)=>{n.d(t,{f:()=>u});var r=n(87960),i=n(98913),s=n(39364),a=n(51917),o=class extends r.mR{static{(0,r.K2)(this,"PieTokenBuilder")}constructor(){super(["pie","showData"])}},l=class extends r.dg{static{(0,r.K2)(this,"PieValueConverter")}runCustomConverter(e,t,n){if("PIE_SECTION_LABEL"===e.name)return t.replace(/"/g,"").trim()}},c={parser:{TokenBuilder:(0,r.K2)(()=>new o,"TokenBuilder"),ValueConverter:(0,r.K2)(()=>new l,"ValueConverter")}};function u(e=a.D){const t=(0,s.WQ)((0,i.u)(e),r.sr),n=(0,s.WQ)((0,i.t)({shared:t}),r.KX,c);return t.ServiceRegistry.register(n),{shared:t,Pie:n}}(0,r.K2)(u,"createPieServices")},69590:(e,t)=>{let n;function r(){if(void 0===n)throw new Error("No runtime abstraction layer installed");return n}Object.defineProperty(t,"__esModule",{value:!0}),function(e){e.install=function(e){if(void 0===e)throw new Error("No runtime abstraction layer provided");n=e}}(r||(r={})),t.default=r},69637:(e,t,n)=>{n.d(t,{ak:()=>V,mT:()=>Pr,LT:()=>Xt,jr:()=>Dr,T6:()=>dr,JG:()=>Mt,wL:()=>M,c$:()=>F,Y2:()=>B,$P:()=>G,Cy:()=>K,Pp:()=>j,BK:()=>H,PW:()=>Ot,my:()=>Zt,jk:()=>En,Sk:()=>Dt,G:()=>Qt});var r=n(8058),i=n(38207),s=n(66401),a=n(74722),o=n(48585),l=n(50053);function c(e){function t(){}t.prototype=e;const n=new t;function r(){return typeof n.bar}return r(),r(),e}const u=function(e,t,n){var r=-1,i=e.length;t<0&&(t=-t>i?0:i+t),(n=n>i?i:n)<0&&(n+=i),i=t>n?0:n-t>>>0,t>>>=0;for(var s=Array(i);++r<i;)s[r]=e[r+t];return s};var d=n(18593);const h=function(e,t,n){var r=null==e?0:e.length;return r?(t=n||void 0===t?1:(0,d.A)(t),u(e,t<0?0:t,r)):[]};var f=n(9703),p=n(52851),m=n(22031),g=n(3767),y=n(38446),T=n(97271),A=n(27422),v=Object.prototype.hasOwnProperty;const R=(0,g.A)(function(e,t){if((0,T.A)(t)||(0,y.A)(t))(0,m.A)(t,(0,A.A)(t),e);else for(var n in t)v.call(t,n)&&(0,p.A)(e,n,t[n])});var $=n(45572),E=n(23958),k=n(99354),x=n(83973);const I=function(e,t){if(null==e)return{};var n=(0,$.A)((0,x.A)(e),function(e){return[e]});return t=(0,E.A)(t),(0,k.A)(e,n,function(e,n){return t(e,n[0])})};var S=n(88496),N=n(53098);const C=function(e){return(0,N.A)(e)&&"[object RegExp]"==(0,S.A)(e)};var w=n(52789),L=n(64841),b=L.A&&L.A.isRegExp;const O=b?(0,w.A)(b):C;function _(e){return t=e,(0,f.A)(t.LABEL)&&""!==t.LABEL?e.LABEL:e.name;var t}class P{get definition(){return this._definition}set definition(e){this._definition=e}constructor(e){this._definition=e}accept(e){e.visit(this),(0,r.A)(this.definition,t=>{t.accept(e)})}}class M extends P{constructor(e){super([]),this.idx=1,R(this,I(e,e=>void 0!==e))}set definition(e){}get definition(){return void 0!==this.referencedRule?this.referencedRule.definition:[]}accept(e){e.visit(this)}}class D extends P{constructor(e){super(e.definition),this.orgText="",R(this,I(e,e=>void 0!==e))}}class U extends P{constructor(e){super(e.definition),this.ignoreAmbiguities=!1,R(this,I(e,e=>void 0!==e))}}class F extends P{constructor(e){super(e.definition),this.idx=1,R(this,I(e,e=>void 0!==e))}}class G extends P{constructor(e){super(e.definition),this.idx=1,R(this,I(e,e=>void 0!==e))}}class K extends P{constructor(e){super(e.definition),this.idx=1,R(this,I(e,e=>void 0!==e))}}class B extends P{constructor(e){super(e.definition),this.idx=1,R(this,I(e,e=>void 0!==e))}}class j extends P{constructor(e){super(e.definition),this.idx=1,R(this,I(e,e=>void 0!==e))}}class V extends P{get definition(){return this._definition}set definition(e){this._definition=e}constructor(e){super(e.definition),this.idx=1,this.ignoreAmbiguities=!1,this.hasPredicates=!1,R(this,I(e,e=>void 0!==e))}}class H{constructor(e){this.idx=1,R(this,I(e,e=>void 0!==e))}accept(e){e.visit(this)}}function W(e){function t(e){return(0,a.A)(e,W)}if(e instanceof M){const t={type:"NonTerminal",name:e.nonTerminalName,idx:e.idx};return(0,f.A)(e.label)&&(t.label=e.label),t}if(e instanceof U)return{type:"Alternative",definition:t(e.definition)};if(e instanceof F)return{type:"Option",idx:e.idx,definition:t(e.definition)};if(e instanceof G)return{type:"RepetitionMandatory",idx:e.idx,definition:t(e.definition)};if(e instanceof K)return{type:"RepetitionMandatoryWithSeparator",idx:e.idx,separator:W(new H({terminalType:e.separator})),definition:t(e.definition)};if(e instanceof j)return{type:"RepetitionWithSeparator",idx:e.idx,separator:W(new H({terminalType:e.separator})),definition:t(e.definition)};if(e instanceof B)return{type:"Repetition",idx:e.idx,definition:t(e.definition)};if(e instanceof V)return{type:"Alternation",idx:e.idx,definition:t(e.definition)};if(e instanceof H){const t={type:"Terminal",name:e.terminalType.name,label:_(e.terminalType),idx:e.idx};(0,f.A)(e.label)&&(t.terminalLabel=e.label);const n=e.terminalType.PATTERN;return e.terminalType.PATTERN&&(t.pattern=O(n)?n.source:n),t}if(e instanceof D)return{type:"Rule",name:e.name,orgText:e.orgText,definition:t(e.definition)};throw Error("non exhaustive match")}class z{visit(e){const t=e;switch(t.constructor){case M:return this.visitNonTerminal(t);case U:return this.visitAlternative(t);case F:return this.visitOption(t);case G:return this.visitRepetitionMandatory(t);case K:return this.visitRepetitionMandatoryWithSeparator(t);case j:return this.visitRepetitionWithSeparator(t);case B:return this.visitRepetition(t);case V:return this.visitAlternation(t);case H:return this.visitTerminal(t);case D:return this.visitRule(t);default:throw Error("non exhaustive match")}}visitNonTerminal(e){}visitAlternative(e){}visitOption(e){}visitRepetition(e){}visitRepetitionMandatory(e){}visitRepetitionMandatoryWithSeparator(e){}visitRepetitionWithSeparator(e){}visitAlternation(e){}visitTerminal(e){}visitRule(e){}}var Y=n(63736),X=n(6240);const q=function(e,t){var n;return(0,X.A)(e,function(e,r,i){return!(n=t(e,r,i))}),!!n};var Q=n(92049),Z=n(6832);const J=function(e,t,n){var r=(0,Q.A)(e)?Y.A:q;return n&&(0,Z.A)(e,t,n)&&(t=void 0),r(e,(0,E.A)(t,3))};var ee=n(60818),te=Math.max;const ne=function(e,t,n,r){e=(0,y.A)(e)?e:(0,i.A)(e),n=n&&!r?(0,d.A)(n):0;var s=e.length;return n<0&&(n=te(s+n,0)),(0,f.A)(e)?n<=s&&e.indexOf(t,n)>-1:!!s&&(0,ee.A)(e,t,n)>-1};const re=function(e,t){for(var n=-1,r=null==e?0:e.length;++n<r;)if(!t(e[n],n,e))return!1;return!0};const ie=function(e,t){var n=!0;return(0,X.A)(e,function(e,r,i){return n=!!t(e,r,i)}),n};const se=function(e,t,n){var r=(0,Q.A)(e)?re:ie;return n&&(0,Z.A)(e,t,n)&&(t=void 0),r(e,(0,E.A)(t,3))};function ae(e,t=[]){return!!(e instanceof F||e instanceof B||e instanceof j)||(e instanceof V?J(e.definition,e=>ae(e,t)):!(e instanceof M&&ne(t,e))&&(e instanceof P&&(e instanceof M&&t.push(e),se(e.definition,e=>ae(e,t)))))}function oe(e){if(e instanceof M)return"SUBRULE";if(e instanceof F)return"OPTION";if(e instanceof V)return"OR";if(e instanceof G)return"AT_LEAST_ONE";if(e instanceof K)return"AT_LEAST_ONE_SEP";if(e instanceof j)return"MANY_SEP";if(e instanceof B)return"MANY";if(e instanceof H)return"CONSUME";throw Error("non exhaustive match")}class le{walk(e,t=[]){(0,r.A)(e.definition,(n,r)=>{const i=h(e.definition,r+1);if(n instanceof M)this.walkProdRef(n,i,t);else if(n instanceof H)this.walkTerminal(n,i,t);else if(n instanceof U)this.walkFlat(n,i,t);else if(n instanceof F)this.walkOption(n,i,t);else if(n instanceof G)this.walkAtLeastOne(n,i,t);else if(n instanceof K)this.walkAtLeastOneSep(n,i,t);else if(n instanceof j)this.walkManySep(n,i,t);else if(n instanceof B)this.walkMany(n,i,t);else{if(!(n instanceof V))throw Error("non exhaustive match");this.walkOr(n,i,t)}})}walkTerminal(e,t,n){}walkProdRef(e,t,n){}walkFlat(e,t,n){const r=t.concat(n);this.walk(e,r)}walkOption(e,t,n){const r=t.concat(n);this.walk(e,r)}walkAtLeastOne(e,t,n){const r=[new F({definition:e.definition})].concat(t,n);this.walk(e,r)}walkAtLeastOneSep(e,t,n){const r=ce(e,t,n);this.walk(e,r)}walkMany(e,t,n){const r=[new F({definition:e.definition})].concat(t,n);this.walk(e,r)}walkManySep(e,t,n){const r=ce(e,t,n);this.walk(e,r)}walkOr(e,t,n){const i=t.concat(n);(0,r.A)(e.definition,e=>{const t=new U({definition:[e]});this.walk(t,i)})}}function ce(e,t,n){return[new F({definition:[new H({terminalType:e.separator})].concat(e.definition)})].concat(t,n)}var ue=n(99902);const de=function(e){return e&&e.length?(0,ue.A)(e):[]};var he=n(34098);function fe(e){if(e instanceof M)return fe(e.referencedRule);if(e instanceof H)return[e.terminalType];if(function(e){return e instanceof U||e instanceof F||e instanceof B||e instanceof G||e instanceof K||e instanceof j||e instanceof H||e instanceof D}(e))return function(e){let t=[];const n=e.definition;let r,i=0,s=n.length>i,a=!0;for(;s&&a;)r=n[i],a=ae(r),t=t.concat(fe(r)),i+=1,s=n.length>i;return de(t)}(e);if(function(e){return e instanceof V}(e))return function(e){const t=(0,a.A)(e.definition,e=>fe(e));return de((0,he.A)(t))}(e);throw Error("non exhaustive match")}const pe="_~IN~_";class me extends le{constructor(e){super(),this.topProd=e,this.follows={}}startWalking(){return this.walk(this.topProd),this.follows}walkTerminal(e,t,n){}walkProdRef(e,t,n){const r=(i=e.referencedRule,s=e.idx,i.name+s+pe+this.topProd.name);var i,s;const a=t.concat(n),o=fe(new U({definition:a}));this.follows[r]=o}}var ge=n(69592),ye=n(85186),Te=n(23068),Ae=n(2634),ve=n(51790);const Re=function(e){if("function"!=typeof e)throw new TypeError("Expected a function");return function(){var t=arguments;switch(t.length){case 0:return!e.call(this);case 1:return!e.call(this,t[0]);case 2:return!e.call(this,t[0],t[1]);case 3:return!e.call(this,t[0],t[1],t[2])}return!e.apply(this,t)}};const $e=function(e,t){return((0,Q.A)(e)?Ae.A:ve.A)(e,Re((0,E.A)(t,3)))};var Ee=n(89610),ke=Math.max;const xe=function(e,t,n){var r=null==e?0:e.length;if(!r)return-1;var i=null==n?0:(0,d.A)(n);return i<0&&(i=ke(r+i,0)),(0,ee.A)(e,t,i)};var Ie=n(89463),Se=n(94092),Ne=n(62062),Ce=n(83149),we=n(87809),Le=n(64099);const be=function(e,t,n,r){var i=-1,s=Ce.A,a=!0,o=e.length,l=[],c=t.length;if(!o)return l;n&&(t=(0,$.A)(t,(0,w.A)(n))),r?(s=we.A,a=!1):t.length>=200&&(s=Le.A,a=!1,t=new Ne.A(t));e:for(;++i<o;){var u=e[i],d=null==n?u:n(u);if(u=r||0!==u?u:0,a&&d==d){for(var h=c;h--;)if(t[h]===d)continue e;l.push(u)}else s(t,d,r)||l.push(u)}return l};var Oe=n(13588),_e=n(24326),Pe=n(53533);const Me=(0,_e.A)(function(e,t){return(0,Pe.A)(e)?be(e,(0,Oe.A)(t,1,Pe.A,!0)):[]});const De=function(e){for(var t=-1,n=null==e?0:e.length,r=0,i=[];++t<n;){var s=e[t];s&&(i[r++]=s)}return i};const Ue=function(e){return e&&e.length?e[0]:void 0};var Fe=n(16145);function Ge(e){console&&console.error&&console.error(`Error: ${e}`)}function Ke(e){console&&console.warn&&console.warn(`Warning: ${e}`)}let Be={};const je=new ye.H;function Ve(e){const t=e.toString();if(Be.hasOwnProperty(t))return Be[t];{const e=je.pattern(t);return Be[t]=e,e}}const He="Complement Sets are not supported for first char optimization",We='Unable to use "first char" lexer optimizations:\n';function ze(e,t=!1){try{const t=Ve(e);return Ye(t.value,{},t.flags.ignoreCase)}catch(n){if(n.message===He)t&&Ke(`${We}\tUnable to optimize: < ${e.toString()} >\n\tComplement Sets cannot be automatically optimized.\n\tThis will disable the lexer's first char optimizations.\n\tSee: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#COMPLEMENT for details.`);else{let n="";t&&(n="\n\tThis will disable the lexer's first char optimizations.\n\tSee: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#REGEXP_PARSING for details."),Ge(`${We}\n\tFailed parsing: < ${e.toString()} >\n\tUsing the @chevrotain/regexp-to-ast library\n\tPlease open an issue at: https://github.com/chevrotain/chevrotain/issues`+n)}}return[]}function Ye(e,t,n){switch(e.type){case"Disjunction":for(let r=0;r<e.value.length;r++)Ye(e.value[r],t,n);break;case"Alternative":const i=e.value;for(let e=0;e<i.length;e++){const s=i[e];switch(s.type){case"EndAnchor":case"GroupBackReference":case"Lookahead":case"NegativeLookahead":case"StartAnchor":case"WordBoundary":case"NonWordBoundary":continue}const a=s;switch(a.type){case"Character":Xe(a.value,t,n);break;case"Set":if(!0===a.complement)throw Error(He);(0,r.A)(a.value,e=>{if("number"==typeof e)Xe(e,t,n);else{const r=e;if(!0===n)for(let e=r.from;e<=r.to;e++)Xe(e,t,n);else{for(let e=r.from;e<=r.to&&e<yt;e++)Xe(e,t,n);if(r.to>=yt){const e=r.from>=yt?r.from:yt,n=r.to,i=At(e),s=At(n);for(let r=i;r<=s;r++)t[r]=r}}}});break;case"Group":Ye(a.value,t,n);break;default:throw Error("Non Exhaustive Match")}const o=void 0!==a.quantifier&&0===a.quantifier.atLeast;if("Group"===a.type&&!1===Qe(a)||"Group"!==a.type&&!1===o)break}break;default:throw Error("non exhaustive match!")}return(0,i.A)(t)}function Xe(e,t,n){const r=At(e);t[r]=r,!0===n&&function(e,t){const n=String.fromCharCode(e),r=n.toUpperCase();if(r!==n){const e=At(r.charCodeAt(0));t[e]=e}else{const e=n.toLowerCase();if(e!==n){const n=At(e.charCodeAt(0));t[n]=n}}}(e,t)}function qe(e,t){return(0,Fe.A)(e.value,e=>{if("number"==typeof e)return ne(t,e);{const n=e;return void 0!==(0,Fe.A)(t,e=>n.from<=e&&e<=n.to)}})}function Qe(e){const t=e.quantifier;return!(!t||0!==t.atLeast)||!!e.value&&((0,Q.A)(e.value)?se(e.value,Qe):Qe(e.value))}class Ze extends ye.z{constructor(e){super(),this.targetCharCodes=e,this.found=!1}visitChildren(e){if(!0!==this.found){switch(e.type){case"Lookahead":return void this.visitLookahead(e);case"NegativeLookahead":return void this.visitNegativeLookahead(e)}super.visitChildren(e)}}visitCharacter(e){ne(this.targetCharCodes,e.value)&&(this.found=!0)}visitSet(e){e.complement?void 0===qe(e,this.targetCharCodes)&&(this.found=!0):void 0!==qe(e,this.targetCharCodes)&&(this.found=!0)}}function Je(e,t){if(t instanceof RegExp){const n=Ve(t),r=new Ze(e);return r.visit(n),r.found}return void 0!==(0,Fe.A)(t,t=>ne(e,t.charCodeAt(0)))}const et="PATTERN",tt="defaultMode",nt="modes";let rt="boolean"==typeof new RegExp("(?:)").sticky;function it(e,t){const n=(t=(0,Te.A)(t,{useSticky:rt,debug:!1,safeMode:!1,positionTracking:"full",lineTerminatorCharacters:["\r","\n"],tracer:(e,t)=>t()})).tracer;let i;n("initCharCodeToOptimizedIndexMap",()=>{!function(){if((0,s.A)(Tt)){Tt=new Array(65536);for(let e=0;e<65536;e++)Tt[e]=e>255?255+~~(e/255):e}}()}),n("Reject Lexer.NA",()=>{i=$e(e,e=>e[et]===Mt.NA)});let l,c,u,d,h,p,m,g,y,T,A,v=!1;n("Transform Patterns",()=>{v=!1,l=(0,a.A)(i,e=>{const n=e[et];if(O(n)){const e=n.source;return 1!==e.length||"^"===e||"$"===e||"."===e||n.ignoreCase?2!==e.length||"\\"!==e[0]||ne(["d","D","s","S","t","r","n","t","0","c","b","B","f","v","w","W"],e[1])?t.useSticky?ct(n):lt(n):e[1]:e}if((0,Ee.A)(n))return v=!0,{exec:n};if("object"==typeof n)return v=!0,n;if("string"==typeof n){if(1===n.length)return n;{const e=n.replace(/[\\^$.*+?()[\]{}|]/g,"\\$&"),r=new RegExp(e);return t.useSticky?ct(r):lt(r)}}throw Error("non exhaustive match")})}),n("misc mapping",()=>{c=(0,a.A)(i,e=>e.tokenTypeIdx),u=(0,a.A)(i,e=>{const t=e.GROUP;if(t!==Mt.SKIPPED){if((0,f.A)(t))return t;if((0,ge.A)(t))return!1;throw Error("non exhaustive match")}}),d=(0,a.A)(i,e=>{const t=e.LONGER_ALT;if(t){return(0,Q.A)(t)?(0,a.A)(t,e=>xe(i,e)):[xe(i,t)]}}),h=(0,a.A)(i,e=>e.PUSH_MODE),p=(0,a.A)(i,e=>(0,o.A)(e,"POP_MODE"))}),n("Line Terminator Handling",()=>{const e=mt(t.lineTerminatorCharacters);m=(0,a.A)(i,e=>!1),"onlyOffset"!==t.positionTracking&&(m=(0,a.A)(i,t=>(0,o.A)(t,"LINE_BREAKS")?!!t.LINE_BREAKS:!1===pt(t,e)&&Je(e,t.PATTERN)))}),n("Misc Mapping #2",()=>{g=(0,a.A)(i,dt),y=(0,a.A)(l,ht),T=(0,Ie.A)(i,(e,t)=>{const n=t.GROUP;return(0,f.A)(n)&&n!==Mt.SKIPPED&&(e[n]=[]),e},{}),A=(0,a.A)(l,(e,t)=>({pattern:l[t],longerAlt:d[t],canLineTerminator:m[t],isCustom:g[t],short:y[t],group:u[t],push:h[t],pop:p[t],tokenTypeIdx:c[t],tokenType:i[t]}))});let R=!0,$=[];return t.safeMode||n("First Char Optimization",()=>{$=(0,Ie.A)(i,(e,n,i)=>{if("string"==typeof n.PATTERN){const t=At(n.PATTERN.charCodeAt(0));gt(e,t,A[i])}else if((0,Q.A)(n.START_CHARS_HINT)){let t;(0,r.A)(n.START_CHARS_HINT,n=>{const r=At("string"==typeof n?n.charCodeAt(0):n);t!==r&&(t=r,gt(e,r,A[i]))})}else if(O(n.PATTERN))if(n.PATTERN.unicode)R=!1,t.ensureOptimizations&&Ge(`${We}\tUnable to analyze < ${n.PATTERN.toString()} > pattern.\n\tThe regexp unicode flag is not currently supported by the regexp-to-ast library.\n\tThis will disable the lexer's first char optimizations.\n\tFor details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNICODE_OPTIMIZE`);else{const a=ze(n.PATTERN,t.ensureOptimizations);(0,s.A)(a)&&(R=!1),(0,r.A)(a,t=>{gt(e,t,A[i])})}else t.ensureOptimizations&&Ge(`${We}\tTokenType: <${n.name}> is using a custom token pattern without providing <start_chars_hint> parameter.\n\tThis will disable the lexer's first char optimizations.\n\tFor details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_OPTIMIZE`),R=!1;return e},[])}),{emptyGroups:T,patternIdxToConfig:A,charCodeToPatternIdxToConfig:$,hasCustom:v,canBeOptimized:R}}function st(e,t){let n=[];const i=function(e){const t=(0,Se.A)(e,e=>!(0,o.A)(e,et)),n=(0,a.A)(t,e=>({message:"Token Type: ->"+e.name+"<- missing static 'PATTERN' property",type:_t.MISSING_PATTERN,tokenTypes:[e]})),r=Me(e,t);return{errors:n,valid:r}}(e);n=n.concat(i.errors);const s=function(e){const t=(0,Se.A)(e,e=>{const t=e[et];return!(O(t)||(0,Ee.A)(t)||(0,o.A)(t,"exec")||(0,f.A)(t))}),n=(0,a.A)(t,e=>({message:"Token Type: ->"+e.name+"<- static 'PATTERN' can only be a RegExp, a Function matching the {CustomPatternMatcherFunc} type or an Object matching the {ICustomPattern} interface.",type:_t.INVALID_PATTERN,tokenTypes:[e]})),r=Me(e,t);return{errors:n,valid:r}}(i.valid),l=s.valid;return n=n.concat(s.errors),n=n.concat(function(e){let t=[];const n=(0,Se.A)(e,e=>O(e[et]));return t=t.concat(function(e){class t extends ye.z{constructor(){super(...arguments),this.found=!1}visitEndAnchor(e){this.found=!0}}const n=(0,Se.A)(e,e=>{const n=e.PATTERN;try{const e=Ve(n),r=new t;return r.visit(e),r.found}catch(r){return at.test(n.source)}}),r=(0,a.A)(n,e=>({message:"Unexpected RegExp Anchor Error:\n\tToken Type: ->"+e.name+"<- static 'PATTERN' cannot contain end of input anchor '$'\n\tSee chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS\tfor details.",type:_t.EOI_ANCHOR_FOUND,tokenTypes:[e]}));return r}(n)),t=t.concat(function(e){class t extends ye.z{constructor(){super(...arguments),this.found=!1}visitStartAnchor(e){this.found=!0}}const n=(0,Se.A)(e,e=>{const n=e.PATTERN;try{const e=Ve(n),r=new t;return r.visit(e),r.found}catch(r){return ot.test(n.source)}}),r=(0,a.A)(n,e=>({message:"Unexpected RegExp Anchor Error:\n\tToken Type: ->"+e.name+"<- static 'PATTERN' cannot contain start of input anchor '^'\n\tSee https://chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS\tfor details.",type:_t.SOI_ANCHOR_FOUND,tokenTypes:[e]}));return r}(n)),t=t.concat(function(e){const t=(0,Se.A)(e,e=>{const t=e[et];return t instanceof RegExp&&(t.multiline||t.global)}),n=(0,a.A)(t,e=>({message:"Token Type: ->"+e.name+"<- static 'PATTERN' may NOT contain global('g') or multiline('m')",type:_t.UNSUPPORTED_FLAGS_FOUND,tokenTypes:[e]}));return n}(n)),t=t.concat(function(e){const t=[];let n=(0,a.A)(e,n=>(0,Ie.A)(e,(e,r)=>(n.PATTERN.source!==r.PATTERN.source||ne(t,r)||r.PATTERN===Mt.NA||(t.push(r),e.push(r)),e),[]));n=De(n);const r=(0,Se.A)(n,e=>e.length>1),i=(0,a.A)(r,e=>{const t=(0,a.A)(e,e=>e.name);return{message:`The same RegExp pattern ->${Ue(e).PATTERN}<-has been used in all of the following Token Types: ${t.join(", ")} <-`,type:_t.DUPLICATE_PATTERNS_FOUND,tokenTypes:e}});return i}(n)),t=t.concat(function(e){const t=(0,Se.A)(e,e=>e.PATTERN.test("")),n=(0,a.A)(t,e=>({message:"Token Type: ->"+e.name+"<- static 'PATTERN' must not match an empty string",type:_t.EMPTY_MATCH_PATTERN,tokenTypes:[e]}));return n}(n)),t}(l)),n=n.concat(function(e){const t=(0,Se.A)(e,e=>{if(!(0,o.A)(e,"GROUP"))return!1;const t=e.GROUP;return t!==Mt.SKIPPED&&t!==Mt.NA&&!(0,f.A)(t)}),n=(0,a.A)(t,e=>({message:"Token Type: ->"+e.name+"<- static 'GROUP' can only be Lexer.SKIPPED/Lexer.NA/A String",type:_t.INVALID_GROUP_TYPE_FOUND,tokenTypes:[e]}));return n}(l)),n=n.concat(function(e,t){const n=(0,Se.A)(e,e=>void 0!==e.PUSH_MODE&&!ne(t,e.PUSH_MODE)),r=(0,a.A)(n,e=>({message:`Token Type: ->${e.name}<- static 'PUSH_MODE' value cannot refer to a Lexer Mode ->${e.PUSH_MODE}<-which does not exist`,type:_t.PUSH_MODE_DOES_NOT_EXIST,tokenTypes:[e]}));return r}(l,t)),n=n.concat(function(e){const t=[],n=(0,Ie.A)(e,(e,t,n)=>{const r=t.PATTERN;return r===Mt.NA||((0,f.A)(r)?e.push({str:r,idx:n,tokenType:t}):O(r)&&function(e){const t=[".","\\","[","]","|","^","$","(",")","?","*","+","{"];return void 0===(0,Fe.A)(t,t=>-1!==e.source.indexOf(t))}(r)&&e.push({str:r.source,idx:n,tokenType:t})),e},[]);return(0,r.A)(e,(e,i)=>{(0,r.A)(n,({str:n,idx:r,tokenType:s})=>{if(i<r&&function(e,t){if(O(t)){const n=t.exec(e);return null!==n&&0===n.index}if((0,Ee.A)(t))return t(e,0,[],{});if((0,o.A)(t,"exec"))return t.exec(e,0,[],{});if("string"==typeof t)return t===e;throw Error("non exhaustive match")}(n,e.PATTERN)){const n=`Token: ->${s.name}<- can never be matched.\nBecause it appears AFTER the Token Type ->${e.name}<-in the lexer's definition.\nSee https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNREACHABLE`;t.push({message:n,type:_t.UNREACHABLE_PATTERN,tokenTypes:[e,s]})}})}),t}(l)),n}const at=/[^\\][$]/;const ot=/[^\\[][\^]|^\^/;function lt(e){const t=e.ignoreCase?"i":"";return new RegExp(`^(?:${e.source})`,t)}function ct(e){const t=e.ignoreCase?"iy":"y";return new RegExp(`${e.source}`,t)}function ut(e,t,n){const s=[];let a=!1;const l=De((0,he.A)((0,i.A)(e.modes))),c=$e(l,e=>e[et]===Mt.NA),u=mt(n);return t&&(0,r.A)(c,e=>{const t=pt(e,u);if(!1!==t){const n=function(e,t){if(t.issue===_t.IDENTIFY_TERMINATOR)return`Warning: unable to identify line terminator usage in pattern.\n\tThe problem is in the <${e.name}> Token Type\n\t Root cause: ${t.errMsg}.\n\tFor details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#IDENTIFY_TERMINATOR`;if(t.issue===_t.CUSTOM_LINE_BREAK)return`Warning: A Custom Token Pattern should specify the <line_breaks> option.\n\tThe problem is in the <${e.name}> Token Type\n\tFor details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_LINE_BREAK`;throw Error("non exhaustive match")}(e,t),r={message:n,type:t.issue,tokenType:e};s.push(r)}else(0,o.A)(e,"LINE_BREAKS")?!0===e.LINE_BREAKS&&(a=!0):Je(u,e.PATTERN)&&(a=!0)}),t&&!a&&s.push({message:"Warning: No LINE_BREAKS Found.\n\tThis Lexer has been defined to track line and column information,\n\tBut none of the Token Types can be identified as matching a line terminator.\n\tSee https://chevrotain.io/docs/guide/resolving_lexer_errors.html#LINE_BREAKS \n\tfor details.",type:_t.NO_LINE_BREAKS_FLAGS}),s}function dt(e){const t=e.PATTERN;if(O(t))return!1;if((0,Ee.A)(t))return!0;if((0,o.A)(t,"exec"))return!0;if((0,f.A)(t))return!1;throw Error("non exhaustive match")}function ht(e){return!(!(0,f.A)(e)||1!==e.length)&&e.charCodeAt(0)}const ft={test:function(e){const t=e.length;for(let n=this.lastIndex;n<t;n++){const t=e.charCodeAt(n);if(10===t)return this.lastIndex=n+1,!0;if(13===t)return 10===e.charCodeAt(n+1)?this.lastIndex=n+2:this.lastIndex=n+1,!0}return!1},lastIndex:0};function pt(e,t){if((0,o.A)(e,"LINE_BREAKS"))return!1;if(O(e.PATTERN)){try{Je(t,e.PATTERN)}catch(n){return{issue:_t.IDENTIFY_TERMINATOR,errMsg:n.message}}return!1}if((0,f.A)(e.PATTERN))return!1;if(dt(e))return{issue:_t.CUSTOM_LINE_BREAK};throw Error("non exhaustive match")}function mt(e){return(0,a.A)(e,e=>(0,f.A)(e)?e.charCodeAt(0):e)}function gt(e,t,n){void 0===e[t]?e[t]=[n]:e[t].push(n)}const yt=256;let Tt=[];function At(e){return e<yt?e:Tt[e]}var vt=n(29008),Rt=n(42302),$t=n(26666);function Et(e){const t=(new Date).getTime(),n=e();return{time:(new Date).getTime()-t,value:n}}function kt(e,t){const n=e.tokenTypeIdx;return n===t.tokenTypeIdx||!0===t.isParent&&!0===t.categoryMatchesMap[n]}function xt(e,t){return e.tokenTypeIdx===t.tokenTypeIdx}let It=1;const St={};function Nt(e){const t=function(e){let t=(0,l.A)(e),n=e,r=!0;for(;r;){n=De((0,he.A)((0,a.A)(n,e=>e.CATEGORIES)));const e=Me(n,t);t=t.concat(e),(0,s.A)(e)?r=!1:n=e}return t}(e);!function(e){(0,r.A)(e,e=>{var t;wt(e)||(St[It]=e,e.tokenTypeIdx=It++),Lt(e)&&!(0,Q.A)(e.CATEGORIES)&&(e.CATEGORIES=[e.CATEGORIES]),Lt(e)||(e.CATEGORIES=[]),t=e,(0,o.A)(t,"categoryMatches")||(e.categoryMatches=[]),function(e){return(0,o.A)(e,"categoryMatchesMap")}(e)||(e.categoryMatchesMap={})})}(t),function(e){(0,r.A)(e,e=>{Ct([],e)})}(t),function(e){(0,r.A)(e,e=>{e.categoryMatches=[],(0,r.A)(e.categoryMatchesMap,(t,n)=>{e.categoryMatches.push(St[n].tokenTypeIdx)})})}(t),(0,r.A)(t,e=>{e.isParent=e.categoryMatches.length>0})}function Ct(e,t){(0,r.A)(e,e=>{t.categoryMatchesMap[e.tokenTypeIdx]=!0}),(0,r.A)(t.CATEGORIES,n=>{const r=e.concat(t);ne(r,n)||Ct(r,n)})}function wt(e){return(0,o.A)(e,"tokenTypeIdx")}function Lt(e){return(0,o.A)(e,"CATEGORIES")}function bt(e){return(0,o.A)(e,"tokenTypeIdx")}const Ot={buildUnableToPopLexerModeMessage:e=>`Unable to pop Lexer Mode after encountering Token ->${e.image}<- The Mode Stack is empty`,buildUnexpectedCharactersMessage:(e,t,n,r,i)=>`unexpected character: ->${e.charAt(t)}<- at offset: ${t}, skipped ${n} characters.`};var _t;!function(e){e[e.MISSING_PATTERN=0]="MISSING_PATTERN",e[e.INVALID_PATTERN=1]="INVALID_PATTERN",e[e.EOI_ANCHOR_FOUND=2]="EOI_ANCHOR_FOUND",e[e.UNSUPPORTED_FLAGS_FOUND=3]="UNSUPPORTED_FLAGS_FOUND",e[e.DUPLICATE_PATTERNS_FOUND=4]="DUPLICATE_PATTERNS_FOUND",e[e.INVALID_GROUP_TYPE_FOUND=5]="INVALID_GROUP_TYPE_FOUND",e[e.PUSH_MODE_DOES_NOT_EXIST=6]="PUSH_MODE_DOES_NOT_EXIST",e[e.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE=7]="MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE",e[e.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY=8]="MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY",e[e.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST=9]="MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST",e[e.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED=10]="LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED",e[e.SOI_ANCHOR_FOUND=11]="SOI_ANCHOR_FOUND",e[e.EMPTY_MATCH_PATTERN=12]="EMPTY_MATCH_PATTERN",e[e.NO_LINE_BREAKS_FLAGS=13]="NO_LINE_BREAKS_FLAGS",e[e.UNREACHABLE_PATTERN=14]="UNREACHABLE_PATTERN",e[e.IDENTIFY_TERMINATOR=15]="IDENTIFY_TERMINATOR",e[e.CUSTOM_LINE_BREAK=16]="CUSTOM_LINE_BREAK",e[e.MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE=17]="MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE"}(_t||(_t={}));const Pt={deferDefinitionErrorsHandling:!1,positionTracking:"full",lineTerminatorsPattern:/\n|\r\n?/g,lineTerminatorCharacters:["\n","\r"],ensureOptimizations:!1,safeMode:!1,errorMessageProvider:Ot,traceInitPerf:!1,skipValidations:!1,recoveryEnabled:!0};Object.freeze(Pt);class Mt{constructor(e,t=Pt){if(this.lexerDefinition=e,this.lexerDefinitionErrors=[],this.lexerDefinitionWarning=[],this.patternIdxToConfig={},this.charCodeToPatternIdxToConfig={},this.modes=[],this.emptyGroups={},this.trackStartLines=!0,this.trackEndLines=!0,this.hasCustom=!1,this.canModeBeOptimized={},this.TRACE_INIT=(e,t)=>{if(!0===this.traceInitPerf){this.traceInitIndent++;const n=new Array(this.traceInitIndent+1).join("\t");this.traceInitIndent<this.traceInitMaxIdent&&console.log(`${n}--\x3e <${e}>`);const{time:r,value:i}=Et(t),s=r>10?console.warn:console.log;return this.traceInitIndent<this.traceInitMaxIdent&&s(`${n}<-- <${e}> time: ${r}ms`),this.traceInitIndent--,i}return t()},"boolean"==typeof t)throw Error("The second argument to the Lexer constructor is now an ILexerConfig Object.\na boolean 2nd argument is no longer supported");this.config=R({},Pt,t);const n=this.config.traceInitPerf;!0===n?(this.traceInitMaxIdent=1/0,this.traceInitPerf=!0):"number"==typeof n&&(this.traceInitMaxIdent=n,this.traceInitPerf=!0),this.traceInitIndent=-1,this.TRACE_INIT("Lexer Constructor",()=>{let n,i=!0;this.TRACE_INIT("Lexer Config handling",()=>{if(this.config.lineTerminatorsPattern===Pt.lineTerminatorsPattern)this.config.lineTerminatorsPattern=ft;else if(this.config.lineTerminatorCharacters===Pt.lineTerminatorCharacters)throw Error("Error: Missing <lineTerminatorCharacters> property on the Lexer config.\n\tFor details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#MISSING_LINE_TERM_CHARS");if(t.safeMode&&t.ensureOptimizations)throw Error('"safeMode" and "ensureOptimizations" flags are mutually exclusive.');this.trackStartLines=/full|onlyStart/i.test(this.config.positionTracking),this.trackEndLines=/full/i.test(this.config.positionTracking),(0,Q.A)(e)?n={modes:{defaultMode:(0,l.A)(e)},defaultMode:tt}:(i=!1,n=(0,l.A)(e))}),!1===this.config.skipValidations&&(this.TRACE_INIT("performRuntimeChecks",()=>{this.lexerDefinitionErrors=this.lexerDefinitionErrors.concat(function(e){const t=[];return(0,o.A)(e,tt)||t.push({message:"A MultiMode Lexer cannot be initialized without a <"+tt+"> property in its definition\n",type:_t.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE}),(0,o.A)(e,nt)||t.push({message:"A MultiMode Lexer cannot be initialized without a <modes> property in its definition\n",type:_t.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY}),(0,o.A)(e,nt)&&(0,o.A)(e,tt)&&!(0,o.A)(e.modes,e.defaultMode)&&t.push({message:`A MultiMode Lexer cannot be initialized with a ${tt}: <${e.defaultMode}>which does not exist\n`,type:_t.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST}),(0,o.A)(e,nt)&&(0,r.A)(e.modes,(e,n)=>{(0,r.A)(e,(i,s)=>{if((0,ge.A)(i))t.push({message:`A Lexer cannot be initialized using an undefined Token Type. Mode:<${n}> at index: <${s}>\n`,type:_t.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED});else if((0,o.A)(i,"LONGER_ALT")){const s=(0,Q.A)(i.LONGER_ALT)?i.LONGER_ALT:[i.LONGER_ALT];(0,r.A)(s,r=>{(0,ge.A)(r)||ne(e,r)||t.push({message:`A MultiMode Lexer cannot be initialized with a longer_alt <${r.name}> on token <${i.name}> outside of mode <${n}>\n`,type:_t.MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE})})}})}),t}(n,this.trackStartLines,this.config.lineTerminatorCharacters))}),this.TRACE_INIT("performWarningRuntimeChecks",()=>{this.lexerDefinitionWarning=this.lexerDefinitionWarning.concat(ut(n,this.trackStartLines,this.config.lineTerminatorCharacters))})),n.modes=n.modes?n.modes:{},(0,r.A)(n.modes,(e,t)=>{n.modes[t]=$e(e,e=>(0,ge.A)(e))});const u=(0,A.A)(n.modes);if((0,r.A)(n.modes,(e,n)=>{this.TRACE_INIT(`Mode: <${n}> processing`,()=>{if(this.modes.push(n),!1===this.config.skipValidations&&this.TRACE_INIT("validatePatterns",()=>{this.lexerDefinitionErrors=this.lexerDefinitionErrors.concat(st(e,u))}),(0,s.A)(this.lexerDefinitionErrors)){let r;Nt(e),this.TRACE_INIT("analyzeTokenTypes",()=>{r=it(e,{lineTerminatorCharacters:this.config.lineTerminatorCharacters,positionTracking:t.positionTracking,ensureOptimizations:t.ensureOptimizations,safeMode:t.safeMode,tracer:this.TRACE_INIT})}),this.patternIdxToConfig[n]=r.patternIdxToConfig,this.charCodeToPatternIdxToConfig[n]=r.charCodeToPatternIdxToConfig,this.emptyGroups=R({},this.emptyGroups,r.emptyGroups),this.hasCustom=r.hasCustom||this.hasCustom,this.canModeBeOptimized[n]=r.canBeOptimized}})}),this.defaultMode=n.defaultMode,!(0,s.A)(this.lexerDefinitionErrors)&&!this.config.deferDefinitionErrorsHandling){const e=(0,a.A)(this.lexerDefinitionErrors,e=>e.message).join("-----------------------\n");throw new Error("Errors detected in definition of Lexer:\n"+e)}(0,r.A)(this.lexerDefinitionWarning,e=>{Ke(e.message)}),this.TRACE_INIT("Choosing sub-methods implementations",()=>{if(rt?(this.chopInput=vt.A,this.match=this.matchWithTest):(this.updateLastIndex=Rt.A,this.match=this.matchWithExec),i&&(this.handleModes=Rt.A),!1===this.trackStartLines&&(this.computeNewColumn=vt.A),!1===this.trackEndLines&&(this.updateTokenEndLineColumnLocation=Rt.A),/full/i.test(this.config.positionTracking))this.createTokenInstance=this.createFullToken;else if(/onlyStart/i.test(this.config.positionTracking))this.createTokenInstance=this.createStartOnlyToken;else{if(!/onlyOffset/i.test(this.config.positionTracking))throw Error(`Invalid <positionTracking> config option: "${this.config.positionTracking}"`);this.createTokenInstance=this.createOffsetOnlyToken}this.hasCustom?(this.addToken=this.addTokenUsingPush,this.handlePayload=this.handlePayloadWithCustom):(this.addToken=this.addTokenUsingMemberAccess,this.handlePayload=this.handlePayloadNoCustom)}),this.TRACE_INIT("Failed Optimization Warnings",()=>{const e=(0,Ie.A)(this.canModeBeOptimized,(e,t,n)=>(!1===t&&e.push(n),e),[]);if(t.ensureOptimizations&&!(0,s.A)(e))throw Error(`Lexer Modes: < ${e.join(", ")} > cannot be optimized.\n\t Disable the "ensureOptimizations" lexer config flag to silently ignore this and run the lexer in an un-optimized mode.\n\t Or inspect the console log for details on how to resolve these issues.`)}),this.TRACE_INIT("clearRegExpParserCache",()=>{Be={}}),this.TRACE_INIT("toFastProperties",()=>{c(this)})})}tokenize(e,t=this.defaultMode){if(!(0,s.A)(this.lexerDefinitionErrors)){const e=(0,a.A)(this.lexerDefinitionErrors,e=>e.message).join("-----------------------\n");throw new Error("Unable to Tokenize because Errors detected in definition of Lexer:\n"+e)}return this.tokenizeInternal(e,t)}tokenizeInternal(e,t){let n,i,s,a,o,l,c,u,d,h,f,p,m,g,y;const T=e,v=T.length;let R=0,$=0;const E=this.hasCustom?0:Math.floor(e.length/10),k=new Array(E),x=[];let I=this.trackStartLines?1:void 0,S=this.trackStartLines?1:void 0;const N=function(e){const t={},n=(0,A.A)(e);return(0,r.A)(n,n=>{const r=e[n];if(!(0,Q.A)(r))throw Error("non exhaustive match");t[n]=[]}),t}(this.emptyGroups),C=this.trackStartLines,w=this.config.lineTerminatorsPattern;let L=0,b=[],O=[];const _=[],P=[];let M;function D(){return b}function U(e){const t=At(e),n=O[t];return void 0===n?P:n}Object.freeze(P);const F=e=>{if(1===_.length&&void 0===e.tokenType.PUSH_MODE){const t=this.config.errorMessageProvider.buildUnableToPopLexerModeMessage(e);x.push({offset:e.startOffset,line:e.startLine,column:e.startColumn,length:e.image.length,message:t})}else{_.pop();const e=(0,$t.A)(_);b=this.patternIdxToConfig[e],O=this.charCodeToPatternIdxToConfig[e],L=b.length;const t=this.canModeBeOptimized[e]&&!1===this.config.safeMode;M=O&&t?U:D}};function G(e){_.push(e),O=this.charCodeToPatternIdxToConfig[e],b=this.patternIdxToConfig[e],L=b.length,L=b.length;const t=this.canModeBeOptimized[e]&&!1===this.config.safeMode;M=O&&t?U:D}let K;G.call(this,t);const B=this.config.recoveryEnabled;for(;R<v;){l=null;const t=T.charCodeAt(R),r=M(t),A=r.length;for(n=0;n<A;n++){K=r[n];const i=K.pattern;c=null;const d=K.short;if(!1!==d?t===d&&(l=i):!0===K.isCustom?(y=i.exec(T,R,k,N),null!==y?(l=y[0],void 0!==y.payload&&(c=y.payload)):l=null):(this.updateLastIndex(i,R),l=this.match(i,e,R)),null!==l){if(o=K.longerAlt,void 0!==o){const t=o.length;for(s=0;s<t;s++){const t=b[o[s]],n=t.pattern;if(u=null,!0===t.isCustom?(y=n.exec(T,R,k,N),null!==y?(a=y[0],void 0!==y.payload&&(u=y.payload)):a=null):(this.updateLastIndex(n,R),a=this.match(n,e,R)),a&&a.length>l.length){l=a,c=u,K=t;break}}}break}}if(null!==l){if(d=l.length,h=K.group,void 0!==h&&(f=K.tokenTypeIdx,p=this.createTokenInstance(l,R,f,K.tokenType,I,S,d),this.handlePayload(p,c),!1===h?$=this.addToken(k,$,p):N[h].push(p)),e=this.chopInput(e,d),R+=d,S=this.computeNewColumn(S,d),!0===C&&!0===K.canLineTerminator){let e,t,n=0;w.lastIndex=0;do{e=w.test(l),!0===e&&(t=w.lastIndex-1,n++)}while(!0===e);0!==n&&(I+=n,S=d-t,this.updateTokenEndLineColumnLocation(p,h,t,n,I,S,d))}this.handleModes(K,F,G,p)}else{const t=R,n=I,r=S;let s=!1===B;for(;!1===s&&R<v;)for(e=this.chopInput(e,1),R++,i=0;i<L;i++){const t=b[i],n=t.pattern,r=t.short;if(!1!==r?T.charCodeAt(R)===r&&(s=!0):!0===t.isCustom?s=null!==n.exec(T,R,k,N):(this.updateLastIndex(n,R),s=null!==n.exec(e)),!0===s)break}if(m=R-t,S=this.computeNewColumn(S,m),g=this.config.errorMessageProvider.buildUnexpectedCharactersMessage(T,t,m,n,r),x.push({offset:t,line:n,column:r,length:m,message:g}),!1===B)break}}return this.hasCustom||(k.length=$),{tokens:k,groups:N,errors:x}}handleModes(e,t,n,r){if(!0===e.pop){const i=e.push;t(r),void 0!==i&&n.call(this,i)}else void 0!==e.push&&n.call(this,e.push)}chopInput(e,t){return e.substring(t)}updateLastIndex(e,t){e.lastIndex=t}updateTokenEndLineColumnLocation(e,t,n,r,i,s,a){let o,l;void 0!==t&&(o=n===a-1,l=o?-1:0,1===r&&!0===o||(e.endLine=i+l,e.endColumn=s-1-l))}computeNewColumn(e,t){return e+t}createOffsetOnlyToken(e,t,n,r){return{image:e,startOffset:t,tokenTypeIdx:n,tokenType:r}}createStartOnlyToken(e,t,n,r,i,s){return{image:e,startOffset:t,startLine:i,startColumn:s,tokenTypeIdx:n,tokenType:r}}createFullToken(e,t,n,r,i,s,a){return{image:e,startOffset:t,endOffset:t+a-1,startLine:i,endLine:i,startColumn:s,endColumn:s+a-1,tokenTypeIdx:n,tokenType:r}}addTokenUsingPush(e,t,n){return e.push(n),t}addTokenUsingMemberAccess(e,t,n){return e[t]=n,++t}handlePayloadNoCustom(e,t){}handlePayloadWithCustom(e,t){null!==t&&(e.payload=t)}matchWithTest(e,t,n){return!0===e.test(t)?t.substring(n,e.lastIndex):null}matchWithExec(e,t){const n=e.exec(t);return null!==n?n[0]:null}}function Dt(e){return Ut(e)?e.LABEL:e.name}function Ut(e){return(0,f.A)(e.LABEL)&&""!==e.LABEL}Mt.SKIPPED="This marks a skipped Token pattern, this means each token identified by it willbe consumed and then thrown into oblivion, this can be used to for example to completely ignore whitespace.",Mt.NA=/NOT_APPLICABLE/;const Ft="parent",Gt="categories",Kt="label",Bt="group",jt="push_mode",Vt="pop_mode",Ht="longer_alt",Wt="line_breaks",zt="start_chars_hint";function Yt(e){return function(e){const t=e.pattern,n={};n.name=e.name,(0,ge.A)(t)||(n.PATTERN=t);if((0,o.A)(e,Ft))throw"The parent property is no longer supported.\nSee: https://github.com/chevrotain/chevrotain/issues/564#issuecomment-349062346 for details.";(0,o.A)(e,Gt)&&(n.CATEGORIES=e[Gt]);Nt([n]),(0,o.A)(e,Kt)&&(n.LABEL=e[Kt]);(0,o.A)(e,Bt)&&(n.GROUP=e[Bt]);(0,o.A)(e,Vt)&&(n.POP_MODE=e[Vt]);(0,o.A)(e,jt)&&(n.PUSH_MODE=e[jt]);(0,o.A)(e,Ht)&&(n.LONGER_ALT=e[Ht]);(0,o.A)(e,Wt)&&(n.LINE_BREAKS=e[Wt]);(0,o.A)(e,zt)&&(n.START_CHARS_HINT=e[zt]);return n}(e)}const Xt=Yt({name:"EOF",pattern:Mt.NA});function qt(e,t,n,r,i,s,a,o){return{image:t,startOffset:n,endOffset:r,startLine:i,endLine:s,startColumn:a,endColumn:o,tokenTypeIdx:e.tokenTypeIdx,tokenType:e}}function Qt(e,t){return kt(e,t)}Nt([Xt]);const Zt={buildMismatchTokenMessage:({expected:e,actual:t,previous:n,ruleName:r})=>`Expecting ${Ut(e)?`--\x3e ${Dt(e)} <--`:`token of type --\x3e ${e.name} <--`} but found --\x3e '${t.image}' <--`,buildNotAllInputParsedMessage:({firstRedundant:e,ruleName:t})=>"Redundant input, expecting EOF but found: "+e.image,buildNoViableAltMessage({expectedPathsPerAlt:e,actual:t,previous:n,customUserDescription:r,ruleName:i}){const s="Expecting: ",o="\nbut found: '"+Ue(t).image+"'";if(r)return s+r+o;{const t=(0,Ie.A)(e,(e,t)=>e.concat(t),[]),n=(0,a.A)(t,e=>`[${(0,a.A)(e,e=>Dt(e)).join(", ")}]`);return s+`one of these possible Token sequences:\n${(0,a.A)(n,(e,t)=>` ${t+1}. ${e}`).join("\n")}`+o}},buildEarlyExitMessage({expectedIterationPaths:e,actual:t,customUserDescription:n,ruleName:r}){const i="Expecting: ",s="\nbut found: '"+Ue(t).image+"'";if(n)return i+n+s;return i+`expecting at least one iteration which starts with one of these possible Token sequences::\n <${(0,a.A)(e,e=>`[${(0,a.A)(e,e=>Dt(e)).join(",")}]`).join(" ,")}>`+s}};Object.freeze(Zt);const Jt={buildRuleNotFoundError:(e,t)=>"Invalid grammar, reference to a rule which is not defined: ->"+t.nonTerminalName+"<-\ninside top level rule: ->"+e.name+"<-"},en={buildDuplicateFoundError(e,t){const n=e.name,r=Ue(t),i=r.idx,s=oe(r),a=(o=r)instanceof H?o.terminalType.name:o instanceof M?o.nonTerminalName:"";var o;let l=`->${s}${i>0?i:""}<- ${a?`with argument: ->${a}<-`:""}\n appears more than once (${t.length} times) in the top level rule: ->${n}<-. \n For further details see: https://chevrotain.io/docs/FAQ.html#NUMERICAL_SUFFIXES \n `;return l=l.replace(/[ \t]+/g," "),l=l.replace(/\s\s+/g,"\n"),l},buildNamespaceConflictError:e=>`Namespace conflict found in grammar.\nThe grammar has both a Terminal(Token) and a Non-Terminal(Rule) named: <${e.name}>.\nTo resolve this make sure each Terminal and Non-Terminal names are unique\nThis is easy to accomplish by using the convention that Terminal names start with an uppercase letter\nand Non-Terminal names start with a lower case letter.`,buildAlternationPrefixAmbiguityError(e){const t=(0,a.A)(e.prefixPath,e=>Dt(e)).join(", "),n=0===e.alternation.idx?"":e.alternation.idx;return`Ambiguous alternatives: <${e.ambiguityIndices.join(" ,")}> due to common lookahead prefix\nin <OR${n}> inside <${e.topLevelRule.name}> Rule,\n<${t}> may appears as a prefix path in all these alternatives.\nSee: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX\nFor Further details.`},buildAlternationAmbiguityError(e){const t=(0,a.A)(e.prefixPath,e=>Dt(e)).join(", "),n=0===e.alternation.idx?"":e.alternation.idx;let r=`Ambiguous Alternatives Detected: <${e.ambiguityIndices.join(" ,")}> in <OR${n}> inside <${e.topLevelRule.name}> Rule,\n<${t}> may appears as a prefix path in all these alternatives.\n`;return r+="See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES\nFor Further details.",r},buildEmptyRepetitionError(e){let t=oe(e.repetition);0!==e.repetition.idx&&(t+=e.repetition.idx);return`The repetition <${t}> within Rule <${e.topLevelRule.name}> can never consume any tokens.\nThis could lead to an infinite loop.`},buildTokenNameError:e=>"deprecated",buildEmptyAlternationError:e=>`Ambiguous empty alternative: <${e.emptyChoiceIdx+1}> in <OR${e.alternation.idx}> inside <${e.topLevelRule.name}> Rule.\nOnly the last alternative may be an empty alternative.`,buildTooManyAlternativesError:e=>`An Alternation cannot have more than 256 alternatives:\n<OR${e.alternation.idx}> inside <${e.topLevelRule.name}> Rule.\n has ${e.alternation.definition.length+1} alternatives.`,buildLeftRecursionError(e){const t=e.topLevelRule.name;return`Left Recursion found in grammar.\nrule: <${t}> can be invoked from itself (directly or indirectly)\nwithout consuming any Tokens. The grammar path that causes this is: \n ${`${t} --\x3e ${(0,a.A)(e.leftRecursionPath,e=>e.name).concat([t]).join(" --\x3e ")}`}\n To fix this refactor your grammar to remove the left recursion.\nsee: https://en.wikipedia.org/wiki/LL_parser#Left_factoring.`},buildInvalidRuleNameError:e=>"deprecated",buildDuplicateRuleNameError(e){let t;t=e.topLevelRule instanceof D?e.topLevelRule.name:e.topLevelRule;return`Duplicate definition, rule: ->${t}<- is already defined in the grammar: ->${e.grammarName}<-`}};class tn extends z{constructor(e,t){super(),this.nameToTopRule=e,this.errMsgProvider=t,this.errors=[]}resolveRefs(){(0,r.A)((0,i.A)(this.nameToTopRule),e=>{this.currTopLevel=e,e.accept(this)})}visitNonTerminal(e){const t=this.nameToTopRule[e.nonTerminalName];if(t)e.referencedRule=t;else{const t=this.errMsgProvider.buildRuleNotFoundError(this.currTopLevel,e);this.errors.push({message:t,type:Or.UNRESOLVED_SUBRULE_REF,ruleName:this.currTopLevel.name,unresolvedRefName:e.nonTerminalName})}}}var nn=n(18139),rn=n(52528);const sn=function(e,t,n,r){for(var i=-1,s=null==e?0:e.length;++i<s;){var a=e[i];t(r,a,n(a),e)}return r};const an=function(e,t,n,r){return(0,X.A)(e,function(e,i,s){t(r,e,n(e),s)}),r};const on=function(e,t){return function(n,r){var i=(0,Q.A)(n)?sn:an,s=t?t():{};return i(n,e,(0,E.A)(r,2),s)}};var ln=Object.prototype.hasOwnProperty;const cn=on(function(e,t,n){ln.call(e,n)?e[n].push(t):(0,rn.A)(e,n,[t])});const un=function(e,t,n){var r=null==e?0:e.length;return r?(t=n||void 0===t?1:(0,d.A)(t),u(e,0,(t=r-t)<0?0:t)):[]};class dn extends le{constructor(e,t){super(),this.topProd=e,this.path=t,this.possibleTokTypes=[],this.nextProductionName="",this.nextProductionOccurrence=0,this.found=!1,this.isAtEndOfPath=!1}startWalking(){if(this.found=!1,this.path.ruleStack[0]!==this.topProd.name)throw Error("The path does not start with the walker's top Rule!");return this.ruleStack=(0,l.A)(this.path.ruleStack).reverse(),this.occurrenceStack=(0,l.A)(this.path.occurrenceStack).reverse(),this.ruleStack.pop(),this.occurrenceStack.pop(),this.updateExpectedNext(),this.walk(this.topProd),this.possibleTokTypes}walk(e,t=[]){this.found||super.walk(e,t)}walkProdRef(e,t,n){if(e.referencedRule.name===this.nextProductionName&&e.idx===this.nextProductionOccurrence){const r=t.concat(n);this.updateExpectedNext(),this.walk(e.referencedRule,r)}}updateExpectedNext(){(0,s.A)(this.ruleStack)?(this.nextProductionName="",this.nextProductionOccurrence=0,this.isAtEndOfPath=!0):(this.nextProductionName=this.ruleStack.pop(),this.nextProductionOccurrence=this.occurrenceStack.pop())}}class hn extends dn{constructor(e,t){super(e,t),this.path=t,this.nextTerminalName="",this.nextTerminalOccurrence=0,this.nextTerminalName=this.path.lastTok.name,this.nextTerminalOccurrence=this.path.lastTokOccurrence}walkTerminal(e,t,n){if(this.isAtEndOfPath&&e.terminalType.name===this.nextTerminalName&&e.idx===this.nextTerminalOccurrence&&!this.found){const e=t.concat(n),r=new U({definition:e});this.possibleTokTypes=fe(r),this.found=!0}}}class fn extends le{constructor(e,t){super(),this.topRule=e,this.occurrence=t,this.result={token:void 0,occurrence:void 0,isEndOfRule:void 0}}startWalking(){return this.walk(this.topRule),this.result}}class pn extends fn{walkMany(e,t,n){if(e.idx===this.occurrence){const e=Ue(t.concat(n));this.result.isEndOfRule=void 0===e,e instanceof H&&(this.result.token=e.terminalType,this.result.occurrence=e.idx)}else super.walkMany(e,t,n)}}class mn extends fn{walkManySep(e,t,n){if(e.idx===this.occurrence){const e=Ue(t.concat(n));this.result.isEndOfRule=void 0===e,e instanceof H&&(this.result.token=e.terminalType,this.result.occurrence=e.idx)}else super.walkManySep(e,t,n)}}class gn extends fn{walkAtLeastOne(e,t,n){if(e.idx===this.occurrence){const e=Ue(t.concat(n));this.result.isEndOfRule=void 0===e,e instanceof H&&(this.result.token=e.terminalType,this.result.occurrence=e.idx)}else super.walkAtLeastOne(e,t,n)}}class yn extends fn{walkAtLeastOneSep(e,t,n){if(e.idx===this.occurrence){const e=Ue(t.concat(n));this.result.isEndOfRule=void 0===e,e instanceof H&&(this.result.token=e.terminalType,this.result.occurrence=e.idx)}else super.walkAtLeastOneSep(e,t,n)}}function Tn(e,t,n=[]){n=(0,l.A)(n);let i=[],a=0;function o(r){const s=Tn(r.concat(h(e,a+1)),t,n);return i.concat(s)}for(;n.length<t&&a<e.length;){const t=e[a];if(t instanceof U)return o(t.definition);if(t instanceof M)return o(t.definition);if(t instanceof F)i=o(t.definition);else{if(t instanceof G){return o(t.definition.concat([new B({definition:t.definition})]))}if(t instanceof K){return o([new U({definition:t.definition}),new B({definition:[new H({terminalType:t.separator})].concat(t.definition)})])}if(t instanceof j){const e=t.definition.concat([new B({definition:[new H({terminalType:t.separator})].concat(t.definition)})]);i=o(e)}else if(t instanceof B){const e=t.definition.concat([new B({definition:t.definition})]);i=o(e)}else{if(t instanceof V)return(0,r.A)(t.definition,e=>{!1===(0,s.A)(e.definition)&&(i=o(e.definition))}),i;if(!(t instanceof H))throw Error("non exhaustive match");n.push(t.terminalType)}}a++}return i.push({partialPath:n,suffixDef:h(e,a)}),i}function An(e,t,n,r){const i="EXIT_NONE_TERMINAL",a=[i],o="EXIT_ALTERNATIVE";let c=!1;const u=t.length,d=u-r-1,f=[],p=[];for(p.push({idx:-1,def:e,ruleStack:[],occurrenceStack:[]});!(0,s.A)(p);){const e=p.pop();if(e===o){c&&(0,$t.A)(p).idx<=d&&p.pop();continue}const r=e.def,m=e.idx,g=e.ruleStack,y=e.occurrenceStack;if((0,s.A)(r))continue;const T=r[0];if(T===i){const e={idx:m,def:h(r),ruleStack:un(g),occurrenceStack:un(y)};p.push(e)}else if(T instanceof H)if(m<u-1){const e=m+1;if(n(t[e],T.terminalType)){const t={idx:e,def:h(r),ruleStack:g,occurrenceStack:y};p.push(t)}}else{if(m!==u-1)throw Error("non exhaustive match");f.push({nextTokenType:T.terminalType,nextTokenOccurrence:T.idx,ruleStack:g,occurrenceStack:y}),c=!0}else if(T instanceof M){const e=(0,l.A)(g);e.push(T.nonTerminalName);const t=(0,l.A)(y);t.push(T.idx);const n={idx:m,def:T.definition.concat(a,h(r)),ruleStack:e,occurrenceStack:t};p.push(n)}else if(T instanceof F){const e={idx:m,def:h(r),ruleStack:g,occurrenceStack:y};p.push(e),p.push(o);const t={idx:m,def:T.definition.concat(h(r)),ruleStack:g,occurrenceStack:y};p.push(t)}else if(T instanceof G){const e=new B({definition:T.definition,idx:T.idx}),t={idx:m,def:T.definition.concat([e],h(r)),ruleStack:g,occurrenceStack:y};p.push(t)}else if(T instanceof K){const e=new H({terminalType:T.separator}),t=new B({definition:[e].concat(T.definition),idx:T.idx}),n={idx:m,def:T.definition.concat([t],h(r)),ruleStack:g,occurrenceStack:y};p.push(n)}else if(T instanceof j){const e={idx:m,def:h(r),ruleStack:g,occurrenceStack:y};p.push(e),p.push(o);const t=new H({terminalType:T.separator}),n=new B({definition:[t].concat(T.definition),idx:T.idx}),i={idx:m,def:T.definition.concat([n],h(r)),ruleStack:g,occurrenceStack:y};p.push(i)}else if(T instanceof B){const e={idx:m,def:h(r),ruleStack:g,occurrenceStack:y};p.push(e),p.push(o);const t=new B({definition:T.definition,idx:T.idx}),n={idx:m,def:T.definition.concat([t],h(r)),ruleStack:g,occurrenceStack:y};p.push(n)}else if(T instanceof V)for(let t=T.definition.length-1;t>=0;t--){const e={idx:m,def:T.definition[t].definition.concat(h(r)),ruleStack:g,occurrenceStack:y};p.push(e),p.push(o)}else if(T instanceof U)p.push({idx:m,def:T.definition.concat(h(r)),ruleStack:g,occurrenceStack:y});else{if(!(T instanceof D))throw Error("non exhaustive match");p.push(vn(T,m,g,y))}}return f}function vn(e,t,n,r){const i=(0,l.A)(n);i.push(e.name);const s=(0,l.A)(r);return s.push(1),{idx:t,def:e.definition,ruleStack:i,occurrenceStack:s}}var Rn;function $n(e){if(e instanceof F||"Option"===e)return Rn.OPTION;if(e instanceof B||"Repetition"===e)return Rn.REPETITION;if(e instanceof G||"RepetitionMandatory"===e)return Rn.REPETITION_MANDATORY;if(e instanceof K||"RepetitionMandatoryWithSeparator"===e)return Rn.REPETITION_MANDATORY_WITH_SEPARATOR;if(e instanceof j||"RepetitionWithSeparator"===e)return Rn.REPETITION_WITH_SEPARATOR;if(e instanceof V||"Alternation"===e)return Rn.ALTERNATION;throw Error("non exhaustive match")}function En(e){const{occurrence:t,rule:n,prodType:r,maxLookahead:i}=e,s=$n(r);return s===Rn.ALTERNATION?bn(t,n,i):On(t,n,s,i)}function kn(e,t,n,i){const s=e.length,l=se(e,e=>se(e,e=>1===e.length));if(t)return function(t){const r=(0,a.A)(t,e=>e.GATE);for(let i=0;i<s;i++){const t=e[i],s=t.length,a=r[i];if(void 0===a||!1!==a.call(this))e:for(let e=0;e<s;e++){const r=t[e],s=r.length;for(let e=0;e<s;e++){const t=this.LA(e+1);if(!1===n(t,r[e]))continue e}return i}}};if(l&&!i){const t=(0,a.A)(e,e=>(0,he.A)(e)),n=(0,Ie.A)(t,(e,t,n)=>((0,r.A)(t,t=>{(0,o.A)(e,t.tokenTypeIdx)||(e[t.tokenTypeIdx]=n),(0,r.A)(t.categoryMatches,t=>{(0,o.A)(e,t)||(e[t]=n)})}),e),{});return function(){const e=this.LA(1);return n[e.tokenTypeIdx]}}return function(){for(let t=0;t<s;t++){const r=e[t],i=r.length;e:for(let e=0;e<i;e++){const i=r[e],s=i.length;for(let e=0;e<s;e++){const t=this.LA(e+1);if(!1===n(t,i[e]))continue e}return t}}}}function xn(e,t,n){const i=se(e,e=>1===e.length),a=e.length;if(i&&!n){const t=(0,he.A)(e);if(1===t.length&&(0,s.A)(t[0].categoryMatches)){const e=t[0].tokenTypeIdx;return function(){return this.LA(1).tokenTypeIdx===e}}{const e=(0,Ie.A)(t,(e,t,n)=>(e[t.tokenTypeIdx]=!0,(0,r.A)(t.categoryMatches,t=>{e[t]=!0}),e),[]);return function(){const t=this.LA(1);return!0===e[t.tokenTypeIdx]}}}return function(){e:for(let n=0;n<a;n++){const r=e[n],i=r.length;for(let e=0;e<i;e++){const n=this.LA(e+1);if(!1===t(n,r[e]))continue e}return!0}return!1}}!function(e){e[e.OPTION=0]="OPTION",e[e.REPETITION=1]="REPETITION",e[e.REPETITION_MANDATORY=2]="REPETITION_MANDATORY",e[e.REPETITION_MANDATORY_WITH_SEPARATOR=3]="REPETITION_MANDATORY_WITH_SEPARATOR",e[e.REPETITION_WITH_SEPARATOR=4]="REPETITION_WITH_SEPARATOR",e[e.ALTERNATION=5]="ALTERNATION"}(Rn||(Rn={}));class In extends le{constructor(e,t,n){super(),this.topProd=e,this.targetOccurrence=t,this.targetProdType=n}startWalking(){return this.walk(this.topProd),this.restDef}checkIsTarget(e,t,n,r){return e.idx===this.targetOccurrence&&this.targetProdType===t&&(this.restDef=n.concat(r),!0)}walkOption(e,t,n){this.checkIsTarget(e,Rn.OPTION,t,n)||super.walkOption(e,t,n)}walkAtLeastOne(e,t,n){this.checkIsTarget(e,Rn.REPETITION_MANDATORY,t,n)||super.walkOption(e,t,n)}walkAtLeastOneSep(e,t,n){this.checkIsTarget(e,Rn.REPETITION_MANDATORY_WITH_SEPARATOR,t,n)||super.walkOption(e,t,n)}walkMany(e,t,n){this.checkIsTarget(e,Rn.REPETITION,t,n)||super.walkOption(e,t,n)}walkManySep(e,t,n){this.checkIsTarget(e,Rn.REPETITION_WITH_SEPARATOR,t,n)||super.walkOption(e,t,n)}}class Sn extends z{constructor(e,t,n){super(),this.targetOccurrence=e,this.targetProdType=t,this.targetRef=n,this.result=[]}checkIsTarget(e,t){e.idx!==this.targetOccurrence||this.targetProdType!==t||void 0!==this.targetRef&&e!==this.targetRef||(this.result=e.definition)}visitOption(e){this.checkIsTarget(e,Rn.OPTION)}visitRepetition(e){this.checkIsTarget(e,Rn.REPETITION)}visitRepetitionMandatory(e){this.checkIsTarget(e,Rn.REPETITION_MANDATORY)}visitRepetitionMandatoryWithSeparator(e){this.checkIsTarget(e,Rn.REPETITION_MANDATORY_WITH_SEPARATOR)}visitRepetitionWithSeparator(e){this.checkIsTarget(e,Rn.REPETITION_WITH_SEPARATOR)}visitAlternation(e){this.checkIsTarget(e,Rn.ALTERNATION)}}function Nn(e){const t=new Array(e);for(let n=0;n<e;n++)t[n]=[];return t}function Cn(e){let t=[""];for(let n=0;n<e.length;n++){const r=e[n],i=[];for(let e=0;e<t.length;e++){const n=t[e];i.push(n+"_"+r.tokenTypeIdx);for(let e=0;e<r.categoryMatches.length;e++){const t="_"+r.categoryMatches[e];i.push(n+t)}}t=i}return t}function wn(e,t,n){for(let r=0;r<e.length;r++){if(r===n)continue;const i=e[r];for(let e=0;e<t.length;e++){if(!0===i[t[e]])return!1}}return!0}function Ln(e,t){const n=(0,a.A)(e,e=>Tn([e],1)),i=Nn(n.length),o=(0,a.A)(n,e=>{const t={};return(0,r.A)(e,e=>{const n=Cn(e.partialPath);(0,r.A)(n,e=>{t[e]=!0})}),t});let l=n;for(let a=1;a<=t;a++){const e=l;l=Nn(e.length);for(let n=0;n<e.length;n++){const c=e[n];for(let e=0;e<c.length;e++){const u=c[e].partialPath,d=c[e].suffixDef,h=Cn(u);if(wn(o,h,n)||(0,s.A)(d)||u.length===t){const e=i[n];if(!1===_n(e,u)){e.push(u);for(let e=0;e<h.length;e++){const t=h[e];o[n][t]=!0}}}else{const e=Tn(d,a+1,u);l[n]=l[n].concat(e),(0,r.A)(e,e=>{const t=Cn(e.partialPath);(0,r.A)(t,e=>{o[n][e]=!0})})}}}}return i}function bn(e,t,n,r){const i=new Sn(e,Rn.ALTERNATION,r);return t.accept(i),Ln(i.result,n)}function On(e,t,n,r){const i=new Sn(e,n);t.accept(i);const s=i.result,a=new In(t,e,n).startWalking();return Ln([new U({definition:s}),new U({definition:a})],r)}function _n(e,t){e:for(let n=0;n<e.length;n++){const r=e[n];if(r.length===t.length){for(let e=0;e<r.length;e++){const n=t[e],i=r[e];if(!1===(n===i||void 0!==i.categoryMatchesMap[n.tokenTypeIdx]))continue e}return!0}}return!1}function Pn(e){return se(e,e=>se(e,e=>se(e,e=>(0,s.A)(e.categoryMatches))))}function Mn(e,t,n,s){const o=(0,nn.A)(e,e=>function(e,t){const n=new Fn;e.accept(n);const r=n.allProductions,s=cn(r,Dn),o=I(s,e=>e.length>1),l=(0,a.A)((0,i.A)(o),n=>{const r=Ue(n),i=t.buildDuplicateFoundError(e,n),s=oe(r),a={message:i,type:Or.DUPLICATE_PRODUCTIONS,ruleName:e.name,dslName:s,occurrence:r.idx},o=Un(r);return o&&(a.parameter=o),a});return l}(e,n)),l=function(e,t,n){const i=[],s=(0,a.A)(t,e=>e.name);return(0,r.A)(e,e=>{const t=e.name;if(ne(s,t)){const r=n.buildNamespaceConflictError(e);i.push({message:r,type:Or.CONFLICT_TOKENS_RULES_NAMESPACE,ruleName:t})}}),i}(e,t,n),c=(0,nn.A)(e,e=>function(e,t){const n=new Bn;e.accept(n);const r=n.alternations,i=(0,nn.A)(r,n=>n.definition.length>255?[{message:t.buildTooManyAlternativesError({topLevelRule:e,alternation:n}),type:Or.TOO_MANY_ALTS,ruleName:e.name,occurrence:n.idx}]:[]);return i}(e,n)),u=(0,nn.A)(e,t=>function(e,t,n,r){const i=[],s=(0,Ie.A)(t,(t,n)=>n.name===e.name?t+1:t,0);if(s>1){const t=r.buildDuplicateRuleNameError({topLevelRule:e,grammarName:n});i.push({message:t,type:Or.DUPLICATE_RULE_NAME,ruleName:e.name})}return i}(t,e,s,n));return o.concat(l,c,u)}function Dn(e){return`${oe(e)}_#_${e.idx}_#_${Un(e)}`}function Un(e){return e instanceof H?e.terminalType.name:e instanceof M?e.nonTerminalName:""}class Fn extends z{constructor(){super(...arguments),this.allProductions=[]}visitNonTerminal(e){this.allProductions.push(e)}visitOption(e){this.allProductions.push(e)}visitRepetitionWithSeparator(e){this.allProductions.push(e)}visitRepetitionMandatory(e){this.allProductions.push(e)}visitRepetitionMandatoryWithSeparator(e){this.allProductions.push(e)}visitRepetition(e){this.allProductions.push(e)}visitAlternation(e){this.allProductions.push(e)}visitTerminal(e){this.allProductions.push(e)}}function Gn(e,t,n,r=[]){const i=[],a=Kn(t.definition);if((0,s.A)(a))return[];{const t=e.name;ne(a,e)&&i.push({message:n.buildLeftRecursionError({topLevelRule:e,leftRecursionPath:r}),type:Or.LEFT_RECURSION,ruleName:t});const s=Me(a,r.concat([e])),o=(0,nn.A)(s,t=>{const i=(0,l.A)(r);return i.push(t),Gn(e,t,n,i)});return i.concat(o)}}function Kn(e){let t=[];if((0,s.A)(e))return t;const n=Ue(e);if(n instanceof M)t.push(n.referencedRule);else if(n instanceof U||n instanceof F||n instanceof G||n instanceof K||n instanceof j||n instanceof B)t=t.concat(Kn(n.definition));else if(n instanceof V)t=(0,he.A)((0,a.A)(n.definition,e=>Kn(e.definition)));else if(!(n instanceof H))throw Error("non exhaustive match");const r=ae(n),i=e.length>1;if(r&&i){const n=h(e);return t.concat(Kn(n))}return t}class Bn extends z{constructor(){super(...arguments),this.alternations=[]}visitAlternation(e){this.alternations.push(e)}}function jn(e,t,n){const i=new Bn;e.accept(i);let s=i.alternations;s=$e(s,e=>!0===e.ignoreAmbiguities);const o=(0,nn.A)(s,i=>{const s=i.idx,o=i.maxLookahead||t,l=bn(s,e,o,i),c=function(e,t,n,i){const s=[],o=(0,Ie.A)(e,(n,i,a)=>(!0===t.definition[a].ignoreAmbiguities||(0,r.A)(i,i=>{const o=[a];(0,r.A)(e,(e,n)=>{a!==n&&_n(e,i)&&!0!==t.definition[n].ignoreAmbiguities&&o.push(n)}),o.length>1&&!_n(s,i)&&(s.push(i),n.push({alts:o,path:i}))}),n),[]),l=(0,a.A)(o,e=>{const r=(0,a.A)(e.alts,e=>e+1);return{message:i.buildAlternationAmbiguityError({topLevelRule:n,alternation:t,ambiguityIndices:r,prefixPath:e.path}),type:Or.AMBIGUOUS_ALTS,ruleName:n.name,occurrence:t.idx,alternatives:e.alts}});return l}(l,i,e,n),u=function(e,t,n,r){const i=(0,Ie.A)(e,(e,t,n)=>{const r=(0,a.A)(t,e=>({idx:n,path:e}));return e.concat(r)},[]),s=De((0,nn.A)(i,e=>{if(!0===t.definition[e.idx].ignoreAmbiguities)return[];const s=e.idx,o=e.path,l=(0,Se.A)(i,e=>{return!0!==t.definition[e.idx].ignoreAmbiguities&&e.idx<s&&(n=e.path,r=o,n.length<r.length&&se(n,(e,t)=>{const n=r[t];return e===n||n.categoryMatchesMap[e.tokenTypeIdx]}));var n,r});return(0,a.A)(l,e=>{const i=[e.idx+1,s+1],a=0===t.idx?"":t.idx;return{message:r.buildAlternationPrefixAmbiguityError({topLevelRule:n,alternation:t,ambiguityIndices:i,prefixPath:e.path}),type:Or.AMBIGUOUS_PREFIX_ALTS,ruleName:n.name,occurrence:a,alternatives:i}})}));return s}(l,i,e,n);return c.concat(u)});return o}class Vn extends z{constructor(){super(...arguments),this.allProductions=[]}visitRepetitionWithSeparator(e){this.allProductions.push(e)}visitRepetitionMandatory(e){this.allProductions.push(e)}visitRepetitionMandatoryWithSeparator(e){this.allProductions.push(e)}visitRepetition(e){this.allProductions.push(e)}}function Hn(e){const t=(0,Te.A)(e,{errMsgProvider:Jt}),n={};return(0,r.A)(e.rules,e=>{n[e.name]=e}),function(e,t){const n=new tn(e,t);return n.resolveRefs(),n.errors}(n,t.errMsgProvider)}const Wn="MismatchedTokenException",zn="NoViableAltException",Yn="EarlyExitException",Xn="NotAllInputParsedException",qn=[Wn,zn,Yn,Xn];function Qn(e){return ne(qn,e.name)}Object.freeze(qn);class Zn extends Error{constructor(e,t){super(e),this.token=t,this.resyncedTokens=[],Object.setPrototypeOf(this,new.target.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}class Jn extends Zn{constructor(e,t,n){super(e,t),this.previousToken=n,this.name=Wn}}class er extends Zn{constructor(e,t,n){super(e,t),this.previousToken=n,this.name=zn}}class tr extends Zn{constructor(e,t){super(e,t),this.name=Xn}}class nr extends Zn{constructor(e,t,n){super(e,t),this.previousToken=n,this.name=Yn}}const rr={},ir="InRuleRecoveryException";class sr extends Error{constructor(e){super(e),this.name=ir}}function ar(e,t,n,r,i,s,a){const o=this.getKeyForAutomaticLookahead(r,i);let l=this.firstAfterRepMap[o];if(void 0===l){const e=this.getCurrRuleFullName();l=new s(this.getGAstProductions()[e],i).startWalking(),this.firstAfterRepMap[o]=l}let c=l.token,u=l.occurrence;const d=l.isEndOfRule;1===this.RULE_STACK.length&&d&&void 0===c&&(c=Xt,u=1),void 0!==c&&void 0!==u&&this.shouldInRepetitionRecoveryBeTried(c,u,a)&&this.tryInRepetitionRecovery(e,t,n,c)}const or=1024,lr=1280,cr=1536;function ur(e,t,n){return n|t|e}class dr{constructor(e){var t;this.maxLookahead=null!==(t=null==e?void 0:e.maxLookahead)&&void 0!==t?t:Lr.maxLookahead}validate(e){const t=this.validateNoLeftRecursion(e.rules);if((0,s.A)(t)){const n=this.validateEmptyOrAlternatives(e.rules),r=this.validateAmbiguousAlternationAlternatives(e.rules,this.maxLookahead),i=this.validateSomeNonEmptyLookaheadPath(e.rules,this.maxLookahead);return[...t,...n,...r,...i]}return t}validateNoLeftRecursion(e){return(0,nn.A)(e,e=>Gn(e,e,en))}validateEmptyOrAlternatives(e){return(0,nn.A)(e,e=>function(e,t){const n=new Bn;e.accept(n);const r=n.alternations;return(0,nn.A)(r,n=>{const r=un(n.definition);return(0,nn.A)(r,(r,i)=>{const a=An([r],[],kt,1);return(0,s.A)(a)?[{message:t.buildEmptyAlternationError({topLevelRule:e,alternation:n,emptyChoiceIdx:i}),type:Or.NONE_LAST_EMPTY_ALT,ruleName:e.name,occurrence:n.idx,alternative:i+1}]:[]})})}(e,en))}validateAmbiguousAlternationAlternatives(e,t){return(0,nn.A)(e,e=>jn(e,t,en))}validateSomeNonEmptyLookaheadPath(e,t){return function(e,t,n){const i=[];return(0,r.A)(e,e=>{const a=new Vn;e.accept(a);const o=a.allProductions;(0,r.A)(o,r=>{const a=$n(r),o=r.maxLookahead||t,l=On(r.idx,e,a,o)[0];if((0,s.A)((0,he.A)(l))){const t=n.buildEmptyRepetitionError({topLevelRule:e,repetition:r});i.push({message:t,type:Or.NO_NON_EMPTY_LOOKAHEAD,ruleName:e.name})}})}),i}(e,t,en)}buildLookaheadForAlternation(e){return function(e,t,n,r,i,s){const a=bn(e,t,n);return s(a,r,Pn(a)?xt:kt,i)}(e.prodOccurrence,e.rule,e.maxLookahead,e.hasPredicates,e.dynamicTokensEnabled,kn)}buildLookaheadForOptional(e){return function(e,t,n,r,i,s){const a=On(e,t,i,n),o=Pn(a)?xt:kt;return s(a[0],o,r)}(e.prodOccurrence,e.rule,e.maxLookahead,e.dynamicTokensEnabled,$n(e.prodType),xn)}}const hr=new class extends z{constructor(){super(...arguments),this.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]}}reset(){this.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]}}visitOption(e){this.dslMethods.option.push(e)}visitRepetitionWithSeparator(e){this.dslMethods.repetitionWithSeparator.push(e)}visitRepetitionMandatory(e){this.dslMethods.repetitionMandatory.push(e)}visitRepetitionMandatoryWithSeparator(e){this.dslMethods.repetitionMandatoryWithSeparator.push(e)}visitRepetition(e){this.dslMethods.repetition.push(e)}visitAlternation(e){this.dslMethods.alternation.push(e)}};function fr(e,t){!0===isNaN(e.startOffset)?(e.startOffset=t.startOffset,e.endOffset=t.endOffset):e.endOffset<t.endOffset==!0&&(e.endOffset=t.endOffset)}function pr(e,t){!0===isNaN(e.startOffset)?(e.startOffset=t.startOffset,e.startColumn=t.startColumn,e.startLine=t.startLine,e.endOffset=t.endOffset,e.endColumn=t.endColumn,e.endLine=t.endLine):e.endOffset<t.endOffset==!0&&(e.endOffset=t.endOffset,e.endColumn=t.endColumn,e.endLine=t.endLine)}function mr(e,t){Object.defineProperty(e,"name",{enumerable:!1,configurable:!0,writable:!1,value:t})}function gr(e,t){const n=(0,A.A)(e),r=n.length;for(let i=0;i<r;i++){const r=e[n[i]],s=r.length;for(let e=0;e<s;e++){const n=r[e];void 0===n.tokenTypeIdx&&this[n.name](n.children,t)}}}function yr(e,t){const n=function(){};mr(n,e+"BaseSemantics");const r={visit:function(e,t){if((0,Q.A)(e)&&(e=e[0]),!(0,ge.A)(e))return this[e.name](e.children,t)},validateVisitor:function(){const e=function(e,t){const n=function(e,t){const n=(0,Se.A)(t,t=>!1===(0,Ee.A)(e[t])),r=(0,a.A)(n,t=>({msg:`Missing visitor method: <${t}> on ${e.constructor.name} CST Visitor.`,type:Tr.MISSING_METHOD,methodName:t}));return De(r)}(e,t);return n}(this,t);if(!(0,s.A)(e)){const t=(0,a.A)(e,e=>e.msg);throw Error(`Errors Detected in CST Visitor <${this.constructor.name}>:\n\t${t.join("\n\n").replace(/\n/g,"\n\t")}`)}}};return(n.prototype=r).constructor=n,n._RULE_NAMES=t,n}var Tr;!function(e){e[e.REDUNDANT_METHOD=0]="REDUNDANT_METHOD",e[e.MISSING_METHOD=1]="MISSING_METHOD"}(Tr||(Tr={}));var Ar=n(23149);const vr={description:"This Object indicates the Parser is during Recording Phase"};Object.freeze(vr);const Rr=!0,$r=Math.pow(2,8)-1,Er=Yt({name:"RECORDING_PHASE_TOKEN",pattern:Mt.NA});Nt([Er]);const kr=qt(Er,"This IToken indicates the Parser is in Recording Phase\n\tSee: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details",-1,-1,-1,-1,-1,-1);Object.freeze(kr);const xr={name:"This CSTNode indicates the Parser is in Recording Phase\n\tSee: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details",children:{}};function Ir(e,t,n,r=!1){Cr(n);const i=(0,$t.A)(this.recordingProdStack),s=(0,Ee.A)(t)?t:t.DEF,a=new e({definition:[],idx:n});return r&&(a.separator=t.SEP),(0,o.A)(t,"MAX_LOOKAHEAD")&&(a.maxLookahead=t.MAX_LOOKAHEAD),this.recordingProdStack.push(a),s.call(this),i.definition.push(a),this.recordingProdStack.pop(),vr}function Sr(e,t){Cr(t);const n=(0,$t.A)(this.recordingProdStack),i=!1===(0,Q.A)(e),s=!1===i?e:e.DEF,a=new V({definition:[],idx:t,ignoreAmbiguities:i&&!0===e.IGNORE_AMBIGUITIES});(0,o.A)(e,"MAX_LOOKAHEAD")&&(a.maxLookahead=e.MAX_LOOKAHEAD);const l=J(s,e=>(0,Ee.A)(e.GATE));return a.hasPredicates=l,n.definition.push(a),(0,r.A)(s,e=>{const t=new U({definition:[]});a.definition.push(t),(0,o.A)(e,"IGNORE_AMBIGUITIES")?t.ignoreAmbiguities=e.IGNORE_AMBIGUITIES:(0,o.A)(e,"GATE")&&(t.ignoreAmbiguities=!0),this.recordingProdStack.push(t),e.ALT.call(this),this.recordingProdStack.pop()}),vr}function Nr(e){return 0===e?"":`${e}`}function Cr(e){if(e<0||e>$r){const t=new Error(`Invalid DSL Method idx value: <${e}>\n\tIdx value must be a none negative value smaller than ${$r+1}`);throw t.KNOWN_RECORDER_ERROR=!0,t}}const wr=qt(Xt,"",NaN,NaN,NaN,NaN,NaN,NaN);Object.freeze(wr);const Lr=Object.freeze({recoveryEnabled:!1,maxLookahead:3,dynamicTokensEnabled:!1,outputCst:!0,errorMessageProvider:Zt,nodeLocationTracking:"none",traceInitPerf:!1,skipValidations:!1}),br=Object.freeze({recoveryValueFunc:()=>{},resyncEnabled:!0});var Or,_r;function Pr(e=void 0){return function(){return e}}!function(e){e[e.INVALID_RULE_NAME=0]="INVALID_RULE_NAME",e[e.DUPLICATE_RULE_NAME=1]="DUPLICATE_RULE_NAME",e[e.INVALID_RULE_OVERRIDE=2]="INVALID_RULE_OVERRIDE",e[e.DUPLICATE_PRODUCTIONS=3]="DUPLICATE_PRODUCTIONS",e[e.UNRESOLVED_SUBRULE_REF=4]="UNRESOLVED_SUBRULE_REF",e[e.LEFT_RECURSION=5]="LEFT_RECURSION",e[e.NONE_LAST_EMPTY_ALT=6]="NONE_LAST_EMPTY_ALT",e[e.AMBIGUOUS_ALTS=7]="AMBIGUOUS_ALTS",e[e.CONFLICT_TOKENS_RULES_NAMESPACE=8]="CONFLICT_TOKENS_RULES_NAMESPACE",e[e.INVALID_TOKEN_NAME=9]="INVALID_TOKEN_NAME",e[e.NO_NON_EMPTY_LOOKAHEAD=10]="NO_NON_EMPTY_LOOKAHEAD",e[e.AMBIGUOUS_PREFIX_ALTS=11]="AMBIGUOUS_PREFIX_ALTS",e[e.TOO_MANY_ALTS=12]="TOO_MANY_ALTS",e[e.CUSTOM_LOOKAHEAD_VALIDATION=13]="CUSTOM_LOOKAHEAD_VALIDATION"}(Or||(Or={}));class Mr{static performSelfAnalysis(e){throw Error("The **static** `performSelfAnalysis` method has been deprecated.\t\nUse the **instance** method with the same name instead.")}performSelfAnalysis(){this.TRACE_INIT("performSelfAnalysis",()=>{let e;this.selfAnalysisDone=!0;const t=this.className;this.TRACE_INIT("toFastProps",()=>{c(this)}),this.TRACE_INIT("Grammar Recording",()=>{try{this.enableRecording(),(0,r.A)(this.definedRulesNames,e=>{const t=this[e].originalGrammarAction;let n;this.TRACE_INIT(`${e} Rule`,()=>{n=this.topLevelRuleRecord(e,t)}),this.gastProductionsCache[e]=n})}finally{this.disableRecording()}});let n=[];if(this.TRACE_INIT("Grammar Resolving",()=>{n=Hn({rules:(0,i.A)(this.gastProductionsCache)}),this.definitionErrors=this.definitionErrors.concat(n)}),this.TRACE_INIT("Grammar Validations",()=>{if((0,s.A)(n)&&!1===this.skipValidations){const n=(e={rules:(0,i.A)(this.gastProductionsCache),tokenTypes:(0,i.A)(this.tokensMap),errMsgProvider:en,grammarName:t},Mn((e=(0,Te.A)(e,{errMsgProvider:en})).rules,e.tokenTypes,e.errMsgProvider,e.grammarName)),r=function(e){const t=e.lookaheadStrategy.validate({rules:e.rules,tokenTypes:e.tokenTypes,grammarName:e.grammarName});return(0,a.A)(t,e=>Object.assign({type:Or.CUSTOM_LOOKAHEAD_VALIDATION},e))}({lookaheadStrategy:this.lookaheadStrategy,rules:(0,i.A)(this.gastProductionsCache),tokenTypes:(0,i.A)(this.tokensMap),grammarName:t});this.definitionErrors=this.definitionErrors.concat(n,r)}var e}),(0,s.A)(this.definitionErrors)&&(this.recoveryEnabled&&this.TRACE_INIT("computeAllProdsFollows",()=>{const e=function(e){const t={};return(0,r.A)(e,e=>{const n=new me(e).startWalking();R(t,n)}),t}((0,i.A)(this.gastProductionsCache));this.resyncFollows=e}),this.TRACE_INIT("ComputeLookaheadFunctions",()=>{var e,t;null===(t=(e=this.lookaheadStrategy).initialize)||void 0===t||t.call(e,{rules:(0,i.A)(this.gastProductionsCache)}),this.preComputeLookaheadFunctions((0,i.A)(this.gastProductionsCache))})),!Mr.DEFER_DEFINITION_ERRORS_HANDLING&&!(0,s.A)(this.definitionErrors))throw e=(0,a.A)(this.definitionErrors,e=>e.message),new Error(`Parser Definition Errors detected:\n ${e.join("\n-------------------------------\n")}`)})}constructor(e,t){this.definitionErrors=[],this.selfAnalysisDone=!1;const n=this;if(n.initErrorHandler(t),n.initLexerAdapter(),n.initLooksAhead(t),n.initRecognizerEngine(e,t),n.initRecoverable(t),n.initTreeBuilder(t),n.initContentAssist(),n.initGastRecorder(t),n.initPerformanceTracer(t),(0,o.A)(t,"ignoredIssues"))throw new Error("The <ignoredIssues> IParserConfig property has been deprecated.\n\tPlease use the <IGNORE_AMBIGUITIES> flag on the relevant DSL method instead.\n\tSee: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#IGNORING_AMBIGUITIES\n\tFor further details.");this.skipValidations=(0,o.A)(t,"skipValidations")?t.skipValidations:Lr.skipValidations}}Mr.DEFER_DEFINITION_ERRORS_HANDLING=!1,_r=Mr,[class{initRecoverable(e){this.firstAfterRepMap={},this.resyncFollows={},this.recoveryEnabled=(0,o.A)(e,"recoveryEnabled")?e.recoveryEnabled:Lr.recoveryEnabled,this.recoveryEnabled&&(this.attemptInRepetitionRecovery=ar)}getTokenToInsert(e){const t=qt(e,"",NaN,NaN,NaN,NaN,NaN,NaN);return t.isInsertedInRecovery=!0,t}canTokenTypeBeInsertedInRecovery(e){return!0}canTokenTypeBeDeletedInRecovery(e){return!0}tryInRepetitionRecovery(e,t,n,r){const i=this.findReSyncTokenType(),s=this.exportLexerState(),a=[];let o=!1;const l=this.LA(1);let c=this.LA(1);const u=()=>{const e=this.LA(0),t=this.errorMessageProvider.buildMismatchTokenMessage({expected:r,actual:l,previous:e,ruleName:this.getCurrRuleFullName()}),n=new Jn(t,l,this.LA(0));n.resyncedTokens=un(a),this.SAVE_ERROR(n)};for(;!o;){if(this.tokenMatcher(c,r))return void u();if(n.call(this))return u(),void e.apply(this,t);this.tokenMatcher(c,i)?o=!0:(c=this.SKIP_TOKEN(),this.addToResyncTokens(c,a))}this.importLexerState(s)}shouldInRepetitionRecoveryBeTried(e,t,n){return!1!==n&&!this.tokenMatcher(this.LA(1),e)&&!this.isBackTracking()&&!this.canPerformInRuleRecovery(e,this.getFollowsForInRuleRecovery(e,t))}getFollowsForInRuleRecovery(e,t){const n=this.getCurrentGrammarPath(e,t);return this.getNextPossibleTokenTypes(n)}tryInRuleRecovery(e,t){if(this.canRecoverWithSingleTokenInsertion(e,t))return this.getTokenToInsert(e);if(this.canRecoverWithSingleTokenDeletion(e)){const e=this.SKIP_TOKEN();return this.consumeToken(),e}throw new sr("sad sad panda")}canPerformInRuleRecovery(e,t){return this.canRecoverWithSingleTokenInsertion(e,t)||this.canRecoverWithSingleTokenDeletion(e)}canRecoverWithSingleTokenInsertion(e,t){if(!this.canTokenTypeBeInsertedInRecovery(e))return!1;if((0,s.A)(t))return!1;const n=this.LA(1);return void 0!==(0,Fe.A)(t,e=>this.tokenMatcher(n,e))}canRecoverWithSingleTokenDeletion(e){return!!this.canTokenTypeBeDeletedInRecovery(e)&&this.tokenMatcher(this.LA(2),e)}isInCurrentRuleReSyncSet(e){const t=this.getCurrFollowKey(),n=this.getFollowSetFromFollowKey(t);return ne(n,e)}findReSyncTokenType(){const e=this.flattenFollowSet();let t=this.LA(1),n=2;for(;;){const r=(0,Fe.A)(e,e=>Qt(t,e));if(void 0!==r)return r;t=this.LA(n),n++}}getCurrFollowKey(){if(1===this.RULE_STACK.length)return rr;const e=this.getLastExplicitRuleShortName(),t=this.getLastExplicitRuleOccurrenceIndex(),n=this.getPreviousExplicitRuleShortName();return{ruleName:this.shortRuleNameToFullName(e),idxInCallingRule:t,inRule:this.shortRuleNameToFullName(n)}}buildFullFollowKeyStack(){const e=this.RULE_STACK,t=this.RULE_OCCURRENCE_STACK;return(0,a.A)(e,(n,r)=>0===r?rr:{ruleName:this.shortRuleNameToFullName(n),idxInCallingRule:t[r],inRule:this.shortRuleNameToFullName(e[r-1])})}flattenFollowSet(){const e=(0,a.A)(this.buildFullFollowKeyStack(),e=>this.getFollowSetFromFollowKey(e));return(0,he.A)(e)}getFollowSetFromFollowKey(e){if(e===rr)return[Xt];const t=e.ruleName+e.idxInCallingRule+pe+e.inRule;return this.resyncFollows[t]}addToResyncTokens(e,t){return this.tokenMatcher(e,Xt)||t.push(e),t}reSyncTo(e){const t=[];let n=this.LA(1);for(;!1===this.tokenMatcher(n,e);)n=this.SKIP_TOKEN(),this.addToResyncTokens(n,t);return un(t)}attemptInRepetitionRecovery(e,t,n,r,i,s,a){}getCurrentGrammarPath(e,t){return{ruleStack:this.getHumanReadableRuleStack(),occurrenceStack:(0,l.A)(this.RULE_OCCURRENCE_STACK),lastTok:e,lastTokOccurrence:t}}getHumanReadableRuleStack(){return(0,a.A)(this.RULE_STACK,e=>this.shortRuleNameToFullName(e))}},class{initLooksAhead(e){this.dynamicTokensEnabled=(0,o.A)(e,"dynamicTokensEnabled")?e.dynamicTokensEnabled:Lr.dynamicTokensEnabled,this.maxLookahead=(0,o.A)(e,"maxLookahead")?e.maxLookahead:Lr.maxLookahead,this.lookaheadStrategy=(0,o.A)(e,"lookaheadStrategy")?e.lookaheadStrategy:new dr({maxLookahead:this.maxLookahead}),this.lookAheadFuncsCache=new Map}preComputeLookaheadFunctions(e){(0,r.A)(e,e=>{this.TRACE_INIT(`${e.name} Rule Lookahead`,()=>{const{alternation:t,repetition:n,option:i,repetitionMandatory:s,repetitionMandatoryWithSeparator:a,repetitionWithSeparator:o}=function(e){hr.reset(),e.accept(hr);const t=hr.dslMethods;return hr.reset(),t}(e);(0,r.A)(t,t=>{const n=0===t.idx?"":t.idx;this.TRACE_INIT(`${oe(t)}${n}`,()=>{const n=this.lookaheadStrategy.buildLookaheadForAlternation({prodOccurrence:t.idx,rule:e,maxLookahead:t.maxLookahead||this.maxLookahead,hasPredicates:t.hasPredicates,dynamicTokensEnabled:this.dynamicTokensEnabled}),r=ur(this.fullRuleNameToShort[e.name],256,t.idx);this.setLaFuncCache(r,n)})}),(0,r.A)(n,t=>{this.computeLookaheadFunc(e,t.idx,768,"Repetition",t.maxLookahead,oe(t))}),(0,r.A)(i,t=>{this.computeLookaheadFunc(e,t.idx,512,"Option",t.maxLookahead,oe(t))}),(0,r.A)(s,t=>{this.computeLookaheadFunc(e,t.idx,or,"RepetitionMandatory",t.maxLookahead,oe(t))}),(0,r.A)(a,t=>{this.computeLookaheadFunc(e,t.idx,cr,"RepetitionMandatoryWithSeparator",t.maxLookahead,oe(t))}),(0,r.A)(o,t=>{this.computeLookaheadFunc(e,t.idx,lr,"RepetitionWithSeparator",t.maxLookahead,oe(t))})})})}computeLookaheadFunc(e,t,n,r,i,s){this.TRACE_INIT(`${s}${0===t?"":t}`,()=>{const s=this.lookaheadStrategy.buildLookaheadForOptional({prodOccurrence:t,rule:e,maxLookahead:i||this.maxLookahead,dynamicTokensEnabled:this.dynamicTokensEnabled,prodType:r}),a=ur(this.fullRuleNameToShort[e.name],n,t);this.setLaFuncCache(a,s)})}getKeyForAutomaticLookahead(e,t){return ur(this.getLastExplicitRuleShortName(),e,t)}getLaFuncFromCache(e){return this.lookAheadFuncsCache.get(e)}setLaFuncCache(e,t){this.lookAheadFuncsCache.set(e,t)}},class{initTreeBuilder(e){if(this.CST_STACK=[],this.outputCst=e.outputCst,this.nodeLocationTracking=(0,o.A)(e,"nodeLocationTracking")?e.nodeLocationTracking:Lr.nodeLocationTracking,this.outputCst)if(/full/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=pr,this.setNodeLocationFromNode=pr,this.cstPostRule=Rt.A,this.setInitialNodeLocation=this.setInitialNodeLocationFullRecovery):(this.setNodeLocationFromToken=Rt.A,this.setNodeLocationFromNode=Rt.A,this.cstPostRule=this.cstPostRuleFull,this.setInitialNodeLocation=this.setInitialNodeLocationFullRegular);else if(/onlyOffset/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=fr,this.setNodeLocationFromNode=fr,this.cstPostRule=Rt.A,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRecovery):(this.setNodeLocationFromToken=Rt.A,this.setNodeLocationFromNode=Rt.A,this.cstPostRule=this.cstPostRuleOnlyOffset,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRegular);else{if(!/none/i.test(this.nodeLocationTracking))throw Error(`Invalid <nodeLocationTracking> config option: "${e.nodeLocationTracking}"`);this.setNodeLocationFromToken=Rt.A,this.setNodeLocationFromNode=Rt.A,this.cstPostRule=Rt.A,this.setInitialNodeLocation=Rt.A}else this.cstInvocationStateUpdate=Rt.A,this.cstFinallyStateUpdate=Rt.A,this.cstPostTerminal=Rt.A,this.cstPostNonTerminal=Rt.A,this.cstPostRule=Rt.A}setInitialNodeLocationOnlyOffsetRecovery(e){e.location={startOffset:NaN,endOffset:NaN}}setInitialNodeLocationOnlyOffsetRegular(e){e.location={startOffset:this.LA(1).startOffset,endOffset:NaN}}setInitialNodeLocationFullRecovery(e){e.location={startOffset:NaN,startLine:NaN,startColumn:NaN,endOffset:NaN,endLine:NaN,endColumn:NaN}}setInitialNodeLocationFullRegular(e){const t=this.LA(1);e.location={startOffset:t.startOffset,startLine:t.startLine,startColumn:t.startColumn,endOffset:NaN,endLine:NaN,endColumn:NaN}}cstInvocationStateUpdate(e){const t={name:e,children:Object.create(null)};this.setInitialNodeLocation(t),this.CST_STACK.push(t)}cstFinallyStateUpdate(){this.CST_STACK.pop()}cstPostRuleFull(e){const t=this.LA(0),n=e.location;n.startOffset<=t.startOffset==1?(n.endOffset=t.endOffset,n.endLine=t.endLine,n.endColumn=t.endColumn):(n.startOffset=NaN,n.startLine=NaN,n.startColumn=NaN)}cstPostRuleOnlyOffset(e){const t=this.LA(0),n=e.location;n.startOffset<=t.startOffset==1?n.endOffset=t.endOffset:n.startOffset=NaN}cstPostTerminal(e,t){const n=this.CST_STACK[this.CST_STACK.length-1];var r,i,s;i=t,s=e,void 0===(r=n).children[s]?r.children[s]=[i]:r.children[s].push(i),this.setNodeLocationFromToken(n.location,t)}cstPostNonTerminal(e,t){const n=this.CST_STACK[this.CST_STACK.length-1];!function(e,t,n){void 0===e.children[t]?e.children[t]=[n]:e.children[t].push(n)}(n,t,e),this.setNodeLocationFromNode(n.location,e.location)}getBaseCstVisitorConstructor(){if((0,ge.A)(this.baseCstVisitorConstructor)){const e=yr(this.className,(0,A.A)(this.gastProductionsCache));return this.baseCstVisitorConstructor=e,e}return this.baseCstVisitorConstructor}getBaseCstVisitorConstructorWithDefaults(){if((0,ge.A)(this.baseCstVisitorWithDefaultsConstructor)){const e=function(e,t,n){const i=function(){};mr(i,e+"BaseSemanticsWithDefaults");const s=Object.create(n.prototype);return(0,r.A)(t,e=>{s[e]=gr}),(i.prototype=s).constructor=i,i}(this.className,(0,A.A)(this.gastProductionsCache),this.getBaseCstVisitorConstructor());return this.baseCstVisitorWithDefaultsConstructor=e,e}return this.baseCstVisitorWithDefaultsConstructor}getLastExplicitRuleShortName(){const e=this.RULE_STACK;return e[e.length-1]}getPreviousExplicitRuleShortName(){const e=this.RULE_STACK;return e[e.length-2]}getLastExplicitRuleOccurrenceIndex(){const e=this.RULE_OCCURRENCE_STACK;return e[e.length-1]}},class{initLexerAdapter(){this.tokVector=[],this.tokVectorLength=0,this.currIdx=-1}set input(e){if(!0!==this.selfAnalysisDone)throw Error("Missing <performSelfAnalysis> invocation at the end of the Parser's constructor.");this.reset(),this.tokVector=e,this.tokVectorLength=e.length}get input(){return this.tokVector}SKIP_TOKEN(){return this.currIdx<=this.tokVector.length-2?(this.consumeToken(),this.LA(1)):wr}LA(e){const t=this.currIdx+e;return t<0||this.tokVectorLength<=t?wr:this.tokVector[t]}consumeToken(){this.currIdx++}exportLexerState(){return this.currIdx}importLexerState(e){this.currIdx=e}resetLexerState(){this.currIdx=-1}moveToTerminatedState(){this.currIdx=this.tokVector.length-1}getLexerPosition(){return this.exportLexerState()}},class{initRecognizerEngine(e,t){if(this.className=this.constructor.name,this.shortRuleNameToFull={},this.fullRuleNameToShort={},this.ruleShortNameIdx=256,this.tokenMatcher=xt,this.subruleIdx=0,this.definedRulesNames=[],this.tokensMap={},this.isBackTrackingStack=[],this.RULE_STACK=[],this.RULE_OCCURRENCE_STACK=[],this.gastProductionsCache={},(0,o.A)(t,"serializedGrammar"))throw Error("The Parser's configuration can no longer contain a <serializedGrammar> property.\n\tSee: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_6-0-0\n\tFor Further details.");if((0,Q.A)(e)){if((0,s.A)(e))throw Error("A Token Vocabulary cannot be empty.\n\tNote that the first argument for the parser constructor\n\tis no longer a Token vector (since v4.0).");if("number"==typeof e[0].startOffset)throw Error("The Parser constructor no longer accepts a token vector as the first argument.\n\tSee: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_4-0-0\n\tFor Further details.")}if((0,Q.A)(e))this.tokensMap=(0,Ie.A)(e,(e,t)=>(e[t.name]=t,e),{});else if((0,o.A)(e,"modes")&&se((0,he.A)((0,i.A)(e.modes)),bt)){const t=(0,he.A)((0,i.A)(e.modes)),n=de(t);this.tokensMap=(0,Ie.A)(n,(e,t)=>(e[t.name]=t,e),{})}else{if(!(0,Ar.A)(e))throw new Error("<tokensDictionary> argument must be An Array of Token constructors, A dictionary of Token constructors or an IMultiModeLexerDefinition");this.tokensMap=(0,l.A)(e)}this.tokensMap.EOF=Xt;const n=(0,o.A)(e,"modes")?(0,he.A)((0,i.A)(e.modes)):(0,i.A)(e),r=se(n,e=>(0,s.A)(e.categoryMatches));this.tokenMatcher=r?xt:kt,Nt((0,i.A)(this.tokensMap))}defineRule(e,t,n){if(this.selfAnalysisDone)throw Error(`Grammar rule <${e}> may not be defined after the 'performSelfAnalysis' method has been called'\nMake sure that all grammar rule definitions are done before 'performSelfAnalysis' is called.`);const r=(0,o.A)(n,"resyncEnabled")?n.resyncEnabled:br.resyncEnabled,i=(0,o.A)(n,"recoveryValueFunc")?n.recoveryValueFunc:br.recoveryValueFunc,s=this.ruleShortNameIdx<<12;let a;return this.ruleShortNameIdx++,this.shortRuleNameToFull[s]=e,this.fullRuleNameToShort[e]=s,a=!0===this.outputCst?function(...n){try{this.ruleInvocationStateUpdate(s,e,this.subruleIdx),t.apply(this,n);const r=this.CST_STACK[this.CST_STACK.length-1];return this.cstPostRule(r),r}catch(a){return this.invokeRuleCatch(a,r,i)}finally{this.ruleFinallyStateUpdate()}}:function(...n){try{return this.ruleInvocationStateUpdate(s,e,this.subruleIdx),t.apply(this,n)}catch(a){return this.invokeRuleCatch(a,r,i)}finally{this.ruleFinallyStateUpdate()}},Object.assign(a,{ruleName:e,originalGrammarAction:t})}invokeRuleCatch(e,t,n){const r=1===this.RULE_STACK.length,i=t&&!this.isBackTracking()&&this.recoveryEnabled;if(Qn(e)){const t=e;if(i){const r=this.findReSyncTokenType();if(this.isInCurrentRuleReSyncSet(r)){if(t.resyncedTokens=this.reSyncTo(r),this.outputCst){const e=this.CST_STACK[this.CST_STACK.length-1];return e.recoveredNode=!0,e}return n(e)}if(this.outputCst){const e=this.CST_STACK[this.CST_STACK.length-1];e.recoveredNode=!0,t.partialCstResult=e}throw t}if(r)return this.moveToTerminatedState(),n(e);throw t}throw e}optionInternal(e,t){const n=this.getKeyForAutomaticLookahead(512,t);return this.optionInternalLogic(e,t,n)}optionInternalLogic(e,t,n){let r,i=this.getLaFuncFromCache(n);if("function"!=typeof e){r=e.DEF;const t=e.GATE;if(void 0!==t){const e=i;i=()=>t.call(this)&&e.call(this)}}else r=e;if(!0===i.call(this))return r.call(this)}atLeastOneInternal(e,t){const n=this.getKeyForAutomaticLookahead(or,e);return this.atLeastOneInternalLogic(e,t,n)}atLeastOneInternalLogic(e,t,n){let r,i=this.getLaFuncFromCache(n);if("function"!=typeof t){r=t.DEF;const e=t.GATE;if(void 0!==e){const t=i;i=()=>e.call(this)&&t.call(this)}}else r=t;if(!0!==i.call(this))throw this.raiseEarlyExitException(e,Rn.REPETITION_MANDATORY,t.ERR_MSG);{let e=this.doSingleRepetition(r);for(;!0===i.call(this)&&!0===e;)e=this.doSingleRepetition(r)}this.attemptInRepetitionRecovery(this.atLeastOneInternal,[e,t],i,or,e,gn)}atLeastOneSepFirstInternal(e,t){const n=this.getKeyForAutomaticLookahead(cr,e);this.atLeastOneSepFirstInternalLogic(e,t,n)}atLeastOneSepFirstInternalLogic(e,t,n){const r=t.DEF,i=t.SEP;if(!0!==this.getLaFuncFromCache(n).call(this))throw this.raiseEarlyExitException(e,Rn.REPETITION_MANDATORY_WITH_SEPARATOR,t.ERR_MSG);{r.call(this);const t=()=>this.tokenMatcher(this.LA(1),i);for(;!0===this.tokenMatcher(this.LA(1),i);)this.CONSUME(i),r.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,i,t,r,yn],t,cr,e,yn)}}manyInternal(e,t){const n=this.getKeyForAutomaticLookahead(768,e);return this.manyInternalLogic(e,t,n)}manyInternalLogic(e,t,n){let r,i=this.getLaFuncFromCache(n);if("function"!=typeof t){r=t.DEF;const e=t.GATE;if(void 0!==e){const t=i;i=()=>e.call(this)&&t.call(this)}}else r=t;let s=!0;for(;!0===i.call(this)&&!0===s;)s=this.doSingleRepetition(r);this.attemptInRepetitionRecovery(this.manyInternal,[e,t],i,768,e,pn,s)}manySepFirstInternal(e,t){const n=this.getKeyForAutomaticLookahead(lr,e);this.manySepFirstInternalLogic(e,t,n)}manySepFirstInternalLogic(e,t,n){const r=t.DEF,i=t.SEP;if(!0===this.getLaFuncFromCache(n).call(this)){r.call(this);const t=()=>this.tokenMatcher(this.LA(1),i);for(;!0===this.tokenMatcher(this.LA(1),i);)this.CONSUME(i),r.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,i,t,r,mn],t,lr,e,mn)}}repetitionSepSecondInternal(e,t,n,r,i){for(;n();)this.CONSUME(t),r.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,t,n,r,i],n,cr,e,i)}doSingleRepetition(e){const t=this.getLexerPosition();return e.call(this),this.getLexerPosition()>t}orInternal(e,t){const n=this.getKeyForAutomaticLookahead(256,t),r=(0,Q.A)(e)?e:e.DEF,i=this.getLaFuncFromCache(n).call(this,r);if(void 0!==i)return r[i].ALT.call(this);this.raiseNoAltException(t,e.ERR_MSG)}ruleFinallyStateUpdate(){if(this.RULE_STACK.pop(),this.RULE_OCCURRENCE_STACK.pop(),this.cstFinallyStateUpdate(),0===this.RULE_STACK.length&&!1===this.isAtEndOfInput()){const e=this.LA(1),t=this.errorMessageProvider.buildNotAllInputParsedMessage({firstRedundant:e,ruleName:this.getCurrRuleFullName()});this.SAVE_ERROR(new tr(t,e))}}subruleInternal(e,t,n){let r;try{const i=void 0!==n?n.ARGS:void 0;return this.subruleIdx=t,r=e.apply(this,i),this.cstPostNonTerminal(r,void 0!==n&&void 0!==n.LABEL?n.LABEL:e.ruleName),r}catch(i){throw this.subruleInternalError(i,n,e.ruleName)}}subruleInternalError(e,t,n){throw Qn(e)&&void 0!==e.partialCstResult&&(this.cstPostNonTerminal(e.partialCstResult,void 0!==t&&void 0!==t.LABEL?t.LABEL:n),delete e.partialCstResult),e}consumeInternal(e,t,n){let r;try{const t=this.LA(1);!0===this.tokenMatcher(t,e)?(this.consumeToken(),r=t):this.consumeInternalError(e,t,n)}catch(i){r=this.consumeInternalRecovery(e,t,i)}return this.cstPostTerminal(void 0!==n&&void 0!==n.LABEL?n.LABEL:e.name,r),r}consumeInternalError(e,t,n){let r;const i=this.LA(0);throw r=void 0!==n&&n.ERR_MSG?n.ERR_MSG:this.errorMessageProvider.buildMismatchTokenMessage({expected:e,actual:t,previous:i,ruleName:this.getCurrRuleFullName()}),this.SAVE_ERROR(new Jn(r,t,i))}consumeInternalRecovery(e,t,n){if(!this.recoveryEnabled||"MismatchedTokenException"!==n.name||this.isBackTracking())throw n;{const i=this.getFollowsForInRuleRecovery(e,t);try{return this.tryInRuleRecovery(e,i)}catch(r){throw r.name===ir?n:r}}}saveRecogState(){const e=this.errors,t=(0,l.A)(this.RULE_STACK);return{errors:e,lexerState:this.exportLexerState(),RULE_STACK:t,CST_STACK:this.CST_STACK}}reloadRecogState(e){this.errors=e.errors,this.importLexerState(e.lexerState),this.RULE_STACK=e.RULE_STACK}ruleInvocationStateUpdate(e,t,n){this.RULE_OCCURRENCE_STACK.push(n),this.RULE_STACK.push(e),this.cstInvocationStateUpdate(t)}isBackTracking(){return 0!==this.isBackTrackingStack.length}getCurrRuleFullName(){const e=this.getLastExplicitRuleShortName();return this.shortRuleNameToFull[e]}shortRuleNameToFullName(e){return this.shortRuleNameToFull[e]}isAtEndOfInput(){return this.tokenMatcher(this.LA(1),Xt)}reset(){this.resetLexerState(),this.subruleIdx=0,this.isBackTrackingStack=[],this.errors=[],this.RULE_STACK=[],this.CST_STACK=[],this.RULE_OCCURRENCE_STACK=[]}},class{ACTION(e){return e.call(this)}consume(e,t,n){return this.consumeInternal(t,e,n)}subrule(e,t,n){return this.subruleInternal(t,e,n)}option(e,t){return this.optionInternal(t,e)}or(e,t){return this.orInternal(t,e)}many(e,t){return this.manyInternal(e,t)}atLeastOne(e,t){return this.atLeastOneInternal(e,t)}CONSUME(e,t){return this.consumeInternal(e,0,t)}CONSUME1(e,t){return this.consumeInternal(e,1,t)}CONSUME2(e,t){return this.consumeInternal(e,2,t)}CONSUME3(e,t){return this.consumeInternal(e,3,t)}CONSUME4(e,t){return this.consumeInternal(e,4,t)}CONSUME5(e,t){return this.consumeInternal(e,5,t)}CONSUME6(e,t){return this.consumeInternal(e,6,t)}CONSUME7(e,t){return this.consumeInternal(e,7,t)}CONSUME8(e,t){return this.consumeInternal(e,8,t)}CONSUME9(e,t){return this.consumeInternal(e,9,t)}SUBRULE(e,t){return this.subruleInternal(e,0,t)}SUBRULE1(e,t){return this.subruleInternal(e,1,t)}SUBRULE2(e,t){return this.subruleInternal(e,2,t)}SUBRULE3(e,t){return this.subruleInternal(e,3,t)}SUBRULE4(e,t){return this.subruleInternal(e,4,t)}SUBRULE5(e,t){return this.subruleInternal(e,5,t)}SUBRULE6(e,t){return this.subruleInternal(e,6,t)}SUBRULE7(e,t){return this.subruleInternal(e,7,t)}SUBRULE8(e,t){return this.subruleInternal(e,8,t)}SUBRULE9(e,t){return this.subruleInternal(e,9,t)}OPTION(e){return this.optionInternal(e,0)}OPTION1(e){return this.optionInternal(e,1)}OPTION2(e){return this.optionInternal(e,2)}OPTION3(e){return this.optionInternal(e,3)}OPTION4(e){return this.optionInternal(e,4)}OPTION5(e){return this.optionInternal(e,5)}OPTION6(e){return this.optionInternal(e,6)}OPTION7(e){return this.optionInternal(e,7)}OPTION8(e){return this.optionInternal(e,8)}OPTION9(e){return this.optionInternal(e,9)}OR(e){return this.orInternal(e,0)}OR1(e){return this.orInternal(e,1)}OR2(e){return this.orInternal(e,2)}OR3(e){return this.orInternal(e,3)}OR4(e){return this.orInternal(e,4)}OR5(e){return this.orInternal(e,5)}OR6(e){return this.orInternal(e,6)}OR7(e){return this.orInternal(e,7)}OR8(e){return this.orInternal(e,8)}OR9(e){return this.orInternal(e,9)}MANY(e){this.manyInternal(0,e)}MANY1(e){this.manyInternal(1,e)}MANY2(e){this.manyInternal(2,e)}MANY3(e){this.manyInternal(3,e)}MANY4(e){this.manyInternal(4,e)}MANY5(e){this.manyInternal(5,e)}MANY6(e){this.manyInternal(6,e)}MANY7(e){this.manyInternal(7,e)}MANY8(e){this.manyInternal(8,e)}MANY9(e){this.manyInternal(9,e)}MANY_SEP(e){this.manySepFirstInternal(0,e)}MANY_SEP1(e){this.manySepFirstInternal(1,e)}MANY_SEP2(e){this.manySepFirstInternal(2,e)}MANY_SEP3(e){this.manySepFirstInternal(3,e)}MANY_SEP4(e){this.manySepFirstInternal(4,e)}MANY_SEP5(e){this.manySepFirstInternal(5,e)}MANY_SEP6(e){this.manySepFirstInternal(6,e)}MANY_SEP7(e){this.manySepFirstInternal(7,e)}MANY_SEP8(e){this.manySepFirstInternal(8,e)}MANY_SEP9(e){this.manySepFirstInternal(9,e)}AT_LEAST_ONE(e){this.atLeastOneInternal(0,e)}AT_LEAST_ONE1(e){return this.atLeastOneInternal(1,e)}AT_LEAST_ONE2(e){this.atLeastOneInternal(2,e)}AT_LEAST_ONE3(e){this.atLeastOneInternal(3,e)}AT_LEAST_ONE4(e){this.atLeastOneInternal(4,e)}AT_LEAST_ONE5(e){this.atLeastOneInternal(5,e)}AT_LEAST_ONE6(e){this.atLeastOneInternal(6,e)}AT_LEAST_ONE7(e){this.atLeastOneInternal(7,e)}AT_LEAST_ONE8(e){this.atLeastOneInternal(8,e)}AT_LEAST_ONE9(e){this.atLeastOneInternal(9,e)}AT_LEAST_ONE_SEP(e){this.atLeastOneSepFirstInternal(0,e)}AT_LEAST_ONE_SEP1(e){this.atLeastOneSepFirstInternal(1,e)}AT_LEAST_ONE_SEP2(e){this.atLeastOneSepFirstInternal(2,e)}AT_LEAST_ONE_SEP3(e){this.atLeastOneSepFirstInternal(3,e)}AT_LEAST_ONE_SEP4(e){this.atLeastOneSepFirstInternal(4,e)}AT_LEAST_ONE_SEP5(e){this.atLeastOneSepFirstInternal(5,e)}AT_LEAST_ONE_SEP6(e){this.atLeastOneSepFirstInternal(6,e)}AT_LEAST_ONE_SEP7(e){this.atLeastOneSepFirstInternal(7,e)}AT_LEAST_ONE_SEP8(e){this.atLeastOneSepFirstInternal(8,e)}AT_LEAST_ONE_SEP9(e){this.atLeastOneSepFirstInternal(9,e)}RULE(e,t,n=br){if(ne(this.definedRulesNames,e)){const t={message:en.buildDuplicateRuleNameError({topLevelRule:e,grammarName:this.className}),type:Or.DUPLICATE_RULE_NAME,ruleName:e};this.definitionErrors.push(t)}this.definedRulesNames.push(e);const r=this.defineRule(e,t,n);return this[e]=r,r}OVERRIDE_RULE(e,t,n=br){const r=function(e,t,n){const r=[];let i;return ne(t,e)||(i=`Invalid rule override, rule: ->${e}<- cannot be overridden in the grammar: ->${n}<-as it is not defined in any of the super grammars `,r.push({message:i,type:Or.INVALID_RULE_OVERRIDE,ruleName:e})),r}(e,this.definedRulesNames,this.className);this.definitionErrors=this.definitionErrors.concat(r);const i=this.defineRule(e,t,n);return this[e]=i,i}BACKTRACK(e,t){return function(){this.isBackTrackingStack.push(1);const n=this.saveRecogState();try{return e.apply(this,t),!0}catch(r){if(Qn(r))return!1;throw r}finally{this.reloadRecogState(n),this.isBackTrackingStack.pop()}}}getGAstProductions(){return this.gastProductionsCache}getSerializedGastProductions(){return e=(0,i.A)(this.gastProductionsCache),(0,a.A)(e,W);var e}},class{initErrorHandler(e){this._errors=[],this.errorMessageProvider=(0,o.A)(e,"errorMessageProvider")?e.errorMessageProvider:Lr.errorMessageProvider}SAVE_ERROR(e){if(Qn(e))return e.context={ruleStack:this.getHumanReadableRuleStack(),ruleOccurrenceStack:(0,l.A)(this.RULE_OCCURRENCE_STACK)},this._errors.push(e),e;throw Error("Trying to save an Error which is not a RecognitionException")}get errors(){return(0,l.A)(this._errors)}set errors(e){this._errors=e}raiseEarlyExitException(e,t,n){const r=this.getCurrRuleFullName(),i=On(e,this.getGAstProductions()[r],t,this.maxLookahead)[0],s=[];for(let o=1;o<=this.maxLookahead;o++)s.push(this.LA(o));const a=this.errorMessageProvider.buildEarlyExitMessage({expectedIterationPaths:i,actual:s,previous:this.LA(0),customUserDescription:n,ruleName:r});throw this.SAVE_ERROR(new nr(a,this.LA(1),this.LA(0)))}raiseNoAltException(e,t){const n=this.getCurrRuleFullName(),r=bn(e,this.getGAstProductions()[n],this.maxLookahead),i=[];for(let o=1;o<=this.maxLookahead;o++)i.push(this.LA(o));const s=this.LA(0),a=this.errorMessageProvider.buildNoViableAltMessage({expectedPathsPerAlt:r,actual:i,previous:s,customUserDescription:t,ruleName:this.getCurrRuleFullName()});throw this.SAVE_ERROR(new er(a,this.LA(1),s))}},class{initContentAssist(){}computeContentAssist(e,t){const n=this.gastProductionsCache[e];if((0,ge.A)(n))throw Error(`Rule ->${e}<- does not exist in this grammar.`);return An([n],t,this.tokenMatcher,this.maxLookahead)}getNextPossibleTokenTypes(e){const t=Ue(e.ruleStack),n=this.getGAstProductions()[t];return new hn(n,e).startWalking()}},class{initGastRecorder(e){this.recordingProdStack=[],this.RECORDING_PHASE=!1}enableRecording(){this.RECORDING_PHASE=!0,this.TRACE_INIT("Enable Recording",()=>{for(let e=0;e<10;e++){const t=e>0?e:"";this[`CONSUME${t}`]=function(t,n){return this.consumeInternalRecord(t,e,n)},this[`SUBRULE${t}`]=function(t,n){return this.subruleInternalRecord(t,e,n)},this[`OPTION${t}`]=function(t){return this.optionInternalRecord(t,e)},this[`OR${t}`]=function(t){return this.orInternalRecord(t,e)},this[`MANY${t}`]=function(t){this.manyInternalRecord(e,t)},this[`MANY_SEP${t}`]=function(t){this.manySepFirstInternalRecord(e,t)},this[`AT_LEAST_ONE${t}`]=function(t){this.atLeastOneInternalRecord(e,t)},this[`AT_LEAST_ONE_SEP${t}`]=function(t){this.atLeastOneSepFirstInternalRecord(e,t)}}this.consume=function(e,t,n){return this.consumeInternalRecord(t,e,n)},this.subrule=function(e,t,n){return this.subruleInternalRecord(t,e,n)},this.option=function(e,t){return this.optionInternalRecord(t,e)},this.or=function(e,t){return this.orInternalRecord(t,e)},this.many=function(e,t){this.manyInternalRecord(e,t)},this.atLeastOne=function(e,t){this.atLeastOneInternalRecord(e,t)},this.ACTION=this.ACTION_RECORD,this.BACKTRACK=this.BACKTRACK_RECORD,this.LA=this.LA_RECORD})}disableRecording(){this.RECORDING_PHASE=!1,this.TRACE_INIT("Deleting Recording methods",()=>{const e=this;for(let t=0;t<10;t++){const n=t>0?t:"";delete e[`CONSUME${n}`],delete e[`SUBRULE${n}`],delete e[`OPTION${n}`],delete e[`OR${n}`],delete e[`MANY${n}`],delete e[`MANY_SEP${n}`],delete e[`AT_LEAST_ONE${n}`],delete e[`AT_LEAST_ONE_SEP${n}`]}delete e.consume,delete e.subrule,delete e.option,delete e.or,delete e.many,delete e.atLeastOne,delete e.ACTION,delete e.BACKTRACK,delete e.LA})}ACTION_RECORD(e){}BACKTRACK_RECORD(e,t){return()=>!0}LA_RECORD(e){return wr}topLevelRuleRecord(e,t){try{const n=new D({definition:[],name:e});return n.name=e,this.recordingProdStack.push(n),t.call(this),this.recordingProdStack.pop(),n}catch(n){if(!0!==n.KNOWN_RECORDER_ERROR)try{n.message=n.message+'\n\t This error was thrown during the "grammar recording phase" For more info see:\n\thttps://chevrotain.io/docs/guide/internals.html#grammar-recording'}catch(r){throw n}throw n}}optionInternalRecord(e,t){return Ir.call(this,F,e,t)}atLeastOneInternalRecord(e,t){Ir.call(this,G,t,e)}atLeastOneSepFirstInternalRecord(e,t){Ir.call(this,K,t,e,Rr)}manyInternalRecord(e,t){Ir.call(this,B,t,e)}manySepFirstInternalRecord(e,t){Ir.call(this,j,t,e,Rr)}orInternalRecord(e,t){return Sr.call(this,e,t)}subruleInternalRecord(e,t,n){if(Cr(t),!e||!1===(0,o.A)(e,"ruleName")){const n=new Error(`<SUBRULE${Nr(t)}> argument is invalid expecting a Parser method reference but got: <${JSON.stringify(e)}>\n inside top level rule: <${this.recordingProdStack[0].name}>`);throw n.KNOWN_RECORDER_ERROR=!0,n}const r=(0,$t.A)(this.recordingProdStack),i=e.ruleName,s=new M({idx:t,nonTerminalName:i,label:null==n?void 0:n.LABEL,referencedRule:void 0});return r.definition.push(s),this.outputCst?xr:vr}consumeInternalRecord(e,t,n){if(Cr(t),!wt(e)){const n=new Error(`<CONSUME${Nr(t)}> argument is invalid expecting a TokenType reference but got: <${JSON.stringify(e)}>\n inside top level rule: <${this.recordingProdStack[0].name}>`);throw n.KNOWN_RECORDER_ERROR=!0,n}const r=(0,$t.A)(this.recordingProdStack),i=new H({idx:t,terminalType:e,label:null==n?void 0:n.LABEL});return r.definition.push(i),kr}},class{initPerformanceTracer(e){if((0,o.A)(e,"traceInitPerf")){const t=e.traceInitPerf,n="number"==typeof t;this.traceInitMaxIdent=n?t:1/0,this.traceInitPerf=n?t>0:t}else this.traceInitMaxIdent=0,this.traceInitPerf=Lr.traceInitPerf;this.traceInitIndent=-1}TRACE_INIT(e,t){if(!0===this.traceInitPerf){this.traceInitIndent++;const n=new Array(this.traceInitIndent+1).join("\t");this.traceInitIndent<this.traceInitMaxIdent&&console.log(`${n}--\x3e <${e}>`);const{time:r,value:i}=Et(t),s=r>10?console.warn:console.log;return this.traceInitIndent<this.traceInitMaxIdent&&s(`${n}<-- <${e}> time: ${r}ms`),this.traceInitIndent--,i}return t()}}].forEach(e=>{const t=e.prototype;Object.getOwnPropertyNames(t).forEach(n=>{if("constructor"===n)return;const r=Object.getOwnPropertyDescriptor(t,n);r&&(r.get||r.set)?Object.defineProperty(_r.prototype,n,r):_r.prototype[n]=e.prototype[n]})});class Dr extends Mr{constructor(e,t=Lr){const n=(0,l.A)(t);n.outputCst=!1,super(e,n)}}},71564:(e,t,n)=>{n.d(t,{W:()=>r,d:()=>i});class r extends Error{constructor(e,t){super(e?`${t} at ${e.range.start.line}:${e.range.start.character}`:t)}}function i(e){throw new Error("Error! The input value was not handled.")}},72559:(e,t,n)=>{n.d(t,{A:()=>i});var r=n(61882);const i=function(e,t,n){for(var i=-1,s=e.length;++i<s;){var a=e[i],o=t(a);if(null!=o&&(void 0===l?o==o&&!(0,r.A)(o):n(o,l)))var l=o,c=a}return c}},73858:(e,t,n)=>{n.d(t,{$:()=>c});var r=n(87960),i=n(98913),s=n(39364),a=n(51917),o=class extends r.mR{static{(0,r.K2)(this,"PacketTokenBuilder")}constructor(){super(["packet"])}},l={parser:{TokenBuilder:(0,r.K2)(()=>new o,"TokenBuilder"),ValueConverter:(0,r.K2)(()=>new r.Tm,"ValueConverter")}};function c(e=a.D){const t=(0,s.WQ)((0,i.u)(e),r.sr),n=(0,s.WQ)((0,i.t)({shared:t}),r.AM,l);return t.ServiceRegistry.register(n),{shared:t,Packet:n}}(0,r.K2)(c,"createPacketServices")},74342:(e,t,n)=>{n.d(t,{A:()=>m});var r=/\s/;const i=function(e){for(var t=e.length;t--&&r.test(e.charAt(t)););return t};var s=/^\s+/;const a=function(e){return e?e.slice(0,i(e)+1).replace(s,""):e};var o=n(23149),l=n(61882),c=/^[-+]0x[0-9a-f]+$/i,u=/^0b[01]+$/i,d=/^0o[0-7]+$/i,h=parseInt;const f=function(e){if("number"==typeof e)return e;if((0,l.A)(e))return NaN;if((0,o.A)(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=(0,o.A)(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=a(e);var n=u.test(e);return n||d.test(e)?h(e.slice(2),n?2:8):c.test(e)?NaN:+e};var p=1/0;const m=function(e){return e?(e=f(e))===p||e===-1/0?17976931348623157e292*(e<0?-1:1):e==e?e:0:0===e?e:0}},74722:(e,t,n)=>{n.d(t,{A:()=>o});var r=n(45572),i=n(23958),s=n(52568),a=n(92049);const o=function(e,t){return((0,a.A)(e)?r.A:s.A)(e,(0,i.A)(t,3))}},76373:(e,t,n)=>{n.d(t,{El:()=>d,NS:()=>a,SX:()=>c,pO:()=>o,r4:()=>u,v:()=>h,wf:()=>l});var r,i=n(32479),s=n(91719);function a(e){return new s.Vj(e,e=>(0,i.mD)(e)?e.content:[],{includeRoot:!0})}function o(e,t){for(;e.container;)if((e=e.container)===t)return!0;return!1}function l(e){return{start:{character:e.startColumn-1,line:e.startLine-1},end:{character:e.endColumn,line:e.endLine-1}}}function c(e){if(!e)return;const{offset:t,end:n,range:r}=e;return{range:r,offset:t,end:n,length:n-t}}function u(e,t){const n=function(e,t){if(e.end.line<t.start.line||e.end.line===t.start.line&&e.end.character<=t.start.character)return r.Before;if(e.start.line>t.end.line||e.start.line===t.end.line&&e.start.character>=t.end.character)return r.After;const n=e.start.line>t.start.line||e.start.line===t.start.line&&e.start.character>=t.start.character,i=e.end.line<t.end.line||e.end.line===t.end.line&&e.end.character<=t.end.character;return n&&i?r.Inside:n?r.OverlapBack:i?r.OverlapFront:r.Outside}(e,t);return n>r.After}!function(e){e[e.Before=0]="Before",e[e.After=1]="After",e[e.OverlapFront=2]="OverlapFront",e[e.OverlapBack=3]="OverlapBack",e[e.Inside=4]="Inside",e[e.Outside=5]="Outside"}(r||(r={}));const d=/^[\w\p{L}]$/u;function h(e,t){if(e){const n=function(e,t=!0){for(;e.container;){const n=e.container;let r=n.content.indexOf(e);for(;r>0;){r--;const e=n.content[r];if(t||!e.hidden)return e}e=n}return}(e,!0);if(n&&f(n,t))return n;if((0,i.br)(e)){for(let n=e.content.findIndex(e=>!e.hidden)-1;n>=0;n--){const r=e.content[n];if(f(r,t))return r}}}}function f(e,t){return(0,i.FC)(e)&&t.includes(e.tokenType.name)}},78585:(e,t)=>{function n(e){return"string"==typeof e||e instanceof String}function r(e){return Array.isArray(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.stringArray=t.array=t.func=t.error=t.number=t.string=t.boolean=void 0,t.boolean=function(e){return!0===e||!1===e},t.string=n,t.number=function(e){return"number"==typeof e||e instanceof Number},t.error=function(e){return e instanceof Error},t.func=function(e){return"function"==typeof e},t.array=r,t.stringArray=function(e){return r(e)&&e.every(e=>n(e))}},78731:(e,t,n)=>{n.d(t,{qg:()=>a});n(67539),n(91885),n(73858),n(69150),n(38980),n(87846),n(51633);var r=n(87960),i={},s={info:(0,r.K2)(async()=>{const{createInfoServices:e}=await n.e(3490).then(n.bind(n,3490)),t=e().Info.parser.LangiumParser;i.info=t},"info"),packet:(0,r.K2)(async()=>{const{createPacketServices:e}=await n.e(2325).then(n.bind(n,2325)),t=e().Packet.parser.LangiumParser;i.packet=t},"packet"),pie:(0,r.K2)(async()=>{const{createPieServices:e}=await n.e(617).then(n.bind(n,50617)),t=e().Pie.parser.LangiumParser;i.pie=t},"pie"),architecture:(0,r.K2)(async()=>{const{createArchitectureServices:e}=await n.e(6366).then(n.bind(n,86366)),t=e().Architecture.parser.LangiumParser;i.architecture=t},"architecture"),gitGraph:(0,r.K2)(async()=>{const{createGitGraphServices:e}=await n.e(4250).then(n.bind(n,81869)),t=e().GitGraph.parser.LangiumParser;i.gitGraph=t},"gitGraph"),radar:(0,r.K2)(async()=>{const{createRadarServices:e}=await n.e(1e3).then(n.bind(n,91e3)),t=e().Radar.parser.LangiumParser;i.radar=t},"radar"),treemap:(0,r.K2)(async()=>{const{createTreemapServices:e}=await n.e(5901).then(n.bind(n,75901)),t=e().Treemap.parser.LangiumParser;i.treemap=t},"treemap")};async function a(e,t){const n=s[e];if(!n)throw new Error(`Unknown diagram type: ${e}`);i[e]||await n();const r=i[e].parse(t);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new o(r);return r.value}(0,r.K2)(a,"parse");var o=class extends Error{constructor(e){super(`Parsing failed: ${e.lexerErrors.map(e=>e.message).join("\n")} ${e.parserErrors.map(e=>e.message).join("\n")}`),this.result=e}static{(0,r.K2)(this,"MermaidParseError")}}},82806:(e,t,n)=>{n.d(t,{Ao:()=>h,Nt:()=>d,PC:()=>f,TH:()=>i,Yv:()=>u,lU:()=>l});var r=n(85186);const i=/\r?\n/gm,s=new r.H;class a extends r.z{constructor(){super(...arguments),this.isStarting=!0,this.endRegexpStack=[],this.multiline=!1}get endRegex(){return this.endRegexpStack.join("")}reset(e){this.multiline=!1,this.regex=e,this.startRegexp="",this.isStarting=!0,this.endRegexpStack=[]}visitGroup(e){e.quantifier&&(this.isStarting=!1,this.endRegexpStack=[])}visitCharacter(e){const t=String.fromCharCode(e.value);if(this.multiline||"\n"!==t||(this.multiline=!0),e.quantifier)this.isStarting=!1,this.endRegexpStack=[];else{const e=d(t);this.endRegexpStack.push(e),this.isStarting&&(this.startRegexp+=e)}}visitSet(e){if(!this.multiline){const t=this.regex.substring(e.loc.begin,e.loc.end),n=new RegExp(t);this.multiline=Boolean("\n".match(n))}if(e.quantifier)this.isStarting=!1,this.endRegexpStack=[];else{const t=this.regex.substring(e.loc.begin,e.loc.end);this.endRegexpStack.push(t),this.isStarting&&(this.startRegexp+=t)}}visitChildren(e){if("Group"===e.type){if(e.quantifier)return}super.visitChildren(e)}}const o=new a;function l(e){try{return"string"==typeof e&&(e=new RegExp(e)),e=e.toString(),o.reset(e),o.visit(s.pattern(e)),o.multiline}catch(t){return!1}}const c="\f\n\r\t\v \xa0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000\ufeff".split("");function u(e){const t="string"==typeof e?new RegExp(e):e;return c.some(e=>t.test(e))}function d(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function h(e){return Array.prototype.map.call(e,e=>/\w/.test(e)?`[${e.toLowerCase()}${e.toUpperCase()}]`:d(e)).join("")}function f(e,t){const n=function(e){"string"==typeof e&&(e=new RegExp(e));const t=e,n=e.source;let r=0;function i(){let e,s="";function a(e){s+=n.substr(r,e),r+=e}function o(e){s+="(?:"+n.substr(r,e)+"|$)",r+=e}for(;r<n.length;)switch(n[r]){case"\\":switch(n[r+1]){case"c":o(3);break;case"x":o(4);break;case"u":t.unicode?"{"===n[r+2]?o(n.indexOf("}",r)-r+1):o(6):o(2);break;case"p":case"P":t.unicode?o(n.indexOf("}",r)-r+1):o(2);break;case"k":o(n.indexOf(">",r)-r+1);break;default:o(2)}break;case"[":e=/\[(?:\\.|.)*?\]/g,e.lastIndex=r,e=e.exec(n)||[],o(e[0].length);break;case"|":case"^":case"$":case"*":case"+":case"?":a(1);break;case"{":e=/\{\d+,?\d*\}/g,e.lastIndex=r,e=e.exec(n),e?a(e[0].length):o(1);break;case"(":if("?"===n[r+1])switch(n[r+2]){case":":s+="(?:",r+=3,s+=i()+"|$)";break;case"=":s+="(?=",r+=3,s+=i()+")";break;case"!":e=r,r+=3,i(),s+=n.substr(e,r-e);break;case"<":switch(n[r+3]){case"=":case"!":e=r,r+=4,i(),s+=n.substr(e,r-e);break;default:a(n.indexOf(">",r)-r+1),s+=i()+"|$)"}}else a(1),s+=i()+"|$)";break;case")":return++r,s;default:o(1)}return s}return new RegExp(i(),e.flags)}(e),r=t.match(n);return!!r&&r[0].length>0}},85186:(e,t,n)=>{function r(e){return e.charCodeAt(0)}function i(e,t){Array.isArray(e)?e.forEach(function(e){t.push(e)}):t.push(e)}function s(e,t){if(!0===e[t])throw"duplicate flag "+t;e[t];e[t]=!0}function a(e){if(void 0===e)throw Error("Internal Error - Should never get here!");return!0}function o(){throw Error("Internal Error - Should never get here!")}function l(e){return"Character"===e.type}n.d(t,{z:()=>g,H:()=>m});const c=[];for(let y=r("0");y<=r("9");y++)c.push(y);const u=[r("_")].concat(c);for(let y=r("a");y<=r("z");y++)u.push(y);for(let y=r("A");y<=r("Z");y++)u.push(y);const d=[r(" "),r("\f"),r("\n"),r("\r"),r("\t"),r("\v"),r("\t"),r("\xa0"),r("\u1680"),r("\u2000"),r("\u2001"),r("\u2002"),r("\u2003"),r("\u2004"),r("\u2005"),r("\u2006"),r("\u2007"),r("\u2008"),r("\u2009"),r("\u200a"),r("\u2028"),r("\u2029"),r("\u202f"),r("\u205f"),r("\u3000"),r("\ufeff")],h=/[0-9a-fA-F]/,f=/[0-9]/,p=/[1-9]/;class m{constructor(){this.idx=0,this.input="",this.groupIdx=0}saveState(){return{idx:this.idx,input:this.input,groupIdx:this.groupIdx}}restoreState(e){this.idx=e.idx,this.input=e.input,this.groupIdx=e.groupIdx}pattern(e){this.idx=0,this.input=e,this.groupIdx=0,this.consumeChar("/");const t=this.disjunction();this.consumeChar("/");const n={type:"Flags",loc:{begin:this.idx,end:e.length},global:!1,ignoreCase:!1,multiLine:!1,unicode:!1,sticky:!1};for(;this.isRegExpFlag();)switch(this.popChar()){case"g":s(n,"global");break;case"i":s(n,"ignoreCase");break;case"m":s(n,"multiLine");break;case"u":s(n,"unicode");break;case"y":s(n,"sticky")}if(this.idx!==this.input.length)throw Error("Redundant input: "+this.input.substring(this.idx));return{type:"Pattern",flags:n,value:t,loc:this.loc(0)}}disjunction(){const e=[],t=this.idx;for(e.push(this.alternative());"|"===this.peekChar();)this.consumeChar("|"),e.push(this.alternative());return{type:"Disjunction",value:e,loc:this.loc(t)}}alternative(){const e=[],t=this.idx;for(;this.isTerm();)e.push(this.term());return{type:"Alternative",value:e,loc:this.loc(t)}}term(){return this.isAssertion()?this.assertion():this.atom()}assertion(){const e=this.idx;switch(this.popChar()){case"^":return{type:"StartAnchor",loc:this.loc(e)};case"$":return{type:"EndAnchor",loc:this.loc(e)};case"\\":switch(this.popChar()){case"b":return{type:"WordBoundary",loc:this.loc(e)};case"B":return{type:"NonWordBoundary",loc:this.loc(e)}}throw Error("Invalid Assertion Escape");case"(":let t;switch(this.consumeChar("?"),this.popChar()){case"=":t="Lookahead";break;case"!":t="NegativeLookahead"}a(t);const n=this.disjunction();return this.consumeChar(")"),{type:t,value:n,loc:this.loc(e)}}return o()}quantifier(e=!1){let t;const n=this.idx;switch(this.popChar()){case"*":t={atLeast:0,atMost:1/0};break;case"+":t={atLeast:1,atMost:1/0};break;case"?":t={atLeast:0,atMost:1};break;case"{":const n=this.integerIncludingZero();switch(this.popChar()){case"}":t={atLeast:n,atMost:n};break;case",":let e;this.isDigit()?(e=this.integerIncludingZero(),t={atLeast:n,atMost:e}):t={atLeast:n,atMost:1/0},this.consumeChar("}")}if(!0===e&&void 0===t)return;a(t)}if(!0!==e||void 0!==t)return a(t)?("?"===this.peekChar(0)?(this.consumeChar("?"),t.greedy=!1):t.greedy=!0,t.type="Quantifier",t.loc=this.loc(n),t):void 0}atom(){let e;const t=this.idx;switch(this.peekChar()){case".":e=this.dotAll();break;case"\\":e=this.atomEscape();break;case"[":e=this.characterClass();break;case"(":e=this.group()}return void 0===e&&this.isPatternCharacter()&&(e=this.patternCharacter()),a(e)?(e.loc=this.loc(t),this.isQuantifier()&&(e.quantifier=this.quantifier()),e):o()}dotAll(){return this.consumeChar("."),{type:"Set",complement:!0,value:[r("\n"),r("\r"),r("\u2028"),r("\u2029")]}}atomEscape(){switch(this.consumeChar("\\"),this.peekChar()){case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":return this.decimalEscapeAtom();case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}}decimalEscapeAtom(){return{type:"GroupBackReference",value:this.positiveInteger()}}characterClassEscape(){let e,t=!1;switch(this.popChar()){case"d":e=c;break;case"D":e=c,t=!0;break;case"s":e=d;break;case"S":e=d,t=!0;break;case"w":e=u;break;case"W":e=u,t=!0}return a(e)?{type:"Set",value:e,complement:t}:o()}controlEscapeAtom(){let e;switch(this.popChar()){case"f":e=r("\f");break;case"n":e=r("\n");break;case"r":e=r("\r");break;case"t":e=r("\t");break;case"v":e=r("\v")}return a(e)?{type:"Character",value:e}:o()}controlLetterEscapeAtom(){this.consumeChar("c");const e=this.popChar();if(!1===/[a-zA-Z]/.test(e))throw Error("Invalid ");return{type:"Character",value:e.toUpperCase().charCodeAt(0)-64}}nulCharacterAtom(){return this.consumeChar("0"),{type:"Character",value:r("\0")}}hexEscapeSequenceAtom(){return this.consumeChar("x"),this.parseHexDigits(2)}regExpUnicodeEscapeSequenceAtom(){return this.consumeChar("u"),this.parseHexDigits(4)}identityEscapeAtom(){return{type:"Character",value:r(this.popChar())}}classPatternCharacterAtom(){switch(this.peekChar()){case"\n":case"\r":case"\u2028":case"\u2029":case"\\":case"]":throw Error("TBD");default:return{type:"Character",value:r(this.popChar())}}}characterClass(){const e=[];let t=!1;for(this.consumeChar("["),"^"===this.peekChar(0)&&(this.consumeChar("^"),t=!0);this.isClassAtom();){const t=this.classAtom();t.type;if(l(t)&&this.isRangeDash()){this.consumeChar("-");const n=this.classAtom();n.type;if(l(n)){if(n.value<t.value)throw Error("Range out of order in character class");e.push({from:t.value,to:n.value})}else i(t.value,e),e.push(r("-")),i(n.value,e)}else i(t.value,e)}return this.consumeChar("]"),{type:"Set",complement:t,value:e}}classAtom(){switch(this.peekChar()){case"]":case"\n":case"\r":case"\u2028":case"\u2029":throw Error("TBD");case"\\":return this.classEscape();default:return this.classPatternCharacterAtom()}}classEscape(){switch(this.consumeChar("\\"),this.peekChar()){case"b":return this.consumeChar("b"),{type:"Character",value:r("\b")};case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}}group(){let e=!0;if(this.consumeChar("("),"?"===this.peekChar(0))this.consumeChar("?"),this.consumeChar(":"),e=!1;else this.groupIdx++;const t=this.disjunction();this.consumeChar(")");const n={type:"Group",capturing:e,value:t};return e&&(n.idx=this.groupIdx),n}positiveInteger(){let e=this.popChar();if(!1===p.test(e))throw Error("Expecting a positive integer");for(;f.test(this.peekChar(0));)e+=this.popChar();return parseInt(e,10)}integerIncludingZero(){let e=this.popChar();if(!1===f.test(e))throw Error("Expecting an integer");for(;f.test(this.peekChar(0));)e+=this.popChar();return parseInt(e,10)}patternCharacter(){const e=this.popChar();switch(e){case"\n":case"\r":case"\u2028":case"\u2029":case"^":case"$":case"\\":case".":case"*":case"+":case"?":case"(":case")":case"[":case"|":throw Error("TBD");default:return{type:"Character",value:r(e)}}}isRegExpFlag(){switch(this.peekChar(0)){case"g":case"i":case"m":case"u":case"y":return!0;default:return!1}}isRangeDash(){return"-"===this.peekChar()&&this.isClassAtom(1)}isDigit(){return f.test(this.peekChar(0))}isClassAtom(e=0){switch(this.peekChar(e)){case"]":case"\n":case"\r":case"\u2028":case"\u2029":return!1;default:return!0}}isTerm(){return this.isAtom()||this.isAssertion()}isAtom(){if(this.isPatternCharacter())return!0;switch(this.peekChar(0)){case".":case"\\":case"[":case"(":return!0;default:return!1}}isAssertion(){switch(this.peekChar(0)){case"^":case"$":return!0;case"\\":switch(this.peekChar(1)){case"b":case"B":return!0;default:return!1}case"(":return"?"===this.peekChar(1)&&("="===this.peekChar(2)||"!"===this.peekChar(2));default:return!1}}isQuantifier(){const e=this.saveState();try{return void 0!==this.quantifier(!0)}catch(t){return!1}finally{this.restoreState(e)}}isPatternCharacter(){switch(this.peekChar()){case"^":case"$":case"\\":case".":case"*":case"+":case"?":case"(":case")":case"[":case"|":case"/":case"\n":case"\r":case"\u2028":case"\u2029":return!1;default:return!0}}parseHexDigits(e){let t="";for(let n=0;n<e;n++){const e=this.popChar();if(!1===h.test(e))throw Error("Expecting a HexDecimal digits");t+=e}return{type:"Character",value:parseInt(t,16)}}peekChar(e=0){return this.input[this.idx+e]}popChar(){const e=this.peekChar(0);return this.consumeChar(void 0),e}consumeChar(e){if(void 0!==e&&this.input[this.idx]!==e)throw Error("Expected: '"+e+"' but found: '"+this.input[this.idx]+"' at offset: "+this.idx);if(this.idx>=this.input.length)throw Error("Unexpected end of input");this.idx++}loc(e){return{begin:e,end:this.idx}}}class g{visitChildren(e){for(const t in e){const n=e[t];e.hasOwnProperty(t)&&(void 0!==n.type?this.visit(n):Array.isArray(n)&&n.forEach(e=>{this.visit(e)},this))}}visit(e){switch(e.type){case"Pattern":this.visitPattern(e);break;case"Flags":this.visitFlags(e);break;case"Disjunction":this.visitDisjunction(e);break;case"Alternative":this.visitAlternative(e);break;case"StartAnchor":this.visitStartAnchor(e);break;case"EndAnchor":this.visitEndAnchor(e);break;case"WordBoundary":this.visitWordBoundary(e);break;case"NonWordBoundary":this.visitNonWordBoundary(e);break;case"Lookahead":this.visitLookahead(e);break;case"NegativeLookahead":this.visitNegativeLookahead(e);break;case"Character":this.visitCharacter(e);break;case"Set":this.visitSet(e);break;case"Group":this.visitGroup(e);break;case"GroupBackReference":this.visitGroupBackReference(e);break;case"Quantifier":this.visitQuantifier(e)}this.visitChildren(e)}visitPattern(e){}visitFlags(e){}visitDisjunction(e){}visitAlternative(e){}visitStartAnchor(e){}visitEndAnchor(e){}visitWordBoundary(e){}visitNonWordBoundary(e){}visitLookahead(e){}visitNegativeLookahead(e){}visitCharacter(e){}visitSet(e){}visitGroup(e){}visitGroupBackReference(e){}visitQuantifier(e){}}},86452:(e,t,n)=>{n.d(t,{A:()=>a});var r=n(72559),i=n(36224),s=n(29008);const a=function(e){return e&&e.length?(0,r.A)(e,s.A,i.A):void 0}},87846:(e,t,n)=>{n.d(t,{f:()=>c});var r=n(87960),i=n(98913),s=n(39364),a=n(51917),o=class extends r.mR{static{(0,r.K2)(this,"RadarTokenBuilder")}constructor(){super(["radar-beta"])}},l={parser:{TokenBuilder:(0,r.K2)(()=>new o,"TokenBuilder"),ValueConverter:(0,r.K2)(()=>new r.Tm,"ValueConverter")}};function c(e=a.D){const t=(0,s.WQ)((0,i.u)(e),r.sr),n=(0,s.WQ)((0,i.t)({shared:t}),r.YP,l);return t.ServiceRegistry.register(n),{shared:t,Radar:n}}(0,r.K2)(c,"createRadarServices")},87960:(e,t,n)=>{n.d(t,{mR:()=>xe,dg:()=>Ee,jE:()=>Te,Tm:()=>ke,eZ:()=>Ae,e5:()=>me,sr:()=>pe,AM:()=>ge,KX:()=>ye,YP:()=>ve,eV:()=>Re,K2:()=>m});var r=n(32479),i=n(98913),s=n(39364),a=n(32151),o=n(51917),l=n(37608);const c={Grammar:()=>{},LanguageMetaData:()=>({caseInsensitive:!1,fileExtensions:[".langium"],languageId:"langium"})},u={AstReflection:()=>new a.QX};function d(e){var t;const n=function(){const e=(0,s.WQ)((0,i.u)(o.D),u),t=(0,s.WQ)((0,i.t)({shared:e}),c);return e.ServiceRegistry.register(t),t}(),r=n.serializer.JsonSerializer.deserialize(e);return n.shared.workspace.LangiumDocumentFactory.fromModel(r,l.r.parse(`memory://${null!==(t=r.name)&&void 0!==t?t:"grammar"}.langium`)),r}var h=n(65033),f=n(44326),p=Object.defineProperty,m=(e,t)=>p(e,"name",{value:t,configurable:!0}),g="Statement",y="Architecture";m(function(e){return J.isInstance(e,y)},"isArchitecture");var T="Axis",A="Branch";m(function(e){return J.isInstance(e,A)},"isBranch");var v="Checkout",R="CherryPicking",$="ClassDefStatement",E="Commit";m(function(e){return J.isInstance(e,E)},"isCommit");var k="Curve",x="Edge",I="Entry",S="GitGraph";m(function(e){return J.isInstance(e,S)},"isGitGraph");var N="Group",C="Info";m(function(e){return J.isInstance(e,C)},"isInfo");var w="Item",L="Junction",b="Merge";m(function(e){return J.isInstance(e,b)},"isMerge");var O="Option",_="Packet";m(function(e){return J.isInstance(e,_)},"isPacket");var P="PacketBlock";m(function(e){return J.isInstance(e,P)},"isPacketBlock");var M="Pie";m(function(e){return J.isInstance(e,M)},"isPie");var D="PieSection";m(function(e){return J.isInstance(e,D)},"isPieSection");var U="Radar",F="Service",G="Treemap";m(function(e){return J.isInstance(e,G)},"isTreemap");var K,B,j,V,H,W,z,Y="TreemapRow",X="Direction",q="Leaf",Q="Section",Z=class extends r.kD{static{m(this,"MermaidAstReflection")}getAllTypes(){return[y,T,A,v,R,$,E,k,X,x,I,S,N,C,w,L,q,b,O,_,P,M,D,U,Q,F,g,G,Y]}computeIsSubtype(e,t){switch(e){case A:case v:case R:case E:case b:return this.isSubtype(g,t);case X:return this.isSubtype(S,t);case q:case Q:return this.isSubtype(w,t);default:return!1}}getReferenceType(e){const t=`${e.container.$type}:${e.property}`;if("Entry:axis"===t)return T;throw new Error(`${t} is not a valid reference id.`)}getTypeMetaData(e){switch(e){case y:return{name:y,properties:[{name:"accDescr"},{name:"accTitle"},{name:"edges",defaultValue:[]},{name:"groups",defaultValue:[]},{name:"junctions",defaultValue:[]},{name:"services",defaultValue:[]},{name:"title"}]};case T:return{name:T,properties:[{name:"label"},{name:"name"}]};case A:return{name:A,properties:[{name:"name"},{name:"order"}]};case v:return{name:v,properties:[{name:"branch"}]};case R:return{name:R,properties:[{name:"id"},{name:"parent"},{name:"tags",defaultValue:[]}]};case $:return{name:$,properties:[{name:"className"},{name:"styleText"}]};case E:return{name:E,properties:[{name:"id"},{name:"message"},{name:"tags",defaultValue:[]},{name:"type"}]};case k:return{name:k,properties:[{name:"entries",defaultValue:[]},{name:"label"},{name:"name"}]};case x:return{name:x,properties:[{name:"lhsDir"},{name:"lhsGroup",defaultValue:!1},{name:"lhsId"},{name:"lhsInto",defaultValue:!1},{name:"rhsDir"},{name:"rhsGroup",defaultValue:!1},{name:"rhsId"},{name:"rhsInto",defaultValue:!1},{name:"title"}]};case I:return{name:I,properties:[{name:"axis"},{name:"value"}]};case S:return{name:S,properties:[{name:"accDescr"},{name:"accTitle"},{name:"statements",defaultValue:[]},{name:"title"}]};case N:return{name:N,properties:[{name:"icon"},{name:"id"},{name:"in"},{name:"title"}]};case C:return{name:C,properties:[{name:"accDescr"},{name:"accTitle"},{name:"title"}]};case w:return{name:w,properties:[{name:"classSelector"},{name:"name"}]};case L:return{name:L,properties:[{name:"id"},{name:"in"}]};case b:return{name:b,properties:[{name:"branch"},{name:"id"},{name:"tags",defaultValue:[]},{name:"type"}]};case O:return{name:O,properties:[{name:"name"},{name:"value",defaultValue:!1}]};case _:return{name:_,properties:[{name:"accDescr"},{name:"accTitle"},{name:"blocks",defaultValue:[]},{name:"title"}]};case P:return{name:P,properties:[{name:"bits"},{name:"end"},{name:"label"},{name:"start"}]};case M:return{name:M,properties:[{name:"accDescr"},{name:"accTitle"},{name:"sections",defaultValue:[]},{name:"showData",defaultValue:!1},{name:"title"}]};case D:return{name:D,properties:[{name:"label"},{name:"value"}]};case U:return{name:U,properties:[{name:"accDescr"},{name:"accTitle"},{name:"axes",defaultValue:[]},{name:"curves",defaultValue:[]},{name:"options",defaultValue:[]},{name:"title"}]};case F:return{name:F,properties:[{name:"icon"},{name:"iconText"},{name:"id"},{name:"in"},{name:"title"}]};case G:return{name:G,properties:[{name:"accDescr"},{name:"accTitle"},{name:"title"},{name:"TreemapRows",defaultValue:[]}]};case Y:return{name:Y,properties:[{name:"indent"},{name:"item"}]};case X:return{name:X,properties:[{name:"accDescr"},{name:"accTitle"},{name:"dir"},{name:"statements",defaultValue:[]},{name:"title"}]};case q:return{name:q,properties:[{name:"classSelector"},{name:"name"},{name:"value"}]};case Q:return{name:Q,properties:[{name:"classSelector"},{name:"name"}]};default:return{name:e,properties:[]}}}},J=new Z,ee=m(()=>K??(K=d('{"$type":"Grammar","isDeclared":true,"name":"Info","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Info","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[],"cardinality":"*"},{"$type":"Keyword","value":"info"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[],"cardinality":"*"},{"$type":"Group","elements":[{"$type":"Keyword","value":"showInfo"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[],"cardinality":"*"}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"?"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@7"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@8"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|\'([^\'\\\\\\\\]|\\\\\\\\.)*\'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[],"types":[],"usedGrammars":[]}')),"InfoGrammar"),te=m(()=>B??(B=d('{"$type":"Grammar","isDeclared":true,"name":"Packet","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Packet","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"packet"},{"$type":"Keyword","value":"packet-beta"}]},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]},{"$type":"Assignment","feature":"blocks","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"PacketBlock","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Assignment","feature":"start","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"-"},{"$type":"Assignment","feature":"end","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}}],"cardinality":"?"}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"+"},{"$type":"Assignment","feature":"bits","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}}]}]},{"$type":"Keyword","value":":"},{"$type":"Assignment","feature":"label","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@8"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@9"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|\'([^\'\\\\\\\\]|\\\\\\\\.)*\'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[],"types":[],"usedGrammars":[]}')),"PacketGrammar"),ne=m(()=>j??(j=d('{"$type":"Grammar","isDeclared":true,"name":"Pie","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Pie","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@16"},"arguments":[],"cardinality":"*"},{"$type":"Keyword","value":"pie"},{"$type":"Assignment","feature":"showData","operator":"?=","terminal":{"$type":"Keyword","value":"showData"},"cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]},{"$type":"Assignment","feature":"sections","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@16"},"arguments":[]}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"PieSection","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"label","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@14"},"arguments":[]}},{"$type":"Keyword","value":":"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"FLOAT_PIE","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/-?[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT_PIE","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/-?(0|[1-9][0-9]*)(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER_PIE","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@2"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@3"}}]},"fragment":false,"hidden":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@16"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@11"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@12"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|\'([^\'\\\\\\\\]|\\\\\\\\.)*\'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[],"types":[],"usedGrammars":[]}')),"PieGrammar"),re=m(()=>V??(V=d('{"$type":"Grammar","isDeclared":true,"name":"Architecture","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Architecture","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@23"},"arguments":[],"cardinality":"*"},{"$type":"Keyword","value":"architecture-beta"},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@23"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"Statement","definition":{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"groups","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Assignment","feature":"services","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}},{"$type":"Assignment","feature":"junctions","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}},{"$type":"Assignment","feature":"edges","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"LeftPort","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":":"},{"$type":"Assignment","feature":"lhsDir","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"RightPort","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"rhsDir","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}},{"$type":"Keyword","value":":"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"Arrow","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]},{"$type":"Assignment","feature":"lhsInto","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]},"cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"--"},{"$type":"Group","elements":[{"$type":"Keyword","value":"-"},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@29"},"arguments":[]}},{"$type":"Keyword","value":"-"}]}]},{"$type":"Assignment","feature":"rhsInto","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]},"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Group","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"group"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Assignment","feature":"icon","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@28"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@29"},"arguments":[]},"cardinality":"?"},{"$type":"Group","elements":[{"$type":"Keyword","value":"in"},{"$type":"Assignment","feature":"in","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Service","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"service"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"iconText","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@21"},"arguments":[]}},{"$type":"Assignment","feature":"icon","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@28"},"arguments":[]}}],"cardinality":"?"},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@29"},"arguments":[]},"cardinality":"?"},{"$type":"Group","elements":[{"$type":"Keyword","value":"in"},{"$type":"Assignment","feature":"in","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Junction","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"junction"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"in"},{"$type":"Assignment","feature":"in","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Edge","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"lhsId","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Assignment","feature":"lhsGroup","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]},"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]},{"$type":"Assignment","feature":"rhsId","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Assignment","feature":"rhsGroup","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]},"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"ARROW_DIRECTION","definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"L"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"R"}}]},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"T"}}]},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"B"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARROW_GROUP","definition":{"$type":"RegexToken","regex":"/\\\\{group\\\\}/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARROW_INTO","definition":{"$type":"RegexToken","regex":"/<|>/"},"fragment":false,"hidden":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@23"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@16"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@18"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@19"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|\'([^\'\\\\\\\\]|\\\\\\\\.)*\'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false},{"$type":"TerminalRule","name":"ARCH_ICON","definition":{"$type":"RegexToken","regex":"/\\\\([\\\\w-:]+\\\\)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARCH_TITLE","definition":{"$type":"RegexToken","regex":"/\\\\[[\\\\w ]+\\\\]/"},"fragment":false,"hidden":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[],"types":[],"usedGrammars":[]}')),"ArchitectureGrammar"),ie=m(()=>H??(H=d('{"$type":"Grammar","isDeclared":true,"name":"GitGraph","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"GitGraph","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"gitGraph"},{"$type":"Group","elements":[{"$type":"Keyword","value":"gitGraph"},{"$type":"Keyword","value":":"}]},{"$type":"Keyword","value":"gitGraph:"},{"$type":"Group","elements":[{"$type":"Keyword","value":"gitGraph"},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]},{"$type":"Keyword","value":":"}]}]},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]},{"$type":"Assignment","feature":"statements","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Statement","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Direction","definition":{"$type":"Assignment","feature":"dir","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"LR"},{"$type":"Keyword","value":"TB"},{"$type":"Keyword","value":"BT"}]}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Commit","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"commit"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"id:"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"msg:","cardinality":"?"},{"$type":"Assignment","feature":"message","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"tag:"},{"$type":"Assignment","feature":"tags","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"type:"},{"$type":"Assignment","feature":"type","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"NORMAL"},{"$type":"Keyword","value":"REVERSE"},{"$type":"Keyword","value":"HIGHLIGHT"}]}}]}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Branch","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"branch"},{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@24"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"order:"},{"$type":"Assignment","feature":"order","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Merge","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"merge"},{"$type":"Assignment","feature":"branch","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@24"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]}},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"id:"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"tag:"},{"$type":"Assignment","feature":"tags","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"type:"},{"$type":"Assignment","feature":"type","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"NORMAL"},{"$type":"Keyword","value":"REVERSE"},{"$type":"Keyword","value":"HIGHLIGHT"}]}}]}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Checkout","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"checkout"},{"$type":"Keyword","value":"switch"}]},{"$type":"Assignment","feature":"branch","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@24"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"CherryPicking","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"cherry-pick"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"id:"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"tag:"},{"$type":"Assignment","feature":"tags","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"parent:"},{"$type":"Assignment","feature":"parent","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@14"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@15"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|\'([^\'\\\\\\\\]|\\\\\\\\.)*\'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false},{"$type":"TerminalRule","name":"REFERENCE","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\\\w([-\\\\./\\\\w]*[-\\\\w])?/"},"fragment":false,"hidden":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[],"types":[],"usedGrammars":[]}')),"GitGraphGrammar"),se=m(()=>W??(W=d('{"$type":"Grammar","isDeclared":true,"name":"Radar","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Radar","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"radar-beta"},{"$type":"Keyword","value":"radar-beta:"},{"$type":"Group","elements":[{"$type":"Keyword","value":"radar-beta"},{"$type":"Keyword","value":":"}]}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]},{"$type":"Group","elements":[{"$type":"Keyword","value":"axis"},{"$type":"Assignment","feature":"axes","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"Assignment","feature":"axes","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}}],"cardinality":"*"}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"curve"},{"$type":"Assignment","feature":"curves","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"Assignment","feature":"curves","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}}],"cardinality":"*"}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"options","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"Assignment","feature":"options","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}}],"cardinality":"*"}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"Label","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"["},{"$type":"Assignment","feature":"label","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]}},{"$type":"Keyword","value":"]"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Axis","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Curve","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[],"cardinality":"?"},{"$type":"Keyword","value":"{"},{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"Entries","definition":{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Assignment","feature":"entries","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Assignment","feature":"entries","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"}]},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Assignment","feature":"entries","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"},{"$type":"Assignment","feature":"entries","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"*"}]}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DetailedEntry","returnType":{"$ref":"#/interfaces@0"},"definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"axis","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@2"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]},"deprecatedSyntax":false}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"NumberEntry","returnType":{"$ref":"#/interfaces@0"},"definition":{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Option","definition":{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"showLegend"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"ticks"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"max"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"min"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"graticule"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}}]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"GRATICULE","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"circle"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"polygon"}}]},"fragment":false,"hidden":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@14"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"FLOAT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+\\\\.[0-9]+(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*(?!\\\\.)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@15"}},{"$type":"TerminalRuleCall","rule":{"$ref":"#/rules@16"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\"([^\\"\\\\\\\\]|\\\\\\\\.)*\\"|\'([^\'\\\\\\\\]|\\\\\\\\.)*\'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[\\\\w]([-\\\\w]*\\\\w)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"interfaces":[{"$type":"Interface","name":"Entry","attributes":[{"$type":"TypeAttribute","name":"axis","isOptional":true,"type":{"$type":"ReferenceType","referenceType":{"$type":"SimpleType","typeRef":{"$ref":"#/rules@2"}}}},{"$type":"TypeAttribute","name":"value","type":{"$type":"SimpleType","primitiveType":"number"},"isOptional":false}],"superTypes":[]}],"definesHiddenTokens":false,"hiddenTokens":[],"types":[],"usedGrammars":[]}')),"RadarGrammar"),ae=m(()=>z??(z=d('{"$type":"Grammar","isDeclared":true,"name":"Treemap","rules":[{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]}}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"ParserRule","entry":true,"name":"Treemap","returnType":{"$ref":"#/interfaces@4"},"definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@0"},"arguments":[]},{"$type":"Assignment","feature":"TreemapRows","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@14"},"arguments":[]}}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"TREEMAP_KEYWORD","definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"treemap-beta"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"treemap"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"CLASS_DEF","definition":{"$type":"RegexToken","regex":"/classDef\\\\s+([a-zA-Z_][a-zA-Z0-9_]+)(?:\\\\s+([^;\\\\r\\\\n]*))?(?:;)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STYLE_SEPARATOR","definition":{"$type":"CharacterRange","left":{"$type":"Keyword","value":":::"}},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"SEPARATOR","definition":{"$type":"CharacterRange","left":{"$type":"Keyword","value":":"}},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"COMMA","definition":{"$type":"CharacterRange","left":{"$type":"Keyword","value":","}},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WS","definition":{"$type":"RegexToken","regex":"/[ \\\\t]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"ML_COMMENT","definition":{"$type":"RegexToken","regex":"/\\\\%\\\\%[^\\\\n]*/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"NL","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false},{"$type":"ParserRule","name":"TreemapRow","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"indent","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]},"cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"item","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@16"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]}]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ClassDef","dataType":"string","definition":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Item","returnType":{"$ref":"#/interfaces@0"},"definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Section","returnType":{"$ref":"#/interfaces@1"},"definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@23"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]},{"$type":"Assignment","feature":"classSelector","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Leaf","returnType":{"$ref":"#/interfaces@2"},"definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@23"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[],"cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[],"cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]},{"$type":"Assignment","feature":"classSelector","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"INDENTATION","definition":{"$type":"RegexToken","regex":"/[ \\\\t]{1,}/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID2","definition":{"$type":"RegexToken","regex":"/[a-zA-Z_][a-zA-Z0-9_]*/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NUMBER2","definition":{"$type":"RegexToken","regex":"/[0-9_\\\\.\\\\,]+/"},"fragment":false,"hidden":false},{"$type":"ParserRule","name":"MyNumber","dataType":"number","definition":{"$type":"RuleCall","rule":{"$ref":"#/rules@21"},"arguments":[]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"STRING2","definition":{"$type":"RegexToken","regex":"/\\"[^\\"]*\\"|\'[^\']*\'/"},"fragment":false,"hidden":false}],"interfaces":[{"$type":"Interface","name":"Item","attributes":[{"$type":"TypeAttribute","name":"name","type":{"$type":"SimpleType","primitiveType":"string"},"isOptional":false},{"$type":"TypeAttribute","name":"classSelector","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}}],"superTypes":[]},{"$type":"Interface","name":"Section","superTypes":[{"$ref":"#/interfaces@0"}],"attributes":[]},{"$type":"Interface","name":"Leaf","superTypes":[{"$ref":"#/interfaces@0"}],"attributes":[{"$type":"TypeAttribute","name":"value","type":{"$type":"SimpleType","primitiveType":"number"},"isOptional":false}]},{"$type":"Interface","name":"ClassDefStatement","attributes":[{"$type":"TypeAttribute","name":"className","type":{"$type":"SimpleType","primitiveType":"string"},"isOptional":false},{"$type":"TypeAttribute","name":"styleText","type":{"$type":"SimpleType","primitiveType":"string"},"isOptional":false}],"superTypes":[]},{"$type":"Interface","name":"Treemap","attributes":[{"$type":"TypeAttribute","name":"TreemapRows","type":{"$type":"ArrayType","elementType":{"$type":"SimpleType","typeRef":{"$ref":"#/rules@14"}}},"isOptional":false},{"$type":"TypeAttribute","name":"title","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"accTitle","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"accDescr","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}}],"superTypes":[]}],"definesHiddenTokens":false,"hiddenTokens":[],"imports":[],"types":[],"usedGrammars":[],"$comment":"/**\\n * Treemap grammar for Langium\\n * Converted from mindmap grammar\\n *\\n * The ML_COMMENT and NL hidden terminals handle whitespace, comments, and newlines\\n * before the treemap keyword, allowing for empty lines and comments before the\\n * treemap declaration.\\n */"}')),"TreemapGrammar"),oe={languageId:"info",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},le={languageId:"packet",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},ce={languageId:"pie",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},ue={languageId:"architecture",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},de={languageId:"gitGraph",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},he={languageId:"radar",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},fe={languageId:"treemap",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},pe={AstReflection:m(()=>new Z,"AstReflection")},me={Grammar:m(()=>ee(),"Grammar"),LanguageMetaData:m(()=>oe,"LanguageMetaData"),parser:{}},ge={Grammar:m(()=>te(),"Grammar"),LanguageMetaData:m(()=>le,"LanguageMetaData"),parser:{}},ye={Grammar:m(()=>ne(),"Grammar"),LanguageMetaData:m(()=>ce,"LanguageMetaData"),parser:{}},Te={Grammar:m(()=>re(),"Grammar"),LanguageMetaData:m(()=>ue,"LanguageMetaData"),parser:{}},Ae={Grammar:m(()=>ie(),"Grammar"),LanguageMetaData:m(()=>de,"LanguageMetaData"),parser:{}},ve={Grammar:m(()=>se(),"Grammar"),LanguageMetaData:m(()=>he,"LanguageMetaData"),parser:{}},Re={Grammar:m(()=>ae(),"Grammar"),LanguageMetaData:m(()=>fe,"LanguageMetaData"),parser:{}},$e={ACC_DESCR:/accDescr(?:[\t ]*:([^\n\r]*)|\s*{([^}]*)})/,ACC_TITLE:/accTitle[\t ]*:([^\n\r]*)/,TITLE:/title([\t ][^\n\r]*|)/},Ee=class extends h.d{static{m(this,"AbstractMermaidValueConverter")}runConverter(e,t,n){let r=this.runCommonConverter(e,t,n);return void 0===r&&(r=this.runCustomConverter(e,t,n)),void 0===r?super.runConverter(e,t,n):r}runCommonConverter(e,t,n){const r=$e[e.name];if(void 0===r)return;const i=r.exec(t);return null!==i?void 0!==i[1]?i[1].trim().replace(/[\t ]{2,}/gm," "):void 0!==i[2]?i[2].replace(/^\s*/gm,"").replace(/\s+$/gm,"").replace(/[\t ]{2,}/gm," ").replace(/[\n\r]{2,}/gm,"\n"):void 0:void 0}},ke=class extends Ee{static{m(this,"CommonValueConverter")}runCustomConverter(e,t,n){}},xe=class extends f.Q{static{m(this,"AbstractMermaidTokenBuilder")}constructor(e){super(),this.keywords=new Set(e)}buildKeywordTokens(e,t,n){const r=super.buildKeywordTokens(e,t,n);return r.forEach(e=>{this.keywords.has(e.name)&&void 0!==e.PATTERN&&(e.PATTERN=new RegExp(e.PATTERN.toString()+"(?:(?=%%)|(?!\\S))"))}),r}};(class extends xe{static{m(this,"CommonTokenBuilder")}})},90418:(e,t,n)=>{n.d(t,{Bd:()=>f,P3:()=>x,PV:()=>E,Rp:()=>T,S:()=>I,SS:()=>g,U5:()=>A,Uz:()=>k,Xq:()=>R,YV:()=>c,eb:()=>h,g4:()=>d,qO:()=>p});var r=n(71564),i=n(32151),s=n(32479),a=n(49683),o=n(76373),l=n(82806);function c(e,t){const n=new Set,r=function(e){return e.rules.find(e=>i.s7(e)&&e.entry)}(e);if(!r)return new Set(e.rules);const s=[r].concat(function(e){return e.rules.filter(e=>i.rE(e)&&e.hidden)}(e));for(const i of s)u(i,n,t);const a=new Set;for(const o of e.rules)(n.has(o.name)||i.rE(o)&&o.hidden)&&a.add(o);return a}function u(e,t,n){t.add(e.name),(0,a.Uo)(e).forEach(e=>{if(i.$g(e)||n&&i.lF(e)){const r=e.rule.ref;r&&!t.has(r.name)&&u(r,t,n)}})}function d(e){if(e.terminal)return e.terminal;if(e.type.ref){const t=A(e.type.ref);return null==t?void 0:t.terminal}}function h(e){return e.hidden&&!(0,l.Yv)(I(e))}function f(e,t){return e&&t?m(e,t,e.astNode,!0):[]}function p(e,t,n){if(!e||!t)return;const r=m(e,t,e.astNode,!0);return 0!==r.length?r[n=void 0!==n?Math.max(0,Math.min(n,r.length-1)):0]:void 0}function m(e,t,n,r){if(!r){const n=(0,a.XG)(e.grammarSource,i.wh);if(n&&n.feature===t)return[e]}return(0,s.mD)(e)&&e.astNode===n?e.content.flatMap(e=>m(e,t,n,!1)):[]}function g(e,t,n){if(!e)return;const r=y(e,t,null==e?void 0:e.astNode);return 0!==r.length?r[n=void 0!==n?Math.max(0,Math.min(n,r.length-1)):0]:void 0}function y(e,t,n){if(e.astNode!==n)return[];if(i.wb(e.grammarSource)&&e.grammarSource.value===t)return[e];const r=(0,o.NS)(e).iterator();let s;const a=[];do{if(s=r.next(),!s.done){const e=s.value;e.astNode===n?i.wb(e.grammarSource)&&e.grammarSource.value===t&&a.push(e):r.prune()}}while(!s.done);return a}function T(e){var t;const n=e.astNode;for(;n===(null===(t=e.container)||void 0===t?void 0:t.astNode);){const t=(0,a.XG)(e.grammarSource,i.wh);if(t)return t;e=e.container}}function A(e){let t=e;return i.SP(t)&&(i.ve(t.$container)?t=t.$container.$container:i.s7(t.$container)?t=t.$container:(0,r.d)(t.$container)),v(e,t,new Map)}function v(e,t,n){var r;function s(t,r){let s;return(0,a.XG)(t,i.wh)||(s=v(r,r,n)),n.set(e,s),s}if(n.has(e))return n.get(e);n.set(e,void 0);for(const o of(0,a.Uo)(t)){if(i.wh(o)&&"name"===o.feature.toLowerCase())return n.set(e,o),o;if(i.$g(o)&&i.s7(o.rule.ref))return s(o,o.rule.ref);if(i.D8(o)&&(null===(r=o.typeRef)||void 0===r?void 0:r.ref))return s(o,o.typeRef.ref)}}function R(e){return $(e,new Set)}function $(e,t){if(t.has(e))return!0;t.add(e);for(const n of(0,a.Uo)(e))if(i.$g(n)){if(!n.rule.ref)return!1;if(i.s7(n.rule.ref)&&!$(n.rule.ref,t))return!1}else{if(i.wh(n))return!1;if(i.ve(n))return!1}return Boolean(e.definition)}function E(e){if(e.inferredType)return e.inferredType.name;if(e.dataType)return e.dataType;if(e.returnType){const t=e.returnType.ref;if(t){if(i.s7(t))return t.name;if(i.S2(t)||i.Xj(t))return t.name}}}function k(e){var t;if(i.s7(e))return R(e)?e.name:null!==(t=E(e))&&void 0!==t?t:e.name;if(i.S2(e)||i.Xj(e)||i.fG(e))return e.name;if(i.ve(e)){const t=function(e){var t;if(e.inferredType)return e.inferredType.name;if(null===(t=e.type)||void 0===t?void 0:t.ref)return k(e.type.ref);return}(e);if(t)return t}else if(i.SP(e))return e.name;throw new Error("Cannot get name of Unknown Type")}function x(e){var t,n,r;return i.rE(e)?null!==(n=null===(t=e.type)||void 0===t?void 0:t.name)&&void 0!==n?n:"string":null!==(r=E(e))&&void 0!==r?r:e.name}function I(e){const t={s:!1,i:!1,u:!1},n=N(e.definition,t),r=Object.entries(t).filter(([,e])=>e).map(([e])=>e).join("");return new RegExp(n,r)}const S=/[\s\S]/.source;function N(e,t){if(i.Fy(e))return w((a=e).elements.map(e=>N(e)).join("|"),{cardinality:a.cardinality,lookahead:a.lookahead});if(i.O4(e))return w((s=e).elements.map(e=>N(e)).join(""),{cardinality:s.cardinality,lookahead:s.lookahead});if(i.Bg(e))return function(e){if(e.right)return w(`[${C(e.left)}-${C(e.right)}]`,{cardinality:e.cardinality,lookahead:e.lookahead,wrap:!1});return w(C(e.left),{cardinality:e.cardinality,lookahead:e.lookahead,wrap:!1})}(e);if(i.lF(e)){const t=e.rule.ref;if(!t)throw new Error("Missing rule reference.");return w(N(t.definition),{cardinality:e.cardinality,lookahead:e.lookahead})}if(i.GL(e))return w(`(?!${N((r=e).terminal)})${S}*?`,{cardinality:r.cardinality,lookahead:r.lookahead});if(i.Mz(e))return w(`${S}*?${N((n=e).terminal)}`,{cardinality:n.cardinality,lookahead:n.lookahead});if(i.vd(e)){const n=e.regex.lastIndexOf("/"),r=e.regex.substring(1,n),i=e.regex.substring(n+1);return t&&(t.i=i.includes("i"),t.s=i.includes("s"),t.u=i.includes("u")),w(r,{cardinality:e.cardinality,lookahead:e.lookahead,wrap:!1})}if(i.z2(e))return w(S,{cardinality:e.cardinality,lookahead:e.lookahead});throw new Error(`Invalid terminal element: ${null==e?void 0:e.$type}`);var n,r,s,a}function C(e){return(0,l.Nt)(e.value)}function w(e,t){var n;return(!1!==t.wrap||t.lookahead)&&(e=`(${null!==(n=t.lookahead)&&void 0!==n?n:""}${e})`),t.cardinality?`${e}${t.cardinality}`:e}},91719:(e,t,n)=>{n.d(t,{B5:()=>a,Rf:()=>o,Td:()=>l,Vj:()=>c,fq:()=>r,iD:()=>u});class r{constructor(e,t){this.startFn=e,this.nextFn=t}iterator(){const e={state:this.startFn(),next:()=>this.nextFn(e.state),[Symbol.iterator]:()=>e};return e}[Symbol.iterator](){return this.iterator()}isEmpty(){const e=this.iterator();return Boolean(e.next().done)}count(){const e=this.iterator();let t=0,n=e.next();for(;!n.done;)t++,n=e.next();return t}toArray(){const e=[],t=this.iterator();let n;do{n=t.next(),void 0!==n.value&&e.push(n.value)}while(!n.done);return e}toSet(){return new Set(this)}toMap(e,t){const n=this.map(n=>[e?e(n):n,t?t(n):n]);return new Map(n)}toString(){return this.join()}concat(e){return new r(()=>({first:this.startFn(),firstDone:!1,iterator:e[Symbol.iterator]()}),e=>{let t;if(!e.firstDone){do{if(t=this.nextFn(e.first),!t.done)return t}while(!t.done);e.firstDone=!0}do{if(t=e.iterator.next(),!t.done)return t}while(!t.done);return o})}join(e=","){const t=this.iterator();let n,r="",s=!1;do{n=t.next(),n.done||(s&&(r+=e),r+=i(n.value)),s=!0}while(!n.done);return r}indexOf(e,t=0){const n=this.iterator();let r=0,i=n.next();for(;!i.done;){if(r>=t&&i.value===e)return r;i=n.next(),r++}return-1}every(e){const t=this.iterator();let n=t.next();for(;!n.done;){if(!e(n.value))return!1;n=t.next()}return!0}some(e){const t=this.iterator();let n=t.next();for(;!n.done;){if(e(n.value))return!0;n=t.next()}return!1}forEach(e){const t=this.iterator();let n=0,r=t.next();for(;!r.done;)e(r.value,n),r=t.next(),n++}map(e){return new r(this.startFn,t=>{const{done:n,value:r}=this.nextFn(t);return n?o:{done:!1,value:e(r)}})}filter(e){return new r(this.startFn,t=>{let n;do{if(n=this.nextFn(t),!n.done&&e(n.value))return n}while(!n.done);return o})}nonNullable(){return this.filter(e=>null!=e)}reduce(e,t){const n=this.iterator();let r=t,i=n.next();for(;!i.done;)r=void 0===r?i.value:e(r,i.value),i=n.next();return r}reduceRight(e,t){return this.recursiveReduce(this.iterator(),e,t)}recursiveReduce(e,t,n){const r=e.next();if(r.done)return n;const i=this.recursiveReduce(e,t,n);return void 0===i?r.value:t(i,r.value)}find(e){const t=this.iterator();let n=t.next();for(;!n.done;){if(e(n.value))return n.value;n=t.next()}}findIndex(e){const t=this.iterator();let n=0,r=t.next();for(;!r.done;){if(e(r.value))return n;r=t.next(),n++}return-1}includes(e){const t=this.iterator();let n=t.next();for(;!n.done;){if(n.value===e)return!0;n=t.next()}return!1}flatMap(e){return new r(()=>({this:this.startFn()}),t=>{do{if(t.iterator){const e=t.iterator.next();if(!e.done)return e;t.iterator=void 0}const{done:n,value:r}=this.nextFn(t.this);if(!n){const n=e(r);if(!s(n))return{done:!1,value:n};t.iterator=n[Symbol.iterator]()}}while(t.iterator);return o})}flat(e){if(void 0===e&&(e=1),e<=0)return this;const t=e>1?this.flat(e-1):this;return new r(()=>({this:t.startFn()}),e=>{do{if(e.iterator){const t=e.iterator.next();if(!t.done)return t;e.iterator=void 0}const{done:n,value:r}=t.nextFn(e.this);if(!n){if(!s(r))return{done:!1,value:r};e.iterator=r[Symbol.iterator]()}}while(e.iterator);return o})}head(){const e=this.iterator().next();if(!e.done)return e.value}tail(e=1){return new r(()=>{const t=this.startFn();for(let n=0;n<e;n++){if(this.nextFn(t).done)return t}return t},this.nextFn)}limit(e){return new r(()=>({size:0,state:this.startFn()}),t=>(t.size++,t.size>e?o:this.nextFn(t.state)))}distinct(e){return new r(()=>({set:new Set,internalState:this.startFn()}),t=>{let n;do{if(n=this.nextFn(t.internalState),!n.done){const r=e?e(n.value):n.value;if(!t.set.has(r))return t.set.add(r),n}}while(!n.done);return o})}exclude(e,t){const n=new Set;for(const r of e){const e=t?t(r):r;n.add(e)}return this.filter(e=>{const r=t?t(e):e;return!n.has(r)})}}function i(e){return"string"==typeof e?e:void 0===e?"undefined":"function"==typeof e.toString?e.toString():Object.prototype.toString.call(e)}function s(e){return!!e&&"function"==typeof e[Symbol.iterator]}const a=new r(()=>{},()=>o),o=Object.freeze({done:!0,value:void 0});function l(...e){if(1===e.length){const t=e[0];if(t instanceof r)return t;if(s(t))return new r(()=>t[Symbol.iterator](),e=>e.next());if("number"==typeof t.length)return new r(()=>({index:0}),e=>e.index<t.length?{done:!1,value:t[e.index++]}:o)}return e.length>1?new r(()=>({collIndex:0,arrIndex:0}),t=>{do{if(t.iterator){const e=t.iterator.next();if(!e.done)return e;t.iterator=void 0}if(t.array){if(t.arrIndex<t.array.length)return{done:!1,value:t.array[t.arrIndex++]};t.array=void 0,t.arrIndex=0}if(t.collIndex<e.length){const n=e[t.collIndex++];s(n)?t.iterator=n[Symbol.iterator]():n&&"number"==typeof n.length&&(t.array=n)}}while(t.iterator||t.array||t.collIndex<e.length);return o}):a}class c extends r{constructor(e,t,n){super(()=>({iterators:(null==n?void 0:n.includeRoot)?[[e][Symbol.iterator]()]:[t(e)[Symbol.iterator]()],pruned:!1}),e=>{for(e.pruned&&(e.iterators.pop(),e.pruned=!1);e.iterators.length>0;){const n=e.iterators[e.iterators.length-1].next();if(!n.done)return e.iterators.push(t(n.value)[Symbol.iterator]()),n;e.iterators.pop()}return o})}iterator(){const e={state:this.startFn(),next:()=>this.nextFn(e.state),prune:()=>{e.state.pruned=!0},[Symbol.iterator]:()=>e};return e}}var u;!function(e){e.sum=function(e){return e.reduce((e,t)=>e+t,0)},e.product=function(e){return e.reduce((e,t)=>e*t,0)},e.min=function(e){return e.reduce((e,t)=>Math.min(e,t))},e.max=function(e){return e.reduce((e,t)=>Math.max(e,t))}}(u||(u={}))},91885:(e,t,n)=>{n.d(t,{v:()=>c});var r=n(87960),i=n(98913),s=n(39364),a=n(51917),o=class extends r.mR{static{(0,r.K2)(this,"InfoTokenBuilder")}constructor(){super(["info","showInfo"])}},l={parser:{TokenBuilder:(0,r.K2)(()=>new o,"TokenBuilder"),ValueConverter:(0,r.K2)(()=>new r.Tm,"ValueConverter")}};function c(e=a.D){const t=(0,s.WQ)((0,i.u)(e),r.sr),n=(0,s.WQ)((0,i.t)({shared:t}),r.e5,l);return t.ServiceRegistry.register(n),{shared:t,Info:n}}(0,r.K2)(c,"createInfoServices")},98913:(e,t,n)=>{n.d(t,{t:()=>Fr,u:()=>Gr});var r=n(76373),i=n(90418),s=n(82806),a=n(32151);var o=n(69637),l=n(74722),c=n(94092);function u(e,t,n){return`${e.name}_${t}_${n}`}class d{constructor(e){this.target=e}isEpsilon(){return!1}}class h extends d{constructor(e,t){super(e),this.tokenType=t}}class f extends d{constructor(e){super(e)}isEpsilon(){return!0}}class p extends d{constructor(e,t,n){super(e),this.rule=t,this.followState=n}isEpsilon(){return!0}}function m(e){const t={decisionMap:{},decisionStates:[],ruleToStartState:new Map,ruleToStopState:new Map,states:[]};!function(e,t){const n=t.length;for(let r=0;r<n;r++){const n=t[r],i=x(e,n,void 0,{type:2}),s=x(e,n,void 0,{type:7});i.stop=s,e.ruleToStartState.set(n,i),e.ruleToStopState.set(n,s)}}(t,e);const n=e.length;for(let r=0;r<n;r++){const n=e[r],i=y(t,n,n);void 0!==i&&E(t,n,i)}return t}function g(e,t,n){return n instanceof o.BK?$(e,t,n.terminalType,n):n instanceof o.wL?function(e,t,n){const r=n.referencedRule,i=e.ruleToStartState.get(r),s=x(e,t,n,{type:1}),a=x(e,t,n,{type:1}),o=new p(i,r,a);return I(s,o),{left:s,right:a}}(e,t,n):n instanceof o.ak?function(e,t,n){const r=x(e,t,n,{type:1});v(e,r);const i=(0,l.A)(n.definition,n=>g(e,t,n)),s=R(e,t,r,n,...i);return s}(e,t,n):n instanceof o.c$?function(e,t,n){const r=x(e,t,n,{type:1});v(e,r);const i=R(e,t,r,n,y(e,t,n));return function(e,t,n,r){const i=r.left,s=r.right;return k(i,s),e.decisionMap[u(t,"Option",n.idx)]=i,r}(e,t,n,i)}(e,t,n):n instanceof o.Y2?function(e,t,n){const r=x(e,t,n,{type:5});v(e,r);const i=R(e,t,r,n,y(e,t,n));return A(e,t,n,i)}(e,t,n):n instanceof o.Pp?function(e,t,n){const r=x(e,t,n,{type:5});v(e,r);const i=R(e,t,r,n,y(e,t,n)),s=$(e,t,n.separator,n);return A(e,t,n,i,s)}(e,t,n):n instanceof o.$P?function(e,t,n){const r=x(e,t,n,{type:4});v(e,r);const i=R(e,t,r,n,y(e,t,n));return T(e,t,n,i)}(e,t,n):n instanceof o.Cy?function(e,t,n){const r=x(e,t,n,{type:4});v(e,r);const i=R(e,t,r,n,y(e,t,n)),s=$(e,t,n.separator,n);return T(e,t,n,i,s)}(e,t,n):y(e,t,n)}function y(e,t,n){const r=(0,c.A)((0,l.A)(n.definition,n=>g(e,t,n)),e=>void 0!==e);return 1===r.length?r[0]:0===r.length?void 0:function(e,t){const n=t.length;for(let s=0;s<n-1;s++){const n=t[s];let r;1===n.left.transitions.length&&(r=n.left.transitions[0]);const i=r instanceof p,a=r,o=t[s+1].left;1===n.left.type&&1===n.right.type&&void 0!==r&&(i&&a.followState===n.right||r.target===n.right)?(i?a.followState=o:r.target=o,S(e,n.right)):k(n.right,o)}const r=t[0],i=t[n-1];return{left:r.left,right:i.right}}(e,r)}function T(e,t,n,r,i){const s=r.left,a=r.right,o=x(e,t,n,{type:11});v(e,o);const l=x(e,t,n,{type:12});return s.loopback=o,l.loopback=o,e.decisionMap[u(t,i?"RepetitionMandatoryWithSeparator":"RepetitionMandatory",n.idx)]=o,k(a,o),void 0===i?(k(o,s),k(o,l)):(k(o,l),k(o,i.left),k(i.right,s)),{left:s,right:l}}function A(e,t,n,r,i){const s=r.left,a=r.right,o=x(e,t,n,{type:10});v(e,o);const l=x(e,t,n,{type:12}),c=x(e,t,n,{type:9});return o.loopback=c,l.loopback=c,k(o,s),k(o,l),k(a,c),void 0!==i?(k(c,l),k(c,i.left),k(i.right,s)):k(c,o),e.decisionMap[u(t,i?"RepetitionWithSeparator":"Repetition",n.idx)]=o,{left:o,right:l}}function v(e,t){return e.decisionStates.push(t),t.decision=e.decisionStates.length-1,t.decision}function R(e,t,n,r,...i){const s=x(e,t,r,{type:8,start:n});n.end=s;for(const o of i)void 0!==o?(k(n,o.left),k(o.right,s)):k(n,s);const a={left:n,right:s};return e.decisionMap[u(t,function(e){if(e instanceof o.ak)return"Alternation";if(e instanceof o.c$)return"Option";if(e instanceof o.Y2)return"Repetition";if(e instanceof o.Pp)return"RepetitionWithSeparator";if(e instanceof o.$P)return"RepetitionMandatory";if(e instanceof o.Cy)return"RepetitionMandatoryWithSeparator";throw new Error("Invalid production type encountered")}(r),r.idx)]=n,a}function $(e,t,n,r){const i=x(e,t,r,{type:1}),s=x(e,t,r,{type:1});return I(i,new h(s,n)),{left:i,right:s}}function E(e,t,n){const r=e.ruleToStartState.get(t);k(r,n.left);const i=e.ruleToStopState.get(t);k(n.right,i);return{left:r,right:i}}function k(e,t){I(e,new f(t))}function x(e,t,n,r){const i=Object.assign({atn:e,production:n,epsilonOnlyTransitions:!1,rule:t,transitions:[],nextTokenWithinRule:[],stateNumber:e.states.length},r);return e.states.push(i),i}function I(e,t){0===e.transitions.length&&(e.epsilonOnlyTransitions=t.isEpsilon()),e.transitions.push(t)}function S(e,t){e.states.splice(e.states.indexOf(t),1)}const N={};class C{constructor(){this.map={},this.configs=[]}get size(){return this.configs.length}finalize(){this.map={}}add(e){const t=w(e);t in this.map||(this.map[t]=this.configs.length,this.configs.push(e))}get elements(){return this.configs}get alts(){return(0,l.A)(this.configs,e=>e.alt)}get key(){let e="";for(const t in this.map)e+=t+":";return e}}function w(e,t=!0){return`${t?`a${e.alt}`:""}s${e.state.stateNumber}:${e.stack.map(e=>e.stateNumber.toString()).join("_")}`}var L=n(86452),b=n(18139),O=n(23958),_=n(99902);const P=function(e,t){return e&&e.length?(0,_.A)(e,(0,O.A)(t,2)):[]};var M=n(34098),D=n(8058),U=n(66401),F=n(89463);function G(e,t){const n={};return r=>{const i=r.toString();let s=n[i];return void 0!==s||(s={atnStartState:e,decision:t,states:{}},n[i]=s),s}}class K{constructor(){this.predicates=[]}is(e){return e>=this.predicates.length||this.predicates[e]}set(e,t){this.predicates[e]=t}toString(){let e="";const t=this.predicates.length;for(let n=0;n<t;n++)e+=!0===this.predicates[n]?"1":"0";return e}}const B=new K;class j extends o.T6{constructor(e){var t;super(),this.logging=null!==(t=null==e?void 0:e.logging)&&void 0!==t?t:e=>console.log(e)}initialize(e){this.atn=m(e.rules),this.dfas=function(e){const t=e.decisionStates.length,n=Array(t);for(let r=0;r<t;r++)n[r]=G(e.decisionStates[r],r);return n}(this.atn)}validateAmbiguousAlternationAlternatives(){return[]}validateEmptyOrAlternatives(){return[]}buildLookaheadForAlternation(e){const{prodOccurrence:t,rule:n,hasPredicates:r,dynamicTokensEnabled:i}=e,s=this.dfas,a=this.logging,c=u(n,"Alternation",t),d=this.atn.decisionMap[c].decision,h=(0,l.A)((0,o.jk)({maxLookahead:1,occurrence:t,prodType:"Alternation",rule:n}),e=>(0,l.A)(e,e=>e[0]));if(V(h,!1)&&!i){const e=(0,F.A)(h,(e,t,n)=>((0,D.A)(t,t=>{t&&(e[t.tokenTypeIdx]=n,(0,D.A)(t.categoryMatches,t=>{e[t]=n}))}),e),{});return r?function(t){var n;const r=this.LA(1),i=e[r.tokenTypeIdx];if(void 0!==t&&void 0!==i){const e=null===(n=t[i])||void 0===n?void 0:n.GATE;if(void 0!==e&&!1===e.call(this))return}return i}:function(){const t=this.LA(1);return e[t.tokenTypeIdx]}}return r?function(e){const t=new K,n=void 0===e?0:e.length;for(let i=0;i<n;i++){const n=null==e?void 0:e[i].GATE;t.set(i,void 0===n||n.call(this))}const r=H.call(this,s,d,t,a);return"number"==typeof r?r:void 0}:function(){const e=H.call(this,s,d,B,a);return"number"==typeof e?e:void 0}}buildLookaheadForOptional(e){const{prodOccurrence:t,rule:n,prodType:r,dynamicTokensEnabled:i}=e,s=this.dfas,a=this.logging,c=u(n,r,t),d=this.atn.decisionMap[c].decision,h=(0,l.A)((0,o.jk)({maxLookahead:1,occurrence:t,prodType:r,rule:n}),e=>(0,l.A)(e,e=>e[0]));if(V(h)&&h[0][0]&&!i){const e=h[0],t=(0,M.A)(e);if(1===t.length&&(0,U.A)(t[0].categoryMatches)){const e=t[0].tokenTypeIdx;return function(){return this.LA(1).tokenTypeIdx===e}}{const e=(0,F.A)(t,(e,t)=>(void 0!==t&&(e[t.tokenTypeIdx]=!0,(0,D.A)(t.categoryMatches,t=>{e[t]=!0})),e),{});return function(){const t=this.LA(1);return!0===e[t.tokenTypeIdx]}}}return function(){const e=H.call(this,s,d,B,a);return"object"!=typeof e&&0===e}}}function V(e,t=!0){const n=new Set;for(const r of e){const e=new Set;for(const i of r){if(void 0===i){if(t)break;return!1}const r=[i.tokenTypeIdx].concat(i.categoryMatches);for(const t of r)if(n.has(t)){if(!e.has(t))return!1}else n.add(t),e.add(t)}}return!0}function H(e,t,n,r){const i=e[t](n);let s=i.start;if(void 0===s){s=ee(i,Z(te(i.atnStartState))),i.start=s}return W.apply(this,[i,s,n,r])}function W(e,t,n,r){let i=t,s=1;const a=[];let o=this.LA(s++);for(;;){let t=q(i,o);if(void 0===t&&(t=z.apply(this,[e,i,o,s,n,r])),t===N)return X(a,i,o);if(!0===t.isAcceptState)return t.prediction;i=t,a.push(o),o=this.LA(s++)}}function z(e,t,n,r,i,s){const a=function(e,t,n){const r=new C,i=[];for(const a of e.elements){if(!1===n.is(a.alt))continue;if(7===a.state.type){i.push(a);continue}const e=a.state.transitions.length;for(let n=0;n<e;n++){const e=Q(a.state.transitions[n],t);void 0!==e&&r.add({state:e,alt:a.alt,stack:a.stack})}}let s;0===i.length&&1===r.size&&(s=r);if(void 0===s){s=new C;for(const e of r.elements)ne(e,s)}if(i.length>0&&!function(e){for(const t of e.elements)if(7===t.state.type)return!0;return!1}(s))for(const a of i)s.add(a);return s}(t.configs,n,i);if(0===a.size)return J(e,t,n,N),N;let o=Z(a);const l=function(e,t){let n;for(const r of e.elements)if(!0===t.is(r.alt))if(void 0===n)n=r.alt;else if(n!==r.alt)return;return n}(a,i);if(void 0!==l)o.isAcceptState=!0,o.prediction=l,o.configs.uniqueAlt=l;else if(function(e){if(function(e){for(const t of e.elements)if(7!==t.state.type)return!1;return!0}(e))return!0;const t=function(e){const t=new Map;for(const n of e){const e=w(n,!1);let r=t.get(e);void 0===r&&(r={},t.set(e,r)),r[n.alt]=!0}return t}(e.elements);return function(e){for(const t of Array.from(e.values()))if(Object.keys(t).length>1)return!0;return!1}(t)&&!function(e){for(const t of Array.from(e.values()))if(1===Object.keys(t).length)return!0;return!1}(t)}(a)){const t=(0,L.A)(a.alts);o.isAcceptState=!0,o.prediction=t,o.configs.uniqueAlt=t,Y.apply(this,[e,r,a.alts,s])}return o=J(e,t,n,o),o}function Y(e,t,n,r){const i=[];for(let a=1;a<=t;a++)i.push(this.LA(a).tokenType);const s=e.atnStartState;r(function(e){const t=(0,l.A)(e.prefixPath,e=>(0,o.Sk)(e)).join(", "),n=0===e.production.idx?"":e.production.idx;let r=`Ambiguous Alternatives Detected: <${e.ambiguityIndices.join(", ")}> in <${function(e){if(e instanceof o.wL)return"SUBRULE";if(e instanceof o.c$)return"OPTION";if(e instanceof o.ak)return"OR";if(e instanceof o.$P)return"AT_LEAST_ONE";if(e instanceof o.Cy)return"AT_LEAST_ONE_SEP";if(e instanceof o.Pp)return"MANY_SEP";if(e instanceof o.Y2)return"MANY";if(e instanceof o.BK)return"CONSUME";throw Error("non exhaustive match")}(e.production)}${n}> inside <${e.topLevelRule.name}> Rule,\n<${t}> may appears as a prefix path in all these alternatives.\n`;return r+="See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES\nFor Further details.",r}({topLevelRule:s.rule,ambiguityIndices:n,production:s.production,prefixPath:i}))}function X(e,t,n){const r=(0,b.A)(t.configs.elements,e=>e.state.transitions);return{actualToken:n,possibleTokenTypes:P(r.filter(e=>e instanceof h).map(e=>e.tokenType),e=>e.tokenTypeIdx),tokenPath:e}}function q(e,t){return e.edges[t.tokenTypeIdx]}function Q(e,t){if(e instanceof h&&(0,o.G)(t,e.tokenType))return e.target}function Z(e){return{configs:e,edges:{},isAcceptState:!1,prediction:-1}}function J(e,t,n,r){return r=ee(e,r),t.edges[n.tokenTypeIdx]=r,r}function ee(e,t){if(t===N)return t;const n=t.configs.key,r=e.states[n];return void 0!==r?r:(t.configs.finalize(),e.states[n]=t,t)}function te(e){const t=new C,n=e.transitions.length;for(let r=0;r<n;r++){ne({state:e.transitions[r].target,alt:r,stack:[]},t)}return t}function ne(e,t){const n=e.state;if(7===n.type){if(e.stack.length>0){const n=[...e.stack];ne({state:n.pop(),alt:e.alt,stack:n},t)}else t.add(e);return}n.epsilonOnlyTransitions||t.add(e);const r=n.transitions.length;for(let i=0;i<r;i++){const r=re(e,n.transitions[i]);void 0!==r&&ne(r,t)}}function re(e,t){if(t instanceof f)return{state:t.target,alt:e.alt,stack:e.stack};if(t instanceof p){const n=[...e.stack,t.followState];return{state:t.target,alt:e.alt,stack:n}}}var ie,se,ae,oe,le,ce,ue,de,he,fe,pe,me,ge,ye,Te,Ae,ve,Re,$e,Ee,ke,xe,Ie,Se,Ne,Ce,we,Le,be,Oe,_e,Pe,Me,De,Ue,Fe,Ge,Ke,Be,je,Ve,He,We,ze,Ye,Xe,qe,Qe,Ze,Je,et,tt,nt,rt,it,st,at,ot,lt,ct,ut,dt,ht,ft,pt,mt,gt,yt,Tt,At,vt,Rt,$t,Et,kt,xt,It,St,Nt=n(49683);!function(e){e.is=function(e){return"string"==typeof e}}(ie||(ie={})),function(e){e.is=function(e){return"string"==typeof e}}(se||(se={})),function(e){e.MIN_VALUE=-2147483648,e.MAX_VALUE=2147483647,e.is=function(t){return"number"==typeof t&&e.MIN_VALUE<=t&&t<=e.MAX_VALUE}}(ae||(ae={})),function(e){e.MIN_VALUE=0,e.MAX_VALUE=2147483647,e.is=function(t){return"number"==typeof t&&e.MIN_VALUE<=t&&t<=e.MAX_VALUE}}(oe||(oe={})),function(e){e.create=function(e,t){return e===Number.MAX_VALUE&&(e=oe.MAX_VALUE),t===Number.MAX_VALUE&&(t=oe.MAX_VALUE),{line:e,character:t}},e.is=function(e){let t=e;return wt.objectLiteral(t)&&wt.uinteger(t.line)&&wt.uinteger(t.character)}}(le||(le={})),function(e){e.create=function(e,t,n,r){if(wt.uinteger(e)&&wt.uinteger(t)&&wt.uinteger(n)&&wt.uinteger(r))return{start:le.create(e,t),end:le.create(n,r)};if(le.is(e)&&le.is(t))return{start:e,end:t};throw new Error(`Range#create called with invalid arguments[${e}, ${t}, ${n}, ${r}]`)},e.is=function(e){let t=e;return wt.objectLiteral(t)&&le.is(t.start)&&le.is(t.end)}}(ce||(ce={})),function(e){e.create=function(e,t){return{uri:e,range:t}},e.is=function(e){let t=e;return wt.objectLiteral(t)&&ce.is(t.range)&&(wt.string(t.uri)||wt.undefined(t.uri))}}(ue||(ue={})),function(e){e.create=function(e,t,n,r){return{targetUri:e,targetRange:t,targetSelectionRange:n,originSelectionRange:r}},e.is=function(e){let t=e;return wt.objectLiteral(t)&&ce.is(t.targetRange)&&wt.string(t.targetUri)&&ce.is(t.targetSelectionRange)&&(ce.is(t.originSelectionRange)||wt.undefined(t.originSelectionRange))}}(de||(de={})),function(e){e.create=function(e,t,n,r){return{red:e,green:t,blue:n,alpha:r}},e.is=function(e){const t=e;return wt.objectLiteral(t)&&wt.numberRange(t.red,0,1)&&wt.numberRange(t.green,0,1)&&wt.numberRange(t.blue,0,1)&&wt.numberRange(t.alpha,0,1)}}(he||(he={})),function(e){e.create=function(e,t){return{range:e,color:t}},e.is=function(e){const t=e;return wt.objectLiteral(t)&&ce.is(t.range)&&he.is(t.color)}}(fe||(fe={})),function(e){e.create=function(e,t,n){return{label:e,textEdit:t,additionalTextEdits:n}},e.is=function(e){const t=e;return wt.objectLiteral(t)&&wt.string(t.label)&&(wt.undefined(t.textEdit)||Ee.is(t))&&(wt.undefined(t.additionalTextEdits)||wt.typedArray(t.additionalTextEdits,Ee.is))}}(pe||(pe={})),function(e){e.Comment="comment",e.Imports="imports",e.Region="region"}(me||(me={})),function(e){e.create=function(e,t,n,r,i,s){const a={startLine:e,endLine:t};return wt.defined(n)&&(a.startCharacter=n),wt.defined(r)&&(a.endCharacter=r),wt.defined(i)&&(a.kind=i),wt.defined(s)&&(a.collapsedText=s),a},e.is=function(e){const t=e;return wt.objectLiteral(t)&&wt.uinteger(t.startLine)&&wt.uinteger(t.startLine)&&(wt.undefined(t.startCharacter)||wt.uinteger(t.startCharacter))&&(wt.undefined(t.endCharacter)||wt.uinteger(t.endCharacter))&&(wt.undefined(t.kind)||wt.string(t.kind))}}(ge||(ge={})),function(e){e.create=function(e,t){return{location:e,message:t}},e.is=function(e){let t=e;return wt.defined(t)&&ue.is(t.location)&&wt.string(t.message)}}(ye||(ye={})),function(e){e.Error=1,e.Warning=2,e.Information=3,e.Hint=4}(Te||(Te={})),function(e){e.Unnecessary=1,e.Deprecated=2}(Ae||(Ae={})),function(e){e.is=function(e){const t=e;return wt.objectLiteral(t)&&wt.string(t.href)}}(ve||(ve={})),function(e){e.create=function(e,t,n,r,i,s){let a={range:e,message:t};return wt.defined(n)&&(a.severity=n),wt.defined(r)&&(a.code=r),wt.defined(i)&&(a.source=i),wt.defined(s)&&(a.relatedInformation=s),a},e.is=function(e){var t;let n=e;return wt.defined(n)&&ce.is(n.range)&&wt.string(n.message)&&(wt.number(n.severity)||wt.undefined(n.severity))&&(wt.integer(n.code)||wt.string(n.code)||wt.undefined(n.code))&&(wt.undefined(n.codeDescription)||wt.string(null===(t=n.codeDescription)||void 0===t?void 0:t.href))&&(wt.string(n.source)||wt.undefined(n.source))&&(wt.undefined(n.relatedInformation)||wt.typedArray(n.relatedInformation,ye.is))}}(Re||(Re={})),function(e){e.create=function(e,t,...n){let r={title:e,command:t};return wt.defined(n)&&n.length>0&&(r.arguments=n),r},e.is=function(e){let t=e;return wt.defined(t)&&wt.string(t.title)&&wt.string(t.command)}}($e||($e={})),function(e){e.replace=function(e,t){return{range:e,newText:t}},e.insert=function(e,t){return{range:{start:e,end:e},newText:t}},e.del=function(e){return{range:e,newText:""}},e.is=function(e){const t=e;return wt.objectLiteral(t)&&wt.string(t.newText)&&ce.is(t.range)}}(Ee||(Ee={})),function(e){e.create=function(e,t,n){const r={label:e};return void 0!==t&&(r.needsConfirmation=t),void 0!==n&&(r.description=n),r},e.is=function(e){const t=e;return wt.objectLiteral(t)&&wt.string(t.label)&&(wt.boolean(t.needsConfirmation)||void 0===t.needsConfirmation)&&(wt.string(t.description)||void 0===t.description)}}(ke||(ke={})),function(e){e.is=function(e){const t=e;return wt.string(t)}}(xe||(xe={})),function(e){e.replace=function(e,t,n){return{range:e,newText:t,annotationId:n}},e.insert=function(e,t,n){return{range:{start:e,end:e},newText:t,annotationId:n}},e.del=function(e,t){return{range:e,newText:"",annotationId:t}},e.is=function(e){const t=e;return Ee.is(t)&&(ke.is(t.annotationId)||xe.is(t.annotationId))}}(Ie||(Ie={})),function(e){e.create=function(e,t){return{textDocument:e,edits:t}},e.is=function(e){let t=e;return wt.defined(t)&&_e.is(t.textDocument)&&Array.isArray(t.edits)}}(Se||(Se={})),function(e){e.create=function(e,t,n){let r={kind:"create",uri:e};return void 0===t||void 0===t.overwrite&&void 0===t.ignoreIfExists||(r.options=t),void 0!==n&&(r.annotationId=n),r},e.is=function(e){let t=e;return t&&"create"===t.kind&&wt.string(t.uri)&&(void 0===t.options||(void 0===t.options.overwrite||wt.boolean(t.options.overwrite))&&(void 0===t.options.ignoreIfExists||wt.boolean(t.options.ignoreIfExists)))&&(void 0===t.annotationId||xe.is(t.annotationId))}}(Ne||(Ne={})),function(e){e.create=function(e,t,n,r){let i={kind:"rename",oldUri:e,newUri:t};return void 0===n||void 0===n.overwrite&&void 0===n.ignoreIfExists||(i.options=n),void 0!==r&&(i.annotationId=r),i},e.is=function(e){let t=e;return t&&"rename"===t.kind&&wt.string(t.oldUri)&&wt.string(t.newUri)&&(void 0===t.options||(void 0===t.options.overwrite||wt.boolean(t.options.overwrite))&&(void 0===t.options.ignoreIfExists||wt.boolean(t.options.ignoreIfExists)))&&(void 0===t.annotationId||xe.is(t.annotationId))}}(Ce||(Ce={})),function(e){e.create=function(e,t,n){let r={kind:"delete",uri:e};return void 0===t||void 0===t.recursive&&void 0===t.ignoreIfNotExists||(r.options=t),void 0!==n&&(r.annotationId=n),r},e.is=function(e){let t=e;return t&&"delete"===t.kind&&wt.string(t.uri)&&(void 0===t.options||(void 0===t.options.recursive||wt.boolean(t.options.recursive))&&(void 0===t.options.ignoreIfNotExists||wt.boolean(t.options.ignoreIfNotExists)))&&(void 0===t.annotationId||xe.is(t.annotationId))}}(we||(we={})),function(e){e.is=function(e){let t=e;return t&&(void 0!==t.changes||void 0!==t.documentChanges)&&(void 0===t.documentChanges||t.documentChanges.every(e=>wt.string(e.kind)?Ne.is(e)||Ce.is(e)||we.is(e):Se.is(e)))}}(Le||(Le={}));!function(e){e.create=function(e){return{uri:e}},e.is=function(e){let t=e;return wt.defined(t)&&wt.string(t.uri)}}(be||(be={})),function(e){e.create=function(e,t){return{uri:e,version:t}},e.is=function(e){let t=e;return wt.defined(t)&&wt.string(t.uri)&&wt.integer(t.version)}}(Oe||(Oe={})),function(e){e.create=function(e,t){return{uri:e,version:t}},e.is=function(e){let t=e;return wt.defined(t)&&wt.string(t.uri)&&(null===t.version||wt.integer(t.version))}}(_e||(_e={})),function(e){e.create=function(e,t,n,r){return{uri:e,languageId:t,version:n,text:r}},e.is=function(e){let t=e;return wt.defined(t)&&wt.string(t.uri)&&wt.string(t.languageId)&&wt.integer(t.version)&&wt.string(t.text)}}(Pe||(Pe={})),function(e){e.PlainText="plaintext",e.Markdown="markdown",e.is=function(t){const n=t;return n===e.PlainText||n===e.Markdown}}(Me||(Me={})),function(e){e.is=function(e){const t=e;return wt.objectLiteral(e)&&Me.is(t.kind)&&wt.string(t.value)}}(De||(De={})),function(e){e.Text=1,e.Method=2,e.Function=3,e.Constructor=4,e.Field=5,e.Variable=6,e.Class=7,e.Interface=8,e.Module=9,e.Property=10,e.Unit=11,e.Value=12,e.Enum=13,e.Keyword=14,e.Snippet=15,e.Color=16,e.File=17,e.Reference=18,e.Folder=19,e.EnumMember=20,e.Constant=21,e.Struct=22,e.Event=23,e.Operator=24,e.TypeParameter=25}(Ue||(Ue={})),function(e){e.PlainText=1,e.Snippet=2}(Fe||(Fe={})),function(e){e.Deprecated=1}(Ge||(Ge={})),function(e){e.create=function(e,t,n){return{newText:e,insert:t,replace:n}},e.is=function(e){const t=e;return t&&wt.string(t.newText)&&ce.is(t.insert)&&ce.is(t.replace)}}(Ke||(Ke={})),function(e){e.asIs=1,e.adjustIndentation=2}(Be||(Be={})),function(e){e.is=function(e){const t=e;return t&&(wt.string(t.detail)||void 0===t.detail)&&(wt.string(t.description)||void 0===t.description)}}(je||(je={})),function(e){e.create=function(e){return{label:e}}}(Ve||(Ve={})),function(e){e.create=function(e,t){return{items:e||[],isIncomplete:!!t}}}(He||(He={})),function(e){e.fromPlainText=function(e){return e.replace(/[\\`*_{}[\]()#+\-.!]/g,"\\$&")},e.is=function(e){const t=e;return wt.string(t)||wt.objectLiteral(t)&&wt.string(t.language)&&wt.string(t.value)}}(We||(We={})),function(e){e.is=function(e){let t=e;return!!t&&wt.objectLiteral(t)&&(De.is(t.contents)||We.is(t.contents)||wt.typedArray(t.contents,We.is))&&(void 0===e.range||ce.is(e.range))}}(ze||(ze={})),function(e){e.create=function(e,t){return t?{label:e,documentation:t}:{label:e}}}(Ye||(Ye={})),function(e){e.create=function(e,t,...n){let r={label:e};return wt.defined(t)&&(r.documentation=t),wt.defined(n)?r.parameters=n:r.parameters=[],r}}(Xe||(Xe={})),function(e){e.Text=1,e.Read=2,e.Write=3}(qe||(qe={})),function(e){e.create=function(e,t){let n={range:e};return wt.number(t)&&(n.kind=t),n}}(Qe||(Qe={})),function(e){e.File=1,e.Module=2,e.Namespace=3,e.Package=4,e.Class=5,e.Method=6,e.Property=7,e.Field=8,e.Constructor=9,e.Enum=10,e.Interface=11,e.Function=12,e.Variable=13,e.Constant=14,e.String=15,e.Number=16,e.Boolean=17,e.Array=18,e.Object=19,e.Key=20,e.Null=21,e.EnumMember=22,e.Struct=23,e.Event=24,e.Operator=25,e.TypeParameter=26}(Ze||(Ze={})),function(e){e.Deprecated=1}(Je||(Je={})),function(e){e.create=function(e,t,n,r,i){let s={name:e,kind:t,location:{uri:r,range:n}};return i&&(s.containerName=i),s}}(et||(et={})),function(e){e.create=function(e,t,n,r){return void 0!==r?{name:e,kind:t,location:{uri:n,range:r}}:{name:e,kind:t,location:{uri:n}}}}(tt||(tt={})),function(e){e.create=function(e,t,n,r,i,s){let a={name:e,detail:t,kind:n,range:r,selectionRange:i};return void 0!==s&&(a.children=s),a},e.is=function(e){let t=e;return t&&wt.string(t.name)&&wt.number(t.kind)&&ce.is(t.range)&&ce.is(t.selectionRange)&&(void 0===t.detail||wt.string(t.detail))&&(void 0===t.deprecated||wt.boolean(t.deprecated))&&(void 0===t.children||Array.isArray(t.children))&&(void 0===t.tags||Array.isArray(t.tags))}}(nt||(nt={})),function(e){e.Empty="",e.QuickFix="quickfix",e.Refactor="refactor",e.RefactorExtract="refactor.extract",e.RefactorInline="refactor.inline",e.RefactorRewrite="refactor.rewrite",e.Source="source",e.SourceOrganizeImports="source.organizeImports",e.SourceFixAll="source.fixAll"}(rt||(rt={})),function(e){e.Invoked=1,e.Automatic=2}(it||(it={})),function(e){e.create=function(e,t,n){let r={diagnostics:e};return null!=t&&(r.only=t),null!=n&&(r.triggerKind=n),r},e.is=function(e){let t=e;return wt.defined(t)&&wt.typedArray(t.diagnostics,Re.is)&&(void 0===t.only||wt.typedArray(t.only,wt.string))&&(void 0===t.triggerKind||t.triggerKind===it.Invoked||t.triggerKind===it.Automatic)}}(st||(st={})),function(e){e.create=function(e,t,n){let r={title:e},i=!0;return"string"==typeof t?(i=!1,r.kind=t):$e.is(t)?r.command=t:r.edit=t,i&&void 0!==n&&(r.kind=n),r},e.is=function(e){let t=e;return t&&wt.string(t.title)&&(void 0===t.diagnostics||wt.typedArray(t.diagnostics,Re.is))&&(void 0===t.kind||wt.string(t.kind))&&(void 0!==t.edit||void 0!==t.command)&&(void 0===t.command||$e.is(t.command))&&(void 0===t.isPreferred||wt.boolean(t.isPreferred))&&(void 0===t.edit||Le.is(t.edit))}}(at||(at={})),function(e){e.create=function(e,t){let n={range:e};return wt.defined(t)&&(n.data=t),n},e.is=function(e){let t=e;return wt.defined(t)&&ce.is(t.range)&&(wt.undefined(t.command)||$e.is(t.command))}}(ot||(ot={})),function(e){e.create=function(e,t){return{tabSize:e,insertSpaces:t}},e.is=function(e){let t=e;return wt.defined(t)&&wt.uinteger(t.tabSize)&&wt.boolean(t.insertSpaces)}}(lt||(lt={})),function(e){e.create=function(e,t,n){return{range:e,target:t,data:n}},e.is=function(e){let t=e;return wt.defined(t)&&ce.is(t.range)&&(wt.undefined(t.target)||wt.string(t.target))}}(ct||(ct={})),function(e){e.create=function(e,t){return{range:e,parent:t}},e.is=function(t){let n=t;return wt.objectLiteral(n)&&ce.is(n.range)&&(void 0===n.parent||e.is(n.parent))}}(ut||(ut={})),function(e){e.namespace="namespace",e.type="type",e.class="class",e.enum="enum",e.interface="interface",e.struct="struct",e.typeParameter="typeParameter",e.parameter="parameter",e.variable="variable",e.property="property",e.enumMember="enumMember",e.event="event",e.function="function",e.method="method",e.macro="macro",e.keyword="keyword",e.modifier="modifier",e.comment="comment",e.string="string",e.number="number",e.regexp="regexp",e.operator="operator",e.decorator="decorator"}(dt||(dt={})),function(e){e.declaration="declaration",e.definition="definition",e.readonly="readonly",e.static="static",e.deprecated="deprecated",e.abstract="abstract",e.async="async",e.modification="modification",e.documentation="documentation",e.defaultLibrary="defaultLibrary"}(ht||(ht={})),function(e){e.is=function(e){const t=e;return wt.objectLiteral(t)&&(void 0===t.resultId||"string"==typeof t.resultId)&&Array.isArray(t.data)&&(0===t.data.length||"number"==typeof t.data[0])}}(ft||(ft={})),function(e){e.create=function(e,t){return{range:e,text:t}},e.is=function(e){const t=e;return null!=t&&ce.is(t.range)&&wt.string(t.text)}}(pt||(pt={})),function(e){e.create=function(e,t,n){return{range:e,variableName:t,caseSensitiveLookup:n}},e.is=function(e){const t=e;return null!=t&&ce.is(t.range)&&wt.boolean(t.caseSensitiveLookup)&&(wt.string(t.variableName)||void 0===t.variableName)}}(mt||(mt={})),function(e){e.create=function(e,t){return{range:e,expression:t}},e.is=function(e){const t=e;return null!=t&&ce.is(t.range)&&(wt.string(t.expression)||void 0===t.expression)}}(gt||(gt={})),function(e){e.create=function(e,t){return{frameId:e,stoppedLocation:t}},e.is=function(e){const t=e;return wt.defined(t)&&ce.is(e.stoppedLocation)}}(yt||(yt={})),function(e){e.Type=1,e.Parameter=2,e.is=function(e){return 1===e||2===e}}(Tt||(Tt={})),function(e){e.create=function(e){return{value:e}},e.is=function(e){const t=e;return wt.objectLiteral(t)&&(void 0===t.tooltip||wt.string(t.tooltip)||De.is(t.tooltip))&&(void 0===t.location||ue.is(t.location))&&(void 0===t.command||$e.is(t.command))}}(At||(At={})),function(e){e.create=function(e,t,n){const r={position:e,label:t};return void 0!==n&&(r.kind=n),r},e.is=function(e){const t=e;return wt.objectLiteral(t)&&le.is(t.position)&&(wt.string(t.label)||wt.typedArray(t.label,At.is))&&(void 0===t.kind||Tt.is(t.kind))&&void 0===t.textEdits||wt.typedArray(t.textEdits,Ee.is)&&(void 0===t.tooltip||wt.string(t.tooltip)||De.is(t.tooltip))&&(void 0===t.paddingLeft||wt.boolean(t.paddingLeft))&&(void 0===t.paddingRight||wt.boolean(t.paddingRight))}}(vt||(vt={})),function(e){e.createSnippet=function(e){return{kind:"snippet",value:e}}}(Rt||(Rt={})),function(e){e.create=function(e,t,n,r){return{insertText:e,filterText:t,range:n,command:r}}}($t||($t={})),function(e){e.create=function(e){return{items:e}}}(Et||(Et={})),function(e){e.Invoked=0,e.Automatic=1}(kt||(kt={})),function(e){e.create=function(e,t){return{range:e,text:t}}}(xt||(xt={})),function(e){e.create=function(e,t){return{triggerKind:e,selectedCompletionInfo:t}}}(It||(It={})),function(e){e.is=function(e){const t=e;return wt.objectLiteral(t)&&se.is(t.uri)&&wt.string(t.name)}}(St||(St={}));var Ct,wt;!function(e){function t(e,n){if(e.length<=1)return e;const r=e.length/2|0,i=e.slice(0,r),s=e.slice(r);t(i,n),t(s,n);let a=0,o=0,l=0;for(;a<i.length&&o<s.length;){let t=n(i[a],s[o]);e[l++]=t<=0?i[a++]:s[o++]}for(;a<i.length;)e[l++]=i[a++];for(;o<s.length;)e[l++]=s[o++];return e}e.create=function(e,t,n,r){return new Lt(e,t,n,r)},e.is=function(e){let t=e;return!!(wt.defined(t)&&wt.string(t.uri)&&(wt.undefined(t.languageId)||wt.string(t.languageId))&&wt.uinteger(t.lineCount)&&wt.func(t.getText)&&wt.func(t.positionAt)&&wt.func(t.offsetAt))},e.applyEdits=function(e,n){let r=e.getText(),i=t(n,(e,t)=>{let n=e.range.start.line-t.range.start.line;return 0===n?e.range.start.character-t.range.start.character:n}),s=r.length;for(let t=i.length-1;t>=0;t--){let n=i[t],a=e.offsetAt(n.range.start),o=e.offsetAt(n.range.end);if(!(o<=s))throw new Error("Overlapping edit");r=r.substring(0,a)+n.newText+r.substring(o,r.length),s=a}return r}}(Ct||(Ct={}));class Lt{constructor(e,t,n,r){this._uri=e,this._languageId=t,this._version=n,this._content=r,this._lineOffsets=void 0}get uri(){return this._uri}get languageId(){return this._languageId}get version(){return this._version}getText(e){if(e){let t=this.offsetAt(e.start),n=this.offsetAt(e.end);return this._content.substring(t,n)}return this._content}update(e,t){this._content=e.text,this._version=t,this._lineOffsets=void 0}getLineOffsets(){if(void 0===this._lineOffsets){let e=[],t=this._content,n=!0;for(let r=0;r<t.length;r++){n&&(e.push(r),n=!1);let i=t.charAt(r);n="\r"===i||"\n"===i,"\r"===i&&r+1<t.length&&"\n"===t.charAt(r+1)&&r++}n&&t.length>0&&e.push(t.length),this._lineOffsets=e}return this._lineOffsets}positionAt(e){e=Math.max(Math.min(e,this._content.length),0);let t=this.getLineOffsets(),n=0,r=t.length;if(0===r)return le.create(0,e);for(;n<r;){let i=Math.floor((n+r)/2);t[i]>e?r=i:n=i+1}let i=n-1;return le.create(i,e-t[i])}offsetAt(e){let t=this.getLineOffsets();if(e.line>=t.length)return this._content.length;if(e.line<0)return 0;let n=t[e.line],r=e.line+1<t.length?t[e.line+1]:this._content.length;return Math.max(Math.min(n+e.character,r),n)}get lineCount(){return this.getLineOffsets().length}}!function(e){const t=Object.prototype.toString;e.defined=function(e){return void 0!==e},e.undefined=function(e){return void 0===e},e.boolean=function(e){return!0===e||!1===e},e.string=function(e){return"[object String]"===t.call(e)},e.number=function(e){return"[object Number]"===t.call(e)},e.numberRange=function(e,n,r){return"[object Number]"===t.call(e)&&n<=e&&e<=r},e.integer=function(e){return"[object Number]"===t.call(e)&&-2147483648<=e&&e<=2147483647},e.uinteger=function(e){return"[object Number]"===t.call(e)&&0<=e&&e<=2147483647},e.func=function(e){return"[object Function]"===t.call(e)},e.objectLiteral=function(e){return null!==e&&"object"==typeof e},e.typedArray=function(e,t){return Array.isArray(e)&&e.every(t)}}(wt||(wt={}));class bt{constructor(){this.nodeStack=[]}get current(){var e;return null!==(e=this.nodeStack[this.nodeStack.length-1])&&void 0!==e?e:this.rootNode}buildRootNode(e){return this.rootNode=new Dt(e),this.rootNode.root=this.rootNode,this.nodeStack=[this.rootNode],this.rootNode}buildCompositeNode(e){const t=new Pt;return t.grammarSource=e,t.root=this.rootNode,this.current.content.push(t),this.nodeStack.push(t),t}buildLeafNode(e,t){const n=new _t(e.startOffset,e.image.length,(0,r.wf)(e),e.tokenType,!t);return n.grammarSource=t,n.root=this.rootNode,this.current.content.push(n),n}removeNode(e){const t=e.container;if(t){const n=t.content.indexOf(e);n>=0&&t.content.splice(n,1)}}addHiddenNodes(e){const t=[];for(const s of e){const e=new _t(s.startOffset,s.image.length,(0,r.wf)(s),s.tokenType,!0);e.root=this.rootNode,t.push(e)}let n=this.current,i=!1;if(n.content.length>0)n.content.push(...t);else{for(;n.container;){const e=n.container.content.indexOf(n);if(e>0){n.container.content.splice(e,0,...t),i=!0;break}n=n.container}i||this.rootNode.content.unshift(...t)}}construct(e){const t=this.current;"string"==typeof e.$type&&(this.current.astNode=e),e.$cstNode=t;const n=this.nodeStack.pop();0===(null==n?void 0:n.content.length)&&this.removeNode(n)}}class Ot{get parent(){return this.container}get feature(){return this.grammarSource}get hidden(){return!1}get astNode(){var e,t;const n="string"==typeof(null===(e=this._astNode)||void 0===e?void 0:e.$type)?this._astNode:null===(t=this.container)||void 0===t?void 0:t.astNode;if(!n)throw new Error("This node has no associated AST element");return n}set astNode(e){this._astNode=e}get element(){return this.astNode}get text(){return this.root.fullText.substring(this.offset,this.end)}}class _t extends Ot{get offset(){return this._offset}get length(){return this._length}get end(){return this._offset+this._length}get hidden(){return this._hidden}get tokenType(){return this._tokenType}get range(){return this._range}constructor(e,t,n,r,i=!1){super(),this._hidden=i,this._offset=e,this._tokenType=r,this._length=t,this._range=n}}class Pt extends Ot{constructor(){super(...arguments),this.content=new Mt(this)}get children(){return this.content}get offset(){var e,t;return null!==(t=null===(e=this.firstNonHiddenNode)||void 0===e?void 0:e.offset)&&void 0!==t?t:0}get length(){return this.end-this.offset}get end(){var e,t;return null!==(t=null===(e=this.lastNonHiddenNode)||void 0===e?void 0:e.end)&&void 0!==t?t:0}get range(){const e=this.firstNonHiddenNode,t=this.lastNonHiddenNode;if(e&&t){if(void 0===this._rangeCache){const{range:n}=e,{range:r}=t;this._rangeCache={start:n.start,end:r.end.line<n.start.line?n.start:r.end}}return this._rangeCache}return{start:le.create(0,0),end:le.create(0,0)}}get firstNonHiddenNode(){for(const e of this.content)if(!e.hidden)return e;return this.content[0]}get lastNonHiddenNode(){for(let e=this.content.length-1;e>=0;e--){const t=this.content[e];if(!t.hidden)return t}return this.content[this.content.length-1]}}class Mt extends Array{constructor(e){super(),this.parent=e,Object.setPrototypeOf(this,Mt.prototype)}push(...e){return this.addParents(e),super.push(...e)}unshift(...e){return this.addParents(e),super.unshift(...e)}splice(e,t,...n){return this.addParents(n),super.splice(e,t,...n)}addParents(e){for(const t of e)t.container=this.parent}}class Dt extends Pt{get text(){return this._text.substring(this.offset,this.end)}get fullText(){return this._text}constructor(e){super(),this._text="",this._text=null!=e?e:""}}const Ut=Symbol("Datatype");function Ft(e){return e.$type===Ut}const Gt=e=>e.endsWith("\u200b")?e:e+"\u200b";class Kt{constructor(e){this._unorderedGroups=new Map,this.allRules=new Map,this.lexer=e.parser.Lexer;const t=this.lexer.definition,n="production"===e.LanguageMetaData.mode;this.wrapper=new zt(t,Object.assign(Object.assign({},e.parser.ParserConfig),{skipValidations:n,errorMessageProvider:e.parser.ParserErrorMessageProvider}))}alternatives(e,t){this.wrapper.wrapOr(e,t)}optional(e,t){this.wrapper.wrapOption(e,t)}many(e,t){this.wrapper.wrapMany(e,t)}atLeastOne(e,t){this.wrapper.wrapAtLeastOne(e,t)}getRule(e){return this.allRules.get(e)}isRecording(){return this.wrapper.IS_RECORDING}get unorderedGroups(){return this._unorderedGroups}getRuleStack(){return this.wrapper.RULE_STACK}finalize(){this.wrapper.wrapSelfAnalysis()}}class Bt extends Kt{get current(){return this.stack[this.stack.length-1]}constructor(e){super(e),this.nodeBuilder=new bt,this.stack=[],this.assignmentMap=new Map,this.linker=e.references.Linker,this.converter=e.parser.ValueConverter,this.astReflection=e.shared.AstReflection}rule(e,t){const n=this.computeRuleType(e),r=this.wrapper.DEFINE_RULE(Gt(e.name),this.startImplementation(n,t).bind(this));return this.allRules.set(e.name,r),e.entry&&(this.mainRule=r),r}computeRuleType(e){if(!e.fragment){if((0,i.Xq)(e))return Ut;{const t=(0,i.PV)(e);return null!=t?t:e.name}}}parse(e,t={}){this.nodeBuilder.buildRootNode(e);const n=this.lexerResult=this.lexer.tokenize(e);this.wrapper.input=n.tokens;const r=t.rule?this.allRules.get(t.rule):this.mainRule;if(!r)throw new Error(t.rule?`No rule found with name '${t.rule}'`:"No main rule available.");const i=r.call(this.wrapper,{});return this.nodeBuilder.addHiddenNodes(n.hidden),this.unorderedGroups.clear(),this.lexerResult=void 0,{value:i,lexerErrors:n.errors,lexerReport:n.report,parserErrors:this.wrapper.errors}}startImplementation(e,t){return n=>{const r=!this.isRecording()&&void 0!==e;if(r){const t={$type:e};this.stack.push(t),e===Ut&&(t.value="")}let i;try{i=t(n)}catch(s){i=void 0}return void 0===i&&r&&(i=this.construct()),i}}extractHiddenTokens(e){const t=this.lexerResult.hidden;if(!t.length)return[];const n=e.startOffset;for(let r=0;r<t.length;r++){if(t[r].startOffset>n)return t.splice(0,r)}return t.splice(0,t.length)}consume(e,t,n){const r=this.wrapper.wrapConsume(e,t);if(!this.isRecording()&&this.isValidToken(r)){const e=this.extractHiddenTokens(r);this.nodeBuilder.addHiddenNodes(e);const t=this.nodeBuilder.buildLeafNode(r,n),{assignment:i,isCrossRef:s}=this.getAssignment(n),o=this.current;if(i){const e=(0,a.wb)(n)?r.image:this.converter.convert(r.image,t);this.assign(i.operator,i.feature,e,t,s)}else if(Ft(o)){let e=r.image;(0,a.wb)(n)||(e=this.converter.convert(e,t).toString()),o.value+=e}}}isValidToken(e){return!e.isInsertedInRecovery&&!isNaN(e.startOffset)&&"number"==typeof e.endOffset&&!isNaN(e.endOffset)}subrule(e,t,n,r,i){let s;this.isRecording()||n||(s=this.nodeBuilder.buildCompositeNode(r));const a=this.wrapper.wrapSubrule(e,t,i);!this.isRecording()&&s&&s.length>0&&this.performSubruleAssignment(a,r,s)}performSubruleAssignment(e,t,n){const{assignment:r,isCrossRef:i}=this.getAssignment(t);if(r)this.assign(r.operator,r.feature,e,n,i);else if(!r){const t=this.current;if(Ft(t))t.value+=e.toString();else if("object"==typeof e&&e){const n=this.assignWithoutOverride(e,t);this.stack.pop(),this.stack.push(n)}}}action(e,t){if(!this.isRecording()){let n=this.current;if(t.feature&&t.operator){n=this.construct(),this.nodeBuilder.removeNode(n.$cstNode);this.nodeBuilder.buildCompositeNode(t).content.push(n.$cstNode);const r={$type:e};this.stack.push(r),this.assign(t.operator,t.feature,n,n.$cstNode,!1)}else n.$type=e}}construct(){if(this.isRecording())return;const e=this.current;return(0,Nt.SD)(e),this.nodeBuilder.construct(e),this.stack.pop(),Ft(e)?this.converter.convert(e.value,e.$cstNode):((0,Nt.OP)(this.astReflection,e),e)}getAssignment(e){if(!this.assignmentMap.has(e)){const t=(0,Nt.XG)(e,a.wh);this.assignmentMap.set(e,{assignment:t,isCrossRef:!!t&&(0,a._c)(t.terminal)})}return this.assignmentMap.get(e)}assign(e,t,n,r,i){const s=this.current;let a;switch(a=i&&"string"==typeof n?this.linker.buildReference(s,t,r,n):n,e){case"=":s[t]=a;break;case"?=":s[t]=!0;break;case"+=":Array.isArray(s[t])||(s[t]=[]),s[t].push(a)}}assignWithoutOverride(e,t){for(const[r,i]of Object.entries(t)){const t=e[r];void 0===t?e[r]=i:Array.isArray(t)&&Array.isArray(i)&&(i.push(...t),e[r]=i)}const n=e.$cstNode;return n&&(n.astNode=void 0,e.$cstNode=void 0),e}get definitionErrors(){return this.wrapper.definitionErrors}}class jt{buildMismatchTokenMessage(e){return o.my.buildMismatchTokenMessage(e)}buildNotAllInputParsedMessage(e){return o.my.buildNotAllInputParsedMessage(e)}buildNoViableAltMessage(e){return o.my.buildNoViableAltMessage(e)}buildEarlyExitMessage(e){return o.my.buildEarlyExitMessage(e)}}class Vt extends jt{buildMismatchTokenMessage({expected:e,actual:t}){return`Expecting ${e.LABEL?"`"+e.LABEL+"`":e.name.endsWith(":KW")?`keyword '${e.name.substring(0,e.name.length-3)}'`:`token of type '${e.name}'`} but found \`${t.image}\`.`}buildNotAllInputParsedMessage({firstRedundant:e}){return`Expecting end of file but found \`${e.image}\`.`}}class Ht extends Kt{constructor(){super(...arguments),this.tokens=[],this.elementStack=[],this.lastElementStack=[],this.nextTokenIndex=0,this.stackSize=0}action(){}construct(){}parse(e){this.resetState();const t=this.lexer.tokenize(e,{mode:"partial"});return this.tokens=t.tokens,this.wrapper.input=[...this.tokens],this.mainRule.call(this.wrapper,{}),this.unorderedGroups.clear(),{tokens:this.tokens,elementStack:[...this.lastElementStack],tokenIndex:this.nextTokenIndex}}rule(e,t){const n=this.wrapper.DEFINE_RULE(Gt(e.name),this.startImplementation(t).bind(this));return this.allRules.set(e.name,n),e.entry&&(this.mainRule=n),n}resetState(){this.elementStack=[],this.lastElementStack=[],this.nextTokenIndex=0,this.stackSize=0}startImplementation(e){return t=>{const n=this.keepStackSize();try{e(t)}finally{this.resetStackSize(n)}}}removeUnexpectedElements(){this.elementStack.splice(this.stackSize)}keepStackSize(){const e=this.elementStack.length;return this.stackSize=e,e}resetStackSize(e){this.removeUnexpectedElements(),this.stackSize=e}consume(e,t,n){this.wrapper.wrapConsume(e,t),this.isRecording()||(this.lastElementStack=[...this.elementStack,n],this.nextTokenIndex=this.currIdx+1)}subrule(e,t,n,r,i){this.before(r),this.wrapper.wrapSubrule(e,t,i),this.after(r)}before(e){this.isRecording()||this.elementStack.push(e)}after(e){if(!this.isRecording()){const t=this.elementStack.lastIndexOf(e);t>=0&&this.elementStack.splice(t)}}get currIdx(){return this.wrapper.currIdx}}const Wt={recoveryEnabled:!0,nodeLocationTracking:"full",skipValidations:!0,errorMessageProvider:new Vt};class zt extends o.jr{constructor(e,t){const n=t&&"maxLookahead"in t;super(e,Object.assign(Object.assign(Object.assign({},Wt),{lookaheadStrategy:n?new o.T6({maxLookahead:t.maxLookahead}):new j({logging:t.skipValidations?()=>{}:void 0})}),t))}get IS_RECORDING(){return this.RECORDING_PHASE}DEFINE_RULE(e,t){return this.RULE(e,t)}wrapSelfAnalysis(){this.performSelfAnalysis()}wrapConsume(e,t){return this.consume(e,t)}wrapSubrule(e,t,n){return this.subrule(e,t,{ARGS:[n]})}wrapOr(e,t){this.or(e,t)}wrapOption(e,t){this.option(e,t)}wrapMany(e,t){this.many(e,t)}wrapAtLeastOne(e,t){this.atLeastOne(e,t)}}var Yt=n(71564),Xt=n(91719);function qt(e,t,n){return function(e,t){const n=(0,i.YV)(t,!1),r=(0,Xt.Td)(t.rules).filter(a.s7).filter(e=>n.has(e));for(const i of r){const t=Object.assign(Object.assign({},e),{consume:1,optional:1,subrule:1,many:1,or:1});e.parser.rule(i,Qt(t,i.definition))}}({parser:t,tokens:n,ruleNames:new Map},e),t}function Qt(e,t,n=!1){let r;if((0,a.wb)(t))r=function(e,t){const n=e.consume++,r=e.tokens[t.value];if(!r)throw new Error("Could not find token for keyword: "+t.value);return()=>e.parser.consume(n,r,t)}(e,t);else if((0,a.ve)(t))r=function(e,t){const n=(0,i.Uz)(t);return()=>e.parser.action(n,t)}(e,t);else if((0,a.wh)(t))r=Qt(e,t.terminal);else if((0,a._c)(t))r=en(e,t);else if((0,a.$g)(t))r=function(e,t){const n=t.rule.ref;if((0,a.s7)(n)){const r=e.subrule++,i=n.fragment,s=t.arguments.length>0?function(e,t){const n=t.map(e=>Zt(e.value));return t=>{const r={};for(let i=0;i<n.length;i++){const s=e.parameters[i],a=n[i];r[s.name]=a(t)}return r}}(n,t.arguments):()=>({});return a=>e.parser.subrule(r,nn(e,n),i,t,s(a))}if((0,a.rE)(n)){const r=e.consume++,i=rn(e,n.name);return()=>e.parser.consume(r,i,t)}if(!n)throw new Yt.W(t.$cstNode,`Undefined rule: ${t.rule.$refText}`);(0,Yt.d)(n)}(e,t);else if((0,a.jp)(t))r=function(e,t){if(1===t.elements.length)return Qt(e,t.elements[0]);{const n=[];for(const i of t.elements){const t={ALT:Qt(e,i,!0)},r=Jt(i);r&&(t.GATE=Zt(r)),n.push(t)}const r=e.or++;return t=>e.parser.alternatives(r,n.map(e=>{const n={ALT:()=>e.ALT(t)},r=e.GATE;return r&&(n.GATE=()=>r(t)),n}))}}(e,t);else if((0,a.cY)(t))r=function(e,t){if(1===t.elements.length)return Qt(e,t.elements[0]);const n=[];for(const o of t.elements){const t={ALT:Qt(e,o,!0)},r=Jt(o);r&&(t.GATE=Zt(r)),n.push(t)}const r=e.or++,i=(e,t)=>`uGroup_${e}_${t.getRuleStack().join("-")}`,s=t=>e.parser.alternatives(r,n.map((n,s)=>{const a={ALT:()=>!0},o=e.parser;a.ALT=()=>{if(n.ALT(t),!o.isRecording()){const e=i(r,o);o.unorderedGroups.get(e)||o.unorderedGroups.set(e,[]);const t=o.unorderedGroups.get(e);void 0===(null==t?void 0:t[s])&&(t[s]=!0)}};const l=n.GATE;return a.GATE=l?()=>l(t):()=>{const e=o.unorderedGroups.get(i(r,o));return!(null==e?void 0:e[s])},a})),a=tn(e,Jt(t),s,"*");return t=>{a(t),e.parser.isRecording()||e.parser.unorderedGroups.delete(i(r,e.parser))}}(e,t);else if((0,a.IZ)(t))r=function(e,t){const n=t.elements.map(t=>Qt(e,t));return e=>n.forEach(t=>t(e))}(e,t);else{if(!(0,a.FO)(t))throw new Yt.W(t.$cstNode,`Unexpected element type: ${t.$type}`);{const n=e.consume++;r=()=>e.parser.consume(n,o.LT,t)}}return tn(e,n?void 0:Jt(t),r,t.cardinality)}function Zt(e){if((0,a.RP)(e)){const t=Zt(e.left),n=Zt(e.right);return e=>t(e)||n(e)}if((0,a.Tu)(e)){const t=Zt(e.left),n=Zt(e.right);return e=>t(e)&&n(e)}if((0,a.Ct)(e)){const t=Zt(e.value);return e=>!t(e)}if((0,a.TF)(e)){const t=e.parameter.ref.name;return e=>void 0!==e&&!0===e[t]}if((0,a.Cz)(e)){const t=Boolean(e.true);return()=>t}(0,Yt.d)(e)}function Jt(e){if((0,a.IZ)(e))return e.guardCondition}function en(e,t,n=t.terminal){if(n){if((0,a.$g)(n)&&(0,a.s7)(n.rule.ref)){const r=n.rule.ref,i=e.subrule++;return n=>e.parser.subrule(i,nn(e,r),!1,t,n)}if((0,a.$g)(n)&&(0,a.rE)(n.rule.ref)){const r=e.consume++,i=rn(e,n.rule.ref.name);return()=>e.parser.consume(r,i,t)}if((0,a.wb)(n)){const r=e.consume++,i=rn(e,n.value);return()=>e.parser.consume(r,i,t)}throw new Error("Could not build cross reference parser")}{if(!t.type.ref)throw new Error("Could not resolve reference to type: "+t.type.$refText);const n=(0,i.U5)(t.type.ref),r=null==n?void 0:n.terminal;if(!r)throw new Error("Could not find name assignment for type: "+(0,i.Uz)(t.type.ref));return en(e,t,r)}}function tn(e,t,n,r){const i=t&&Zt(t);if(!r){if(i){const t=e.or++;return r=>e.parser.alternatives(t,[{ALT:()=>n(r),GATE:()=>i(r)},{ALT:(0,o.mT)(),GATE:()=>!i(r)}])}return n}if("*"===r){const t=e.many++;return r=>e.parser.many(t,{DEF:()=>n(r),GATE:i?()=>i(r):void 0})}if("+"===r){const t=e.many++;if(i){const r=e.or++;return s=>e.parser.alternatives(r,[{ALT:()=>e.parser.atLeastOne(t,{DEF:()=>n(s)}),GATE:()=>i(s)},{ALT:(0,o.mT)(),GATE:()=>!i(s)}])}return r=>e.parser.atLeastOne(t,{DEF:()=>n(r)})}if("?"===r){const t=e.optional++;return r=>e.parser.optional(t,{DEF:()=>n(r),GATE:i?()=>i(r):void 0})}(0,Yt.d)(r)}function nn(e,t){const n=function(e,t){if((0,a.s7)(t))return t.name;if(e.ruleNames.has(t))return e.ruleNames.get(t);{let n=t,r=n.$container,i=t.$type;for(;!(0,a.s7)(r);){if((0,a.IZ)(r)||(0,a.jp)(r)||(0,a.cY)(r)){i=r.elements.indexOf(n).toString()+":"+i}n=r,r=r.$container}return i=r.name+":"+i,e.ruleNames.set(t,i),i}}(e,t),r=e.parser.getRule(n);if(!r)throw new Error(`Rule "${n}" not found."`);return r}function rn(e,t){const n=e.tokens[t];if(!n)throw new Error(`Token "${t}" not found."`);return n}function sn(e){const t=function(e){const t=e.Grammar,n=e.parser.Lexer,r=new Bt(e);return qt(t,r,n.definition)}(e);return t.finalize(),t}var an=n(44326),on=n(65033),ln=n(59850),cn=n(32479);let un=0,dn=10;const hn=Symbol("OperationCancelled");function fn(e){return e===hn}async function pn(e){if(e===ln.XO.None)return;const t=performance.now();if(t-un>=dn&&(un=t,await new Promise(e=>{"undefined"==typeof setImmediate?setTimeout(e,0):setImmediate(e)}),un=performance.now()),e.isCancellationRequested)throw hn}class mn{constructor(){this.promise=new Promise((e,t)=>{this.resolve=t=>(e(t),this),this.reject=e=>(t(e),this)})}}class gn{constructor(e,t,n,r){this._uri=e,this._languageId=t,this._version=n,this._content=r,this._lineOffsets=void 0}get uri(){return this._uri}get languageId(){return this._languageId}get version(){return this._version}getText(e){if(e){const t=this.offsetAt(e.start),n=this.offsetAt(e.end);return this._content.substring(t,n)}return this._content}update(e,t){for(const n of e)if(gn.isIncremental(n)){const e=Rn(n.range),t=this.offsetAt(e.start),r=this.offsetAt(e.end);this._content=this._content.substring(0,t)+n.text+this._content.substring(r,this._content.length);const i=Math.max(e.start.line,0),s=Math.max(e.end.line,0);let a=this._lineOffsets;const o=An(n.text,!1,t);if(s-i===o.length)for(let n=0,c=o.length;n<c;n++)a[n+i+1]=o[n];else o.length<1e4?a.splice(i+1,s-i,...o):this._lineOffsets=a=a.slice(0,i+1).concat(o,a.slice(s+1));const l=n.text.length-(r-t);if(0!==l)for(let n=i+1+o.length,c=a.length;n<c;n++)a[n]=a[n]+l}else{if(!gn.isFull(n))throw new Error("Unknown change event received");this._content=n.text,this._lineOffsets=void 0}this._version=t}getLineOffsets(){return void 0===this._lineOffsets&&(this._lineOffsets=An(this._content,!0)),this._lineOffsets}positionAt(e){e=Math.max(Math.min(e,this._content.length),0);const t=this.getLineOffsets();let n=0,r=t.length;if(0===r)return{line:0,character:e};for(;n<r;){const i=Math.floor((n+r)/2);t[i]>e?r=i:n=i+1}const i=n-1;return{line:i,character:(e=this.ensureBeforeEOL(e,t[i]))-t[i]}}offsetAt(e){const t=this.getLineOffsets();if(e.line>=t.length)return this._content.length;if(e.line<0)return 0;const n=t[e.line];if(e.character<=0)return n;const r=e.line+1<t.length?t[e.line+1]:this._content.length,i=Math.min(n+e.character,r);return this.ensureBeforeEOL(i,n)}ensureBeforeEOL(e,t){for(;e>t&&vn(this._content.charCodeAt(e-1));)e--;return e}get lineCount(){return this.getLineOffsets().length}static isIncremental(e){const t=e;return null!=t&&"string"==typeof t.text&&void 0!==t.range&&(void 0===t.rangeLength||"number"==typeof t.rangeLength)}static isFull(e){const t=e;return null!=t&&"string"==typeof t.text&&void 0===t.range&&void 0===t.rangeLength}}var yn;function Tn(e,t){if(e.length<=1)return e;const n=e.length/2|0,r=e.slice(0,n),i=e.slice(n);Tn(r,t),Tn(i,t);let s=0,a=0,o=0;for(;s<r.length&&a<i.length;){const n=t(r[s],i[a]);e[o++]=n<=0?r[s++]:i[a++]}for(;s<r.length;)e[o++]=r[s++];for(;a<i.length;)e[o++]=i[a++];return e}function An(e,t,n=0){const r=t?[n]:[];for(let i=0;i<e.length;i++){const t=e.charCodeAt(i);vn(t)&&(13===t&&i+1<e.length&&10===e.charCodeAt(i+1)&&i++,r.push(n+i+1))}return r}function vn(e){return 13===e||10===e}function Rn(e){const t=e.start,n=e.end;return t.line>n.line||t.line===n.line&&t.character>n.character?{start:n,end:t}:e}function $n(e){const t=Rn(e.range);return t!==e.range?{newText:e.newText,range:t}:e}!function(e){e.create=function(e,t,n,r){return new gn(e,t,n,r)},e.update=function(e,t,n){if(e instanceof gn)return e.update(t,n),e;throw new Error("TextDocument.update: document must be created by TextDocument.create")},e.applyEdits=function(e,t){const n=e.getText(),r=Tn(t.map($n),(e,t)=>{const n=e.range.start.line-t.range.start.line;return 0===n?e.range.start.character-t.range.start.character:n});let i=0;const s=[];for(const a of r){const t=e.offsetAt(a.range.start);if(t<i)throw new Error("Overlapping edit");t>i&&s.push(n.substring(i,t)),a.newText.length&&s.push(a.newText),i=e.offsetAt(a.range.end)}return s.push(n.substr(i)),s.join("")}}(yn||(yn={}));var En,kn=n(37608);!function(e){e[e.Changed=0]="Changed",e[e.Parsed=1]="Parsed",e[e.IndexedContent=2]="IndexedContent",e[e.ComputedScopes=3]="ComputedScopes",e[e.Linked=4]="Linked",e[e.IndexedReferences=5]="IndexedReferences",e[e.Validated=6]="Validated"}(En||(En={}));class xn{constructor(e){this.serviceRegistry=e.ServiceRegistry,this.textDocuments=e.workspace.TextDocuments,this.fileSystemProvider=e.workspace.FileSystemProvider}async fromUri(e,t=ln.XO.None){const n=await this.fileSystemProvider.readFile(e);return this.createAsync(e,n,t)}fromTextDocument(e,t,n){return t=null!=t?t:kn.r.parse(e.uri),ln.XO.is(n)?this.createAsync(t,e,n):this.create(t,e,n)}fromString(e,t,n){return ln.XO.is(n)?this.createAsync(t,e,n):this.create(t,e,n)}fromModel(e,t){return this.create(t,{$model:e})}create(e,t,n){if("string"==typeof t){const r=this.parse(e,t,n);return this.createLangiumDocument(r,e,void 0,t)}if("$model"in t){const n={value:t.$model,parserErrors:[],lexerErrors:[]};return this.createLangiumDocument(n,e)}{const r=this.parse(e,t.getText(),n);return this.createLangiumDocument(r,e,t)}}async createAsync(e,t,n){if("string"==typeof t){const r=await this.parseAsync(e,t,n);return this.createLangiumDocument(r,e,void 0,t)}{const r=await this.parseAsync(e,t.getText(),n);return this.createLangiumDocument(r,e,t)}}createLangiumDocument(e,t,n,r){let i;if(n)i={parseResult:e,uri:t,state:En.Parsed,references:[],textDocument:n};else{const n=this.createTextDocumentGetter(t,r);i={parseResult:e,uri:t,state:En.Parsed,references:[],get textDocument(){return n()}}}return e.value.$document=i,i}async update(e,t){var n,r;const i=null===(n=e.parseResult.value.$cstNode)||void 0===n?void 0:n.root.fullText,s=null===(r=this.textDocuments)||void 0===r?void 0:r.get(e.uri.toString()),a=s?s.getText():await this.fileSystemProvider.readFile(e.uri);if(s)Object.defineProperty(e,"textDocument",{value:s});else{const t=this.createTextDocumentGetter(e.uri,a);Object.defineProperty(e,"textDocument",{get:t})}return i!==a&&(e.parseResult=await this.parseAsync(e.uri,a,t),e.parseResult.value.$document=e),e.state=En.Parsed,e}parse(e,t,n){return this.serviceRegistry.getServices(e).parser.LangiumParser.parse(t,n)}parseAsync(e,t,n){return this.serviceRegistry.getServices(e).parser.AsyncParser.parse(t,n)}createTextDocumentGetter(e,t){const n=this.serviceRegistry;let r;return()=>null!=r?r:r=yn.create(e.toString(),n.getServices(e).LanguageMetaData.languageId,0,null!=t?t:"")}}class In{constructor(e){this.documentMap=new Map,this.langiumDocumentFactory=e.workspace.LangiumDocumentFactory,this.serviceRegistry=e.ServiceRegistry}get all(){return(0,Xt.Td)(this.documentMap.values())}addDocument(e){const t=e.uri.toString();if(this.documentMap.has(t))throw new Error(`A document with the URI '${t}' is already present.`);this.documentMap.set(t,e)}getDocument(e){const t=e.toString();return this.documentMap.get(t)}async getOrCreateDocument(e,t){let n=this.getDocument(e);return n||(n=await this.langiumDocumentFactory.fromUri(e,t),this.addDocument(n),n)}createDocument(e,t,n){if(n)return this.langiumDocumentFactory.fromString(t,e,n).then(e=>(this.addDocument(e),e));{const n=this.langiumDocumentFactory.fromString(t,e);return this.addDocument(n),n}}hasDocument(e){return this.documentMap.has(e.toString())}invalidateDocument(e){const t=e.toString(),n=this.documentMap.get(t);if(n){this.serviceRegistry.getServices(e).references.Linker.unlink(n),n.state=En.Changed,n.precomputedScopes=void 0,n.diagnostics=void 0}return n}deleteDocument(e){const t=e.toString(),n=this.documentMap.get(t);return n&&(n.state=En.Changed,this.documentMap.delete(t)),n}}const Sn=Symbol("ref_resolving");class Nn{constructor(e){this.reflection=e.shared.AstReflection,this.langiumDocuments=()=>e.shared.workspace.LangiumDocuments,this.scopeProvider=e.references.ScopeProvider,this.astNodeLocator=e.workspace.AstNodeLocator}async link(e,t=ln.XO.None){for(const n of(0,Nt.jm)(e.parseResult.value))await pn(t),(0,Nt.DM)(n).forEach(t=>this.doLink(t,e))}doLink(e,t){var n;const r=e.reference;if(void 0===r._ref){r._ref=Sn;try{const t=this.getCandidate(e);if((0,cn.Zl)(t))r._ref=t;else if(r._nodeDescription=t,this.langiumDocuments().hasDocument(t.documentUri)){const n=this.loadAstNode(t);r._ref=null!=n?n:this.createLinkingError(e,t)}else r._ref=void 0}catch(i){console.error(`An error occurred while resolving reference to '${r.$refText}':`,i);const t=null!==(n=i.message)&&void 0!==n?n:String(i);r._ref=Object.assign(Object.assign({},e),{message:`An error occurred while resolving reference to '${r.$refText}': ${t}`})}t.references.push(r)}}unlink(e){for(const t of e.references)delete t._ref,delete t._nodeDescription;e.references=[]}getCandidate(e){const t=this.scopeProvider.getScope(e).getElement(e.reference.$refText);return null!=t?t:this.createLinkingError(e)}buildReference(e,t,n,r){const i=this,s={$refNode:n,$refText:r,get ref(){var n;if((0,cn.ng)(this._ref))return this._ref;if((0,cn.Nr)(this._nodeDescription)){const n=i.loadAstNode(this._nodeDescription);this._ref=null!=n?n:i.createLinkingError({reference:s,container:e,property:t},this._nodeDescription)}else if(void 0===this._ref){this._ref=Sn;const r=(0,Nt.cQ)(e).$document,a=i.getLinkedNode({reference:s,container:e,property:t});if(a.error&&r&&r.state<En.ComputedScopes)return this._ref=void 0;this._ref=null!==(n=a.node)&&void 0!==n?n:a.error,this._nodeDescription=a.descr,null==r||r.references.push(this)}else if(this._ref===Sn)throw new Error(`Cyclic reference resolution detected: ${i.astNodeLocator.getAstNodePath(e)}/${t} (symbol '${r}')`);return(0,cn.ng)(this._ref)?this._ref:void 0},get $nodeDescription(){return this._nodeDescription},get error(){return(0,cn.Zl)(this._ref)?this._ref:void 0}};return s}getLinkedNode(e){var t;try{const t=this.getCandidate(e);if((0,cn.Zl)(t))return{error:t};const n=this.loadAstNode(t);return n?{node:n,descr:t}:{descr:t,error:this.createLinkingError(e,t)}}catch(n){console.error(`An error occurred while resolving reference to '${e.reference.$refText}':`,n);const r=null!==(t=n.message)&&void 0!==t?t:String(n);return{error:Object.assign(Object.assign({},e),{message:`An error occurred while resolving reference to '${e.reference.$refText}': ${r}`})}}}loadAstNode(e){if(e.node)return e.node;const t=this.langiumDocuments().getDocument(e.documentUri);return t?this.astNodeLocator.getAstNode(t.parseResult.value,e.path):void 0}createLinkingError(e,t){const n=(0,Nt.cQ)(e.container).$document;n&&n.state<En.ComputedScopes&&console.warn(`Attempted reference resolution before document reached ComputedScopes state (${n.uri}).`);const r=this.reflection.getReferenceType(e);return Object.assign(Object.assign({},e),{message:`Could not resolve reference to ${r} named '${e.reference.$refText}'.`,targetDescription:t})}}class Cn{getName(e){if(function(e){return"string"==typeof e.name}(e))return e.name}getNameNode(e){return(0,i.qO)(e.$cstNode,"name")}}var wn;!function(e){e.basename=kn.A.basename,e.dirname=kn.A.dirname,e.extname=kn.A.extname,e.joinPath=kn.A.joinPath,e.resolvePath=kn.A.resolvePath,e.equals=function(e,t){return(null==e?void 0:e.toString())===(null==t?void 0:t.toString())},e.relative=function(e,t){const n="string"==typeof e?e:e.path,r="string"==typeof t?t:t.path,i=n.split("/").filter(e=>e.length>0),s=r.split("/").filter(e=>e.length>0);let a=0;for(;a<i.length&&i[a]===s[a];a++);return"../".repeat(i.length-a)+s.slice(a).join("/")},e.normalize=function(e){return kn.r.parse(e.toString()).toString()}}(wn||(wn={}));class Ln{constructor(e){this.nameProvider=e.references.NameProvider,this.index=e.shared.workspace.IndexManager,this.nodeLocator=e.workspace.AstNodeLocator}findDeclaration(e){if(e){const t=(0,i.Rp)(e),n=e.astNode;if(t&&n){const r=n[t.feature];if((0,cn.A_)(r))return r.ref;if(Array.isArray(r))for(const t of r)if((0,cn.A_)(t)&&t.$refNode&&t.$refNode.offset<=e.offset&&t.$refNode.end>=e.end)return t.ref}if(n){const t=this.nameProvider.getNameNode(n);if(t&&(t===e||(0,r.pO)(e,t)))return n}}}findDeclarationNode(e){const t=this.findDeclaration(e);if(null==t?void 0:t.$cstNode){const e=this.nameProvider.getNameNode(t);return null!=e?e:t.$cstNode}}findReferences(e,t){const n=[];if(t.includeDeclaration){const t=this.getReferenceToSelf(e);t&&n.push(t)}let r=this.index.findAllReferences(e,this.nodeLocator.getAstNodePath(e));return t.documentUri&&(r=r.filter(e=>wn.equals(e.sourceUri,t.documentUri))),n.push(...r),(0,Xt.Td)(n)}getReferenceToSelf(e){const t=this.nameProvider.getNameNode(e);if(t){const n=(0,Nt.YE)(e),i=this.nodeLocator.getAstNodePath(e);return{sourceUri:n.uri,sourcePath:i,targetUri:n.uri,targetPath:i,segment:(0,r.SX)(t),local:!0}}}}class bn{constructor(e){if(this.map=new Map,e)for(const[t,n]of e)this.add(t,n)}get size(){return Xt.iD.sum((0,Xt.Td)(this.map.values()).map(e=>e.length))}clear(){this.map.clear()}delete(e,t){if(void 0===t)return this.map.delete(e);{const n=this.map.get(e);if(n){const r=n.indexOf(t);if(r>=0)return 1===n.length?this.map.delete(e):n.splice(r,1),!0}return!1}}get(e){var t;return null!==(t=this.map.get(e))&&void 0!==t?t:[]}has(e,t){if(void 0===t)return this.map.has(e);{const n=this.map.get(e);return!!n&&n.indexOf(t)>=0}}add(e,t){return this.map.has(e)?this.map.get(e).push(t):this.map.set(e,[t]),this}addAll(e,t){return this.map.has(e)?this.map.get(e).push(...t):this.map.set(e,Array.from(t)),this}forEach(e){this.map.forEach((t,n)=>t.forEach(t=>e(t,n,this)))}[Symbol.iterator](){return this.entries().iterator()}entries(){return(0,Xt.Td)(this.map.entries()).flatMap(([e,t])=>t.map(t=>[e,t]))}keys(){return(0,Xt.Td)(this.map.keys())}values(){return(0,Xt.Td)(this.map.values()).flat()}entriesGroupedByKey(){return(0,Xt.Td)(this.map.entries())}}class On{get size(){return this.map.size}constructor(e){if(this.map=new Map,this.inverse=new Map,e)for(const[t,n]of e)this.set(t,n)}clear(){this.map.clear(),this.inverse.clear()}set(e,t){return this.map.set(e,t),this.inverse.set(t,e),this}get(e){return this.map.get(e)}getKey(e){return this.inverse.get(e)}delete(e){const t=this.map.get(e);return void 0!==t&&(this.map.delete(e),this.inverse.delete(t),!0)}}class _n{constructor(e){this.nameProvider=e.references.NameProvider,this.descriptions=e.workspace.AstNodeDescriptionProvider}async computeExports(e,t=ln.XO.None){return this.computeExportsForNode(e.parseResult.value,e,void 0,t)}async computeExportsForNode(e,t,n=Nt.VN,r=ln.XO.None){const i=[];this.exportNode(e,i,t);for(const s of n(e))await pn(r),this.exportNode(s,i,t);return i}exportNode(e,t,n){const r=this.nameProvider.getName(e);r&&t.push(this.descriptions.createDescription(e,r,n))}async computeLocalScopes(e,t=ln.XO.None){const n=e.parseResult.value,r=new bn;for(const i of(0,Nt.Uo)(n))await pn(t),this.processNode(i,e,r);return r}processNode(e,t,n){const r=e.$container;if(r){const i=this.nameProvider.getName(e);i&&n.add(r,this.descriptions.createDescription(e,i,t))}}}class Pn{constructor(e,t,n){var r;this.elements=e,this.outerScope=t,this.caseInsensitive=null!==(r=null==n?void 0:n.caseInsensitive)&&void 0!==r&&r}getAllElements(){return this.outerScope?this.elements.concat(this.outerScope.getAllElements()):this.elements}getElement(e){const t=this.caseInsensitive?this.elements.find(t=>t.name.toLowerCase()===e.toLowerCase()):this.elements.find(t=>t.name===e);return t||(this.outerScope?this.outerScope.getElement(e):void 0)}}class Mn{constructor(e,t,n){var r;this.elements=new Map,this.caseInsensitive=null!==(r=null==n?void 0:n.caseInsensitive)&&void 0!==r&&r;for(const i of e){const e=this.caseInsensitive?i.name.toLowerCase():i.name;this.elements.set(e,i)}this.outerScope=t}getElement(e){const t=this.caseInsensitive?e.toLowerCase():e,n=this.elements.get(t);return n||(this.outerScope?this.outerScope.getElement(e):void 0)}getAllElements(){let e=(0,Xt.Td)(this.elements.values());return this.outerScope&&(e=e.concat(this.outerScope.getAllElements())),e}}class Dn{constructor(){this.toDispose=[],this.isDisposed=!1}onDispose(e){this.toDispose.push(e)}dispose(){this.throwIfDisposed(),this.clear(),this.isDisposed=!0,this.toDispose.forEach(e=>e.dispose())}throwIfDisposed(){if(this.isDisposed)throw new Error("This cache has already been disposed")}}class Un extends Dn{constructor(){super(...arguments),this.cache=new Map}has(e){return this.throwIfDisposed(),this.cache.has(e)}set(e,t){this.throwIfDisposed(),this.cache.set(e,t)}get(e,t){if(this.throwIfDisposed(),this.cache.has(e))return this.cache.get(e);if(t){const n=t();return this.cache.set(e,n),n}}delete(e){return this.throwIfDisposed(),this.cache.delete(e)}clear(){this.throwIfDisposed(),this.cache.clear()}}class Fn extends Dn{constructor(e){super(),this.cache=new Map,this.converter=null!=e?e:e=>e}has(e,t){return this.throwIfDisposed(),this.cacheForContext(e).has(t)}set(e,t,n){this.throwIfDisposed(),this.cacheForContext(e).set(t,n)}get(e,t,n){this.throwIfDisposed();const r=this.cacheForContext(e);if(r.has(t))return r.get(t);if(n){const e=n();return r.set(t,e),e}}delete(e,t){return this.throwIfDisposed(),this.cacheForContext(e).delete(t)}clear(e){if(this.throwIfDisposed(),e){const t=this.converter(e);this.cache.delete(t)}else this.cache.clear()}cacheForContext(e){const t=this.converter(e);let n=this.cache.get(t);return n||(n=new Map,this.cache.set(t,n)),n}}class Gn extends Un{constructor(e,t){super(),t?(this.toDispose.push(e.workspace.DocumentBuilder.onBuildPhase(t,()=>{this.clear()})),this.toDispose.push(e.workspace.DocumentBuilder.onUpdate((e,t)=>{t.length>0&&this.clear()}))):this.toDispose.push(e.workspace.DocumentBuilder.onUpdate(()=>{this.clear()}))}}class Kn{constructor(e){this.reflection=e.shared.AstReflection,this.nameProvider=e.references.NameProvider,this.descriptions=e.workspace.AstNodeDescriptionProvider,this.indexManager=e.shared.workspace.IndexManager,this.globalScopeCache=new Gn(e.shared)}getScope(e){const t=[],n=this.reflection.getReferenceType(e),r=(0,Nt.YE)(e.container).precomputedScopes;if(r){let i=e.container;do{const e=r.get(i);e.length>0&&t.push((0,Xt.Td)(e).filter(e=>this.reflection.isSubtype(e.type,n))),i=i.$container}while(i)}let i=this.getGlobalScope(n,e);for(let s=t.length-1;s>=0;s--)i=this.createScope(t[s],i);return i}createScope(e,t,n){return new Pn((0,Xt.Td)(e),t,n)}createScopeForNodes(e,t,n){const r=(0,Xt.Td)(e).map(e=>{const t=this.nameProvider.getName(e);if(t)return this.descriptions.createDescription(e,t)}).nonNullable();return new Pn(r,t,n)}getGlobalScope(e,t){return this.globalScopeCache.get(e,()=>new Mn(this.indexManager.allElements(e)))}}function Bn(e){return"object"==typeof e&&!!e&&("$ref"in e||"$error"in e)}class jn{constructor(e){this.ignoreProperties=new Set(["$container","$containerProperty","$containerIndex","$document","$cstNode"]),this.langiumDocuments=e.shared.workspace.LangiumDocuments,this.astNodeLocator=e.workspace.AstNodeLocator,this.nameProvider=e.references.NameProvider,this.commentProvider=e.documentation.CommentProvider}serialize(e,t){const n=null!=t?t:{},r=null==t?void 0:t.replacer,i=(e,t)=>this.replacer(e,t,n),s=r?(e,t)=>r(e,t,i):i;try{return this.currentDocument=(0,Nt.YE)(e),JSON.stringify(e,s,null==t?void 0:t.space)}finally{this.currentDocument=void 0}}deserialize(e,t){const n=null!=t?t:{},r=JSON.parse(e);return this.linkNode(r,r,n),r}replacer(e,t,{refText:n,sourceText:r,textRegions:i,comments:s,uriConverter:a}){var o,l,c,u;if(!this.ignoreProperties.has(e)){if((0,cn.A_)(t)){const e=t.ref,r=n?t.$refText:void 0;if(e){const n=(0,Nt.YE)(e);let i="";this.currentDocument&&this.currentDocument!==n&&(i=a?a(n.uri,t):n.uri.toString());return{$ref:`${i}#${this.astNodeLocator.getAstNodePath(e)}`,$refText:r}}return{$error:null!==(l=null===(o=t.error)||void 0===o?void 0:o.message)&&void 0!==l?l:"Could not resolve reference",$refText:r}}if((0,cn.ng)(t)){let n;if(i&&(n=this.addAstNodeRegionWithAssignmentsTo(Object.assign({},t)),e&&!t.$document||!(null==n?void 0:n.$textRegion)||(n.$textRegion.documentURI=null===(c=this.currentDocument)||void 0===c?void 0:c.uri.toString())),r&&!e&&(null!=n||(n=Object.assign({},t)),n.$sourceText=null===(u=t.$cstNode)||void 0===u?void 0:u.text),s){null!=n||(n=Object.assign({},t));const e=this.commentProvider.getComment(t);e&&(n.$comment=e.replace(/\r/g,""))}return null!=n?n:t}return t}}addAstNodeRegionWithAssignmentsTo(e){const t=e=>({offset:e.offset,end:e.end,length:e.length,range:e.range});if(e.$cstNode){const n=(e.$textRegion=t(e.$cstNode)).assignments={};return Object.keys(e).filter(e=>!e.startsWith("$")).forEach(r=>{const s=(0,i.Bd)(e.$cstNode,r).map(t);0!==s.length&&(n[r]=s)}),e}}linkNode(e,t,n,r,i,s){for(const[o,l]of Object.entries(e))if(Array.isArray(l))for(let r=0;r<l.length;r++){const i=l[r];Bn(i)?l[r]=this.reviveReference(e,o,t,i,n):(0,cn.ng)(i)&&this.linkNode(i,t,n,e,o,r)}else Bn(l)?e[o]=this.reviveReference(e,o,t,l,n):(0,cn.ng)(l)&&this.linkNode(l,t,n,e,o);const a=e;a.$container=r,a.$containerProperty=i,a.$containerIndex=s}reviveReference(e,t,n,r,i){let s=r.$refText,a=r.$error;if(r.$ref){const e=this.getRefNode(n,r.$ref,i.uriConverter);if((0,cn.ng)(e))return s||(s=this.nameProvider.getName(e)),{$refText:null!=s?s:"",ref:e};a=e}if(a){const n={$refText:null!=s?s:""};return n.error={container:e,property:t,message:a,reference:n},n}}getRefNode(e,t,n){try{const r=t.indexOf("#");if(0===r){const n=this.astNodeLocator.getAstNode(e,t.substring(1));return n||"Could not resolve path: "+t}if(r<0){const e=n?n(t):kn.r.parse(t),r=this.langiumDocuments.getDocument(e);return r?r.parseResult.value:"Could not find document for URI: "+t}const i=n?n(t.substring(0,r)):kn.r.parse(t.substring(0,r)),s=this.langiumDocuments.getDocument(i);if(!s)return"Could not find document for URI: "+t;if(r===t.length-1)return s.parseResult.value;const a=this.astNodeLocator.getAstNode(s.parseResult.value,t.substring(r+1));return a||"Could not resolve URI: "+t}catch(r){return String(r)}}}class Vn{get map(){return this.fileExtensionMap}constructor(e){this.languageIdMap=new Map,this.fileExtensionMap=new Map,this.textDocuments=null==e?void 0:e.workspace.TextDocuments}register(e){const t=e.LanguageMetaData;for(const n of t.fileExtensions)this.fileExtensionMap.has(n)&&console.warn(`The file extension ${n} is used by multiple languages. It is now assigned to '${t.languageId}'.`),this.fileExtensionMap.set(n,e);this.languageIdMap.set(t.languageId,e),1===this.languageIdMap.size?this.singleton=e:this.singleton=void 0}getServices(e){var t,n;if(void 0!==this.singleton)return this.singleton;if(0===this.languageIdMap.size)throw new Error("The service registry is empty. Use `register` to register the services of a language.");const r=null===(n=null===(t=this.textDocuments)||void 0===t?void 0:t.get(e))||void 0===n?void 0:n.languageId;if(void 0!==r){const e=this.languageIdMap.get(r);if(e)return e}const i=wn.extname(e),s=this.fileExtensionMap.get(i);if(!s)throw r?new Error(`The service registry contains no services for the extension '${i}' for language '${r}'.`):new Error(`The service registry contains no services for the extension '${i}'.`);return s}hasServices(e){try{return this.getServices(e),!0}catch(t){return!1}}get all(){return Array.from(this.languageIdMap.values())}}function Hn(e){return{code:e}}var Wn,zn;!function(e){e.all=["fast","slow","built-in"]}(Wn||(Wn={}));class Yn{constructor(e){this.entries=new bn,this.entriesBefore=[],this.entriesAfter=[],this.reflection=e.shared.AstReflection}register(e,t=this,n="fast"){if("built-in"===n)throw new Error("The 'built-in' category is reserved for lexer, parser, and linker errors.");for(const[r,i]of Object.entries(e)){const e=i;if(Array.isArray(e))for(const i of e){const e={check:this.wrapValidationException(i,t),category:n};this.addEntry(r,e)}else if("function"==typeof e){const i={check:this.wrapValidationException(e,t),category:n};this.addEntry(r,i)}else(0,Yt.d)(e)}}wrapValidationException(e,t){return async(n,r,i)=>{await this.handleException(()=>e.call(t,n,r,i),"An error occurred during validation",r,n)}}async handleException(e,t,n,r){try{await e()}catch(i){if(fn(i))throw i;console.error(`${t}:`,i),i instanceof Error&&i.stack&&console.error(i.stack);n("error",`${t}: ${i instanceof Error?i.message:String(i)}`,{node:r})}}addEntry(e,t){if("AstNode"!==e)for(const n of this.reflection.getAllSubTypes(e))this.entries.add(n,t);else this.entries.add("AstNode",t)}getChecks(e,t){let n=(0,Xt.Td)(this.entries.get(e)).concat(this.entries.get("AstNode"));return t&&(n=n.filter(e=>t.includes(e.category))),n.map(e=>e.check)}registerBeforeDocument(e,t=this){this.entriesBefore.push(this.wrapPreparationException(e,"An error occurred during set-up of the validation",t))}registerAfterDocument(e,t=this){this.entriesAfter.push(this.wrapPreparationException(e,"An error occurred during tear-down of the validation",t))}wrapPreparationException(e,t,n){return async(r,i,s,a)=>{await this.handleException(()=>e.call(n,r,i,s,a),t,i,r)}}get checksBefore(){return this.entriesBefore}get checksAfter(){return this.entriesAfter}}class Xn{constructor(e){this.validationRegistry=e.validation.ValidationRegistry,this.metadata=e.LanguageMetaData}async validateDocument(e,t={},n=ln.XO.None){const r=e.parseResult,i=[];if(await pn(n),!t.categories||t.categories.includes("built-in")){if(this.processLexingErrors(r,i,t),t.stopAfterLexingErrors&&i.some(e=>{var t;return(null===(t=e.data)||void 0===t?void 0:t.code)===zn.LexingError}))return i;if(this.processParsingErrors(r,i,t),t.stopAfterParsingErrors&&i.some(e=>{var t;return(null===(t=e.data)||void 0===t?void 0:t.code)===zn.ParsingError}))return i;if(this.processLinkingErrors(e,i,t),t.stopAfterLinkingErrors&&i.some(e=>{var t;return(null===(t=e.data)||void 0===t?void 0:t.code)===zn.LinkingError}))return i}try{i.push(...await this.validateAst(r.value,t,n))}catch(s){if(fn(s))throw s;console.error("An error occurred during validation:",s)}return await pn(n),i}processLexingErrors(e,t,n){var r,i,s;const a=[...e.lexerErrors,...null!==(i=null===(r=e.lexerReport)||void 0===r?void 0:r.diagnostics)&&void 0!==i?i:[]];for(const o of a){const e=null!==(s=o.severity)&&void 0!==s?s:"error",n={severity:Qn(e),range:{start:{line:o.line-1,character:o.column-1},end:{line:o.line-1,character:o.column+o.length-1}},message:o.message,data:Zn(e),source:this.getSource()};t.push(n)}}processParsingErrors(e,t,n){for(const i of e.parserErrors){let e;if(isNaN(i.token.startOffset)){if("previousToken"in i){const t=i.previousToken;if(isNaN(t.startOffset)){const t={line:0,character:0};e={start:t,end:t}}else{const n={line:t.endLine-1,character:t.endColumn};e={start:n,end:n}}}}else e=(0,r.wf)(i.token);if(e){const n={severity:Qn("error"),range:e,message:i.message,data:Hn(zn.ParsingError),source:this.getSource()};t.push(n)}}}processLinkingErrors(e,t,n){for(const r of e.references){const e=r.error;if(e){const n={node:e.container,property:e.property,index:e.index,data:{code:zn.LinkingError,containerType:e.container.$type,property:e.property,refText:e.reference.$refText}};t.push(this.toDiagnostic("error",e.message,n))}}}async validateAst(e,t,n=ln.XO.None){const r=[],i=(e,t,n)=>{r.push(this.toDiagnostic(e,t,n))};return await this.validateAstBefore(e,t,i,n),await this.validateAstNodes(e,t,i,n),await this.validateAstAfter(e,t,i,n),r}async validateAstBefore(e,t,n,r=ln.XO.None){var i;const s=this.validationRegistry.checksBefore;for(const a of s)await pn(r),await a(e,n,null!==(i=t.categories)&&void 0!==i?i:[],r)}async validateAstNodes(e,t,n,r=ln.XO.None){await Promise.all((0,Nt.jm)(e).map(async e=>{await pn(r);const i=this.validationRegistry.getChecks(e.$type,t.categories);for(const t of i)await t(e,n,r)}))}async validateAstAfter(e,t,n,r=ln.XO.None){var i;const s=this.validationRegistry.checksAfter;for(const a of s)await pn(r),await a(e,n,null!==(i=t.categories)&&void 0!==i?i:[],r)}toDiagnostic(e,t,n){return{message:t,range:qn(n),severity:Qn(e),code:n.code,codeDescription:n.codeDescription,tags:n.tags,relatedInformation:n.relatedInformation,data:n.data,source:this.getSource()}}getSource(){return this.metadata.languageId}}function qn(e){if(e.range)return e.range;let t;return"string"==typeof e.property?t=(0,i.qO)(e.node.$cstNode,e.property,e.index):"string"==typeof e.keyword&&(t=(0,i.SS)(e.node.$cstNode,e.keyword,e.index)),null!=t||(t=e.node.$cstNode),t?t.range:{start:{line:0,character:0},end:{line:0,character:0}}}function Qn(e){switch(e){case"error":return 1;case"warning":return 2;case"info":return 3;case"hint":return 4;default:throw new Error("Invalid diagnostic severity: "+e)}}function Zn(e){switch(e){case"error":return Hn(zn.LexingError);case"warning":return Hn(zn.LexingWarning);case"info":return Hn(zn.LexingInfo);case"hint":return Hn(zn.LexingHint);default:throw new Error("Invalid diagnostic severity: "+e)}}!function(e){e.LexingError="lexing-error",e.LexingWarning="lexing-warning",e.LexingInfo="lexing-info",e.LexingHint="lexing-hint",e.ParsingError="parsing-error",e.LinkingError="linking-error"}(zn||(zn={}));class Jn{constructor(e){this.astNodeLocator=e.workspace.AstNodeLocator,this.nameProvider=e.references.NameProvider}createDescription(e,t,n){const i=null!=n?n:(0,Nt.YE)(e);null!=t||(t=this.nameProvider.getName(e));const s=this.astNodeLocator.getAstNodePath(e);if(!t)throw new Error(`Node at path ${s} has no name.`);let a;const o=()=>{var t;return null!=a?a:a=(0,r.SX)(null!==(t=this.nameProvider.getNameNode(e))&&void 0!==t?t:e.$cstNode)};return{node:e,name:t,get nameSegment(){return o()},selectionSegment:(0,r.SX)(e.$cstNode),type:e.$type,documentUri:i.uri,path:s}}}class er{constructor(e){this.nodeLocator=e.workspace.AstNodeLocator}async createDescriptions(e,t=ln.XO.None){const n=[],r=e.parseResult.value;for(const i of(0,Nt.jm)(r))await pn(t),(0,Nt.DM)(i).filter(e=>!(0,cn.Zl)(e)).forEach(e=>{const t=this.createDescription(e);t&&n.push(t)});return n}createDescription(e){const t=e.reference.$nodeDescription,n=e.reference.$refNode;if(!t||!n)return;const i=(0,Nt.YE)(e.container).uri;return{sourceUri:i,sourcePath:this.nodeLocator.getAstNodePath(e.container),targetUri:t.documentUri,targetPath:t.path,segment:(0,r.SX)(n),local:wn.equals(t.documentUri,i)}}}class tr{constructor(){this.segmentSeparator="/",this.indexSeparator="@"}getAstNodePath(e){if(e.$container){const t=this.getAstNodePath(e.$container),n=this.getPathSegment(e);return t+this.segmentSeparator+n}return""}getPathSegment({$containerProperty:e,$containerIndex:t}){if(!e)throw new Error("Missing '$containerProperty' in AST node.");return void 0!==t?e+this.indexSeparator+t:e}getAstNode(e,t){return t.split(this.segmentSeparator).reduce((e,t)=>{if(!e||0===t.length)return e;const n=t.indexOf(this.indexSeparator);if(n>0){const r=t.substring(0,n),i=parseInt(t.substring(n+1)),s=e[r];return null==s?void 0:s[i]}return e[t]},e)}}var nr,rr=n(62676);class ir{constructor(e){this._ready=new mn,this.settings={},this.workspaceConfig=!1,this.onConfigurationSectionUpdateEmitter=new rr.Emitter,this.serviceRegistry=e.ServiceRegistry}get ready(){return this._ready.promise}initialize(e){var t,n;this.workspaceConfig=null!==(n=null===(t=e.capabilities.workspace)||void 0===t?void 0:t.configuration)&&void 0!==n&&n}async initialized(e){if(this.workspaceConfig){if(e.register){const t=this.serviceRegistry.all;e.register({section:t.map(e=>this.toSectionName(e.LanguageMetaData.languageId))})}if(e.fetchConfiguration){const t=this.serviceRegistry.all.map(e=>({section:this.toSectionName(e.LanguageMetaData.languageId)})),n=await e.fetchConfiguration(t);t.forEach((e,t)=>{this.updateSectionConfiguration(e.section,n[t])})}}this._ready.resolve()}updateConfiguration(e){e.settings&&Object.keys(e.settings).forEach(t=>{const n=e.settings[t];this.updateSectionConfiguration(t,n),this.onConfigurationSectionUpdateEmitter.fire({section:t,configuration:n})})}updateSectionConfiguration(e,t){this.settings[e]=t}async getConfiguration(e,t){await this.ready;const n=this.toSectionName(e);if(this.settings[n])return this.settings[n][t]}toSectionName(e){return`${e}`}get onConfigurationSectionUpdate(){return this.onConfigurationSectionUpdateEmitter.event}}!function(e){e.create=function(e){return{dispose:async()=>await e()}}}(nr||(nr={}));class sr{constructor(e){this.updateBuildOptions={validation:{categories:["built-in","fast"]}},this.updateListeners=[],this.buildPhaseListeners=new bn,this.documentPhaseListeners=new bn,this.buildState=new Map,this.documentBuildWaiters=new Map,this.currentState=En.Changed,this.langiumDocuments=e.workspace.LangiumDocuments,this.langiumDocumentFactory=e.workspace.LangiumDocumentFactory,this.textDocuments=e.workspace.TextDocuments,this.indexManager=e.workspace.IndexManager,this.serviceRegistry=e.ServiceRegistry}async build(e,t={},n=ln.XO.None){var r,i;for(const s of e){const e=s.uri.toString();if(s.state===En.Validated){if("boolean"==typeof t.validation&&t.validation)s.state=En.IndexedReferences,s.diagnostics=void 0,this.buildState.delete(e);else if("object"==typeof t.validation){const n=this.buildState.get(e),a=null===(r=null==n?void 0:n.result)||void 0===r?void 0:r.validationChecks;if(a){const r=(null!==(i=t.validation.categories)&&void 0!==i?i:Wn.all).filter(e=>!a.includes(e));r.length>0&&(this.buildState.set(e,{completed:!1,options:{validation:Object.assign(Object.assign({},t.validation),{categories:r})},result:n.result}),s.state=En.IndexedReferences)}}}else this.buildState.delete(e)}this.currentState=En.Changed,await this.emitUpdate(e.map(e=>e.uri),[]),await this.buildDocuments(e,t,n)}async update(e,t,n=ln.XO.None){this.currentState=En.Changed;for(const s of t)this.langiumDocuments.deleteDocument(s),this.buildState.delete(s.toString()),this.indexManager.remove(s);for(const s of e){if(!this.langiumDocuments.invalidateDocument(s)){const e=this.langiumDocumentFactory.fromModel({$type:"INVALID"},s);e.state=En.Changed,this.langiumDocuments.addDocument(e)}this.buildState.delete(s.toString())}const r=(0,Xt.Td)(e).concat(t).map(e=>e.toString()).toSet();this.langiumDocuments.all.filter(e=>!r.has(e.uri.toString())&&this.shouldRelink(e,r)).forEach(e=>{this.serviceRegistry.getServices(e.uri).references.Linker.unlink(e),e.state=Math.min(e.state,En.ComputedScopes),e.diagnostics=void 0}),await this.emitUpdate(e,t),await pn(n);const i=this.sortDocuments(this.langiumDocuments.all.filter(e=>{var t;return e.state<En.Linked||!(null===(t=this.buildState.get(e.uri.toString()))||void 0===t?void 0:t.completed)}).toArray());await this.buildDocuments(i,this.updateBuildOptions,n)}async emitUpdate(e,t){await Promise.all(this.updateListeners.map(n=>n(e,t)))}sortDocuments(e){let t=0,n=e.length-1;for(;t<n;){for(;t<e.length&&this.hasTextDocument(e[t]);)t++;for(;n>=0&&!this.hasTextDocument(e[n]);)n--;t<n&&([e[t],e[n]]=[e[n],e[t]])}return e}hasTextDocument(e){var t;return Boolean(null===(t=this.textDocuments)||void 0===t?void 0:t.get(e.uri))}shouldRelink(e,t){return!!e.references.some(e=>void 0!==e.error)||this.indexManager.isAffected(e,t)}onUpdate(e){return this.updateListeners.push(e),nr.create(()=>{const t=this.updateListeners.indexOf(e);t>=0&&this.updateListeners.splice(t,1)})}async buildDocuments(e,t,n){this.prepareBuild(e,t),await this.runCancelable(e,En.Parsed,n,e=>this.langiumDocumentFactory.update(e,n)),await this.runCancelable(e,En.IndexedContent,n,e=>this.indexManager.updateContent(e,n)),await this.runCancelable(e,En.ComputedScopes,n,async e=>{const t=this.serviceRegistry.getServices(e.uri).references.ScopeComputation;e.precomputedScopes=await t.computeLocalScopes(e,n)}),await this.runCancelable(e,En.Linked,n,e=>this.serviceRegistry.getServices(e.uri).references.Linker.link(e,n)),await this.runCancelable(e,En.IndexedReferences,n,e=>this.indexManager.updateReferences(e,n));const r=e.filter(e=>this.shouldValidate(e));await this.runCancelable(r,En.Validated,n,e=>this.validate(e,n));for(const i of e){const e=this.buildState.get(i.uri.toString());e&&(e.completed=!0)}}prepareBuild(e,t){for(const n of e){const e=n.uri.toString(),r=this.buildState.get(e);r&&!r.completed||this.buildState.set(e,{completed:!1,options:t,result:null==r?void 0:r.result})}}async runCancelable(e,t,n,r){const i=e.filter(e=>e.state<t);for(const a of i)await pn(n),await r(a),a.state=t,await this.notifyDocumentPhase(a,t,n);const s=e.filter(e=>e.state===t);await this.notifyBuildPhase(s,t,n),this.currentState=t}onBuildPhase(e,t){return this.buildPhaseListeners.add(e,t),nr.create(()=>{this.buildPhaseListeners.delete(e,t)})}onDocumentPhase(e,t){return this.documentPhaseListeners.add(e,t),nr.create(()=>{this.documentPhaseListeners.delete(e,t)})}waitUntil(e,t,n){let r;if(t&&"path"in t?r=t:n=t,null!=n||(n=ln.XO.None),r){const t=this.langiumDocuments.getDocument(r);if(t&&t.state>e)return Promise.resolve(r)}return this.currentState>=e?Promise.resolve(void 0):n.isCancellationRequested?Promise.reject(hn):new Promise((t,i)=>{const s=this.onBuildPhase(e,()=>{if(s.dispose(),a.dispose(),r){const e=this.langiumDocuments.getDocument(r);t(null==e?void 0:e.uri)}else t(void 0)}),a=n.onCancellationRequested(()=>{s.dispose(),a.dispose(),i(hn)})})}async notifyDocumentPhase(e,t,n){const r=this.documentPhaseListeners.get(t).slice();for(const s of r)try{await s(e,n)}catch(i){if(!fn(i))throw i}}async notifyBuildPhase(e,t,n){if(0===e.length)return;const r=this.buildPhaseListeners.get(t).slice();for(const i of r)await pn(n),await i(e,n)}shouldValidate(e){return Boolean(this.getBuildOptions(e).validation)}async validate(e,t){var n,r;const i=this.serviceRegistry.getServices(e.uri).validation.DocumentValidator,s=this.getBuildOptions(e).validation,a="object"==typeof s?s:void 0,o=await i.validateDocument(e,a,t);e.diagnostics?e.diagnostics.push(...o):e.diagnostics=o;const l=this.buildState.get(e.uri.toString());if(l){null!==(n=l.result)&&void 0!==n||(l.result={});const e=null!==(r=null==a?void 0:a.categories)&&void 0!==r?r:Wn.all;l.result.validationChecks?l.result.validationChecks.push(...e):l.result.validationChecks=[...e]}}getBuildOptions(e){var t,n;return null!==(n=null===(t=this.buildState.get(e.uri.toString()))||void 0===t?void 0:t.options)&&void 0!==n?n:{}}}class ar{constructor(e){this.symbolIndex=new Map,this.symbolByTypeIndex=new Fn,this.referenceIndex=new Map,this.documents=e.workspace.LangiumDocuments,this.serviceRegistry=e.ServiceRegistry,this.astReflection=e.AstReflection}findAllReferences(e,t){const n=(0,Nt.YE)(e).uri,r=[];return this.referenceIndex.forEach(e=>{e.forEach(e=>{wn.equals(e.targetUri,n)&&e.targetPath===t&&r.push(e)})}),(0,Xt.Td)(r)}allElements(e,t){let n=(0,Xt.Td)(this.symbolIndex.keys());return t&&(n=n.filter(e=>!t||t.has(e))),n.map(t=>this.getFileDescriptions(t,e)).flat()}getFileDescriptions(e,t){var n;if(!t)return null!==(n=this.symbolIndex.get(e))&&void 0!==n?n:[];const r=this.symbolByTypeIndex.get(e,t,()=>{var n;return(null!==(n=this.symbolIndex.get(e))&&void 0!==n?n:[]).filter(e=>this.astReflection.isSubtype(e.type,t))});return r}remove(e){const t=e.toString();this.symbolIndex.delete(t),this.symbolByTypeIndex.clear(t),this.referenceIndex.delete(t)}async updateContent(e,t=ln.XO.None){const n=this.serviceRegistry.getServices(e.uri),r=await n.references.ScopeComputation.computeExports(e,t),i=e.uri.toString();this.symbolIndex.set(i,r),this.symbolByTypeIndex.clear(i)}async updateReferences(e,t=ln.XO.None){const n=this.serviceRegistry.getServices(e.uri),r=await n.workspace.ReferenceDescriptionProvider.createDescriptions(e,t);this.referenceIndex.set(e.uri.toString(),r)}isAffected(e,t){const n=this.referenceIndex.get(e.uri.toString());return!!n&&n.some(e=>!e.local&&t.has(e.targetUri.toString()))}}class or{constructor(e){this.initialBuildOptions={},this._ready=new mn,this.serviceRegistry=e.ServiceRegistry,this.langiumDocuments=e.workspace.LangiumDocuments,this.documentBuilder=e.workspace.DocumentBuilder,this.fileSystemProvider=e.workspace.FileSystemProvider,this.mutex=e.workspace.WorkspaceLock}get ready(){return this._ready.promise}get workspaceFolders(){return this.folders}initialize(e){var t;this.folders=null!==(t=e.workspaceFolders)&&void 0!==t?t:void 0}initialized(e){return this.mutex.write(e=>{var t;return this.initializeWorkspace(null!==(t=this.folders)&&void 0!==t?t:[],e)})}async initializeWorkspace(e,t=ln.XO.None){const n=await this.performStartup(e);await pn(t),await this.documentBuilder.build(n,this.initialBuildOptions,t)}async performStartup(e){const t=this.serviceRegistry.all.flatMap(e=>e.LanguageMetaData.fileExtensions),n=[],r=e=>{n.push(e),this.langiumDocuments.hasDocument(e.uri)||this.langiumDocuments.addDocument(e)};return await this.loadAdditionalDocuments(e,r),await Promise.all(e.map(e=>[e,this.getRootFolder(e)]).map(async e=>this.traverseFolder(...e,t,r))),this._ready.resolve(),n}loadAdditionalDocuments(e,t){return Promise.resolve()}getRootFolder(e){return kn.r.parse(e.uri)}async traverseFolder(e,t,n,r){const i=await this.fileSystemProvider.readDirectory(t);await Promise.all(i.map(async t=>{if(this.includeEntry(e,t,n))if(t.isDirectory)await this.traverseFolder(e,t.uri,n,r);else if(t.isFile){const e=await this.langiumDocuments.getOrCreateDocument(t.uri);r(e)}}))}includeEntry(e,t,n){const r=wn.basename(t.uri);if(r.startsWith("."))return!1;if(t.isDirectory)return"node_modules"!==r&&"out"!==r;if(t.isFile){const e=wn.extname(t.uri);return n.includes(e)}return!1}}class lr{buildUnexpectedCharactersMessage(e,t,n,r,i){return o.PW.buildUnexpectedCharactersMessage(e,t,n,r,i)}buildUnableToPopLexerModeMessage(e){return o.PW.buildUnableToPopLexerModeMessage(e)}}const cr={mode:"full"};class ur{constructor(e){this.errorMessageProvider=e.parser.LexerErrorMessageProvider,this.tokenBuilder=e.parser.TokenBuilder;const t=this.tokenBuilder.buildTokens(e.Grammar,{caseInsensitive:e.LanguageMetaData.caseInsensitive});this.tokenTypes=this.toTokenTypeDictionary(t);const n=hr(t)?Object.values(t):t,r="production"===e.LanguageMetaData.mode;this.chevrotainLexer=new o.JG(n,{positionTracking:"full",skipValidations:r,errorMessageProvider:this.errorMessageProvider})}get definition(){return this.tokenTypes}tokenize(e,t=cr){var n,r,i;const s=this.chevrotainLexer.tokenize(e);return{tokens:s.tokens,errors:s.errors,hidden:null!==(n=s.groups.hidden)&&void 0!==n?n:[],report:null===(i=(r=this.tokenBuilder).flushLexingReport)||void 0===i?void 0:i.call(r,e)}}toTokenTypeDictionary(e){if(hr(e))return e;const t=dr(e)?Object.values(e.modes).flat():e,n={};return t.forEach(e=>n[e.name]=e),n}}function dr(e){return e&&"modes"in e&&"defaultMode"in e}function hr(e){return!function(e){return Array.isArray(e)&&(0===e.length||"name"in e[0])}(e)&&!dr(e)}function fr(e,t,n){let r,i;"string"==typeof e?(i=t,r=n):(i=e.range.start,r=t),i||(i=le.create(0,0));const s=function(e){var t,n,r;const i=[];let s=e.position.line,a=e.position.character;for(let o=0;o<e.lines.length;o++){const l=0===o,c=o===e.lines.length-1;let u=e.lines[o],d=0;if(l&&e.options.start){const n=null===(t=e.options.start)||void 0===t?void 0:t.exec(u);n&&(d=n.index+n[0].length)}else{const t=null===(n=e.options.line)||void 0===n?void 0:n.exec(u);t&&(d=t.index+t[0].length)}if(c){const t=null===(r=e.options.end)||void 0===r?void 0:r.exec(u);t&&(u=u.substring(0,t.index))}u=u.substring(0,Rr(u));if(vr(u,d)>=u.length){if(i.length>0){const e=le.create(s,a);i.push({type:"break",content:"",range:ce.create(e,e)})}}else{mr.lastIndex=d;const e=mr.exec(u);if(e){const t=e[0],n=e[1],r=le.create(s,a+d),o=le.create(s,a+d+t.length);i.push({type:"tag",content:n,range:ce.create(r,o)}),d+=t.length,d=vr(u,d)}if(d<u.length){const e=u.substring(d),t=Array.from(e.matchAll(gr));i.push(...yr(t,e,s,a+d))}}s++,a=0}if(i.length>0&&"break"===i[i.length-1].type)return i.slice(0,-1);return i}({lines:pr(e),position:i,options:Sr(r)});return function(e){var t,n,r,i;const s=le.create(e.position.line,e.position.character);if(0===e.tokens.length)return new Cr([],ce.create(s,s));const a=[];for(;e.index<e.tokens.length;){const t=$r(e,a[a.length-1]);t&&a.push(t)}const o=null!==(n=null===(t=a[0])||void 0===t?void 0:t.range.start)&&void 0!==n?n:s,l=null!==(i=null===(r=a[a.length-1])||void 0===r?void 0:r.range.end)&&void 0!==i?i:s;return new Cr(a,ce.create(o,l))}({index:0,tokens:s,position:i})}function pr(e){let t="";t="string"==typeof e?e:e.text;return t.split(s.TH)}const mr=/\s*(@([\p{L}][\p{L}\p{N}]*)?)/uy,gr=/\{(@[\p{L}][\p{L}\p{N}]*)(\s*)([^\r\n}]+)?\}/gu;function yr(e,t,n,r){const i=[];if(0===e.length){const e=le.create(n,r),s=le.create(n,r+t.length);i.push({type:"text",content:t,range:ce.create(e,s)})}else{let s=0;for(const o of e){const e=o.index,a=t.substring(s,e);a.length>0&&i.push({type:"text",content:t.substring(s,e),range:ce.create(le.create(n,s+r),le.create(n,e+r))});let l=a.length+1;const c=o[1];if(i.push({type:"inline-tag",content:c,range:ce.create(le.create(n,s+l+r),le.create(n,s+l+c.length+r))}),l+=c.length,4===o.length){l+=o[2].length;const e=o[3];i.push({type:"text",content:e,range:ce.create(le.create(n,s+l+r),le.create(n,s+l+e.length+r))})}else i.push({type:"text",content:"",range:ce.create(le.create(n,s+l+r),le.create(n,s+l+r))});s=e+o[0].length}const a=t.substring(s);a.length>0&&i.push({type:"text",content:a,range:ce.create(le.create(n,s+r),le.create(n,s+r+a.length))})}return i}const Tr=/\S/,Ar=/\s*$/;function vr(e,t){const n=e.substring(t).match(Tr);return n?t+n.index:e.length}function Rr(e){const t=e.match(Ar);if(t&&"number"==typeof t.index)return t.index}function $r(e,t){const n=e.tokens[e.index];return"tag"===n.type?xr(e,!1):"text"===n.type||"inline-tag"===n.type?Er(e):(function(e,t){if(t){const n=new br("",e.range);"inlines"in t?t.inlines.push(n):t.content.inlines.push(n)}}(n,t),void e.index++)}function Er(e){let t=e.tokens[e.index];const n=t;let r=t;const i=[];for(;t&&"break"!==t.type&&"tag"!==t.type;)i.push(kr(e)),r=t,t=e.tokens[e.index];return new Lr(i,ce.create(n.range.start,r.range.end))}function kr(e){return"inline-tag"===e.tokens[e.index].type?xr(e,!0):Ir(e)}function xr(e,t){const n=e.tokens[e.index++],r=n.content.substring(1),i=e.tokens[e.index];if("text"===(null==i?void 0:i.type)){if(t){const i=Ir(e);return new wr(r,new Lr([i],i.range),t,ce.create(n.range.start,i.range.end))}{const i=Er(e);return new wr(r,i,t,ce.create(n.range.start,i.range.end))}}{const e=n.range;return new wr(r,new Lr([],e),t,e)}}function Ir(e){const t=e.tokens[e.index++];return new br(t.content,t.range)}function Sr(e){if(!e)return Sr({start:"/**",end:"*/",line:"*"});const{start:t,end:n,line:r}=e;return{start:Nr(t,!0),end:Nr(n,!1),line:Nr(r,!0)}}function Nr(e,t){if("string"==typeof e||"object"==typeof e){const n="string"==typeof e?(0,s.Nt)(e):e.source;return t?new RegExp(`^\\s*${n}`):new RegExp(`\\s*${n}\\s*$`)}return e}class Cr{constructor(e,t){this.elements=e,this.range=t}getTag(e){return this.getAllTags().find(t=>t.name===e)}getTags(e){return this.getAllTags().filter(t=>t.name===e)}getAllTags(){return this.elements.filter(e=>"name"in e)}toString(){let e="";for(const t of this.elements)if(0===e.length)e=t.toString();else{const n=t.toString();e+=Or(e)+n}return e.trim()}toMarkdown(e){let t="";for(const n of this.elements)if(0===t.length)t=n.toMarkdown(e);else{const r=n.toMarkdown(e);t+=Or(t)+r}return t.trim()}}class wr{constructor(e,t,n,r){this.name=e,this.content=t,this.inline=n,this.range=r}toString(){let e=`@${this.name}`;const t=this.content.toString();return 1===this.content.inlines.length?e=`${e} ${t}`:this.content.inlines.length>1&&(e=`${e}\n${t}`),this.inline?`{${e}}`:e}toMarkdown(e){var t,n;return null!==(n=null===(t=null==e?void 0:e.renderTag)||void 0===t?void 0:t.call(e,this))&&void 0!==n?n:this.toMarkdownDefault(e)}toMarkdownDefault(e){const t=this.content.toMarkdown(e);if(this.inline){const n=function(e,t,n){var r,i;if("linkplain"===e||"linkcode"===e||"link"===e){const s=t.indexOf(" ");let a=t;if(s>0){const e=vr(t,s);a=t.substring(e),t=t.substring(0,s)}("linkcode"===e||"link"===e&&"code"===n.link)&&(a=`\`${a}\``);const o=null!==(i=null===(r=n.renderLink)||void 0===r?void 0:r.call(n,t,a))&&void 0!==i?i:function(e,t){try{return kn.r.parse(e,!0),`[${t}](${e})`}catch(r){return e}}(t,a);return o}return}(this.name,t,null!=e?e:{});if("string"==typeof n)return n}let n="";"italic"===(null==e?void 0:e.tag)||void 0===(null==e?void 0:e.tag)?n="*":"bold"===(null==e?void 0:e.tag)?n="**":"bold-italic"===(null==e?void 0:e.tag)&&(n="***");let r=`${n}@${this.name}${n}`;return 1===this.content.inlines.length?r=`${r} \u2014 ${t}`:this.content.inlines.length>1&&(r=`${r}\n${t}`),this.inline?`{${r}}`:r}}class Lr{constructor(e,t){this.inlines=e,this.range=t}toString(){let e="";for(let t=0;t<this.inlines.length;t++){const n=this.inlines[t],r=this.inlines[t+1];e+=n.toString(),r&&r.range.start.line>n.range.start.line&&(e+="\n")}return e}toMarkdown(e){let t="";for(let n=0;n<this.inlines.length;n++){const r=this.inlines[n],i=this.inlines[n+1];t+=r.toMarkdown(e),i&&i.range.start.line>r.range.start.line&&(t+="\n")}return t}}class br{constructor(e,t){this.text=e,this.range=t}toString(){return this.text}toMarkdown(){return this.text}}function Or(e){return e.endsWith("\n")?"\n":"\n\n"}class _r{constructor(e){this.indexManager=e.shared.workspace.IndexManager,this.commentProvider=e.documentation.CommentProvider}getDocumentation(e){const t=this.commentProvider.getComment(e);if(t&&function(e,t){const n=Sr(t),r=pr(e);if(0===r.length)return!1;const i=r[0],s=r[r.length-1],a=n.start,o=n.end;return Boolean(null==a?void 0:a.exec(i))&&Boolean(null==o?void 0:o.exec(s))}(t)){return fr(t).toMarkdown({renderLink:(t,n)=>this.documentationLinkRenderer(e,t,n),renderTag:t=>this.documentationTagRenderer(e,t)})}}documentationLinkRenderer(e,t,n){var r;const i=null!==(r=this.findNameInPrecomputedScopes(e,t))&&void 0!==r?r:this.findNameInGlobalScope(e,t);if(i&&i.nameSegment){const e=i.nameSegment.range.start.line+1,t=i.nameSegment.range.start.character+1;return`[${n}](${i.documentUri.with({fragment:`L${e},${t}`}).toString()})`}}documentationTagRenderer(e,t){}findNameInPrecomputedScopes(e,t){const n=(0,Nt.YE)(e).precomputedScopes;if(!n)return;let r=e;do{const e=n.get(r).find(e=>e.name===t);if(e)return e;r=r.$container}while(r)}findNameInGlobalScope(e,t){return this.indexManager.allElements().find(e=>e.name===t)}}class Pr{constructor(e){this.grammarConfig=()=>e.parser.GrammarConfig}getComment(e){var t;return function(e){return"string"==typeof e.$comment}(e)?e.$comment:null===(t=(0,r.v)(e.$cstNode,this.grammarConfig().multilineCommentRules))||void 0===t?void 0:t.text}}class Mr{constructor(e){this.syncParser=e.parser.LangiumParser}parse(e,t){return Promise.resolve(this.syncParser.parse(e))}}class Dr{constructor(){this.previousTokenSource=new ln.Qi,this.writeQueue=[],this.readQueue=[],this.done=!0}write(e){this.cancelWrite();const t=(un=performance.now(),new ln.Qi);return this.previousTokenSource=t,this.enqueue(this.writeQueue,e,t.token)}read(e){return this.enqueue(this.readQueue,e)}enqueue(e,t,n=ln.XO.None){const r=new mn,i={action:t,deferred:r,cancellationToken:n};return e.push(i),this.performNextOperation(),r.promise}async performNextOperation(){if(!this.done)return;const e=[];if(this.writeQueue.length>0)e.push(this.writeQueue.shift());else{if(!(this.readQueue.length>0))return;e.push(...this.readQueue.splice(0,this.readQueue.length))}this.done=!1,await Promise.all(e.map(async({action:e,deferred:t,cancellationToken:n})=>{try{const r=await Promise.resolve().then(()=>e(n));t.resolve(r)}catch(r){fn(r)?t.resolve(void 0):t.reject(r)}})),this.done=!0,this.performNextOperation()}cancelWrite(){this.previousTokenSource.cancel()}}class Ur{constructor(e){this.grammarElementIdMap=new On,this.tokenTypeIdMap=new On,this.grammar=e.Grammar,this.lexer=e.parser.Lexer,this.linker=e.references.Linker}dehydrate(e){return{lexerErrors:e.lexerErrors,lexerReport:e.lexerReport?this.dehydrateLexerReport(e.lexerReport):void 0,parserErrors:e.parserErrors.map(e=>Object.assign(Object.assign({},e),{message:e.message})),value:this.dehydrateAstNode(e.value,this.createDehyrationContext(e.value))}}dehydrateLexerReport(e){return e}createDehyrationContext(e){const t=new Map,n=new Map;for(const r of(0,Nt.jm)(e))t.set(r,{});if(e.$cstNode)for(const i of(0,r.NS)(e.$cstNode))n.set(i,{});return{astNodes:t,cstNodes:n}}dehydrateAstNode(e,t){const n=t.astNodes.get(e);n.$type=e.$type,n.$containerIndex=e.$containerIndex,n.$containerProperty=e.$containerProperty,void 0!==e.$cstNode&&(n.$cstNode=this.dehydrateCstNode(e.$cstNode,t));for(const[r,i]of Object.entries(e))if(!r.startsWith("$"))if(Array.isArray(i)){const e=[];n[r]=e;for(const n of i)(0,cn.ng)(n)?e.push(this.dehydrateAstNode(n,t)):(0,cn.A_)(n)?e.push(this.dehydrateReference(n,t)):e.push(n)}else(0,cn.ng)(i)?n[r]=this.dehydrateAstNode(i,t):(0,cn.A_)(i)?n[r]=this.dehydrateReference(i,t):void 0!==i&&(n[r]=i);return n}dehydrateReference(e,t){const n={};return n.$refText=e.$refText,e.$refNode&&(n.$refNode=t.cstNodes.get(e.$refNode)),n}dehydrateCstNode(e,t){const n=t.cstNodes.get(e);return(0,cn.br)(e)?n.fullText=e.fullText:n.grammarSource=this.getGrammarElementId(e.grammarSource),n.hidden=e.hidden,n.astNode=t.astNodes.get(e.astNode),(0,cn.mD)(e)?n.content=e.content.map(e=>this.dehydrateCstNode(e,t)):(0,cn.FC)(e)&&(n.tokenType=e.tokenType.name,n.offset=e.offset,n.length=e.length,n.startLine=e.range.start.line,n.startColumn=e.range.start.character,n.endLine=e.range.end.line,n.endColumn=e.range.end.character),n}hydrate(e){const t=e.value,n=this.createHydrationContext(t);return"$cstNode"in t&&this.hydrateCstNode(t.$cstNode,n),{lexerErrors:e.lexerErrors,lexerReport:e.lexerReport,parserErrors:e.parserErrors,value:this.hydrateAstNode(t,n)}}createHydrationContext(e){const t=new Map,n=new Map;for(const r of(0,Nt.jm)(e))t.set(r,{});let i;if(e.$cstNode)for(const s of(0,r.NS)(e.$cstNode)){let e;"fullText"in s?(e=new Dt(s.fullText),i=e):"content"in s?e=new Pt:"tokenType"in s&&(e=this.hydrateCstLeafNode(s)),e&&(n.set(s,e),e.root=i)}return{astNodes:t,cstNodes:n}}hydrateAstNode(e,t){const n=t.astNodes.get(e);n.$type=e.$type,n.$containerIndex=e.$containerIndex,n.$containerProperty=e.$containerProperty,e.$cstNode&&(n.$cstNode=t.cstNodes.get(e.$cstNode));for(const[r,i]of Object.entries(e))if(!r.startsWith("$"))if(Array.isArray(i)){const e=[];n[r]=e;for(const s of i)(0,cn.ng)(s)?e.push(this.setParent(this.hydrateAstNode(s,t),n)):(0,cn.A_)(s)?e.push(this.hydrateReference(s,n,r,t)):e.push(s)}else(0,cn.ng)(i)?n[r]=this.setParent(this.hydrateAstNode(i,t),n):(0,cn.A_)(i)?n[r]=this.hydrateReference(i,n,r,t):void 0!==i&&(n[r]=i);return n}setParent(e,t){return e.$container=t,e}hydrateReference(e,t,n,r){return this.linker.buildReference(t,n,r.cstNodes.get(e.$refNode),e.$refText)}hydrateCstNode(e,t,n=0){const r=t.cstNodes.get(e);if("number"==typeof e.grammarSource&&(r.grammarSource=this.getGrammarElement(e.grammarSource)),r.astNode=t.astNodes.get(e.astNode),(0,cn.mD)(r))for(const i of e.content){const e=this.hydrateCstNode(i,t,n++);r.content.push(e)}return r}hydrateCstLeafNode(e){const t=this.getTokenType(e.tokenType),n=e.offset,r=e.length,i=e.startLine,s=e.startColumn,a=e.endLine,o=e.endColumn,l=e.hidden;return new _t(n,r,{start:{line:i,character:s},end:{line:a,character:o}},t,l)}getTokenType(e){return this.lexer.definition[e]}getGrammarElementId(e){if(e)return 0===this.grammarElementIdMap.size&&this.createGrammarElementIdMap(),this.grammarElementIdMap.get(e)}getGrammarElement(e){0===this.grammarElementIdMap.size&&this.createGrammarElementIdMap();return this.grammarElementIdMap.getKey(e)}createGrammarElementIdMap(){let e=0;for(const t of(0,Nt.jm)(this.grammar))(0,a.r1)(t)&&this.grammarElementIdMap.set(t,e++)}}function Fr(e){return{documentation:{CommentProvider:e=>new Pr(e),DocumentationProvider:e=>new _r(e)},parser:{AsyncParser:e=>new Mr(e),GrammarConfig:e=>function(e){const t=[],n=e.Grammar;for(const r of n.rules)(0,a.rE)(r)&&(0,i.eb)(r)&&(0,s.lU)((0,i.S)(r))&&t.push(r.name);return{multilineCommentRules:t,nameRegexp:r.El}}(e),LangiumParser:e=>sn(e),CompletionParser:e=>function(e){const t=e.Grammar,n=e.parser.Lexer,r=new Ht(e);return qt(t,r,n.definition),r.finalize(),r}(e),ValueConverter:()=>new on.d,TokenBuilder:()=>new an.Q,Lexer:e=>new ur(e),ParserErrorMessageProvider:()=>new Vt,LexerErrorMessageProvider:()=>new lr},workspace:{AstNodeLocator:()=>new tr,AstNodeDescriptionProvider:e=>new Jn(e),ReferenceDescriptionProvider:e=>new er(e)},references:{Linker:e=>new Nn(e),NameProvider:()=>new Cn,ScopeProvider:e=>new Kn(e),ScopeComputation:e=>new _n(e),References:e=>new Ln(e)},serializer:{Hydrator:e=>new Ur(e),JsonSerializer:e=>new jn(e)},validation:{DocumentValidator:e=>new Xn(e),ValidationRegistry:e=>new Yn(e)},shared:()=>e.shared}}function Gr(e){return{ServiceRegistry:e=>new Vn(e),workspace:{LangiumDocuments:e=>new In(e),LangiumDocumentFactory:e=>new xn(e),DocumentBuilder:e=>new sr(e),IndexManager:e=>new ar(e),WorkspaceManager:e=>new or(e),FileSystemProvider:t=>e.fileSystemProvider(t),WorkspaceLock:()=>new Dr,ConfigurationProvider:e=>new ir(e)}}}},99354:(e,t,n)=>{n.d(t,{A:()=>u});var r=n(66318),i=n(52851),s=n(7819),a=n(25353),o=n(23149),l=n(30901);const c=function(e,t,n,r){if(!(0,o.A)(e))return e;for(var c=-1,u=(t=(0,s.A)(t,e)).length,d=u-1,h=e;null!=h&&++c<u;){var f=(0,l.A)(t[c]),p=n;if("__proto__"===f||"constructor"===f||"prototype"===f)return e;if(c!=d){var m=h[f];void 0===(p=r?r(m,f,h):void 0)&&(p=(0,o.A)(m)?m:(0,a.A)(t[c+1])?[]:{})}(0,i.A)(h,f,p),h=h[f]}return e};const u=function(e,t,n){for(var i=-1,a=t.length,o={};++i<a;){var l=t[i],u=(0,r.A)(e,l);n(u,l)&&c(o,(0,s.A)(l,e),u)}return o}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/8756.289e5e3c.js b/pr-preview/pr-4027/assets/js/8756.289e5e3c.js deleted file mode 100644 index 89adc0922..000000000 --- a/pr-preview/pr-4027/assets/js/8756.289e5e3c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8756],{8756:(t,e,s)=>{s.d(e,{diagram:()=>f});var i=s(89625),n=s(21152),r=s(10045),a=(s(5164),s(28698),s(5894),s(63245),s(32387),s(30092),s(13226)),c=s(67633),o=s(40797),l=s(70451),h=s(25582),u=s(75937),y=function(){var t=(0,o.K2)(function(t,e,s,i){for(s=s||{},i=t.length;i--;s[t[i]]=e);return s},"o"),e=[6,8,10,22,24,26,28,33,34,35,36,37,40,43,44,50],s=[1,10],i=[1,11],n=[1,12],r=[1,13],a=[1,20],c=[1,21],l=[1,22],h=[1,23],u=[1,24],y=[1,19],d=[1,25],p=[1,26],_=[1,18],g=[1,33],b=[1,34],m=[1,35],f=[1,36],E=[1,37],k=[6,8,10,13,15,17,20,21,22,24,26,28,33,34,35,36,37,40,43,44,50,63,64,65,66,67],S=[1,42],O=[1,43],T=[1,52],A=[40,50,68,69],R=[1,63],N=[1,61],I=[1,58],C=[1,62],x=[1,64],v=[6,8,10,13,17,22,24,26,28,33,34,35,36,37,40,41,42,43,44,48,49,50,63,64,65,66,67],D=[63,64,65,66,67],$=[1,81],w=[1,80],K=[1,78],L=[1,79],M=[6,10,42,47],B=[6,10,13,41,42,47,48,49],F=[1,89],P=[1,88],Y=[1,87],G=[19,56],z=[1,98],U=[1,97],Z=[19,56,58,60],j={trace:(0,o.K2)(function(){},"trace"),yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,entityName:11,relSpec:12,COLON:13,role:14,STYLE_SEPARATOR:15,idList:16,BLOCK_START:17,attributes:18,BLOCK_STOP:19,SQS:20,SQE:21,title:22,title_value:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,direction:29,classDefStatement:30,classStatement:31,styleStatement:32,direction_tb:33,direction_bt:34,direction_rl:35,direction_lr:36,CLASSDEF:37,stylesOpt:38,separator:39,UNICODE_TEXT:40,STYLE_TEXT:41,COMMA:42,CLASS:43,STYLE:44,style:45,styleComponent:46,SEMI:47,NUM:48,BRKT:49,ENTITY_NAME:50,attribute:51,attributeType:52,attributeName:53,attributeKeyTypeList:54,attributeComment:55,ATTRIBUTE_WORD:56,attributeKeyType:57,",":58,ATTRIBUTE_KEY:59,COMMENT:60,cardinality:61,relType:62,ZERO_OR_ONE:63,ZERO_OR_MORE:64,ONE_OR_MORE:65,ONLY_ONE:66,MD_PARENT:67,NON_IDENTIFYING:68,IDENTIFYING:69,WORD:70,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",8:"SPACE",10:"NEWLINE",13:"COLON",15:"STYLE_SEPARATOR",17:"BLOCK_START",19:"BLOCK_STOP",20:"SQS",21:"SQE",22:"title",23:"title_value",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"direction_tb",34:"direction_bt",35:"direction_rl",36:"direction_lr",37:"CLASSDEF",40:"UNICODE_TEXT",41:"STYLE_TEXT",42:"COMMA",43:"CLASS",44:"STYLE",47:"SEMI",48:"NUM",49:"BRKT",50:"ENTITY_NAME",56:"ATTRIBUTE_WORD",58:",",59:"ATTRIBUTE_KEY",60:"COMMENT",63:"ZERO_OR_ONE",64:"ZERO_OR_MORE",65:"ONE_OR_MORE",66:"ONLY_ONE",67:"MD_PARENT",68:"NON_IDENTIFYING",69:"IDENTIFYING",70:"WORD"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,5],[9,9],[9,7],[9,7],[9,4],[9,6],[9,3],[9,5],[9,1],[9,3],[9,7],[9,9],[9,6],[9,8],[9,4],[9,6],[9,2],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[9,1],[29,1],[29,1],[29,1],[29,1],[30,4],[16,1],[16,1],[16,3],[16,3],[31,3],[32,4],[38,1],[38,3],[45,1],[45,2],[39,1],[39,1],[39,1],[46,1],[46,1],[46,1],[46,1],[11,1],[11,1],[18,1],[18,2],[51,2],[51,3],[51,3],[51,4],[52,1],[53,1],[54,1],[54,3],[57,1],[55,1],[12,3],[61,1],[61,1],[61,1],[61,1],[61,1],[62,1],[62,1],[14,1],[14,1],[14,1]],performAction:(0,o.K2)(function(t,e,s,i,n,r,a){var c=r.length-1;switch(n){case 1:break;case 2:case 6:case 7:this.$=[];break;case 3:r[c-1].push(r[c]),this.$=r[c-1];break;case 4:case 5:case 55:case 78:case 62:case 63:case 66:this.$=r[c];break;case 8:i.addEntity(r[c-4]),i.addEntity(r[c-2]),i.addRelationship(r[c-4],r[c],r[c-2],r[c-3]);break;case 9:i.addEntity(r[c-8]),i.addEntity(r[c-4]),i.addRelationship(r[c-8],r[c],r[c-4],r[c-5]),i.setClass([r[c-8]],r[c-6]),i.setClass([r[c-4]],r[c-2]);break;case 10:i.addEntity(r[c-6]),i.addEntity(r[c-2]),i.addRelationship(r[c-6],r[c],r[c-2],r[c-3]),i.setClass([r[c-6]],r[c-4]);break;case 11:i.addEntity(r[c-6]),i.addEntity(r[c-4]),i.addRelationship(r[c-6],r[c],r[c-4],r[c-5]),i.setClass([r[c-4]],r[c-2]);break;case 12:i.addEntity(r[c-3]),i.addAttributes(r[c-3],r[c-1]);break;case 13:i.addEntity(r[c-5]),i.addAttributes(r[c-5],r[c-1]),i.setClass([r[c-5]],r[c-3]);break;case 14:i.addEntity(r[c-2]);break;case 15:i.addEntity(r[c-4]),i.setClass([r[c-4]],r[c-2]);break;case 16:i.addEntity(r[c]);break;case 17:i.addEntity(r[c-2]),i.setClass([r[c-2]],r[c]);break;case 18:i.addEntity(r[c-6],r[c-4]),i.addAttributes(r[c-6],r[c-1]);break;case 19:i.addEntity(r[c-8],r[c-6]),i.addAttributes(r[c-8],r[c-1]),i.setClass([r[c-8]],r[c-3]);break;case 20:i.addEntity(r[c-5],r[c-3]);break;case 21:i.addEntity(r[c-7],r[c-5]),i.setClass([r[c-7]],r[c-2]);break;case 22:i.addEntity(r[c-3],r[c-1]);break;case 23:i.addEntity(r[c-5],r[c-3]),i.setClass([r[c-5]],r[c]);break;case 24:case 25:this.$=r[c].trim(),i.setAccTitle(this.$);break;case 26:case 27:this.$=r[c].trim(),i.setAccDescription(this.$);break;case 32:i.setDirection("TB");break;case 33:i.setDirection("BT");break;case 34:i.setDirection("RL");break;case 35:i.setDirection("LR");break;case 36:this.$=r[c-3],i.addClass(r[c-2],r[c-1]);break;case 37:case 38:case 56:case 64:case 43:this.$=[r[c]];break;case 39:case 40:this.$=r[c-2].concat([r[c]]);break;case 41:this.$=r[c-2],i.setClass(r[c-1],r[c]);break;case 42:this.$=r[c-3],i.addCssStyles(r[c-2],r[c-1]);break;case 44:case 65:r[c-2].push(r[c]),this.$=r[c-2];break;case 46:this.$=r[c-1]+r[c];break;case 54:case 76:case 77:case 67:this.$=r[c].replace(/"/g,"");break;case 57:r[c].push(r[c-1]),this.$=r[c];break;case 58:this.$={type:r[c-1],name:r[c]};break;case 59:this.$={type:r[c-2],name:r[c-1],keys:r[c]};break;case 60:this.$={type:r[c-2],name:r[c-1],comment:r[c]};break;case 61:this.$={type:r[c-3],name:r[c-2],keys:r[c-1],comment:r[c]};break;case 68:this.$={cardA:r[c],relType:r[c-1],cardB:r[c-2]};break;case 69:this.$=i.Cardinality.ZERO_OR_ONE;break;case 70:this.$=i.Cardinality.ZERO_OR_MORE;break;case 71:this.$=i.Cardinality.ONE_OR_MORE;break;case 72:this.$=i.Cardinality.ONLY_ONE;break;case 73:this.$=i.Cardinality.MD_PARENT;break;case 74:this.$=i.Identification.NON_IDENTIFYING;break;case 75:this.$=i.Identification.IDENTIFYING}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:9,22:s,24:i,26:n,28:r,29:14,30:15,31:16,32:17,33:a,34:c,35:l,36:h,37:u,40:y,43:d,44:p,50:_},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:27,11:9,22:s,24:i,26:n,28:r,29:14,30:15,31:16,32:17,33:a,34:c,35:l,36:h,37:u,40:y,43:d,44:p,50:_},t(e,[2,5]),t(e,[2,6]),t(e,[2,16],{12:28,61:32,15:[1,29],17:[1,30],20:[1,31],63:g,64:b,65:m,66:f,67:E}),{23:[1,38]},{25:[1,39]},{27:[1,40]},t(e,[2,27]),t(e,[2,28]),t(e,[2,29]),t(e,[2,30]),t(e,[2,31]),t(k,[2,54]),t(k,[2,55]),t(e,[2,32]),t(e,[2,33]),t(e,[2,34]),t(e,[2,35]),{16:41,40:S,41:O},{16:44,40:S,41:O},{16:45,40:S,41:O},t(e,[2,4]),{11:46,40:y,50:_},{16:47,40:S,41:O},{18:48,19:[1,49],51:50,52:51,56:T},{11:53,40:y,50:_},{62:54,68:[1,55],69:[1,56]},t(A,[2,69]),t(A,[2,70]),t(A,[2,71]),t(A,[2,72]),t(A,[2,73]),t(e,[2,24]),t(e,[2,25]),t(e,[2,26]),{13:R,38:57,41:N,42:I,45:59,46:60,48:C,49:x},t(v,[2,37]),t(v,[2,38]),{16:65,40:S,41:O,42:I},{13:R,38:66,41:N,42:I,45:59,46:60,48:C,49:x},{13:[1,67],15:[1,68]},t(e,[2,17],{61:32,12:69,17:[1,70],42:I,63:g,64:b,65:m,66:f,67:E}),{19:[1,71]},t(e,[2,14]),{18:72,19:[2,56],51:50,52:51,56:T},{53:73,56:[1,74]},{56:[2,62]},{21:[1,75]},{61:76,63:g,64:b,65:m,66:f,67:E},t(D,[2,74]),t(D,[2,75]),{6:$,10:w,39:77,42:K,47:L},{40:[1,82],41:[1,83]},t(M,[2,43],{46:84,13:R,41:N,48:C,49:x}),t(B,[2,45]),t(B,[2,50]),t(B,[2,51]),t(B,[2,52]),t(B,[2,53]),t(e,[2,41],{42:I}),{6:$,10:w,39:85,42:K,47:L},{14:86,40:F,50:P,70:Y},{16:90,40:S,41:O},{11:91,40:y,50:_},{18:92,19:[1,93],51:50,52:51,56:T},t(e,[2,12]),{19:[2,57]},t(G,[2,58],{54:94,55:95,57:96,59:z,60:U}),t([19,56,59,60],[2,63]),t(e,[2,22],{15:[1,100],17:[1,99]}),t([40,50],[2,68]),t(e,[2,36]),{13:R,41:N,45:101,46:60,48:C,49:x},t(e,[2,47]),t(e,[2,48]),t(e,[2,49]),t(v,[2,39]),t(v,[2,40]),t(B,[2,46]),t(e,[2,42]),t(e,[2,8]),t(e,[2,76]),t(e,[2,77]),t(e,[2,78]),{13:[1,102],42:I},{13:[1,104],15:[1,103]},{19:[1,105]},t(e,[2,15]),t(G,[2,59],{55:106,58:[1,107],60:U}),t(G,[2,60]),t(Z,[2,64]),t(G,[2,67]),t(Z,[2,66]),{18:108,19:[1,109],51:50,52:51,56:T},{16:110,40:S,41:O},t(M,[2,44],{46:84,13:R,41:N,48:C,49:x}),{14:111,40:F,50:P,70:Y},{16:112,40:S,41:O},{14:113,40:F,50:P,70:Y},t(e,[2,13]),t(G,[2,61]),{57:114,59:z},{19:[1,115]},t(e,[2,20]),t(e,[2,23],{17:[1,116],42:I}),t(e,[2,11]),{13:[1,117],42:I},t(e,[2,10]),t(Z,[2,65]),t(e,[2,18]),{18:118,19:[1,119],51:50,52:51,56:T},{14:120,40:F,50:P,70:Y},{19:[1,121]},t(e,[2,21]),t(e,[2,9]),t(e,[2,19])],defaultActions:{52:[2,62],72:[2,57]},parseError:(0,o.K2)(function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)},"parseError"),parse:(0,o.K2)(function(t){var e=this,s=[0],i=[],n=[null],r=[],a=this.table,c="",l=0,h=0,u=0,y=r.slice.call(arguments,1),d=Object.create(this.lexer),p={yy:{}};for(var _ in this.yy)Object.prototype.hasOwnProperty.call(this.yy,_)&&(p.yy[_]=this.yy[_]);d.setInput(t,p.yy),p.yy.lexer=d,p.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var g=d.yylloc;r.push(g);var b=d.options&&d.options.ranges;function m(){var t;return"number"!=typeof(t=i.pop()||d.lex()||1)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,o.K2)(function(t){s.length=s.length-2*t,n.length=n.length-t,r.length=r.length-t},"popStack"),(0,o.K2)(m,"lex");for(var f,E,k,S,O,T,A,R,N,I={};;){if(k=s[s.length-1],this.defaultActions[k]?S=this.defaultActions[k]:(null==f&&(f=m()),S=a[k]&&a[k][f]),void 0===S||!S.length||!S[0]){var C="";for(T in N=[],a[k])this.terminals_[T]&&T>2&&N.push("'"+this.terminals_[T]+"'");C=d.showPosition?"Parse error on line "+(l+1)+":\n"+d.showPosition()+"\nExpecting "+N.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(C,{text:d.match,token:this.terminals_[f]||f,line:d.yylineno,loc:g,expected:N})}if(S[0]instanceof Array&&S.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+f);switch(S[0]){case 1:s.push(f),n.push(d.yytext),r.push(d.yylloc),s.push(S[1]),f=null,E?(f=E,E=null):(h=d.yyleng,c=d.yytext,l=d.yylineno,g=d.yylloc,u>0&&u--);break;case 2:if(A=this.productions_[S[1]][1],I.$=n[n.length-A],I._$={first_line:r[r.length-(A||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(A||1)].first_column,last_column:r[r.length-1].last_column},b&&(I._$.range=[r[r.length-(A||1)].range[0],r[r.length-1].range[1]]),void 0!==(O=this.performAction.apply(I,[c,h,l,p.yy,S[1],n,r].concat(y))))return O;A&&(s=s.slice(0,-1*A*2),n=n.slice(0,-1*A),r=r.slice(0,-1*A)),s.push(this.productions_[S[1]][0]),n.push(I.$),r.push(I._$),R=a[s[s.length-2]][s[s.length-1]],s.push(R);break;case 3:return!0}}return!0},"parse")},W=function(){return{EOF:1,parseError:(0,o.K2)(function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},"parseError"),setInput:(0,o.K2)(function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:(0,o.K2)(function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},"input"),unput:(0,o.K2)(function(t){var e=t.length,s=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),s.length-1&&(this.yylineno-=s.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:s?(s.length===i.length?this.yylloc.first_column:0)+i[i.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},"unput"),more:(0,o.K2)(function(){return this._more=!0,this},"more"),reject:(0,o.K2)(function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"reject"),less:(0,o.K2)(function(t){this.unput(this.match.slice(t))},"less"),pastInput:(0,o.K2)(function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:(0,o.K2)(function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:(0,o.K2)(function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},"showPosition"),test_match:(0,o.K2)(function(t,e){var s,i,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},"test_match"),next:(0,o.K2)(function(){if(this.done)return this.EOF;var t,e,s,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;r<n.length;r++)if((s=this._input.match(this.rules[n[r]]))&&(!e||s[0].length>e[0].length)){if(e=s,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,n[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,n[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:(0,o.K2)(function(){var t=this.next();return t||this.lex()},"lex"),begin:(0,o.K2)(function(t){this.conditionStack.push(t)},"begin"),popState:(0,o.K2)(function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:(0,o.K2)(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:(0,o.K2)(function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},"topState"),pushState:(0,o.K2)(function(t){this.begin(t)},"pushState"),stateStackSize:(0,o.K2)(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,o.K2)(function(t,e,s,i){switch(s){case 0:return this.begin("acc_title"),24;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),26;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return 33;case 8:return 34;case 9:return 35;case 10:return 36;case 11:return 10;case 12:case 23:case 28:case 35:break;case 13:return 8;case 14:return 50;case 15:return 70;case 16:return 4;case 17:return this.begin("block"),17;case 18:case 19:case 38:return 49;case 20:case 37:return 42;case 21:return 15;case 22:case 36:return 13;case 24:return 59;case 25:case 26:return 56;case 27:return 60;case 29:return this.popState(),19;case 30:case 73:return e.yytext[0];case 31:return 20;case 32:return 21;case 33:return this.begin("style"),44;case 34:return this.popState(),10;case 39:return this.begin("style"),37;case 40:return 43;case 41:case 45:case 46:case 59:return 63;case 42:case 43:case 44:case 52:case 54:case 61:return 65;case 47:case 48:case 49:case 50:case 51:case 53:case 60:return 64;case 55:case 56:case 57:case 58:return 66;case 62:return 67;case 63:case 66:case 67:case 68:return 68;case 64:case 65:return 69;case 69:return 41;case 70:return 47;case 71:return 40;case 72:return 48;case 74:return 6}},"anonymous"),rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:[\s]+)/i,/^(?:"[^"%\r\n\v\b\\]+")/i,/^(?:"[^"]*")/i,/^(?:erDiagram\b)/i,/^(?:\{)/i,/^(?:#)/i,/^(?:#)/i,/^(?:,)/i,/^(?::::)/i,/^(?::)/i,/^(?:\s+)/i,/^(?:\b((?:PK)|(?:FK)|(?:UK))\b)/i,/^(?:([^\s]*)[~].*[~]([^\s]*))/i,/^(?:([\*A-Za-z_\u00C0-\uFFFF][A-Za-z0-9\-\_\[\]\(\)\u00C0-\uFFFF\*]*))/i,/^(?:"[^"]*")/i,/^(?:[\n]+)/i,/^(?:\})/i,/^(?:.)/i,/^(?:\[)/i,/^(?:\])/i,/^(?:style\b)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?::)/i,/^(?:,)/i,/^(?:#)/i,/^(?:classDef\b)/i,/^(?:class\b)/i,/^(?:one or zero\b)/i,/^(?:one or more\b)/i,/^(?:one or many\b)/i,/^(?:1\+)/i,/^(?:\|o\b)/i,/^(?:zero or one\b)/i,/^(?:zero or more\b)/i,/^(?:zero or many\b)/i,/^(?:0\+)/i,/^(?:\}o\b)/i,/^(?:many\(0\))/i,/^(?:many\(1\))/i,/^(?:many\b)/i,/^(?:\}\|)/i,/^(?:one\b)/i,/^(?:only one\b)/i,/^(?:1\b)/i,/^(?:\|\|)/i,/^(?:o\|)/i,/^(?:o\{)/i,/^(?:\|\{)/i,/^(?:\s*u\b)/i,/^(?:\.\.)/i,/^(?:--)/i,/^(?:to\b)/i,/^(?:optionally to\b)/i,/^(?:\.-)/i,/^(?:-\.)/i,/^(?:([^\x00-\x7F]|\w|-|\*)+)/i,/^(?:;)/i,/^(?:([^\x00-\x7F]|\w|-|\*)+)/i,/^(?:[0-9])/i,/^(?:.)/i,/^(?:$)/i],conditions:{style:{rules:[34,35,36,37,38,69,70],inclusive:!1},acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},block:{rules:[23,24,25,26,27,28,29,30],inclusive:!1},INITIAL:{rules:[0,2,4,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,31,32,33,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,71,72,73,74],inclusive:!0}}}}();function X(){this.yy={}}return j.lexer=W,(0,o.K2)(X,"Parser"),X.prototype=j,j.Parser=X,new X}();y.parser=y;var d=y,p=class{constructor(){this.entities=new Map,this.relationships=[],this.classes=new Map,this.direction="TB",this.Cardinality={ZERO_OR_ONE:"ZERO_OR_ONE",ZERO_OR_MORE:"ZERO_OR_MORE",ONE_OR_MORE:"ONE_OR_MORE",ONLY_ONE:"ONLY_ONE",MD_PARENT:"MD_PARENT"},this.Identification={NON_IDENTIFYING:"NON_IDENTIFYING",IDENTIFYING:"IDENTIFYING"},this.setAccTitle=c.SV,this.getAccTitle=c.iN,this.setAccDescription=c.EI,this.getAccDescription=c.m7,this.setDiagramTitle=c.ke,this.getDiagramTitle=c.ab,this.getConfig=(0,o.K2)(()=>(0,c.D7)().er,"getConfig"),this.clear(),this.addEntity=this.addEntity.bind(this),this.addAttributes=this.addAttributes.bind(this),this.addRelationship=this.addRelationship.bind(this),this.setDirection=this.setDirection.bind(this),this.addCssStyles=this.addCssStyles.bind(this),this.addClass=this.addClass.bind(this),this.setClass=this.setClass.bind(this),this.setAccTitle=this.setAccTitle.bind(this),this.setAccDescription=this.setAccDescription.bind(this)}static{(0,o.K2)(this,"ErDB")}addEntity(t,e=""){return this.entities.has(t)?!this.entities.get(t)?.alias&&e&&(this.entities.get(t).alias=e,o.Rm.info(`Add alias '${e}' to entity '${t}'`)):(this.entities.set(t,{id:`entity-${t}-${this.entities.size}`,label:t,attributes:[],alias:e,shape:"erBox",look:(0,c.D7)().look??"default",cssClasses:"default",cssStyles:[]}),o.Rm.info("Added new entity :",t)),this.entities.get(t)}getEntity(t){return this.entities.get(t)}getEntities(){return this.entities}getClasses(){return this.classes}addAttributes(t,e){const s=this.addEntity(t);let i;for(i=e.length-1;i>=0;i--)e[i].keys||(e[i].keys=[]),e[i].comment||(e[i].comment=""),s.attributes.push(e[i]),o.Rm.debug("Added attribute ",e[i].name)}addRelationship(t,e,s,i){const n=this.entities.get(t),r=this.entities.get(s);if(!n||!r)return;const a={entityA:n.id,roleA:e,entityB:r.id,relSpec:i};this.relationships.push(a),o.Rm.debug("Added new relationship :",a)}getRelationships(){return this.relationships}getDirection(){return this.direction}setDirection(t){this.direction=t}getCompiledStyles(t){let e=[];for(const s of t){const t=this.classes.get(s);t?.styles&&(e=[...e,...t.styles??[]].map(t=>t.trim())),t?.textStyles&&(e=[...e,...t.textStyles??[]].map(t=>t.trim()))}return e}addCssStyles(t,e){for(const s of t){const t=this.entities.get(s);if(!e||!t)return;for(const s of e)t.cssStyles.push(s)}}addClass(t,e){t.forEach(t=>{let s=this.classes.get(t);void 0===s&&(s={id:t,styles:[],textStyles:[]},this.classes.set(t,s)),e&&e.forEach(function(t){if(/color/.exec(t)){const e=t.replace("fill","bgFill");s.textStyles.push(e)}s.styles.push(t)})})}setClass(t,e){for(const s of t){const t=this.entities.get(s);if(t)for(const s of e)t.cssClasses+=" "+s}}clear(){this.entities=new Map,this.classes=new Map,this.relationships=[],(0,c.IU)()}getData(){const t=[],e=[],s=(0,c.D7)();for(const n of this.entities.keys()){const e=this.entities.get(n);e&&(e.cssCompiledStyles=this.getCompiledStyles(e.cssClasses.split(" ")),t.push(e))}let i=0;for(const n of this.relationships){const t={id:(0,a.rY)(n.entityA,n.entityB,{prefix:"id",counter:i++}),type:"normal",curve:"basis",start:n.entityA,end:n.entityB,label:n.roleA,labelpos:"c",thickness:"normal",classes:"relationshipLine",arrowTypeStart:n.relSpec.cardB.toLowerCase(),arrowTypeEnd:n.relSpec.cardA.toLowerCase(),pattern:"IDENTIFYING"==n.relSpec.relType?"solid":"dashed",look:s.look};e.push(t)}return{nodes:t,edges:e,other:{},config:s,direction:"TB"}}},_={};(0,o.VA)(_,{draw:()=>g});var g=(0,o.K2)(async function(t,e,s,h){o.Rm.info("REF0:"),o.Rm.info("Drawing er diagram (unified)",e);const{securityLevel:u,er:y,layout:d}=(0,c.D7)(),p=h.db.getData(),_=(0,i.A)(e,u);p.type=h.type,p.layoutAlgorithm=(0,r.q7)(d),p.config.flowchart.nodeSpacing=y?.nodeSpacing||140,p.config.flowchart.rankSpacing=y?.rankSpacing||80,p.direction=h.db.getDirection(),p.markers=["only_one","zero_or_one","one_or_more","zero_or_more"],p.diagramId=e,await(0,r.XX)(p,_),"elk"===p.layoutAlgorithm&&_.select(".edges").lower();const g=_.selectAll('[id*="-background"]');Array.from(g).length>0&&g.each(function(){const t=(0,l.Ltv)(this),e=t.attr("id").replace("-background",""),s=_.select(`#${CSS.escape(e)}`);if(!s.empty()){const e=s.attr("transform");t.attr("transform",e)}});a._K.insertTitle(_,"erDiagramTitleText",y?.titleTopMargin??25,h.db.getDiagramTitle()),(0,n.P)(_,8,"erDiagram",y?.useMaxWidth??!0)},"draw"),b=(0,o.K2)((t,e)=>{const s=u.A,i=s(t,"r"),n=s(t,"g"),r=s(t,"b");return h.A(i,n,r,e)},"fade"),m=(0,o.K2)(t=>`\n .entityBox {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n }\n\n .relationshipLabelBox {\n fill: ${t.tertiaryColor};\n opacity: 0.7;\n background-color: ${t.tertiaryColor};\n rect {\n opacity: 0.5;\n }\n }\n\n .labelBkg {\n background-color: ${b(t.tertiaryColor,.5)};\n }\n\n .edgeLabel .label {\n fill: ${t.nodeBorder};\n font-size: 14px;\n }\n\n .label {\n font-family: ${t.fontFamily};\n color: ${t.nodeTextColor||t.textColor};\n }\n\n .edge-pattern-dashed {\n stroke-dasharray: 8,8;\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon\n {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n .relationshipLine {\n stroke: ${t.lineColor};\n stroke-width: 1;\n fill: none;\n }\n\n .marker {\n fill: none !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n }\n`,"getStyles"),f={parser:d,get db(){return new p},renderer:_,styles:m}},21152:(t,e,s)=>{s.d(e,{P:()=>r});var i=s(67633),n=s(40797),r=(0,n.K2)((t,e,s,r)=>{t.attr("class",s);const{width:o,height:l,x:h,y:u}=a(t,e);(0,i.a$)(t,l,o,r);const y=c(h,u,o,l,e);t.attr("viewBox",y),n.Rm.debug(`viewBox configured: ${y} with padding: ${e}`)},"setupViewPortForSVG"),a=(0,n.K2)((t,e)=>{const s=t.node()?.getBBox()||{width:0,height:0,x:0,y:0};return{width:s.width+2*e,height:s.height+2*e,x:s.x,y:s.y}},"calculateDimensionsWithPadding"),c=(0,n.K2)((t,e,s,i,n)=>`${t-n} ${e-n} ${s} ${i}`,"createViewBox")},75937:(t,e,s)=>{s.d(e,{A:()=>r});var i=s(72453),n=s(74886);const r=(t,e)=>i.A.lang.round(n.A.parse(t)[e])},89625:(t,e,s)=>{s.d(e,{A:()=>r});var i=s(40797),n=s(70451),r=(0,i.K2)((t,e)=>{let s;"sandbox"===e&&(s=(0,n.Ltv)("#i"+t));return("sandbox"===e?(0,n.Ltv)(s.nodes()[0].contentDocument.body):(0,n.Ltv)("body")).select(`[id="${t}"]`)},"getDiagramElement")}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/8948.b0417531.js b/pr-preview/pr-4027/assets/js/8948.b0417531.js deleted file mode 100644 index 7a509a524..000000000 --- a/pr-preview/pr-4027/assets/js/8948.b0417531.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8948],{16567:(t,e,a)=>{a.d(e,{diagram:()=>m});var r=a(73590),i=a(25871),o=a(13226),n=a(67633),s=a(40797),l=a(78731),c=n.UI.packet,d=class{constructor(){this.packet=[],this.setAccTitle=n.SV,this.getAccTitle=n.iN,this.setDiagramTitle=n.ke,this.getDiagramTitle=n.ab,this.getAccDescription=n.m7,this.setAccDescription=n.EI}static{(0,s.K2)(this,"PacketDB")}getConfig(){const t=(0,o.$t)({...c,...(0,n.zj)().packet});return t.showBits&&(t.paddingY+=10),t}getPacket(){return this.packet}pushWord(t){t.length>0&&this.packet.push(t)}clear(){(0,n.IU)(),this.packet=[]}},b=(0,s.K2)((t,e)=>{(0,i.S)(t,e);let a=-1,r=[],o=1;const{bitsPerRow:n}=e.getConfig();for(let{start:i,end:l,bits:c,label:d}of t.blocks){if(void 0!==i&&void 0!==l&&l<i)throw new Error(`Packet block ${i} - ${l} is invalid. End must be greater than start.`);if(i??=a+1,i!==a+1)throw new Error(`Packet block ${i} - ${l??i} is not contiguous. It should start from ${a+1}.`);if(0===c)throw new Error(`Packet block ${i} is invalid. Cannot have a zero bit field.`);for(l??=i+(c??1)-1,c??=l-i+1,a=l,s.Rm.debug(`Packet block ${i} - ${a} with label ${d}`);r.length<=n+1&&e.getPacket().length<1e4;){const[t,a]=h({start:i,end:l,bits:c,label:d},o,n);if(r.push(t),t.end+1===o*n&&(e.pushWord(r),r=[],o++),!a)break;({start:i,end:l,bits:c,label:d}=a)}}e.pushWord(r)},"populate"),h=(0,s.K2)((t,e,a)=>{if(void 0===t.start)throw new Error("start should have been set during first phase");if(void 0===t.end)throw new Error("end should have been set during first phase");if(t.start>t.end)throw new Error(`Block start ${t.start} is greater than block end ${t.end}.`);if(t.end+1<=e*a)return[t,void 0];const r=e*a-1,i=e*a;return[{start:t.start,end:r,label:t.label,bits:r-t.start},{start:i,end:t.end,label:t.label,bits:t.end-i}]},"getNextFittingBlock"),p={parser:{yy:void 0},parse:(0,s.K2)(async t=>{const e=await(0,l.qg)("packet",t),a=p.parser?.yy;if(!(a instanceof d))throw new Error("parser.parser?.yy was not a PacketDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.");s.Rm.debug(e),b(e,a)},"parse")},k=(0,s.K2)((t,e,a,i)=>{const o=i.db,s=o.getConfig(),{rowHeight:l,paddingY:c,bitWidth:d,bitsPerRow:b}=s,h=o.getPacket(),p=o.getDiagramTitle(),k=l+c,u=k*(h.length+1)-(p?0:l),f=d*b+2,w=(0,r.D)(e);w.attr("viewbox",`0 0 ${f} ${u}`),(0,n.a$)(w,u,f,s.useMaxWidth);for(const[r,n]of h.entries())g(w,n,r,s);w.append("text").text(p).attr("x",f/2).attr("y",u-k/2).attr("dominant-baseline","middle").attr("text-anchor","middle").attr("class","packetTitle")},"draw"),g=(0,s.K2)((t,e,a,{rowHeight:r,paddingX:i,paddingY:o,bitWidth:n,bitsPerRow:s,showBits:l})=>{const c=t.append("g"),d=a*(r+o)+o;for(const b of e){const t=b.start%s*n+1,e=(b.end-b.start+1)*n-i;if(c.append("rect").attr("x",t).attr("y",d).attr("width",e).attr("height",r).attr("class","packetBlock"),c.append("text").attr("x",t+e/2).attr("y",d+r/2).attr("class","packetLabel").attr("dominant-baseline","middle").attr("text-anchor","middle").text(b.label),!l)continue;const a=b.end===b.start,o=d-2;c.append("text").attr("x",t+(a?e/2:0)).attr("y",o).attr("class","packetByte start").attr("dominant-baseline","auto").attr("text-anchor",a?"middle":"start").text(b.start),a||c.append("text").attr("x",t+e).attr("y",o).attr("class","packetByte end").attr("dominant-baseline","auto").attr("text-anchor","end").text(b.end)}},"drawWord"),u={draw:k},f={byteFontSize:"10px",startByteColor:"black",endByteColor:"black",labelColor:"black",labelFontSize:"12px",titleColor:"black",titleFontSize:"14px",blockStrokeColor:"black",blockStrokeWidth:"1",blockFillColor:"#efefef"},w=(0,s.K2)(({packet:t}={})=>{const e=(0,o.$t)(f,t);return`\n\t.packetByte {\n\t\tfont-size: ${e.byteFontSize};\n\t}\n\t.packetByte.start {\n\t\tfill: ${e.startByteColor};\n\t}\n\t.packetByte.end {\n\t\tfill: ${e.endByteColor};\n\t}\n\t.packetLabel {\n\t\tfill: ${e.labelColor};\n\t\tfont-size: ${e.labelFontSize};\n\t}\n\t.packetTitle {\n\t\tfill: ${e.titleColor};\n\t\tfont-size: ${e.titleFontSize};\n\t}\n\t.packetBlock {\n\t\tstroke: ${e.blockStrokeColor};\n\t\tstroke-width: ${e.blockStrokeWidth};\n\t\tfill: ${e.blockFillColor};\n\t}\n\t`},"styles"),m={parser:p,get db(){return new d},renderer:u,styles:w}},25871:(t,e,a)=>{function r(t,e){t.accDescr&&e.setAccDescription?.(t.accDescr),t.accTitle&&e.setAccTitle?.(t.accTitle),t.title&&e.setDiagramTitle?.(t.title)}a.d(e,{S:()=>r}),(0,a(40797).K2)(r,"populateCommonDb")}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/8a026b6c.c06d830e.js b/pr-preview/pr-4027/assets/js/8a026b6c.c06d830e.js deleted file mode 100644 index 49c79ca79..000000000 --- a/pr-preview/pr-4027/assets/js/8a026b6c.c06d830e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2301],{28453:(e,n,o)=>{o.d(n,{R:()=>a,x:()=>s});var r=o(96540);const t={},i=r.createContext(t);function a(e){const n=r.useContext(i);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),r.createElement(i.Provider,{value:n},e.children)}},38628:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>m,frontMatter:()=>a,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"overview/performance/performance","title":"Performance analysis of Constellation","description":"This section provides a comprehensive examination of the performance characteristics of Constellation.","source":"@site/versioned_docs/version-2.22/overview/performance/performance.md","sourceDirName":"overview/performance","slug":"/overview/performance/","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/performance/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/overview/performance/performance.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Feature status of clouds","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/clouds"},"next":{"title":"Compute benchmarks","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/performance/compute"}}');var t=o(74848),i=o(28453);const a={},s="Performance analysis of Constellation",c={},l=[{value:"Runtime encryption",id:"runtime-encryption",level:2},{value:"I/O performance benchmarks",id:"io-performance-benchmarks",level:2},{value:"Application benchmarking",id:"application-benchmarking",level:2}];function p(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"performance-analysis-of-constellation",children:"Performance analysis of Constellation"})}),"\n",(0,t.jsx)(n.p,{children:"This section provides a comprehensive examination of the performance characteristics of Constellation."}),"\n",(0,t.jsx)(n.h2,{id:"runtime-encryption",children:"Runtime encryption"}),"\n",(0,t.jsxs)(n.p,{children:["Runtime encryption affects compute performance. ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/overview/performance/compute",children:"Benchmarks by Azure and Google"})," show that the performance degradation of Confidential VMs (CVMs) is small, ranging from 2% to 8% for compute-intensive workloads."]}),"\n",(0,t.jsx)(n.h2,{id:"io-performance-benchmarks",children:"I/O performance benchmarks"}),"\n",(0,t.jsxs)(n.p,{children:["We evaluated the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/overview/performance/io",children:"I/O performance"})," of Constellation, utilizing a collection of synthetic benchmarks targeting networking and storage.\nWe further compared this performance to native managed Kubernetes offerings from various cloud providers, to better understand how Constellation stands in relation to standard practices."]}),"\n",(0,t.jsx)(n.h2,{id:"application-benchmarking",children:"Application benchmarking"}),"\n",(0,t.jsxs)(n.p,{children:["To gauge Constellation's applicability to well-known applications, we performed a ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/overview/performance/application",children:"benchmark of HashiCorp Vault"})," running on Constellation.\nThe results were then compared to deployments on the managed Kubernetes offerings from different cloud providers, providing a tangible perspective on Constellation's performance in actual deployment scenarios."]})]})}function m(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/8a589188.5249ea68.js b/pr-preview/pr-4027/assets/js/8a589188.5249ea68.js deleted file mode 100644 index 8c674efc3..000000000 --- a/pr-preview/pr-4027/assets/js/8a589188.5249ea68.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9579],{28453:(e,r,t)=>{t.d(r,{R:()=>i,x:()=>a});var n=t(96540);const o={},s=n.createContext(o);function i(e){const r=n.useContext(s);return n.useMemo(function(){return"function"==typeof e?e(r):{...r,...e}},[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(s.Provider,{value:r},e.children)}},68212:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"reference/terraform","title":"Terraform usage","description":"Terraform is an Infrastructure as Code (IaC) framework to manage cloud resources. This page explains how Constellation uses it internally and how advanced users may manually use it to have more control over the resource creation.","source":"@site/versioned_docs/version-2.23/reference/terraform.md","sourceDirName":"reference","slug":"/reference/terraform","permalink":"/constellation/pr-preview/pr-4027/2.23/reference/terraform","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/reference/terraform.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Configuration migrations","permalink":"/constellation/pr-preview/pr-4027/2.23/reference/migration"},"next":{"title":"SLSA adoption","permalink":"/constellation/pr-preview/pr-4027/2.23/reference/slsa"}}');var o=t(74848),s=t(28453);const i={},a="Terraform usage",l={},c=[{value:"Terraform state files",id:"terraform-state-files",level:2},{value:"Interacting with Terraform manually",id:"interacting-with-terraform-manually",level:2},{value:"Terraform debugging",id:"terraform-debugging",level:2}];function d(e){const r={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(r.header,{children:(0,o.jsx)(r.h1,{id:"terraform-usage",children:"Terraform usage"})}),"\n",(0,o.jsxs)(r.p,{children:[(0,o.jsx)(r.a,{href:"https://www.terraform.io/",children:"Terraform"})," is an Infrastructure as Code (IaC) framework to manage cloud resources. This page explains how Constellation uses it internally and how advanced users may manually use it to have more control over the resource creation."]}),"\n",(0,o.jsx)(r.admonition,{type:"info",children:(0,o.jsxs)(r.p,{children:["Information on this page is intended for users who are familiar with Terraform.\nIt's not required for common usage of Constellation.\nSee the ",(0,o.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/docs",children:"Terraform documentation"})," if you want to learn more about it."]})}),"\n",(0,o.jsx)(r.h2,{id:"terraform-state-files",children:"Terraform state files"}),"\n",(0,o.jsx)(r.p,{children:"Constellation keeps Terraform state files in subdirectories of the workspace together with the corresponding Terraform configuration files and metadata.\nThe subdirectories are created on the first Constellation CLI action that uses Terraform internally."}),"\n",(0,o.jsx)(r.p,{children:"Currently, these subdirectories are:"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.code,{children:"constellation-terraform"})," - Terraform state files for the resources of the Constellation cluster"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.code,{children:"constellation-iam-terraform"})," - Terraform state files for IAM configuration"]}),"\n"]}),"\n",(0,o.jsxs)(r.p,{children:["As with all commands, commands that work with these files (e.g., ",(0,o.jsx)(r.code,{children:"apply"}),", ",(0,o.jsx)(r.code,{children:"terminate"}),", ",(0,o.jsx)(r.code,{children:"iam"}),") have to be executed from the root of the cluster's ",(0,o.jsx)(r.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/orchestration#workspaces",children:"workspace directory"}),". You usually don't need and shouldn't manipulate or delete the subdirectories manually."]}),"\n",(0,o.jsx)(r.h2,{id:"interacting-with-terraform-manually",children:"Interacting with Terraform manually"}),"\n",(0,o.jsxs)(r.p,{children:["Manual interaction with Terraform state created by Constellation (i.e., via the Terraform CLI) should only be performed by experienced users. It may lead to unrecoverable loss of cloud resources. For the majority of users and use cases, the interaction done by the ",(0,o.jsx)(r.a,{href:"/constellation/pr-preview/pr-4027/2.23/reference/cli",children:"Constellation CLI"})," is sufficient."]}),"\n",(0,o.jsx)(r.h2,{id:"terraform-debugging",children:"Terraform debugging"}),"\n",(0,o.jsxs)(r.p,{children:["To debug Terraform issues, the Constellation CLI offers the ",(0,o.jsx)(r.code,{children:"tf-log"})," flag. You can set it to any of ",(0,o.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform's log levels"}),":"]}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.code,{children:"JSON"})," (JSON-formatted logs at ",(0,o.jsx)(r.code,{children:"TRACE"})," level)"]}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"TRACE"})}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"DEBUG"})}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"INFO"})}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"WARN"})}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"ERROR"})}),"\n"]}),"\n",(0,o.jsxs)(r.p,{children:["The log output is written to the ",(0,o.jsx)(r.code,{children:"terraform.log"})," file in the workspace directory. The output is appended to the file on each run."]})]})}function h(e={}){const{wrapper:r}={...(0,s.R)(),...e.components};return r?(0,o.jsx)(r,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/8ca353b4.fbda2fc6.js b/pr-preview/pr-4027/assets/js/8ca353b4.fbda2fc6.js deleted file mode 100644 index aa4674202..000000000 --- a/pr-preview/pr-4027/assets/js/8ca353b4.fbda2fc6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7466],{3010:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"overview/performance/io","title":"I/O performance benchmarks","description":"To assess the overall performance of Constellation, this benchmark evaluates Constellation v2.6.0 in terms of storage I/O using fio and network performance using the Kubernetes Network Benchmark.","source":"@site/versioned_docs/version-2.22/overview/performance/io.md","sourceDirName":"overview/performance","slug":"/overview/performance/io","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/performance/io","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/overview/performance/io.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Compute benchmarks","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/performance/compute"},"next":{"title":"Application benchmarks","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/performance/application"}}');var i=s(74848),o=s(28453);const t={},a="I/O performance benchmarks",l={},c=[{value:"Configurations",id:"configurations",level:2},{value:"Constellation",id:"constellation",level:3},{value:"AKS",id:"aks",level:3},{value:"GKE",id:"gke",level:3},{value:"Results",id:"results",level:2},{value:"Network",id:"network",level:3},{value:"Pod-to-Pod",id:"pod-to-pod",level:4},{value:"Pod-to-Service",id:"pod-to-service",level:4},{value:"Storage I/O",id:"storage-io",level:3},{value:"Conclusion",id:"conclusion",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",mermaid:"mermaid",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"io-performance-benchmarks",children:"I/O performance benchmarks"})}),"\n",(0,i.jsxs)(n.p,{children:["To assess the overall performance of Constellation, this benchmark evaluates Constellation v2.6.0 in terms of storage I/O using ",(0,i.jsx)(n.a,{href:"https://fio.readthedocs.io/en/latest/fio_doc.html",children:(0,i.jsx)(n.code,{children:"fio"})})," and network performance using the ",(0,i.jsx)(n.a,{href:"https://github.com/InfraBuilder/k8s-bench-suite#knb--kubernetes-network-be",children:"Kubernetes Network Benchmark"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"This benchmark tested Constellation on Azure and GCP and compared the results against the managed Kubernetes offerings AKS and GKE."}),"\n",(0,i.jsx)(n.h2,{id:"configurations",children:"Configurations"}),"\n",(0,i.jsx)(n.h3,{id:"constellation",children:"Constellation"}),"\n",(0,i.jsx)(n.p,{children:"The benchmark was conducted with Constellation v2.6.0, Kubernetes v1.25.7, and Cilium v1.12.\nIt ran on the following infrastructure configurations."}),"\n",(0,i.jsx)(n.p,{children:"Constellation on Azure:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Nodes: 3 (1 Control-plane, 2 Worker)"}),"\n",(0,i.jsxs)(n.li,{children:["Machines: ",(0,i.jsx)(n.code,{children:"DC4as_v5"}),": 3rd Generation AMD EPYC 7763v (Milan) processor with 4 Cores, 16 GiB memory"]}),"\n",(0,i.jsxs)(n.li,{children:["CVM: ",(0,i.jsx)(n.code,{children:"true"})]}),"\n",(0,i.jsxs)(n.li,{children:["Region: ",(0,i.jsx)(n.code,{children:"West US"})]}),"\n",(0,i.jsxs)(n.li,{children:["Zone: ",(0,i.jsx)(n.code,{children:"2"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Constellation on GCP:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Nodes: 3 (1 Control-plane, 2 Worker)"}),"\n",(0,i.jsxs)(n.li,{children:["Machines: ",(0,i.jsx)(n.code,{children:"n2d-standard-4"}),": 2nd Generation AMD EPYC (Rome) processor with 4 Cores, 16 GiB of memory"]}),"\n",(0,i.jsxs)(n.li,{children:["CVM: ",(0,i.jsx)(n.code,{children:"true"})]}),"\n",(0,i.jsxs)(n.li,{children:["Zone: ",(0,i.jsx)(n.code,{children:"europe-west3-b"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"aks",children:"AKS"}),"\n",(0,i.jsxs)(n.p,{children:["On AKS, the benchmark used Kubernetes ",(0,i.jsx)(n.code,{children:"v1.24.9"})," and nodes with version ",(0,i.jsx)(n.code,{children:"AKSUbuntu-1804gen2containerd-2023.02.15"}),".\nAKS ran with the ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/concepts-network#kubenet-basic-networking",children:(0,i.jsx)(n.code,{children:"kubenet"})})," CNI and the ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/azure-disk-csi",children:"default CSI driver"})," for Azure Disk."]}),"\n",(0,i.jsx)(n.p,{children:"The following infrastructure configurations was used:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Nodes: 2 (2 Worker)"}),"\n",(0,i.jsxs)(n.li,{children:["Machines: ",(0,i.jsx)(n.code,{children:"D4as_v5"}),": 3rd Generation AMD EPYC 7763v (Milan) processor with 4 Cores, 16 GiB memory"]}),"\n",(0,i.jsxs)(n.li,{children:["CVM: ",(0,i.jsx)(n.code,{children:"false"})]}),"\n",(0,i.jsxs)(n.li,{children:["Region: ",(0,i.jsx)(n.code,{children:"West US"})]}),"\n",(0,i.jsxs)(n.li,{children:["Zone: ",(0,i.jsx)(n.code,{children:"2"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"gke",children:"GKE"}),"\n",(0,i.jsxs)(n.p,{children:["On GKE, the benchmark used Kubernetes ",(0,i.jsx)(n.code,{children:"v1.24.9"})," and nodes with version ",(0,i.jsx)(n.code,{children:"1.24.9-gke.3200"}),".\nGKE ran with the ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/kubernetes-engine/docs/concepts/network-overview",children:(0,i.jsx)(n.code,{children:"kubenet"})})," CNI and the ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/gce-pd-csi-driver",children:"default CSI driver"})," for Compute Engine persistent disk."]}),"\n",(0,i.jsx)(n.p,{children:"The following infrastructure configurations was used:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Nodes: 2 (2 Worker)"}),"\n",(0,i.jsxs)(n.li,{children:["Machines: ",(0,i.jsx)(n.code,{children:"n2d-standard-4"})," 2nd Generation AMD EPYC (Rome) processor with 4 Cores, 16 GiB of memory"]}),"\n",(0,i.jsxs)(n.li,{children:["CVM: ",(0,i.jsx)(n.code,{children:"false"})]}),"\n",(0,i.jsxs)(n.li,{children:["Zone: ",(0,i.jsx)(n.code,{children:"europe-west3-b"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"results",children:"Results"}),"\n",(0,i.jsx)(n.h3,{id:"network",children:"Network"}),"\n",(0,i.jsxs)(n.p,{children:["This section gives a thorough analysis of the network performance of Constellation, specifically focusing on measuring TCP and UDP bandwidth.\nThe benchmark measured the bandwidth of pod-to-pod and pod-to-service connections between two different nodes using ",(0,i.jsx)(n.a,{href:"https://iperf.fr/",children:(0,i.jsx)(n.code,{children:"iperf"})}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["GKE and Constellation on GCP had a maximum network bandwidth of ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/general-purpose-machines#n2d_machines",children:"10 Gbps"}),".\nAKS with ",(0,i.jsx)(n.code,{children:"Standard_D4as_v5"})," machines a maximum network bandwidth of ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/dasv5-dadsv5-series#dasv5-series",children:"12.5 Gbps"}),".\nThe Confidential VM equivalent ",(0,i.jsx)(n.code,{children:"Standard_DC4as_v5"})," currently has a network bandwidth of ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/dcasv5-dcadsv5-series#dcasv5-series-products",children:"1.25 Gbps"}),".\nTherefore, to make the test comparable, both AKS and Constellation on Azure were running with ",(0,i.jsx)(n.code,{children:"Standard_DC4as_v5"})," machines and 1.25 Gbps bandwidth."]}),"\n",(0,i.jsx)(n.p,{children:"Constellation on Azure and AKS used an MTU of 1500.\nConstellation on GCP used an MTU of 8896. GKE used an MTU of 1450."}),"\n",(0,i.jsx)(n.p,{children:"The difference in network bandwidth can largely be attributed to two factors."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Constellation's ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/networking",children:"network encryption"})," via Cilium and WireGuard, which protects data in-transit."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"https://lore.kernel.org/all/20200204193500.GA15564@ashkalra_ubuntu_server/T/",children:"AMD SEV using SWIOTLB bounce buffers"})," for all DMA including network I/O."]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"pod-to-pod",children:"Pod-to-Pod"}),"\n",(0,i.jsx)(n.p,{children:"In this scenario, the client Pod connects directly to the server pod via its IP address."}),"\n",(0,i.jsx)(n.mermaid,{value:"flowchart LR\n subgraph Node A\n Client[Client]\n end\n subgraph Node B\n Server[Server]\n end\n Client ==>|traffic| Server"}),"\n",(0,i.jsx)(n.p,{children:'The results for "Pod-to-Pod" on Azure are as follows:'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Network Pod2Pod Azure benchmark graph",src:s(7484).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:'The results for "Pod-to-Pod" on GCP are as follows:'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Network Pod2Pod GCP benchmark graph",src:s(11951).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.h4,{id:"pod-to-service",children:"Pod-to-Service"}),"\n",(0,i.jsx)(n.p,{children:"In this scenario, the client Pod connects to the server Pod via a ClusterIP service. This is more relevant to real-world use cases."}),"\n",(0,i.jsx)(n.mermaid,{value:"flowchart LR\n subgraph Node A\n Client[Client] ==>|traffic| Service[Service]\n end\n subgraph Node B\n Server[Server]\n end\n Service ==>|traffic| Server"}),"\n",(0,i.jsx)(n.p,{children:'The results for "Pod-to-Pod" on Azure are as follows:'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Network Pod2SVC Azure benchmark graph",src:s(37962).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:'The results for "Pod-to-Pod" on GCP are as follows:'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Network Pod2SVC GCP benchmark graph",src:s(87085).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"In our recent comparison of Constellation on GCP with GKE, Constellation has 58% less TCP bandwidth. However, UDP bandwidth was slightly better with Constellation, thanks to its higher MTU."}),"\n",(0,i.jsx)(n.p,{children:"Similarly, when comparing Constellation on Azure with AKS using CVMs, Constellation achieved approximately 10% less TCP and 40% less UDP bandwidth."}),"\n",(0,i.jsx)(n.h3,{id:"storage-io",children:"Storage I/O"}),"\n",(0,i.jsxs)(n.p,{children:["Azure and GCP offer persistent storage for their Kubernetes services AKS and GKE via the Container Storage Interface (CSI). CSI storage in Kubernetes is available via ",(0,i.jsx)(n.code,{children:"PersistentVolumes"})," (PV) and consumed via ",(0,i.jsx)(n.code,{children:"PersistentVolumeClaims"})," (PVC).\nUpon requesting persistent storage through a PVC, GKE and AKS will provision a PV as defined by a default ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/storage/storage-classes/",children:"storage class"}),".\nConstellation provides persistent storage on Azure and GCP ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage",children:"that's encrypted on the CSI layer"}),".\nSimilarly, upon a PVC request, Constellation will provision a PV via a default storage class."]}),"\n",(0,i.jsxs)(n.p,{children:["For Constellation on Azure and AKS, the benchmark ran with Azure Disk storage ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/disks-types#standard-ssds",children:"Standard SSD"})," of 400 GiB size.\nThe ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/dasv5-dadsv5-series#dasv5-series",children:"DC4as machine type"})," with four cores provides the following maximum performance:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"6400 (20000 burst) IOPS"}),"\n",(0,i.jsx)(n.li,{children:"144 MB/s (600 MB/s burst) throughput"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["However, the performance is bound by the capabilities of the ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/disks-types#standard-ssds",children:"512 GiB Standard SSD size"})," (the size class of 400 GiB volumes):"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"500 (600 burst) IOPS"}),"\n",(0,i.jsx)(n.li,{children:"60 MB/s (150 MB/s burst) throughput"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["For Constellation on GCP and GKE, the benchmark ran with Compute Engine Persistent Disk Storage ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/disks",children:"pd-balanced"})," of 400 GiB size.\nThe N2D machine type with four cores and pd-balanced provides the following ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/disks/performance#n2d_vms",children:"maximum performance"}),":"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"3,000 read IOPS"}),"\n",(0,i.jsx)(n.li,{children:"15,000 write IOPS"}),"\n",(0,i.jsx)(n.li,{children:"240 MB/s read throughput"}),"\n",(0,i.jsx)(n.li,{children:"240 MB/s write throughput"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["However, the performance is bound by the capabilities of a ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/disks/performance#zonal-persistent-disks",children:(0,i.jsx)(n.code,{children:"Zonal balanced PD"})})," with 400 GiB size:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"2400 read IOPS"}),"\n",(0,i.jsx)(n.li,{children:"2400 write IOPS"}),"\n",(0,i.jsx)(n.li,{children:"112 MB/s read throughput"}),"\n",(0,i.jsx)(n.li,{children:"112 MB/s write throughput"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"https://fio.readthedocs.io/en/latest/fio_doc.html",children:(0,i.jsx)(n.code,{children:"fio"})})," benchmark consists of several tests.\nThe benchmark used ",(0,i.jsx)(n.a,{href:"https://github.com/kastenhq/kubestr",children:(0,i.jsx)(n.code,{children:"Kubestr"})})," to run ",(0,i.jsx)(n.code,{children:"fio"})," in Kubernetes.\nThe default test performs randomized access patterns that accurately depict worst-case I/O scenarios for most applications."]}),"\n",(0,i.jsxs)(n.p,{children:["The following ",(0,i.jsx)(n.code,{children:"fio"})," settings were used:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"No Cloud caching"}),"\n",(0,i.jsx)(n.li,{children:"No OS caching"}),"\n",(0,i.jsx)(n.li,{children:"Single CPU"}),"\n",(0,i.jsx)(n.li,{children:"60 seconds runtime"}),"\n",(0,i.jsx)(n.li,{children:"10 seconds ramp-up time"}),"\n",(0,i.jsx)(n.li,{children:"10 GiB file"}),"\n",(0,i.jsx)(n.li,{children:"IOPS: 4 KB blocks and 128 iodepth"}),"\n",(0,i.jsx)(n.li,{children:"Bandwidth: 1024 KB blocks and 128 iodepth"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["For more details, see the ",(0,i.jsxs)(n.a,{href:"https://github.com/edgelesssys/constellation/blob/main/.github/actions/e2e_benchmark/fio.ini",children:[(0,i.jsx)(n.code,{children:"fio"})," test configuration"]}),"."]}),"\n",(0,i.jsx)(n.p,{children:"The results for IOPS on Azure are as follows:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"I/O IOPS Azure benchmark graph",src:s(76746).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"The results for IOPS on GCP are as follows:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"I/O IOPS GCP benchmark graph",src:s(81503).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"The results for bandwidth on Azure are as follows:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"I/O bandwidth Azure benchmark graph",src:s(7808).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"The results for bandwidth on GCP are as follows:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"I/O bandwidth GCP benchmark graph",src:s(96605).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"On GCP, the results exceed the maximum performance guarantees of the chosen disk type. There are two possible explanations for this. The first is that there may be cloud caching in place that isn't configurable. Alternatively, the underlying provisioned disk size may be larger than what was requested, resulting in higher performance boundaries."}),"\n",(0,i.jsx)(n.p,{children:"When comparing Constellation on GCP with GKE, Constellation has similar bandwidth but about 10% less IOPS performance. On Azure, Constellation has similar IOPS performance compared to AKS, where both likely hit the maximum storage performance. However, Constellation has approximately 15% less read and write bandwidth."}),"\n",(0,i.jsx)(n.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,i.jsxs)(n.p,{children:["Despite the added ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/overview/security-benefits",children:"security benefits"})," that Constellation provides, it only incurs a slight performance overhead when compared to managed Kubernetes offerings such as AKS and GKE. In most compute benchmarks, Constellation is on par with it's alternatives.\nWhile it may be slightly slower in certain I/O scenarios due to network and storage encryption, there is ongoing work to reduce this overhead to single digits."]}),"\n",(0,i.jsxs)(n.p,{children:["For instance, storage encryption only adds between 10% to 15% overhead in terms of bandwidth and IOPS.\nMeanwhile, the biggest performance impact that Constellation currently faces is network encryption, which can incur up to 58% overhead on a 10 Gbps network.\nHowever, the Cilium team has conducted ",(0,i.jsx)(n.a,{href:"https://docs.cilium.io/en/latest/operations/performance/benchmark/#encryption-wireguard-ipsec",children:"benchmarks with Cilium using WireGuard encryption"})," on a 100 Gbps network that yielded over 15 Gbps.\nWe're confident that Constellation will provide a similar level of performance with an upcoming release."]}),"\n",(0,i.jsx)(n.p,{children:"Overall, Constellation strikes a great balance between security and performance, and we're continuously working to improve its performance capabilities while maintaining its high level of security."})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},7484:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_net_p2p_azure-fbad5555553d559281f605939f5e26c8.png"},7808:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_fio_azure_bw-9294313529fb8cc2c0230b3b581faddb.png"},11951:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_net_p2p_gcp-8ce759468868272c67b53f5db2a3cf88.png"},28453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>a});var r=s(96540);const i={},o=r.createContext(i);function t(e){const n=r.useContext(o);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),r.createElement(o.Provider,{value:n},e.children)}},37962:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_net_p2svc_azure-823916c53e426752564179c0f7147266.png"},76746:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_fio_azure_iops-a85caab4031a29df58a3e7175a62b792.png"},81503:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_fio_gcp_iops-ba4f26c2dd679d3d5e4ad7c7b0c8370e.png"},87085:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_net_p2svc_gcp-4ae5b9b8d4317ad9d3005c4243d78367.png"},96605:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_fio_gcp_bw-f8739bb79b0e47f896217bcacba14cdf.png"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/8d448ad2.cf755472.js b/pr-preview/pr-4027/assets/js/8d448ad2.cf755472.js deleted file mode 100644 index e50929c01..000000000 --- a/pr-preview/pr-4027/assets/js/8d448ad2.cf755472.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4100],{28453:(e,s,n)=>{n.d(s,{R:()=>r,x:()=>a});var t=n(96540);const i={},o=t.createContext(i);function r(e){const s=t.useContext(o);return t.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),t.createElement(o.Provider,{value:s},e.children)}},75535:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"workflows/verify-cli","title":"Verify the CLI","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","source":"@site/versioned_docs/version-2.23/workflows/verify-cli.md","sourceDirName":"workflows","slug":"/workflows/verify-cli","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cli","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/workflows/verify-cli.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Workflows","permalink":"/constellation/pr-preview/pr-4027/2.23/category/workflows"},"next":{"title":"Configure your cluster","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/config"}}');var i=n(74848),o=n(28453);const r={},a="Verify the CLI",l={},c=[{value:"Verify the signature",id:"verify-the-signature",level:2},{value:"Optional: Manually inspect the transparency log",id:"optional-manually-inspect-the-transparency-log",level:3},{value:"Verify the provenance",id:"verify-the-provenance",level:2}];function d(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",...(0,o.R)(),...e.components},{AsciinemaWidget:n}=s;return n||function(e,s){throw new Error("Expected "+(s?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("AsciinemaWidget",!0),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.header,{children:(0,i.jsx)(s.h1,{id:"verify-the-cli",children:"Verify the CLI"})}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details."})}),"\n",(0,i.jsx)(n,{src:"/constellation/assets/verify-cli.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsxs)(s.p,{children:["Edgeless Systems uses ",(0,i.jsx)(s.a,{href:"https://www.sigstore.dev/",children:"sigstore"})," and ",(0,i.jsx)(s.a,{href:"https://slsa.dev",children:"SLSA"}),' to ensure supply-chain security for the Constellation CLI and node images ("artifacts"). sigstore consists of three components: ',(0,i.jsx)(s.a,{href:"https://docs.sigstore.dev/cosign/signing/overview/",children:"Cosign"}),", ",(0,i.jsx)(s.a,{href:"https://docs.sigstore.dev/logging/overview",children:"Rekor"}),", and Fulcio. Edgeless Systems uses Cosign to sign artifacts. All signatures are uploaded to the public Rekor transparency log, which resides at ",(0,i.jsx)(s.code,{children:"https://rekor.sigstore.dev"}),"."]}),"\n",(0,i.jsxs)(s.admonition,{type:"note",children:[(0,i.jsx)(s.p,{children:"The public key for Edgeless Systems' long-term code-signing key is:"}),(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT\nJmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==\n-----END PUBLIC KEY-----\n"})}),(0,i.jsxs)(s.p,{children:["The public key is also available for download at ",(0,i.jsx)(s.a,{href:"https://edgeless.systems/es.pub",children:"https://edgeless.systems/es.pub"})," and in the Twitter profile ",(0,i.jsx)(s.a,{href:"https://twitter.com/EdgelessSystems",children:"@EdgelessSystems"}),"."]})]}),"\n",(0,i.jsx)(s.p,{children:"The Rekor transparency log is a public append-only ledger that verifies and records signatures and associated metadata. The Rekor transparency log enables everyone to observe the sequence of (software) signatures issued by Edgeless Systems and many other parties. The transparency log allows for the public identification of dubious or malicious signatures."}),"\n",(0,i.jsx)(s.p,{children:"You should always ensure that (1) your CLI executable was signed with the private key corresponding to the above public key and that (2) there is a corresponding entry in the Rekor transparency log. Both can be done as described in the following."}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"You don't need to verify the Constellation node images. This is done automatically by your CLI and the rest of Constellation."})}),"\n",(0,i.jsx)(s.h2,{id:"verify-the-signature",children:"Verify the signature"}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"This guide assumes Linux on an amd64 processor. The exact steps for other platforms differ slightly."})}),"\n",(0,i.jsxs)(s.p,{children:["First, ",(0,i.jsx)(s.a,{href:"https://docs.sigstore.dev/cosign/system_config/installation/",children:"install the Cosign CLI"}),". Next, ",(0,i.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"download"})," and verify the signature that accompanies your CLI executable, for example:"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:"$ cosign verify-blob --key https://edgeless.systems/es.pub --signature constellation-linux-amd64.sig constellation-linux-amd64\n\nVerified OK\n"})}),"\n",(0,i.jsxs)(s.p,{children:["The above performs an offline verification of the provided public key, signature, and executable. To also verify that a corresponding entry exists in the public Rekor transparency log, add the variable ",(0,i.jsx)(s.code,{children:"COSIGN_EXPERIMENTAL=1"}),":"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:"$ COSIGN_EXPERIMENTAL=1 cosign verify-blob --key https://edgeless.systems/es.pub --signature constellation-linux-amd64.sig constellation-linux-amd64\n\ntlog entry verified with uuid: afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13 index: 3477047\nVerified OK\n"})}),"\n",(0,i.jsx)(s.p,{children:"\ud83c\udfc1 You now know that your CLI executable was officially released and signed by Edgeless Systems."}),"\n",(0,i.jsx)(s.h3,{id:"optional-manually-inspect-the-transparency-log",children:"Optional: Manually inspect the transparency log"}),"\n",(0,i.jsxs)(s.p,{children:["To further inspect the public Rekor transparency log, ",(0,i.jsx)(s.a,{href:"https://docs.sigstore.dev/logging/installation",children:"install the Rekor CLI"}),". A search for the CLI executable should give a single UUID. (Note that this UUID contains the UUID from the previous ",(0,i.jsx)(s.code,{children:"cosign"})," command.)"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:"$ rekor-cli search --artifact constellation-linux-amd64\n\nFound matching entries (listed by UUID):\n362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13\n"})}),"\n",(0,i.jsx)(s.p,{children:"With this UUID you can get the full entry from the transparency log:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:'$ rekor-cli get --uuid=362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13\n\nLogID: c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d\nIndex: 3477047\nIntegratedTime: 2022-09-12T22:28:16Z\nUUID: afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13\nBody: {\n "HashedRekordObj": {\n "data": {\n "hash": {\n "algorithm": "sha256",\n "value": "40e137b9b9b8204d672642fd1e181c6d5ccb50cfc5cc7fcbb06a8c2c78f44aff"\n }\n },\n "signature": {\n "content": "MEUCIQCSER3mGj+j5Pr2kOXTlCIHQC3gT30I7qkLr9Awt6eUUQIgcLUKRIlY50UN8JGwVeNgkBZyYD8HMxwC/LFRWoMn180=",\n "publicKey": {\n "content": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFZjhGMWhwbXdFK1lDRlh6akd0YVFjckw2WFpWVApKbUVlNWlTTHZHMVN5UVNBZXc3V2RNS0Y2bzl0OGUyVEZ1Q2t6bE9oaGx3czJPSFdiaUZabkZXQ0Z3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=="\n }\n }\n }\n}\n'})}),"\n",(0,i.jsxs)(s.p,{children:["The field ",(0,i.jsx)(s.code,{children:"publicKey"})," should contain Edgeless Systems' public key in Base64 encoding."]}),"\n",(0,i.jsx)(s.p,{children:"You can get an exhaustive list of artifact signatures issued by Edgeless Systems via the following command:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-bash",children:"rekor-cli search --public-key https://edgeless.systems/es.pub --pki-format x509\n"})}),"\n",(0,i.jsx)(s.p,{children:"Edgeless Systems monitors this list to detect potential unauthorized use of its private key."}),"\n",(0,i.jsx)(s.h2,{id:"verify-the-provenance",children:"Verify the provenance"}),"\n",(0,i.jsxs)(s.p,{children:["Provenance attests that a software artifact was produced by a specific repository and build system invocation. For more information on provenance visit ",(0,i.jsx)(s.a,{href:"https://slsa.dev/provenance/v0.2",children:"slsa.dev"})," and learn about the ",(0,i.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.23/reference/slsa",children:"adoption of SLSA for Constellation"}),"."]}),"\n",(0,i.jsx)(s.p,{children:"Just as checking its signature proves that the CLI hasn't been manipulated, checking the provenance proves that the artifact was produced by the expected build process and hasn't been tampered with."}),"\n",(0,i.jsxs)(s.p,{children:["To verify the provenance, first install the ",(0,i.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-verifier",children:"slsa-verifier"}),". Then make sure you have the provenance file (",(0,i.jsx)(s.code,{children:"constellation.intoto.jsonl"}),") and Constellation CLI downloaded. Both are available on the ",(0,i.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub release page"}),"."]}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"The same provenance file is valid for all Constellation CLI executables of a given version independent of the target platform."})}),"\n",(0,i.jsx)(s.p,{children:"Use the verifier to perform the check:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-shell-session",children:"$ slsa-verifier verify-artifact constellation-linux-amd64 \\\n --provenance-path constellation.intoto.jsonl \\\n --source-uri github.com/edgelesssys/constellation\n\nVerified signature against tlog entry index 7771317 at URL: https://rekor.sigstore.dev/api/v1/log/entries/24296fb24b8ad77af2c04c8b4ae0d5bc5...\nVerified build using builder https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v1.2.2 at commit 18e9924b416323c37b9cdfd6cc728de8a947424a\nPASSED: Verified SLSA provenance\n"})})]})}function h(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/8ea786c8.db908d2a.js b/pr-preview/pr-4027/assets/js/8ea786c8.db908d2a.js deleted file mode 100644 index 511f1e54c..000000000 --- a/pr-preview/pr-4027/assets/js/8ea786c8.db908d2a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9509],{28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>o});var r=n(96540);const a={},i=r.createContext(a);function s(e){const t=r.useContext(i);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),r.createElement(i.Provider,{value:t},e.children)}},76832:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"architecture/keys","title":"Key management and cryptographic primitives","description":"Constellation protects and isolates your cluster and workloads.","source":"@site/versioned_docs/version-2.23/architecture/keys.md","sourceDirName":"architecture","slug":"/architecture/keys","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/keys","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/architecture/keys.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Images","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/images"},"next":{"title":"Encrypted persistent storage","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage"}}');var a=n(74848),i=n(28453);const s={},o="Key management and cryptographic primitives",l={},c=[{value:"Confidential VMs",id:"confidential-vms",level:2},{value:"Master secret",id:"master-secret",level:2},{value:"Cluster identity",id:"cluster-identity",level:2},{value:"Network encryption",id:"network-encryption",level:2},{value:"Storage encryption",id:"storage-encryption",level:2},{value:"Constellation-managed key management",id:"constellation-managed-key-management",level:3},{value:"Key material and key derivation",id:"key-material-and-key-derivation",level:4},{value:"State and storage",id:"state-and-storage",level:4},{value:"Availability",id:"availability",level:4},{value:"Recovery",id:"recovery",level:4},{value:"User-managed key management",id:"user-managed-key-management",level:3},{value:"Recovery and migration",id:"recovery-and-migration",level:4}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"key-management-and-cryptographic-primitives",children:"Key management and cryptographic primitives"})}),"\n",(0,a.jsx)(t.p,{children:"Constellation protects and isolates your cluster and workloads.\nTo that end, cryptography is the foundation that ensures the confidentiality and integrity of all components.\nEvaluating the security and compliance of Constellation requires a precise understanding of the cryptographic primitives and keys used.\nThe following gives an overview of the architecture and explains the technical details."}),"\n",(0,a.jsx)(t.h2,{id:"confidential-vms",children:"Confidential VMs"}),"\n",(0,a.jsx)(t.p,{children:"Confidential VM (CVM) technology comes with hardware and software components for memory encryption, isolation, and remote attestation.\nFor details on the implementations and cryptographic soundness, refer to the hardware vendors' documentation and advisories."}),"\n",(0,a.jsx)(t.h2,{id:"master-secret",children:"Master secret"}),"\n",(0,a.jsxs)(t.p,{children:["The master secret is the cryptographic material used for deriving the ",(0,a.jsx)(t.a,{href:"#cluster-identity",children:(0,a.jsx)(t.em,{children:"clusterID"})})," and the ",(0,a.jsx)(t.em,{children:"key encryption key (KEK)"})," for ",(0,a.jsx)(t.a,{href:"#storage-encryption",children:"storage encryption"}),".\nIt's generated during the bootstrapping of a Constellation cluster.\nIt can either be managed by ",(0,a.jsx)(t.a,{href:"#constellation-managed-key-management",children:"Constellation"})," or an ",(0,a.jsx)(t.a,{href:"#user-managed-key-management",children:"external key management system"}),".\nIn case of ",(0,a.jsx)(t.a,{href:"#recovery-and-migration",children:"recovery"}),", the master secret allows to decrypt the state and recover a Constellation cluster."]}),"\n",(0,a.jsx)(t.h2,{id:"cluster-identity",children:"Cluster identity"}),"\n",(0,a.jsxs)(t.p,{children:["The identity of a Constellation cluster is represented by cryptographic ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation#runtime-measurements",children:"measurements"}),":"]}),"\n",(0,a.jsxs)(t.p,{children:["The ",(0,a.jsx)(t.strong,{children:"base measurements"})," represent the identity of a valid, uninitialized Constellation node.\nThey depend on the node image, but are otherwise the same for every Constellation cluster.\nOn node boot, they're determined using the CVM's attestation mechanism and ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/images",children:"measured boot up to the read-only root filesystem"}),"."]}),"\n",(0,a.jsxs)(t.p,{children:["The ",(0,a.jsx)(t.strong,{children:"clusterID"})," represents the identity of a single initialized Constellation cluster.\nIt's derived from the master secret and a cryptographically random salt and unique for every Constellation cluster.\nThe ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#bootstrapper",children:"Bootstrapper"})," measures the ",(0,a.jsx)(t.em,{children:"clusterID"})," into its own PCR before executing any code not measured as part of the ",(0,a.jsx)(t.em,{children:"base measurements"}),".\nSee ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation#node-attestation",children:"Node attestation"})," for details."]}),"\n",(0,a.jsxs)(t.p,{children:["The remote attestation statement of a Constellation cluster combines the ",(0,a.jsx)(t.em,{children:"base measurements"})," and the ",(0,a.jsx)(t.em,{children:"clusterID"})," for a verifiable, unspoofable, unique identity."]}),"\n",(0,a.jsx)(t.h2,{id:"network-encryption",children:"Network encryption"}),"\n",(0,a.jsxs)(t.p,{children:["Constellation encrypts all cluster network communication using the ",(0,a.jsx)(t.a,{href:"https://github.com/containernetworking/cni",children:"container network interface (CNI)"}),".\nSee ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/networking",children:"network encryption"})," for more details."]}),"\n",(0,a.jsxs)(t.p,{children:["The Cilium agent running on each node establishes a secure ",(0,a.jsx)(t.a,{href:"https://www.wireguard.com/",children:"WireGuard"})," tunnel between it and all other known nodes in the cluster.\nEach node creates its own ",(0,a.jsx)(t.a,{href:"http://cr.yp.to/ecdh.html",children:"Curve25519"})," encryption key pair and distributes its public key via Kubernetes.\nA node uses another node's public key to decrypt and encrypt traffic from and to Cilium-managed endpoints running on that node.\nConnections are always encrypted peer-to-peer using ",(0,a.jsx)(t.a,{href:"http://cr.yp.to/chacha.html",children:"ChaCha20"})," with ",(0,a.jsx)(t.a,{href:"http://cr.yp.to/mac.html",children:"Poly1305"}),".\nWireGuard implements ",(0,a.jsx)(t.a,{href:"https://lists.zx2c4.com/pipermail/wireguard/2017-December/002141.html",children:"forward secrecy with key rotation every 2 minutes"}),"."]}),"\n",(0,a.jsx)(t.h2,{id:"storage-encryption",children:"Storage encryption"}),"\n",(0,a.jsx)(t.p,{children:"Constellation supports transparent encryption of persistent storage.\nThe Linux kernel's device mapper-based encryption features are used to encrypt the data on the block storage level.\nCurrently, the following primitives are used for block storage encryption:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-crypt.html",children:"dm-crypt"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-integrity.html",children:"dm-integrity"})}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["Adding primitives for integrity protection in the CVM attacker model are under active development and will be available in a future version of Constellation.\nSee ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage",children:"encrypted storage"})," for more details."]}),"\n",(0,a.jsxs)(t.p,{children:["As a cluster administrator, when creating a cluster, you can use the Constellation ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/orchestration",children:"installation program"})," to select one of the following methods for key management:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Constellation-managed key management"}),"\n",(0,a.jsx)(t.li,{children:"User-managed key management"}),"\n"]}),"\n",(0,a.jsx)(t.h3,{id:"constellation-managed-key-management",children:"Constellation-managed key management"}),"\n",(0,a.jsx)(t.h4,{id:"key-material-and-key-derivation",children:"Key material and key derivation"}),"\n",(0,a.jsxs)(t.p,{children:["During the creation of a Constellation cluster, the cluster's master secret is used to derive a KEK.\nThis means creating two clusters with the same master secret will yield the same KEK.\nAny data encryption key (DEK) is derived from the KEK via HKDF.\nNote that the master secret is recommended to be unique for every cluster and shouldn't be reused (except in case of ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/recovery",children:"recovering"})," a cluster)."]}),"\n",(0,a.jsx)(t.h4,{id:"state-and-storage",children:"State and storage"}),"\n",(0,a.jsx)(t.p,{children:"The KEK is derived from the master secret during the initialization.\nSubsequently, all other key material is derived from the KEK.\nGiven the same KEK, any DEK can be derived deterministically from a given identifier.\nHence, there is no need to store DEKs. They can be derived on demand.\nAfter the KEK was derived, it's stored in memory only and never leaves the CVM context."}),"\n",(0,a.jsx)(t.h4,{id:"availability",children:"Availability"}),"\n",(0,a.jsxs)(t.p,{children:["Constellation-managed key management has the same availability as the underlying Kubernetes cluster.\nTherefore, the KEK is stored in the ",(0,a.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/",children:"distributed Kubernetes etcd storage"})," to allow for unexpected but non-fatal (control-plane) node failure.\nThe etcd storage is backed by the encrypted and integrity protected ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/images#state-disk",children:"state disk"})," of the nodes."]}),"\n",(0,a.jsx)(t.h4,{id:"recovery",children:"Recovery"}),"\n",(0,a.jsxs)(t.p,{children:["Constellation clusters can be recovered in the event of a disaster, even when all node machines have been stopped and need to be rebooted.\nFor details on the process see the ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/recovery",children:"recovery workflow"}),"."]}),"\n",(0,a.jsx)(t.h3,{id:"user-managed-key-management",children:"User-managed key management"}),"\n",(0,a.jsx)(t.p,{children:"User-managed key management is under active development and will be available soon.\nIn scenarios where constellation-managed key management isn't an option, this mode allows you to keep full control of your keys.\nFor example, compliance requirements may force you to keep your KEKs in an on-prem key management system (KMS)."}),"\n",(0,a.jsx)(t.p,{children:'During the creation of a Constellation cluster, you specify a KEK present in a remote KMS.\nThis follows the common scheme of "bring your own key" (BYOK).\nConstellation will support several KMSs for managing the storage and access of your KEK.\nInitially, it will support the following KMSs:'}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://aws.amazon.com/kms/",children:"AWS KMS"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://cloud.google.com/security-key-management",children:"GCP KMS"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://azure.microsoft.com/en-us/services/key-vault/#product-overview",children:"Azure Key Vault"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=kmip",children:"KMIP-compatible KMS"})}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Storing the keys in Cloud KMS of AWS, Azure, or GCP binds the key usage to the particular cloud identity access management (IAM).\nIn the future, Constellation will support remote attestation-based access policies for Cloud KMS once available.\nNote that using a Cloud KMS limits the isolation and protection to the guarantees of the particular offering."}),"\n",(0,a.jsx)(t.p,{children:'KMIP support allows you to use your KMIP-compatible on-prem KMS and keep full control over your keys.\nThis follows the common scheme of "hold your own key" (HYOK).'}),"\n",(0,a.jsx)(t.p,{children:'The KEK is used to encrypt per-data "data encryption keys" (DEKs).\nDEKs are generated to encrypt your data before storing it on persistent storage.\nAfter being encrypted by the KEK, the DEKs are stored on dedicated cloud storage for persistence.\nCurrently, Constellation supports the following cloud storage options:'}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://aws.amazon.com/s3/",children:"AWS S3"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://cloud.google.com/storage",children:"GCP Cloud Storage"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://azure.microsoft.com/en-us/services/storage/blobs/#overview",children:"Azure Blob Storage"})}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"The DEKs are only present in plaintext form in the encrypted main memory of the CVMs.\nSimilarly, the cryptographic operations for encrypting data before writing it to persistent storage are performed in the context of the CVMs."}),"\n",(0,a.jsx)(t.h4,{id:"recovery-and-migration",children:"Recovery and migration"}),"\n",(0,a.jsx)(t.p,{children:"In the case of a disaster, the KEK can be used to decrypt the DEKs locally and subsequently use them to decrypt and retrieve the data.\nIn case of migration, configuring the same KEK will provide seamless migration of data.\nThus, only the DEK storage needs to be transferred to the new cluster alongside the encrypted data for seamless migration."})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/9010cc91.a4630109.js b/pr-preview/pr-4027/assets/js/9010cc91.a4630109.js deleted file mode 100644 index 5f1e76612..000000000 --- a/pr-preview/pr-4027/assets/js/9010cc91.a4630109.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6135],{28453:(e,s,t)=>{t.d(s,{R:()=>o,x:()=>l});var n=t(96540);const r={},i=n.createContext(r);function o(e){const s=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(i.Provider,{value:s},e.children)}},53693:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"workflows/storage","title":"Use persistent storage","description":"Persistent storage in Kubernetes requires cloud-specific configuration.","source":"@site/versioned_docs/version-2.23/workflows/storage.md","sourceDirName":"workflows","slug":"/workflows/storage","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/storage","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/workflows/storage.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Verify your cluster","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cluster"},"next":{"title":"Use the Terraform provider","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/terraform-provider"}}');var r=t(74848),i=t(28453);const o={},l="Use persistent storage",a={},c=[{value:"Confidential storage",id:"confidential-storage",level:2},{value:"CSI drivers",id:"csi-drivers",level:2},{value:"Installation",id:"installation",level:2},{value:"Change the default storage class",id:"change-the-default-storage-class",level:3}];function d(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components},{TabItem:t,Tabs:n}=s;return t||p("TabItem",!0),n||p("Tabs",!0),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"use-persistent-storage",children:"Use persistent storage"})}),"\n",(0,r.jsxs)(s.p,{children:["Persistent storage in Kubernetes requires cloud-specific configuration.\nFor abstraction of container storage, Kubernetes offers ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/volumes/",children:"volumes"}),",\nallowing users to mount storage solutions directly into containers.\nThe ",(0,r.jsx)(s.a,{href:"https://kubernetes-csi.github.io/docs/",children:"Container Storage Interface (CSI)"})," is the standard interface for exposing arbitrary block and file storage systems into containers in Kubernetes.\nCloud service providers (CSPs) offer their own CSI-based solutions for cloud storage."]}),"\n",(0,r.jsx)(s.h2,{id:"confidential-storage",children:"Confidential storage"}),"\n",(0,r.jsxs)(s.p,{children:["Most cloud storage solutions support encryption, such as ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/kubernetes-engine/docs/how-to/using-cmek",children:"GCE Persistent Disks (PD)"}),".\nConstellation supports the available CSI-based storage options for Kubernetes engines in AWS, Azure, GCP, and STACKIT.\nHowever, their encryption takes place in the storage backend and is managed by the CSP.\nThus, using the default CSI drivers for these storage types means trusting the CSP with your persistent data."]}),"\n",(0,r.jsxs)(s.p,{children:["To address this, Constellation provides CSI drivers for AWS EBS, Azure Disk, GCE PD, and OpenStack Cinder, offering ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys#storage-encryption",children:"encryption on the node level"}),". They enable transparent encryption for persistent volumes without needing to trust the cloud backend. Plaintext data never leaves the confidential VM context, offering you confidential storage."]}),"\n",(0,r.jsxs)(s.p,{children:["For more details see ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage",children:"encrypted persistent storage"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"csi-drivers",children:"CSI drivers"}),"\n",(0,r.jsx)(s.p,{children:"Constellation supports the following drivers, which offer node-level encryption and optional integrity protection."}),"\n",(0,r.jsxs)(n,{groupId:"csp",children:[(0,r.jsx)(t,{value:"aws",label:"AWS",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Constellation CSI driver for AWS Elastic Block Store"}),"\nMount ",(0,r.jsx)(s.a,{href:"https://aws.amazon.com/ebs/",children:"Elastic Block Store"})," storage volumes into your Constellation cluster.\nFollow the instructions on how to ",(0,r.jsx)(s.a,{href:"#installation",children:"install the Constellation CSI driver"})," or check out the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation-aws-ebs-csi-driver",children:"repository"})," for more information."]})}),(0,r.jsx)(t,{value:"azure",label:"Azure",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Constellation CSI driver for Azure Disk"}),":\nMount Azure ",(0,r.jsx)(s.a,{href:"https://azure.microsoft.com/en-us/services/storage/disks/#overview",children:"Disk Storage"})," into your Constellation cluster.\nSee the instructions on how to ",(0,r.jsx)(s.a,{href:"#installation",children:"install the Constellation CSI driver"})," or check out the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation-azuredisk-csi-driver",children:"repository"})," for more information.\nSince Azure Disks are mounted as ",(0,r.jsx)(s.code,{children:"ReadWriteOnce"}),", they're only available to a single pod."]})}),(0,r.jsx)(t,{value:"gcp",label:"GCP",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Constellation CSI driver for GCP Persistent Disk"}),":\nMount ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/persistent-disk",children:"Persistent Disk"})," block storage into your Constellation cluster.\nFollow the instructions on how to ",(0,r.jsx)(s.a,{href:"#installation",children:"install the Constellation CSI driver"})," or check out the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation-gcp-compute-persistent-disk-csi-driver",children:"repository"})," for more information."]})}),(0,r.jsx)(t,{value:"stackit",label:"STACKIT",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Constellation CSI driver for STACKIT / OpenStack Cinder"}),"\nMount ",(0,r.jsx)(s.a,{href:"https://docs.openstack.org/cinder/latest/",children:"Cinder"})," block storage volumes into your Constellation cluster.\nFollow the instructions on how to ",(0,r.jsx)(s.a,{href:"#installation",children:"install the Constellation CSI driver"})," or check out the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation-cloud-provider-openstack",children:"repository"})," for more information."]})})]}),"\n",(0,r.jsxs)(s.p,{children:["Note that in case the options above aren't a suitable solution for you, Constellation is compatible with all other CSI-based storage options. For example, you can use ",(0,r.jsx)(s.a,{href:"https://docs.aws.amazon.com/en_en/eks/latest/userguide/efs-csi.html",children:"AWS EFS"}),", ",(0,r.jsx)(s.a,{href:"https://docs.microsoft.com/en-us/azure/storage/files/storage-files-introduction",children:"Azure Files"}),", or ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/filestore",children:"GCP Filestore"})," with Constellation out of the box. Constellation is just not providing transparent encryption on the node level for these storage types yet."]}),"\n",(0,r.jsx)(s.h2,{id:"installation",children:"Installation"}),"\n",(0,r.jsxs)(s.p,{children:["The Constellation CLI automatically installs Constellation's CSI driver for the selected CSP in your cluster.\nIf you don't need a CSI driver or wish to deploy your own, you can disable the automatic installation by setting ",(0,r.jsx)(s.code,{children:"deployCSIDriver"})," to ",(0,r.jsx)(s.code,{children:"false"})," in your Constellation config file."]}),"\n",(0,r.jsxs)(n,{groupId:"csp",children:[(0,r.jsxs)(t,{value:"aws",label:"AWS",children:[(0,r.jsx)(s.p,{children:"AWS comes with two storage classes by default."}),(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsxs)(s.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volume-types.html",children:["SSDs of ",(0,r.jsx)(s.code,{children:"gp3"})," type"]})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsxs)(s.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volume-types.html",children:["SSDs of ",(0,r.jsx)(s.code,{children:"gp3"})," type"]})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n",(0,r.jsx)(s.li,{children:"Integrity protection of data written to disk"}),"\n"]}),"\n"]}),"\n"]}),(0,r.jsxs)(s.p,{children:["For more information on encryption algorithms and key sizes, refer to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage#cryptographic-algorithms",children:"cryptographic algorithms"}),"."]}),(0,r.jsxs)(s.admonition,{type:"info",children:[(0,r.jsxs)(s.p,{children:["The default storage class is set to ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," for performance reasons.\nIf you want integrity-protected storage, set the ",(0,r.jsx)(s.code,{children:"storageClassName"})," parameter of your persistent volume claim to ",(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"."]}),(0,r.jsxs)(s.p,{children:["Alternatively, you can create your own storage class with integrity protection enabled by adding ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: ext4-integrity"})," to the class ",(0,r.jsx)(s.code,{children:"parameters"}),".\nOr use another filesystem by specifying another file system type with the suffix ",(0,r.jsx)(s.code,{children:"-integrity"}),", e.g., ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: xfs-integrity"}),"."]}),(0,r.jsx)(s.p,{children:"Note that volume expansion isn't supported for integrity-protected disks."})]})]}),(0,r.jsxs)(t,{value:"azure",label:"Azure",children:[(0,r.jsx)(s.p,{children:"Azure comes with two storage classes by default."}),(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsx)(s.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/disks-types#standard-ssds",children:"Standard SSDs"})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsx)(s.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/disks-types#premium-ssds",children:"Premium SSDs"})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n",(0,r.jsx)(s.li,{children:"Integrity protection of data written to disk"}),"\n"]}),"\n"]}),"\n"]}),(0,r.jsxs)(s.p,{children:["For more information on encryption algorithms and key sizes, refer to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage#cryptographic-algorithms",children:"cryptographic algorithms"}),"."]}),(0,r.jsxs)(s.admonition,{type:"info",children:[(0,r.jsxs)(s.p,{children:["The default storage class is set to ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," for performance reasons.\nIf you want integrity-protected storage, set the ",(0,r.jsx)(s.code,{children:"storageClassName"})," parameter of your persistent volume claim to ",(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"."]}),(0,r.jsxs)(s.p,{children:["Alternatively, you can create your own storage class with integrity protection enabled by adding ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: ext4-integrity"})," to the class ",(0,r.jsx)(s.code,{children:"parameters"}),".\nOr use another filesystem by specifying another file system type with the suffix ",(0,r.jsx)(s.code,{children:"-integrity"}),", e.g., ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: xfs-integrity"}),"."]}),(0,r.jsx)(s.p,{children:"Note that volume expansion isn't supported for integrity-protected disks."})]})]}),(0,r.jsxs)(t,{value:"gcp",label:"GCP",children:[(0,r.jsx)(s.p,{children:"GCP comes with two storage classes by default."}),(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/compute/docs/disks#pdspecs",children:"standard persistent disks"})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/compute/docs/disks#pdspecs",children:"performance (SSD) persistent disks"})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n",(0,r.jsx)(s.li,{children:"Integrity protection of data written to disk"}),"\n"]}),"\n"]}),"\n"]}),(0,r.jsxs)(s.p,{children:["For more information on encryption algorithms and key sizes, refer to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage#cryptographic-algorithms",children:"cryptographic algorithms"}),"."]}),(0,r.jsxs)(s.admonition,{type:"info",children:[(0,r.jsxs)(s.p,{children:["The default storage class is set to ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," for performance reasons.\nIf you want integrity-protected storage, set the ",(0,r.jsx)(s.code,{children:"storageClassName"})," parameter of your persistent volume claim to ",(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"."]}),(0,r.jsxs)(s.p,{children:["Alternatively, you can create your own storage class with integrity protection enabled by adding ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: ext4-integrity"})," to the class ",(0,r.jsx)(s.code,{children:"parameters"}),".\nOr use another filesystem by specifying another file system type with the suffix ",(0,r.jsx)(s.code,{children:"-integrity"}),", e.g., ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: xfs-integrity"}),"."]}),(0,r.jsx)(s.p,{children:"Note that volume expansion isn't supported for integrity-protected disks."})]})]}),(0,r.jsxs)(t,{value:"stackit",label:"STACKIT",children:[(0,r.jsx)(s.p,{children:"STACKIT comes with two storage classes by default."}),(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsxs)(s.a,{href:"https://docs.stackit.cloud/stackit/en/service-plans-blockstorage-75137974.html",children:["disks of ",(0,r.jsx)(s.code,{children:"storage_premium_perf1"})," type"]})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsxs)(s.a,{href:"https://docs.stackit.cloud/stackit/en/service-plans-blockstorage-75137974.html",children:["disks of ",(0,r.jsx)(s.code,{children:"storage_premium_perf1"})," type"]})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n",(0,r.jsx)(s.li,{children:"Integrity protection of data written to disk"}),"\n"]}),"\n"]}),"\n"]}),(0,r.jsxs)(s.p,{children:["For more information on encryption algorithms and key sizes, refer to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage#cryptographic-algorithms",children:"cryptographic algorithms"}),"."]}),(0,r.jsxs)(s.admonition,{type:"info",children:[(0,r.jsxs)(s.p,{children:["The default storage class is set to ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," for performance reasons.\nIf you want integrity-protected storage, set the ",(0,r.jsx)(s.code,{children:"storageClassName"})," parameter of your persistent volume claim to ",(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"."]}),(0,r.jsxs)(s.p,{children:["Alternatively, you can create your own storage class with integrity protection enabled by adding ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: ext4-integrity"})," to the class ",(0,r.jsx)(s.code,{children:"parameters"}),".\nOr use another filesystem by specifying another file system type with the suffix ",(0,r.jsx)(s.code,{children:"-integrity"}),", e.g., ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: xfs-integrity"}),"."]}),(0,r.jsx)(s.p,{children:"Note that volume expansion isn't supported for integrity-protected disks."})]})]})]}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["Create a ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/",children:"persistent volume"})]}),"\n",(0,r.jsxs)(s.p,{children:["A ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims",children:"persistent volume claim"})," is a request for storage with certain properties.\nIt can refer to a storage class.\nThe following creates a persistent volume claim, requesting 20 GB of storage via the ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," storage class:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"cat <<EOF | kubectl apply -f -\nkind: PersistentVolumeClaim\napiVersion: v1\nmetadata:\n name: pvc-example\n namespace: default\nspec:\n accessModes:\n - ReadWriteOnce\n storageClassName: encrypted-rwo\n resources:\n requests:\n storage: 20Gi\nEOF\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Create a Pod with persistent storage"}),"\n",(0,r.jsx)(s.p,{children:"You can assign a persistent volume claim to an application in need of persistent storage.\nThe mounted volume will persist restarts.\nThe following creates a pod that uses the previously created persistent volume claim:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"cat <<EOF | kubectl apply -f -\napiVersion: v1\nkind: Pod\nmetadata:\n name: web-server\n namespace: default\nspec:\n containers:\n - name: web-server\n image: nginx\n volumeMounts:\n - mountPath: /var/lib/www/html\n name: mypvc\n volumes:\n - name: mypvc\n persistentVolumeClaim:\n claimName: pvc-example\n readOnly: false\nEOF\n"})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"change-the-default-storage-class",children:"Change the default storage class"}),"\n",(0,r.jsxs)(s.p,{children:["The default storage class is responsible for all persistent volume claims that don't explicitly request ",(0,r.jsx)(s.code,{children:"storageClassName"}),".\nConstellation creates a storage class with encryption enabled and sets this as the default class.\nIn case you wish to change it, follow the steps below:"]}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"List the storage classes in your cluster:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"kubectl get storageclass\n"})}),"\n",(0,r.jsx)(s.p,{children:"The output is similar to this:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-shell-session",children:"NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE\nencrypted-rwo (default) {your-csp}.csi.confidential.cloud Delete Immediate true 1d\nintegrity-encrypted-rwo {your-csp}.csi.confidential.cloud Delete Immediate false 1d\n"})}),"\n",(0,r.jsxs)(s.p,{children:["The default storage class is marked by ",(0,r.jsx)(s.code,{children:"(default)"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Mark old default storage class as non default"}),"\n",(0,r.jsx)(s.p,{children:"If you previously used another storage class as the default, you will have to remove that annotation:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:'kubectl patch storageclass encrypted-rwo -p \'{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}\'\n'})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Mark new class as the default"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:'kubectl patch storageclass integrity-encrypted-rwo -p \'{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}\'\n'})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Verify that your chosen storage class is default:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"kubectl get storageclass\n"})}),"\n",(0,r.jsx)(s.p,{children:"The output is similar to this:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-shell-session",children:"NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE\nencrypted-rwo {your-csp}.csi.confidential.cloud Delete Immediate true 1d\nintegrity-encrypted-rwo (default) {your-csp}.csi.confidential.cloud Delete Immediate false 1d\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}function p(e,s){throw new Error("Expected "+(s?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/90e117e3.d0992f85.js b/pr-preview/pr-4027/assets/js/90e117e3.d0992f85.js deleted file mode 100644 index 2b56c6034..000000000 --- a/pr-preview/pr-4027/assets/js/90e117e3.d0992f85.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8994],{28453:(e,s,n)=>{n.d(s,{R:()=>r,x:()=>a});var o=n(96540);const t={},i=o.createContext(t);function r(e){const s=o.useContext(i);return o.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),o.createElement(i.Provider,{value:s},e.children)}},59331:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"workflows/sbom","title":"Consume software bill of materials (SBOMs)","description":"---","source":"@site/versioned_docs/version-2.24/workflows/sbom.md","sourceDirName":"workflows","slug":"/workflows/sbom","permalink":"/constellation/pr-preview/pr-4027/workflows/sbom","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/workflows/sbom.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Use the Terraform provider","permalink":"/constellation/pr-preview/pr-4027/workflows/terraform-provider"},"next":{"title":"Reproduce release artifacts","permalink":"/constellation/pr-preview/pr-4027/workflows/reproducible-builds"}}');var t=n(74848),i=n(28453);const r={},a="Consume software bill of materials (SBOMs)",l={},c=[{value:"Verify and download SBOMs",id:"verify-and-download-sboms",level:2},{value:"Constellation CLI",id:"constellation-cli",level:3},{value:"Container Images",id:"container-images",level:3},{value:"Vulnerability scanning",id:"vulnerability-scanning",level:2},{value:"Grype",id:"grype",level:3},{value:"Dependency Track",id:"dependency-track",level:3}];function d(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",...(0,i.R)(),...e.components},{AsciinemaWidget:n}=s;return n||function(e,s){throw new Error("Expected "+(s?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("AsciinemaWidget",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"consume-software-bill-of-materials-sboms",children:"Consume software bill of materials (SBOMs)"})}),"\n",(0,t.jsx)(n,{src:"/constellation/assets/check-sbom.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,t.jsx)(s.hr,{}),"\n",(0,t.jsxs)(s.p,{children:["Constellation builds produce a ",(0,t.jsx)(s.a,{href:"https://www.ntia.gov/SBOM",children:"software bill of materials (SBOM)"})," for each generated ",(0,t.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices",children:"artifact"}),".\nYou can use SBOMs to make informed decisions about dependencies and vulnerabilities in a given application. Enterprises rely on SBOMs to maintain an inventory of used applications, which allows them to take data-driven approaches to managing risks related to vulnerabilities."]}),"\n",(0,t.jsxs)(s.p,{children:["SBOMs for Constellation are generated using ",(0,t.jsx)(s.a,{href:"https://github.com/anchore/syft",children:"Syft"}),", signed using ",(0,t.jsx)(s.a,{href:"https://github.com/sigstore/cosign",children:"Cosign"}),", and stored with the produced artifact."]}),"\n",(0,t.jsxs)(s.admonition,{type:"note",children:[(0,t.jsx)(s.p,{children:"The public key for Edgeless Systems' long-term code-signing key is:"}),(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT\nJmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==\n-----END PUBLIC KEY-----\n"})}),(0,t.jsxs)(s.p,{children:["The public key is also available for download at ",(0,t.jsx)(s.a,{href:"https://edgeless.systems/es.pub",children:"https://edgeless.systems/es.pub"})," and in the Twitter profile ",(0,t.jsx)(s.a,{href:"https://twitter.com/EdgelessSystems",children:"@EdgelessSystems"}),"."]}),(0,t.jsxs)(s.p,{children:["Make sure the key is available in a file named ",(0,t.jsx)(s.code,{children:"cosign.pub"})," to execute the following examples."]})]}),"\n",(0,t.jsx)(s.h2,{id:"verify-and-download-sboms",children:"Verify and download SBOMs"}),"\n",(0,t.jsx)(s.p,{children:"The following sections detail how to work with each type of artifact to verify and extract the SBOM."}),"\n",(0,t.jsx)(s.h3,{id:"constellation-cli",children:"Constellation CLI"}),"\n",(0,t.jsxs)(s.p,{children:["The SBOM for Constellation CLI is made available on the ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub release page"}),". The SBOM (",(0,t.jsx)(s.code,{children:"constellation.spdx.sbom"}),") and corresponding signature (",(0,t.jsx)(s.code,{children:"constellation.spdx.sbom.sig"}),") are valid for each Constellation CLI for a given version, regardless of architecture and operating system."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom\ncurl -LO https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom.sig\ncosign verify-blob --key cosign.pub --signature constellation.spdx.sbom.sig constellation.spdx.sbom\n"})}),"\n",(0,t.jsx)(s.h3,{id:"container-images",children:"Container Images"}),"\n",(0,t.jsxs)(s.p,{children:["SBOMs for container images are ",(0,t.jsx)(s.a,{href:"https://docs.sigstore.dev/cosign/signing/other_types/#sboms-software-bill-of-materials",children:"attached to the image using Cosign"})," and uploaded to the same registry."]}),"\n",(0,t.jsx)(s.p,{children:"As a consumer, use cosign to download and verify the SBOM:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"# Verify and download the attestation statement\ncosign verify-attestation ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --type 'https://cyclonedx.org/bom' --key cosign.pub --output-file verification-service.att.json\n# Extract SBOM from attestation statement\njq -r .payload verification-service.att.json | base64 -d > verification-service.cyclonedx.sbom\n"})}),"\n",(0,t.jsx)(s.p,{children:"A successful verification should result in similar output:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-shell-session",children:"$ cosign verify-attestation ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --type 'https://cyclonedx.org/bom' --key cosign.pub --output-file verification-service.sbom\n\nVerification for ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --\nThe following checks were performed on each of these signatures:\n - The cosign claims were validated\n - The signatures were verified against the specified public key\n$ jq -r .payload verification-service.sbom | base64 -d > verification-service.cyclonedx.sbom\n"})}),"\n",(0,t.jsx)(s.admonition,{type:"note",children:(0,t.jsxs)(s.p,{children:["This example considers only the ",(0,t.jsx)(s.code,{children:"verification-service"}),". The same approach works for all containers in the ",(0,t.jsx)(s.a,{href:"https://github.com/orgs/edgelesssys/packages?repo_name=constellation",children:"Constellation container registry"}),"."]})}),"\n",(0,t.jsx)(s.h2,{id:"vulnerability-scanning",children:"Vulnerability scanning"}),"\n",(0,t.jsxs)(s.p,{children:["You can use a plethora of tools to consume SBOMs. This section provides suggestions for tools that are popular and known to produce reliable results, but any tool that consumes ",(0,t.jsx)(s.a,{href:"https://spdx.dev/",children:"SPDX"})," or ",(0,t.jsx)(s.a,{href:"https://cyclonedx.org/",children:"CycloneDX"})," files should work."]}),"\n",(0,t.jsxs)(s.p,{children:["Syft is able to ",(0,t.jsx)(s.a,{href:"https://github.com/anchore/syft#format-conversion-experimental",children:"convert between the two formats"})," in case you require a specific type."]}),"\n",(0,t.jsx)(s.h3,{id:"grype",children:"Grype"}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"https://github.com/anchore/grype",children:"Grype"})," is a CLI tool that lends itself well for integration into CI/CD systems or local developer machines. It's also able to consume the signed attestation statement directly and does the verification in one go."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"grype att:verification-service.sbom --key cosign.pub --add-cpes-if-none -q\n"})}),"\n",(0,t.jsx)(s.h3,{id:"dependency-track",children:"Dependency Track"}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"https://dependencytrack.org/",children:"Dependency Track"})," is one of the oldest and most mature solutions when it comes to managing software inventory and vulnerabilities. Once imported, it continuously scans SBOMs for new vulnerabilities. It supports the CycloneDX format and provides direct guidance on how to comply with ",(0,t.jsx)(s.a,{href:"https://docs.dependencytrack.org/usage/executive-order-14028/",children:"U.S. Executive Order 14028"}),"."]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/911e2eea.bded8e4c.js b/pr-preview/pr-4027/assets/js/911e2eea.bded8e4c.js deleted file mode 100644 index c2214fc62..000000000 --- a/pr-preview/pr-4027/assets/js/911e2eea.bded8e4c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[998],{59387:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"2.22","label":"2.22","banner":"unmaintained","badge":true,"noIndex":false,"className":"docs-version-2.22","isLast":false,"docsSidebars":{"docs":[{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/","label":"Introduction","docId":"intro","unlisted":false},{"type":"category","label":"Basics","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/overview/confidential-kubernetes","label":"Confidential Kubernetes","docId":"overview/confidential-kubernetes","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/overview/security-benefits","label":"Security benefits","docId":"overview/security-benefits","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/overview/product","label":"Product features","docId":"overview/product","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/overview/clouds","label":"Feature status of clouds","docId":"overview/clouds","unlisted":false},{"type":"category","label":"Performance","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/overview/performance/compute","label":"Compute benchmarks","docId":"overview/performance/compute","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/overview/performance/io","label":"I/O benchmarks","docId":"overview/performance/io","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/overview/performance/application","label":"Application benchmarks","docId":"overview/performance/application","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/2.22/overview/performance/"},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/overview/license","label":"License","docId":"overview/license","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/2.22/category/basics"},{"type":"category","label":"Getting started","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/getting-started/install","label":"Installation","docId":"getting-started/install","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps","label":"First steps (cloud)","docId":"getting-started/first-steps","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local","label":"First steps (local)","docId":"getting-started/first-steps-local","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/getting-started/marketplaces","label":"Cloud Marketplaces","docId":"getting-started/marketplaces","unlisted":false},{"type":"category","label":"Examples","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/emojivoto","label":"Emojivoto","docId":"getting-started/examples/emojivoto","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/online-boutique","label":"Online Boutique","docId":"getting-started/examples/online-boutique","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scaling","label":"Horizontal Pod Autoscaling","docId":"getting-started/examples/horizontal-scaling","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/filestash-s3proxy","label":"Filestash with s3proxy","docId":"getting-started/examples/filestash-s3proxy","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples"}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/2.22/category/getting-started"},{"type":"category","label":"Workflows","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli","label":"Verify the CLI","docId":"workflows/verify-cli","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/workflows/config","label":"Configure your cluster","docId":"workflows/config","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/workflows/create","label":"Create your cluster","docId":"workflows/create","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/workflows/scale","label":"Scale your cluster","docId":"workflows/scale","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade","label":"Upgrade your cluster","docId":"workflows/upgrade","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/workflows/lb","label":"Expose a service","docId":"workflows/lb","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/workflows/cert-manager","label":"Install cert-manager","docId":"workflows/cert-manager","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/workflows/s3proxy","label":"Install s3proxy","docId":"workflows/s3proxy","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/workflows/terminate","label":"Terminate your cluster","docId":"workflows/terminate","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/workflows/recovery","label":"Recover your cluster","docId":"workflows/recovery","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cluster","label":"Verify your cluster","docId":"workflows/verify-cluster","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/workflows/storage","label":"Use persistent storage","docId":"workflows/storage","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/workflows/terraform-provider","label":"Use the Terraform provider","docId":"workflows/terraform-provider","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/workflows/sbom","label":"Consume SBOMs","docId":"workflows/sbom","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/workflows/reproducible-builds","label":"Reproduce release artifacts","docId":"workflows/reproducible-builds","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting","label":"Troubleshooting","docId":"workflows/troubleshooting","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/2.22/category/workflows"},{"type":"category","label":"Architecture","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/architecture/overview","label":"Overview","docId":"architecture/overview","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration","label":"Cluster orchestration","docId":"architecture/orchestration","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/architecture/versions","label":"Versions and support","docId":"architecture/versions","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/architecture/microservices","label":"Microservices","docId":"architecture/microservices","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation","label":"Attestation","docId":"architecture/attestation","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/architecture/images","label":"Images","docId":"architecture/images","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/architecture/keys","label":"Keys and cryptographic primitives","docId":"architecture/keys","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage","label":"Encrypted persistent storage","docId":"architecture/encrypted-storage","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/architecture/networking","label":"Networking","docId":"architecture/networking","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/architecture/observability","label":"Observability","docId":"architecture/observability","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/2.22/category/architecture"},{"type":"category","label":"Reference","items":[{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/reference/cli","label":"CLI","docId":"reference/cli","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/reference/migration","label":"Configuration migrations","docId":"reference/migration","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/reference/terraform","label":"Terraform usage","docId":"reference/terraform","unlisted":false},{"type":"link","href":"/constellation/pr-preview/pr-4027/2.22/reference/slsa","label":"SLSA adoption","docId":"reference/slsa","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/constellation/pr-preview/pr-4027/2.22/category/reference"}]},"docs":{"architecture/attestation":{"id":"architecture/attestation","title":"Attestation","description":"This page explains Constellation\'s attestation process and highlights the cornerstones of its trust model.","sidebar":"docs"},"architecture/encrypted-storage":{"id":"architecture/encrypted-storage","title":"Encrypted persistent storage","description":"Confidential VMs provide runtime memory encryption to protect data in use.","sidebar":"docs"},"architecture/images":{"id":"architecture/images","title":"Constellation images","description":"Constellation uses a minimal version of Fedora as the operating system running inside confidential VMs. This Linux distribution is optimized for containers and designed to be stateless.","sidebar":"docs"},"architecture/keys":{"id":"architecture/keys","title":"Key management and cryptographic primitives","description":"Constellation protects and isolates your cluster and workloads.","sidebar":"docs"},"architecture/microservices":{"id":"architecture/microservices","title":"Microservices","description":"Constellation takes care of bootstrapping and initializing a Confidential Kubernetes cluster.","sidebar":"docs"},"architecture/networking":{"id":"architecture/networking","title":"Network encryption","description":"Constellation encrypts all pod communication using the container network interface (CNI).","sidebar":"docs"},"architecture/observability":{"id":"architecture/observability","title":"Observability","description":"In Kubernetes, observability is the ability to gain insight into the behavior and performance of applications.","sidebar":"docs"},"architecture/orchestration":{"id":"architecture/orchestration","title":"Orchestrating Constellation clusters","description":"You can use the CLI to create a cluster on the supported cloud platforms.","sidebar":"docs"},"architecture/overview":{"id":"architecture/overview","title":"Overview","description":"Constellation is a cloud-based confidential orchestration platform.","sidebar":"docs"},"architecture/versions":{"id":"architecture/versions","title":"Versions and support policy","description":"All components of Constellation use a three-digit version number of the form v...","sidebar":"docs"},"getting-started/examples":{"id":"getting-started/examples","title":"Examples","description":"After you installed the CLI and created your first cluster, you\'re ready to deploy applications. Why not start with one of the following examples?","sidebar":"docs"},"getting-started/examples/emojivoto":{"id":"getting-started/examples/emojivoto","title":"Emojivoto","description":"Emojivoto is a simple and fun application that\'s well suited to test the basic functionality of your cluster.","sidebar":"docs"},"getting-started/examples/filestash-s3proxy":{"id":"getting-started/examples/filestash-s3proxy","title":"Deploying Filestash","description":"Filestash is a web frontend for different storage backends, including S3.","sidebar":"docs"},"getting-started/examples/horizontal-scaling":{"id":"getting-started/examples/horizontal-scaling","title":"Horizontal Pod Autoscaling","description":"This example demonstrates Constellation\'s autoscaling capabilities. It\'s based on the Kubernetes HorizontalPodAutoscaler Walkthrough. During the following steps, Constellation will spawn new VMs on demand, verify them, add them to the cluster, and delete them again when the load has settled down.","sidebar":"docs"},"getting-started/examples/online-boutique":{"id":"getting-started/examples/online-boutique","title":"Online Boutique","description":"Online Boutique is an e-commerce demo application by Google consisting of 11 separate microservices. In this demo, Constellation automatically sets up a load balancer on your CSP, making it easy to expose services from your confidential cluster.","sidebar":"docs"},"getting-started/first-steps":{"id":"getting-started/first-steps","title":"First steps with Constellation","description":"The following steps guide you through the process of creating a cluster and deploying a sample app. This example assumes that you have successfully installed and set up Constellation,","sidebar":"docs"},"getting-started/first-steps-local":{"id":"getting-started/first-steps-local","title":"First steps with a local cluster","description":"A local cluster lets you deploy and test Constellation without a cloud subscription.","sidebar":"docs"},"getting-started/install":{"id":"getting-started/install","title":"Installation and setup","description":"Constellation runs entirely in your cloud environment and can be controlled via a dedicated command-line interface (CLI) or a Terraform provider.","sidebar":"docs"},"getting-started/marketplaces":{"id":"getting-started/marketplaces","title":"Using Constellation via Cloud Marketplaces","description":"Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please contact us.","sidebar":"docs"},"intro":{"id":"intro","title":"Introduction","description":"Welcome to the documentation of Constellation! Constellation is a Kubernetes engine that aims to provide the best possible data security.","sidebar":"docs"},"overview/clouds":{"id":"overview/clouds","title":"Feature status of clouds","description":"What works on which cloud? Currently, Confidential VMs (CVMs) are available in varying quality on the different clouds and software stacks.","sidebar":"docs"},"overview/confidential-kubernetes":{"id":"overview/confidential-kubernetes","title":"Confidential Kubernetes","description":"We use the term Confidential Kubernetes to refer to the concept of using confidential-computing technology to shield entire Kubernetes clusters from the infrastructure. The three defining properties of this concept are:","sidebar":"docs"},"overview/license":{"id":"overview/license","title":"License","description":"Source code","sidebar":"docs"},"overview/performance/application":{"id":"overview/performance/application","title":"Application benchmarks","description":"HashiCorp Vault","sidebar":"docs"},"overview/performance/compute":{"id":"overview/performance/compute","title":"Impact of runtime encryption on compute performance","description":"All nodes in a Constellation cluster are executed inside Confidential VMs (CVMs). Consequently, the performance of Constellation is inherently linked to the performance of these CVMs.","sidebar":"docs"},"overview/performance/io":{"id":"overview/performance/io","title":"I/O performance benchmarks","description":"To assess the overall performance of Constellation, this benchmark evaluates Constellation v2.6.0 in terms of storage I/O using fio and network performance using the Kubernetes Network Benchmark.","sidebar":"docs"},"overview/performance/performance":{"id":"overview/performance/performance","title":"Performance analysis of Constellation","description":"This section provides a comprehensive examination of the performance characteristics of Constellation.","sidebar":"docs"},"overview/product":{"id":"overview/product","title":"Product features","description":"Constellation is a Kubernetes engine that aims to provide the best possible data security in combination with enterprise-grade scalability and reliability features---and a smooth user experience.","sidebar":"docs"},"overview/security-benefits":{"id":"overview/security-benefits","title":"Security benefits and threat model","description":"Constellation implements the Confidential Kubernetes concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be verified.","sidebar":"docs"},"reference/cli":{"id":"reference/cli","title":"CLI reference","description":"Use the Constellation CLI to create and manage your clusters.","sidebar":"docs"},"reference/migration":{"id":"reference/migration","title":"Migrations","description":"This document describes breaking changes and migrations between Constellation releases.","sidebar":"docs"},"reference/slsa":{"id":"reference/slsa","title":"Supply chain levels for software artifacts (SLSA) adoption","description":"Supply chain Levels for Software Artifacts, or SLSA (salsa) is a framework for improving and grading a project\'s build system and engineering processes. SLSA focuses on security improvements for source code storage as well as build system definition, execution, and observation. SLSA is structured in four levels. This page describes the adoption of SLSA for Constellation.","sidebar":"docs"},"reference/terraform":{"id":"reference/terraform","title":"Terraform usage","description":"Terraform is an Infrastructure as Code (IaC) framework to manage cloud resources. This page explains how Constellation uses it internally and how advanced users may manually use it to have more control over the resource creation.","sidebar":"docs"},"workflows/cert-manager":{"id":"workflows/cert-manager","title":"Install cert-manager","description":"If you want to use cert-manager with Constellation, pay attention to the following to avoid potential pitfalls.","sidebar":"docs"},"workflows/config":{"id":"workflows/config","title":"Configure your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","sidebar":"docs"},"workflows/create":{"id":"workflows/create","title":"Create your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","sidebar":"docs"},"workflows/lb":{"id":"workflows/lb","title":"Expose a service","description":"Constellation integrates the native load balancers of each CSP. Therefore, to expose a service simply create a service of type LoadBalancer.","sidebar":"docs"},"workflows/recovery":{"id":"workflows/recovery","title":"Recover your cluster","description":"Recovery of a Constellation cluster means getting it back into a healthy state after too many concurrent node failures in the control plane.","sidebar":"docs"},"workflows/reproducible-builds":{"id":"workflows/reproducible-builds","title":"Reproduce released artifacts","description":"Constellation has first-class support for reproducible builds.","sidebar":"docs"},"workflows/s3proxy":{"id":"workflows/s3proxy","title":"Install s3proxy","description":"Constellation includes a transparent client-side encryption proxy for AWS S3 and compatible stores.","sidebar":"docs"},"workflows/sbom":{"id":"workflows/sbom","title":"Consume software bill of materials (SBOMs)","description":"---","sidebar":"docs"},"workflows/scale":{"id":"workflows/scale","title":"Scale your cluster","description":"Constellation provides all features of a Kubernetes cluster including scaling and autoscaling.","sidebar":"docs"},"workflows/storage":{"id":"workflows/storage","title":"Use persistent storage","description":"Persistent storage in Kubernetes requires cloud-specific configuration.","sidebar":"docs"},"workflows/terminate":{"id":"workflows/terminate","title":"Terminate your cluster","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","sidebar":"docs"},"workflows/terraform-provider":{"id":"workflows/terraform-provider","title":"Use the Terraform provider","description":"The Constellation Terraform provider allows to manage the full lifecycle of a Constellation cluster (namely creation, upgrades, and deletion) via Terraform.","sidebar":"docs"},"workflows/troubleshooting":{"id":"workflows/troubleshooting","title":"Troubleshooting","description":"This section aids you in finding problems when working with Constellation.","sidebar":"docs"},"workflows/trusted-launch":{"id":"workflows/trusted-launch","title":"Use Azure trusted launch VMs","description":"Constellation also supports trusted launch VMs on Microsoft Azure. Trusted launch VMs don\'t offer the same level of security as Confidential VMs, but are available in more regions and in larger quantities. The main difference between trusted launch VMs and normal VMs is that the former offer vTPM-based remote attestation. When used with trusted launch VMs, Constellation relies on vTPM-based remote attestation to verify nodes."},"workflows/upgrade":{"id":"workflows/upgrade","title":"Upgrade your cluster","description":"Constellation provides an easy way to upgrade all components of your cluster, without disrupting its availability.","sidebar":"docs"},"workflows/verify-cli":{"id":"workflows/verify-cli","title":"Verify the CLI","description":"This recording presents the essence of this page. It\'s recommended to read it in full for the motivation and all details.","sidebar":"docs"},"workflows/verify-cluster":{"id":"workflows/verify-cluster","title":"Verify your cluster","description":"Constellation\'s attestation feature allows you, or a third party, to verify the integrity and confidentiality of your Constellation cluster.","sidebar":"docs"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/91c76d4c.1cd3611e.js b/pr-preview/pr-4027/assets/js/91c76d4c.1cd3611e.js deleted file mode 100644 index 83afb5932..000000000 --- a/pr-preview/pr-4027/assets/js/91c76d4c.1cd3611e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8238],{28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>l});var o=i(96540);const s={},t=o.createContext(s);function r(e){const n=o.useContext(t);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(t.Provider,{value:n},e.children)}},47571:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>p,frontMatter:()=>r,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"reference/cli","title":"CLI reference","description":"Use the Constellation CLI to create and manage your clusters.","source":"@site/docs/reference/cli.md","sourceDirName":"reference","slug":"/reference/cli","permalink":"/constellation/pr-preview/pr-4027/next/reference/cli","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/reference/cli.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Reference","permalink":"/constellation/pr-preview/pr-4027/next/category/reference"},"next":{"title":"Configuration migrations","permalink":"/constellation/pr-preview/pr-4027/next/reference/migration"}}');var s=i(74848),t=i(28453);const r={},l="CLI reference",a={},c=[{value:"constellation config",id:"constellation-config",level:2},{value:"Synopsis",id:"synopsis",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"constellation config generate",id:"constellation-config-generate",level:2},{value:"Synopsis",id:"synopsis-1",level:3},{value:"Options",id:"options-1",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-1",level:3},{value:"constellation config fetch-measurements",id:"constellation-config-fetch-measurements",level:2},{value:"Synopsis",id:"synopsis-2",level:3},{value:"Options",id:"options-2",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-2",level:3},{value:"constellation config instance-types",id:"constellation-config-instance-types",level:2},{value:"Synopsis",id:"synopsis-3",level:3},{value:"Options",id:"options-3",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-3",level:3},{value:"constellation config kubernetes-versions",id:"constellation-config-kubernetes-versions",level:2},{value:"Synopsis",id:"synopsis-4",level:3},{value:"Options",id:"options-4",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-4",level:3},{value:"constellation config migrate",id:"constellation-config-migrate",level:2},{value:"Synopsis",id:"synopsis-5",level:3},{value:"Options",id:"options-5",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-5",level:3},{value:"constellation create",id:"constellation-create",level:2},{value:"Synopsis",id:"synopsis-6",level:3},{value:"Options",id:"options-6",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-6",level:3},{value:"constellation apply",id:"constellation-apply",level:2},{value:"Synopsis",id:"synopsis-7",level:3},{value:"Options",id:"options-7",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-7",level:3},{value:"constellation mini",id:"constellation-mini",level:2},{value:"Synopsis",id:"synopsis-8",level:3},{value:"Options",id:"options-8",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-8",level:3},{value:"constellation mini up",id:"constellation-mini-up",level:2},{value:"Synopsis",id:"synopsis-9",level:3},{value:"Options",id:"options-9",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-9",level:3},{value:"constellation mini down",id:"constellation-mini-down",level:2},{value:"Synopsis",id:"synopsis-10",level:3},{value:"Options",id:"options-10",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-10",level:3},{value:"constellation status",id:"constellation-status",level:2},{value:"Synopsis",id:"synopsis-11",level:3},{value:"Options",id:"options-11",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-11",level:3},{value:"constellation verify",id:"constellation-verify",level:2},{value:"Synopsis",id:"synopsis-12",level:3},{value:"Options",id:"options-12",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-12",level:3},{value:"constellation upgrade",id:"constellation-upgrade",level:2},{value:"Synopsis",id:"synopsis-13",level:3},{value:"Options",id:"options-13",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-13",level:3},{value:"constellation upgrade check",id:"constellation-upgrade-check",level:2},{value:"Synopsis",id:"synopsis-14",level:3},{value:"Options",id:"options-14",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-14",level:3},{value:"constellation upgrade apply",id:"constellation-upgrade-apply",level:2},{value:"Synopsis",id:"synopsis-15",level:3},{value:"Options",id:"options-15",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-15",level:3},{value:"constellation recover",id:"constellation-recover",level:2},{value:"Synopsis",id:"synopsis-16",level:3},{value:"Options",id:"options-16",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-16",level:3},{value:"constellation terminate",id:"constellation-terminate",level:2},{value:"Synopsis",id:"synopsis-17",level:3},{value:"Options",id:"options-17",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-17",level:3},{value:"constellation iam",id:"constellation-iam",level:2},{value:"Synopsis",id:"synopsis-18",level:3},{value:"Options",id:"options-18",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-18",level:3},{value:"constellation iam create",id:"constellation-iam-create",level:2},{value:"Synopsis",id:"synopsis-19",level:3},{value:"Options",id:"options-19",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-19",level:3},{value:"constellation iam create aws",id:"constellation-iam-create-aws",level:2},{value:"Synopsis",id:"synopsis-20",level:3},{value:"Options",id:"options-20",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-20",level:3},{value:"constellation iam create azure",id:"constellation-iam-create-azure",level:2},{value:"Synopsis",id:"synopsis-21",level:3},{value:"Options",id:"options-21",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-21",level:3},{value:"constellation iam create gcp",id:"constellation-iam-create-gcp",level:2},{value:"Synopsis",id:"synopsis-22",level:3},{value:"Options",id:"options-22",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-22",level:3},{value:"constellation iam destroy",id:"constellation-iam-destroy",level:2},{value:"Synopsis",id:"synopsis-23",level:3},{value:"Options",id:"options-23",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-23",level:3},{value:"constellation iam upgrade",id:"constellation-iam-upgrade",level:2},{value:"Synopsis",id:"synopsis-24",level:3},{value:"Options",id:"options-24",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-24",level:3},{value:"constellation iam upgrade apply",id:"constellation-iam-upgrade-apply",level:2},{value:"Synopsis",id:"synopsis-25",level:3},{value:"Options",id:"options-25",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-25",level:3},{value:"constellation version",id:"constellation-version",level:2},{value:"Synopsis",id:"synopsis-26",level:3},{value:"Options",id:"options-26",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-26",level:3},{value:"constellation init",id:"constellation-init",level:2},{value:"Synopsis",id:"synopsis-27",level:3},{value:"Options",id:"options-27",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-27",level:3},{value:"constellation ssh",id:"constellation-ssh",level:2},{value:"Synopsis",id:"synopsis-28",level:3},{value:"Options",id:"options-28",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-28",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"cli-reference",children:"CLI reference"})}),"\n",(0,s.jsx)(n.p,{children:"Use the Constellation CLI to create and manage your clusters."}),"\n",(0,s.jsx)(n.p,{children:"Usage:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation [command]\n"})}),"\n",(0,s.jsx)(n.p,{children:"Commands:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config",children:"config"}),": Work with the Constellation configuration file","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-generate",children:"generate"}),": Generate a default configuration and state file"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-fetch-measurements",children:"fetch-measurements"}),": Fetch measurements for configured cloud provider and image"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-instance-types",children:"instance-types"}),": Print the supported instance types for all cloud providers"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-kubernetes-versions",children:"kubernetes-versions"}),": Print the Kubernetes versions supported by this CLI"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-migrate",children:"migrate"}),": Migrate a configuration file to a new version"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-create",children:"create"}),": Create instances on a cloud platform for your Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-apply",children:"apply"}),": Apply a configuration to a Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-mini",children:"mini"}),": Manage MiniConstellation clusters","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-mini-up",children:"up"}),": Create and initialize a new MiniConstellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-mini-down",children:"down"}),": Destroy a MiniConstellation cluster"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-status",children:"status"}),": Show status of a Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-verify",children:"verify"}),": Verify the confidential properties of a Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-upgrade",children:"upgrade"}),": Find and apply upgrades to your Constellation cluster","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-upgrade-check",children:"check"}),": Check for possible upgrades"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-upgrade-apply",children:"apply"}),": Apply an upgrade to a Constellation cluster"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-recover",children:"recover"}),": Recover a completely stopped Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-terminate",children:"terminate"}),": Terminate a Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam",children:"iam"}),": Work with the IAM configuration on your cloud provider","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-create",children:"create"}),": Create IAM configuration on a cloud platform for your Constellation cluster","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-create-aws",children:"aws"}),": Create IAM configuration on AWS for your Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-create-azure",children:"azure"}),": Create IAM configuration on Microsoft Azure for your Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-create-gcp",children:"gcp"}),": Create IAM configuration on GCP for your Constellation cluster"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-destroy",children:"destroy"}),": Destroy an IAM configuration and delete local Terraform files"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-upgrade",children:"upgrade"}),": Find and apply upgrades to your IAM profile","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-upgrade-apply",children:"apply"}),": Apply an upgrade to an IAM profile"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-version",children:"version"}),": Display version of this CLI"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-init",children:"init"}),": Initialize the Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-ssh",children:"ssh"}),": Generate a certificate for emergency SSH access"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config",children:"constellation config"}),"\n",(0,s.jsx)(n.p,{children:"Work with the Constellation configuration file"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Work with the Constellation configuration file."}),"\n",(0,s.jsx)(n.h3,{id:"options",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for config\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-generate",children:"constellation config generate"}),"\n",(0,s.jsx)(n.p,{children:"Generate a default configuration and state file"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-1",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Generate a default configuration and state file for your selected cloud provider."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config generate {aws|azure|gcp|openstack|qemu|stackit} [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-1",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' -a, --attestation string attestation variant to use {aws-sev-snp|aws-nitro-tpm|azure-sev-snp|azure-tdx|azure-trustedlaunch|gcp-sev-snp|gcp-sev-es|qemu-vtpm}. If not specified, the default for the cloud provider is used\n -h, --help help for generate\n -k, --kubernetes string Kubernetes version to use in format MAJOR.MINOR (default "v1.31")\n -t, --tags strings additional tags for created resources given a list of key=value\n'})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-1",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-fetch-measurements",children:"constellation config fetch-measurements"}),"\n",(0,s.jsx)(n.p,{children:"Fetch measurements for configured cloud provider and image"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-2",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Fetch measurements for configured cloud provider and image."}),"\n",(0,s.jsx)(n.p,{children:"A config needs to be generated first."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config fetch-measurements [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-2",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for fetch-measurements\n -s, --signature-url string alternative URL to fetch measurements' signature from\n -u, --url string alternative URL to fetch measurements from\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-2",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-instance-types",children:"constellation config instance-types"}),"\n",(0,s.jsx)(n.p,{children:"Print the supported instance types for all cloud providers"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-3",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Print the supported instance types for all cloud providers."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config instance-types [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-3",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for instance-types\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-3",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-kubernetes-versions",children:"constellation config kubernetes-versions"}),"\n",(0,s.jsx)(n.p,{children:"Print the Kubernetes versions supported by this CLI"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-4",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Print the Kubernetes versions supported by this CLI."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config kubernetes-versions [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-4",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for kubernetes-versions\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-4",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-migrate",children:"constellation config migrate"}),"\n",(0,s.jsx)(n.p,{children:"Migrate a configuration file to a new version"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-5",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Migrate a configuration file to a new version."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config migrate [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-5",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for migrate\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-5",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-create",children:"constellation create"}),"\n",(0,s.jsx)(n.p,{children:"Create instances on a cloud platform for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-6",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create instances on a cloud platform for your Constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation create [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-6",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for create\n -y, --yes create the cluster without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-6",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-apply",children:"constellation apply"}),"\n",(0,s.jsx)(n.p,{children:"Apply a configuration to a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-7",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Apply a configuration to a Constellation cluster to initialize or upgrade the cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation apply [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-7",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" --conformance enable conformance mode\n -h, --help help for apply\n --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config\n --skip-helm-wait install helm charts without waiting for deployments to be ready\n --skip-phases strings comma-separated list of upgrade phases to skip\n one or multiple of { infrastructure | init | attestationconfig | certsans | helm | image | k8s }\n -y, --yes run command without further confirmation\n WARNING: the command might delete or update existing resources without additional checks. Please read the docs.\n \n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-7",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-mini",children:"constellation mini"}),"\n",(0,s.jsx)(n.p,{children:"Manage MiniConstellation clusters"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-8",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Manage MiniConstellation clusters."}),"\n",(0,s.jsx)(n.h3,{id:"options-8",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for mini\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-8",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-mini-up",children:"constellation mini up"}),"\n",(0,s.jsx)(n.p,{children:"Create and initialize a new MiniConstellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-9",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create and initialize a new MiniConstellation cluster."}),"\n",(0,s.jsx)(n.p,{children:"A mini cluster consists of a single control-plane and worker node, hosted using QEMU/KVM."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation mini up [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-9",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for up\n --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config (default true)\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-9",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-mini-down",children:"constellation mini down"}),"\n",(0,s.jsx)(n.p,{children:"Destroy a MiniConstellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-10",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Destroy a MiniConstellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation mini down [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-10",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for down\n -y, --yes terminate the cluster without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-10",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-status",children:"constellation status"}),"\n",(0,s.jsx)(n.p,{children:"Show status of a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-11",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Show the status of a constellation cluster."}),"\n",(0,s.jsx)(n.p,{children:"Shows microservice, image, and Kubernetes versions installed in the cluster. Also shows status of current version upgrades."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation status [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-11",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for status\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-11",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-verify",children:"constellation verify"}),"\n",(0,s.jsx)(n.p,{children:"Verify the confidential properties of a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-12",children:"Synopsis"}),"\n",(0,s.jsxs)(n.p,{children:["Verify the confidential properties of a Constellation cluster.\nIf arguments aren't specified, values are read from ",(0,s.jsx)(n.code,{children:"constellation-state.yaml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation verify [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-12",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" --cluster-id string expected cluster identifier\n -h, --help help for verify\n -e, --node-endpoint string endpoint of the node to verify, passed as HOST[:PORT]\n -o, --output string print the attestation document in the output format {json|raw}\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-12",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-upgrade",children:"constellation upgrade"}),"\n",(0,s.jsx)(n.p,{children:"Find and apply upgrades to your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-13",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Find and apply upgrades to your Constellation cluster."}),"\n",(0,s.jsx)(n.h3,{id:"options-13",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for upgrade\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-13",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-upgrade-check",children:"constellation upgrade check"}),"\n",(0,s.jsx)(n.p,{children:"Check for possible upgrades"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-14",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Check which upgrades can be applied to your Constellation Cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation upgrade check [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-14",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' -h, --help help for check\n --ref string the reference to use for querying new versions (default "-")\n --stream string the stream to use for querying new versions (default "stable")\n -u, --update-config update the specified config file with the suggested versions\n'})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-14",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-upgrade-apply",children:"constellation upgrade apply"}),"\n",(0,s.jsx)(n.p,{children:"Apply an upgrade to a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-15",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Apply an upgrade to a Constellation cluster by applying the chosen configuration."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation upgrade apply [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-15",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" --conformance enable conformance mode\n -h, --help help for apply\n --skip-helm-wait install helm charts without waiting for deployments to be ready\n --skip-phases strings comma-separated list of upgrade phases to skip\n one or multiple of { infrastructure | helm | image | k8s }\n -y, --yes run upgrades without further confirmation\n WARNING: might delete your resources in case you are using cert-manager in your cluster. Please read the docs.\n WARNING: might unintentionally overwrite measurements in the running cluster.\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-15",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-recover",children:"constellation recover"}),"\n",(0,s.jsx)(n.p,{children:"Recover a completely stopped Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-16",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Recover a Constellation cluster by sending a recovery key to an instance in the boot stage."}),"\n",(0,s.jsx)(n.p,{children:"This is only required if instances restart without other instances available for bootstrapping."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation recover [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-16",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -e, --endpoint string endpoint of the instance, passed as HOST[:PORT]\n -h, --help help for recover\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-16",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-terminate",children:"constellation terminate"}),"\n",(0,s.jsx)(n.p,{children:"Terminate a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-17",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Terminate a Constellation cluster."}),"\n",(0,s.jsx)(n.p,{children:"The cluster can't be started again, and all persistent storage will be lost."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation terminate [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-17",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for terminate\n -y, --yes terminate the cluster without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-17",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam",children:"constellation iam"}),"\n",(0,s.jsx)(n.p,{children:"Work with the IAM configuration on your cloud provider"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-18",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Work with the IAM configuration on your cloud provider."}),"\n",(0,s.jsx)(n.h3,{id:"options-18",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for iam\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-18",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-create",children:"constellation iam create"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on a cloud platform for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-19",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on a cloud platform for your Constellation cluster."}),"\n",(0,s.jsx)(n.h3,{id:"options-19",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for create\n --update-config update the config file with the specific IAM information\n -y, --yes create the IAM configuration without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-19",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-create-aws",children:"constellation iam create aws"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on AWS for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-20",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on AWS for your Constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam create aws [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-20",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for aws\n --prefix string name prefix for all resources (required)\n --zone string AWS availability zone the resources will be created in, e.g., us-east-2a (required)\n See the Constellation docs for a list of currently supported regions.\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-20",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n --update-config update the config file with the specific IAM information\n -C, --workspace string path to the Constellation workspace\n -y, --yes create the IAM configuration without further confirmation\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-create-azure",children:"constellation iam create azure"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on Microsoft Azure for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-21",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on Microsoft Azure for your Constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam create azure [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-21",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for azure\n --region string region the resources will be created in, e.g., westus (required)\n --resourceGroup string name prefix of the two resource groups your cluster / IAM resources will be created in (required)\n --servicePrincipal string name of the service principal that will be created (required)\n --subscriptionID string subscription ID of the Azure account. Required if the 'ARM_SUBSCRIPTION_ID' environment variable is not set\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-21",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n --update-config update the config file with the specific IAM information\n -C, --workspace string path to the Constellation workspace\n -y, --yes create the IAM configuration without further confirmation\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-create-gcp",children:"constellation iam create gcp"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on GCP for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-22",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on GCP for your Constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam create gcp [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-22",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for gcp\n --prefix string Prefix for the service account ID and VM ID that will be created (required)\n Must be letters, digits, or hyphens.\n --projectID string ID of the GCP project the configuration will be created in (required)\n Find it on the welcome screen of your project: https://console.cloud.google.com/welcome\n --zone string GCP zone the cluster will be deployed in (required)\n Find a list of available zones here: https://cloud.google.com/compute/docs/regions-zones#available\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-22",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n --update-config update the config file with the specific IAM information\n -C, --workspace string path to the Constellation workspace\n -y, --yes create the IAM configuration without further confirmation\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-destroy",children:"constellation iam destroy"}),"\n",(0,s.jsx)(n.p,{children:"Destroy an IAM configuration and delete local Terraform files"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-23",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Destroy an IAM configuration and delete local Terraform files."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam destroy [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-23",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for destroy\n -y, --yes destroy the IAM configuration without asking for confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-23",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-upgrade",children:"constellation iam upgrade"}),"\n",(0,s.jsx)(n.p,{children:"Find and apply upgrades to your IAM profile"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-24",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Find and apply upgrades to your IAM profile."}),"\n",(0,s.jsx)(n.h3,{id:"options-24",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for upgrade\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-24",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-upgrade-apply",children:"constellation iam upgrade apply"}),"\n",(0,s.jsx)(n.p,{children:"Apply an upgrade to an IAM profile"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-25",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Apply an upgrade to an IAM profile."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam upgrade apply [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-25",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for apply\n -y, --yes run upgrades without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-25",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-version",children:"constellation version"}),"\n",(0,s.jsx)(n.p,{children:"Display version of this CLI"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-26",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Display version of this CLI."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation version [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-26",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for version\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-26",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-init",children:"constellation init"}),"\n",(0,s.jsx)(n.p,{children:"Initialize the Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-27",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Initialize the Constellation cluster."}),"\n",(0,s.jsx)(n.p,{children:"Start your confidential Kubernetes."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation init [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-27",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" --conformance enable conformance mode\n -h, --help help for init\n --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config\n --skip-helm-wait install helm charts without waiting for deployments to be ready\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-27",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-ssh",children:"constellation ssh"}),"\n",(0,s.jsx)(n.p,{children:"Generate a certificate for emergency SSH access"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-28",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Generate a certificate for emergency SSH access to your SSH-enabled constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation ssh [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-28",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for ssh\n --key string the path to an existing SSH public key\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-28",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/92236455.90a907d5.js b/pr-preview/pr-4027/assets/js/92236455.90a907d5.js deleted file mode 100644 index 87eb41f71..000000000 --- a/pr-preview/pr-4027/assets/js/92236455.90a907d5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1031],{28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var s=n(96540);const r={},i=s.createContext(r);function a(e){const t=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:t},e.children)}},30843:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"overview/security-benefits","title":"Security benefits and threat model","description":"Constellation implements the Confidential Kubernetes concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be verified.","source":"@site/versioned_docs/version-2.24/overview/security-benefits.md","sourceDirName":"overview","slug":"/overview/security-benefits","permalink":"/constellation/pr-preview/pr-4027/overview/security-benefits","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/overview/security-benefits.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential Kubernetes","permalink":"/constellation/pr-preview/pr-4027/overview/confidential-kubernetes"},"next":{"title":"Product features","permalink":"/constellation/pr-preview/pr-4027/overview/product"}}');var r=n(74848),i=n(28453);const a={},o="Security benefits and threat model",c={},l=[{value:"Insider access",id:"insider-access",level:2},{value:"Infrastructure-based attacks",id:"infrastructure-based-attacks",level:2},{value:"Supply chain attacks",id:"supply-chain-attacks",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",p:"p",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"security-benefits-and-threat-model",children:"Security benefits and threat model"})}),"\n",(0,r.jsxs)(t.p,{children:["Constellation implements the ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/overview/confidential-kubernetes",children:"Confidential Kubernetes"})," concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the ",(0,r.jsx)(t.em,{children:"cloud & datacenter infrastructure"})," and the ",(0,r.jsx)(t.em,{children:"physical hosts"}),", including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/verify-cluster",children:"verified"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"TCB comparison",src:n(88728).A+"",width:"3988",height:"1380"})}),"\n",(0,r.jsx)(t.p,{children:"Given this background, the following describes the concrete threat classes that Constellation addresses."}),"\n",(0,r.jsx)(t.h2,{id:"insider-access",children:"Insider access"}),"\n",(0,r.jsx)(t.p,{children:"Employees and third-party contractors of cloud service providers (CSPs) have access to different layers of the cloud infrastructure.\nThis opens up a large attack surface where workloads and data can be read, copied, or manipulated. With Constellation, Kubernetes deployments are shielded from the infrastructure and thus such accesses are prevented."}),"\n",(0,r.jsx)(t.h2,{id:"infrastructure-based-attacks",children:"Infrastructure-based attacks"}),"\n",(0,r.jsxs)(t.p,{children:['Malicious cloud users ("hackers") may break out of their tenancy and access other tenants\' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. Analogously to the ',(0,r.jsx)(t.em,{children:"insider access"})," scenario, Constellation also prevents access to a deployment's data in this scenario."]}),"\n",(0,r.jsx)(t.h2,{id:"supply-chain-attacks",children:"Supply chain attacks"}),"\n",(0,r.jsxs)(t.p,{children:["Supply chain security is receiving lots of attention recently due to an ",(0,r.jsx)(t.a,{href:"https://www.enisa.europa.eu/news/enisa-news/understanding-the-increase-in-supply-chain-security-attacks",children:"increasing number of recorded attacks"}),". For instance, a malicious actor could attempt to tamper Constellation node images (including Kubernetes and other software) before they're loaded in the confidential VMs of a cluster. Constellation uses ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/attestation",children:"remote attestation"})," in conjunction with public ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/verify-cli",children:"transparency logs"})," to prevent this."]}),"\n",(0,r.jsx)(t.p,{children:"In the future, Constellation will extend this feature to customer workloads. This will enable cluster owners to create auditable policies that precisely define which containers can run in a given deployment."})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},88728:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/tcb-424516bbf9d20afe12576bc1305ebc29.svg"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/925a7d08.3942d153.js b/pr-preview/pr-4027/assets/js/925a7d08.3942d153.js deleted file mode 100644 index a04a6dd13..000000000 --- a/pr-preview/pr-4027/assets/js/925a7d08.3942d153.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2813],{28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>a});var s=r(96540);const t={},o=s.createContext(t);function i(e){const n=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),s.createElement(o.Provider,{value:n},e.children)}},58096:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"workflows/upgrade","title":"Upgrade your cluster","description":"Constellation provides an easy way to upgrade all components of your cluster, without disrupting its availability.","source":"@site/versioned_docs/version-2.23/workflows/upgrade.md","sourceDirName":"workflows","slug":"/workflows/upgrade","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/upgrade","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/workflows/upgrade.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Scale your cluster","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/scale"},"next":{"title":"Expose a service","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/lb"}}');var t=r(74848),o=r(28453);const i={},a="Upgrade your cluster",l={},c=[{value:"Update the CLI",id:"update-the-cli",level:2},{value:"Migrate the configuration",id:"migrate-the-configuration",level:2},{value:"Check for upgrades",id:"check-for-upgrades",level:2},{value:"Apply the upgrade",id:"apply-the-upgrade",level:2},{value:"Check the status",id:"check-the-status",level:2},{value:"Apply further upgrades",id:"apply-further-upgrades",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"upgrade-your-cluster",children:"Upgrade your cluster"})}),"\n",(0,t.jsxs)(n.p,{children:["Constellation provides an easy way to upgrade all components of your cluster, without disrupting its availability.\nSpecifically, you can upgrade the Kubernetes version, the nodes' image, and the Constellation microservices.\nYou configure the desired versions in your local Constellation configuration and trigger upgrades with the ",(0,t.jsx)(n.code,{children:"apply"})," command.\nTo learn about available versions you use the ",(0,t.jsx)(n.code,{children:"upgrade check"})," command.\nWhich versions are available depends on the CLI version you are using."]}),"\n",(0,t.jsx)(n.h2,{id:"update-the-cli",children:"Update the CLI"}),"\n",(0,t.jsx)(n.p,{children:"Each CLI comes with a set of supported microservice and Kubernetes versions.\nMost importantly, a given CLI version can only upgrade a cluster of the previous minor version, but not older ones.\nThis means that you have to upgrade your CLI and cluster one minor version at a time."}),"\n",(0,t.jsx)(n.p,{children:"For example, if you are currently on CLI version v2.6 and the latest version is v2.8, you should"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"upgrade the CLI to v2.7,"}),"\n",(0,t.jsx)(n.li,{children:"upgrade the cluster to v2.7,"}),"\n",(0,t.jsx)(n.li,{children:"and only then continue upgrading the CLI (and the cluster) to v2.8 after."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Also note that if your current Kubernetes version isn't supported by the next CLI version, use your current CLI to upgrade to a newer Kubernetes version first."}),"\n",(0,t.jsxs)(n.p,{children:["To learn which Kubernetes versions are supported by a particular CLI, run ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/reference/cli#constellation-config-kubernetes-versions",children:"constellation config kubernetes-versions"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"migrate-the-configuration",children:"Migrate the configuration"}),"\n",(0,t.jsxs)(n.p,{children:["The Constellation configuration file is located in the file ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," in your workspace.\nRefer to the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/reference/migration",children:"migration reference"})," to check if you need to update fields in your configuration file.\nUse ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/reference/cli#constellation-config-migrate",children:(0,t.jsx)(n.code,{children:"constellation config migrate"})})," to automatically update an old config file to a new format."]}),"\n",(0,t.jsx)(n.h2,{id:"check-for-upgrades",children:"Check for upgrades"}),"\n",(0,t.jsx)(n.p,{children:"To learn which versions the current CLI can upgrade to and what's installed in your cluster, run:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# Show possible upgrades\nconstellation upgrade check\n\n# Show possible upgrades and write them to config file\nconstellation upgrade check --update-config\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You can either enter the reported target versions into your config manually or run the above command with the ",(0,t.jsx)(n.code,{children:"--update-config"})," flag.\nWhen using this flag, the ",(0,t.jsx)(n.code,{children:"kubernetesVersion"}),", ",(0,t.jsx)(n.code,{children:"image"}),", ",(0,t.jsx)(n.code,{children:"microserviceVersion"}),", and ",(0,t.jsx)(n.code,{children:"attestation"})," fields are overwritten with the smallest available upgrade."]}),"\n",(0,t.jsx)(n.h2,{id:"apply-the-upgrade",children:"Apply the upgrade"}),"\n",(0,t.jsx)(n.p,{children:"Once you updated your config with the desired versions, you can trigger the upgrade with this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation apply\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Microservice upgrades will be finished within a few minutes, depending on the cluster size.\nIf you are interested, you can monitor pods restarting in the ",(0,t.jsx)(n.code,{children:"kube-system"})," namespace with your tool of choice."]}),"\n",(0,t.jsx)(n.p,{children:"Image and Kubernetes upgrades take longer.\nFor each node in your cluster, a new node has to be created and joined.\nThe process usually takes up to ten minutes per node."}),"\n",(0,t.jsxs)(n.p,{children:["When applying an upgrade, the Helm charts for the upgrade as well as backup files of Constellation-managed Custom Resource Definitions, Custom Resources, and Terraform state are created.\nYou can use the Terraform state backup to restore previous resources in case an upgrade misconfigured or erroneously deleted a resource.\nYou can use the Custom Resource (Definition) backup files to restore Custom Resources and Definitions manually (e.g., via ",(0,t.jsx)(n.code,{children:"kubectl apply"}),") if the automatic migration of those resources fails.\nYou can use the Helm charts to manually apply upgrades to the Kubernetes resources, should an upgrade fail."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["For advanced users: the upgrade consists of several phases that can be individually skipped through the ",(0,t.jsx)(n.code,{children:"--skip-phases"})," flag.\nThe phases are ",(0,t.jsx)(n.code,{children:"infrastracture"})," for the cloud resource management through Terraform, ",(0,t.jsx)(n.code,{children:"helm"})," for the chart management of the microservices, ",(0,t.jsx)(n.code,{children:"image"})," for OS image upgrades, and ",(0,t.jsx)(n.code,{children:"k8s"})," for Kubernetes version upgrades."]})}),"\n",(0,t.jsx)(n.h2,{id:"check-the-status",children:"Check the status"}),"\n",(0,t.jsxs)(n.p,{children:["Upgrades are asynchronous operations.\nAfter you run ",(0,t.jsx)(n.code,{children:"apply"}),", it will take a while until the upgrade has completed.\nTo understand if an upgrade is finished, you can run:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation status\n"})}),"\n",(0,t.jsx)(n.p,{children:"This command displays the following information:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The installed services and their versions"}),"\n",(0,t.jsx)(n.li,{children:"The image and Kubernetes version the cluster is expecting on each node"}),"\n",(0,t.jsx)(n.li,{children:"How many nodes are up to date"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here's an example output:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell-session",children:"Target versions:\n Image: v2.6.0\n Kubernetes: v1.25.8\nService versions:\n Cilium: v1.12.1\n cert-manager: v1.10.0\n constellation-operators: v2.6.0\n constellation-services: v2.6.0\nCluster status: Some node versions are out of date\n Image: 23/25\n Kubernetes: 25/25\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This output indicates that the cluster is running Kubernetes version ",(0,t.jsx)(n.code,{children:"1.25.8"}),", and all nodes have the appropriate binaries installed.\n23 out of 25 nodes have already upgraded to the targeted image version of ",(0,t.jsx)(n.code,{children:"2.6.0"}),", while two are still in progress."]}),"\n",(0,t.jsx)(n.h2,{id:"apply-further-upgrades",children:"Apply further upgrades"}),"\n",(0,t.jsxs)(n.p,{children:["After the upgrade is finished, you can run ",(0,t.jsx)(n.code,{children:"constellation upgrade check"})," again to see if there are more upgrades available. If so, repeat the process."]})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/927cf76e.74a50cde.js b/pr-preview/pr-4027/assets/js/927cf76e.74a50cde.js deleted file mode 100644 index 106137a87..000000000 --- a/pr-preview/pr-4027/assets/js/927cf76e.74a50cde.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1226],{9902:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"architecture/observability","title":"Observability","description":"In Kubernetes, observability is the ability to gain insight into the behavior and performance of applications.","source":"@site/docs/architecture/observability.md","sourceDirName":"architecture","slug":"/architecture/observability","permalink":"/constellation/pr-preview/pr-4027/next/architecture/observability","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/architecture/observability.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Networking","permalink":"/constellation/pr-preview/pr-4027/next/architecture/networking"},"next":{"title":"Reference","permalink":"/constellation/pr-preview/pr-4027/next/category/reference"}}');var n=s(74848),r=s(28453);const a={},o="Observability",l={},c=[{value:"Cloud resource monitoring",id:"cloud-resource-monitoring",level:2},{value:"Metrics",id:"metrics",level:2},{value:"Logs",id:"logs",level:2},{value:"System logs",id:"system-logs",level:3},{value:"Kubernetes logs",id:"kubernetes-logs",level:3},{value:"Traces",id:"traces",level:2},{value:"Integrations",id:"integrations",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"observability",children:"Observability"})}),"\n",(0,n.jsx)(t.p,{children:'In Kubernetes, observability is the ability to gain insight into the behavior and performance of applications.\nIt helps identify and resolve issues more effectively, ensuring stability and performance of Kubernetes workloads, reducing downtime and outages, and improving efficiency.\nThe "three pillars of observability" are logs, metrics, and traces.'}),"\n",(0,n.jsx)(t.p,{children:"In the context of Confidential Computing, observability is a delicate subject and needs to be applied such that it doesn't leak any sensitive information.\nThe following gives an overview of where and how you can apply standard observability tools in Constellation."}),"\n",(0,n.jsx)(t.h2,{id:"cloud-resource-monitoring",children:"Cloud resource monitoring"}),"\n",(0,n.jsx)(t.p,{children:"While inaccessible, Constellation's nodes are still visible as black box VMs to the hypervisor.\nResource consumption, such as memory and CPU utilization, can be monitored from the outside and observed via the cloud platforms directly.\nSimilarly, other resources, such as storage and network and their respective metrics, are visible via the cloud platform."}),"\n",(0,n.jsx)(t.h2,{id:"metrics",children:"Metrics"}),"\n",(0,n.jsx)(t.p,{children:"Metrics are numeric representations of data measured over intervals of time. They're essential for understanding system health and gaining insights using telemetry signals."}),"\n",(0,n.jsxs)(t.p,{children:["By default, Constellation exposes the ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/system-metrics/",children:"metrics for Kubernetes system components"})," inside the cluster.\nSimilarly, the ",(0,n.jsx)(t.a,{href:"https://etcd.io/docs/v3.5/metrics/",children:"etcd metrics"})," endpoints are exposed inside the cluster.\nThese ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/system-metrics/#disabling-metrics",children:"metrics endpoints can be disabled"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["You can collect these cluster-internal metrics via tools such as ",(0,n.jsx)(t.a,{href:"https://prometheus.io/",children:"Prometheus"})," or the ",(0,n.jsx)(t.a,{href:"https://www.elastic.co/de/elastic-stack/",children:"Elastic Stack"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["Constellation's CNI Cilium also supports ",(0,n.jsx)(t.a,{href:"https://docs.cilium.io/en/latest/observability/metrics/",children:"metrics via Prometheus endpoints"}),".\nHowever, in Constellation, they're disabled by default and must be enabled first."]}),"\n",(0,n.jsx)(t.h2,{id:"logs",children:"Logs"}),"\n",(0,n.jsx)(t.p,{children:"Logs represent discrete events that usually describe what's happening with your service.\nThe payload is an actual message emitted from your system along with a metadata section containing a timestamp, labels, and tracking identifiers."}),"\n",(0,n.jsx)(t.h3,{id:"system-logs",children:"System logs"}),"\n",(0,n.jsxs)(t.p,{children:["Detailed system-level logs are accessible via ",(0,n.jsx)(t.code,{children:"/var/log"})," and ",(0,n.jsx)(t.a,{href:"https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html",children:"journald"})," on the nodes directly.\nThey can be collected from there, for example, via ",(0,n.jsx)(t.a,{href:"https://www.elastic.co/guide/en/beats/filebeat/current/logstash-output.html",children:"Filebeat and Logstash"}),", which are tools of the ",(0,n.jsx)(t.a,{href:"https://www.elastic.co/de/elastic-stack/",children:"Elastic Stack"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["In case of an error during the initialization, the CLI automatically collects the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#bootstrapper",children:"Bootstrapper"})," logs and returns these as a file for ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/troubleshooting",children:"troubleshooting"}),". Here is an example of such an event:"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell-session",children:'Cluster initialization failed. This error is not recoverable.\nTerminate your cluster and try again.\nFetched bootstrapper logs are stored in "constellation-cluster.log"\n'})}),"\n",(0,n.jsx)(t.h3,{id:"kubernetes-logs",children:"Kubernetes logs"}),"\n",(0,n.jsxs)(t.p,{children:["Constellation supports the ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/logging/",children:"Kubernetes logging architecture"}),".\nBy default, logs are written to the nodes' encrypted state disks.\nThese include the Pod and container logs and the ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/logging/#system-component-logs",children:"system component logs"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices",children:"Constellation services"})," run as Pods inside the ",(0,n.jsx)(t.code,{children:"kube-system"})," namespace and use the standard container logging mechanism.\nThe same applies for the ",(0,n.jsx)(t.a,{href:"https://docs.cilium.io/en/latest/operations/troubleshooting/#logs",children:"Cilium Pods"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["You can collect logs from within the cluster via tools such as ",(0,n.jsx)(t.a,{href:"https://github.com/fluent/fluentd",children:"Fluentd"}),", ",(0,n.jsx)(t.a,{href:"https://github.com/grafana/loki",children:"Loki"}),", or the ",(0,n.jsx)(t.a,{href:"https://www.elastic.co/de/elastic-stack/",children:"Elastic Stack"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"traces",children:"Traces"}),"\n",(0,n.jsx)(t.p,{children:"Modern systems are implemented as interconnected complex and distributed microservices. Understanding request flows and system communications is challenging, mainly because all systems in a chain need to be modified to propagate tracing information. Distributed tracing is a new approach to increasing observability and understanding performance bottlenecks. A trace represents consecutive events that reflect an end-to-end request path in a distributed system."}),"\n",(0,n.jsxs)(t.p,{children:["Constellation supports ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/system-traces/",children:"traces for Kubernetes system components"}),".\nBy default, they're disabled and need to be enabled first."]}),"\n",(0,n.jsxs)(t.p,{children:["Similarly, Cilium can be enabled to ",(0,n.jsx)(t.a,{href:"https://cilium.io/use-cases/metrics-export/",children:"export traces"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["You can collect these traces via tools such as ",(0,n.jsx)(t.a,{href:"https://www.jaegertracing.io/",children:"Jaeger"})," or ",(0,n.jsx)(t.a,{href:"https://zipkin.io/",children:"Zipkin"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"integrations",children:"Integrations"}),"\n",(0,n.jsx)(t.p,{children:"Platforms and SaaS solutions such as Datadog, logz.io, Dynatrace, or New Relic facilitate the observability challenge for Kubernetes and provide all-in-one SaaS solutions.\nThey install agents into the cluster that collect metrics, logs, and tracing information and upload them into the data lake of the platform.\nTechnically, the agent-based approach is compatible with Constellation, and attaching these platforms is straightforward.\nHowever, you need to evaluate if the exported data might violate Constellation's compliance and privacy guarantees by uploading them to a third-party platform."})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>o});var i=s(96540);const n={},r=i.createContext(n);function a(e){const t=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/9412.3eb2f25f.js b/pr-preview/pr-4027/assets/js/9412.3eb2f25f.js deleted file mode 100644 index 3b2ce5ae7..000000000 --- a/pr-preview/pr-4027/assets/js/9412.3eb2f25f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9412],{25871:(e,t,a)=>{function i(e,t){e.accDescr&&t.setAccDescription?.(e.accDescr),e.accTitle&&t.setAccTitle?.(e.accTitle),e.title&&t.setDiagramTitle?.(e.title)}a.d(t,{S:()=>i}),(0,a(40797).K2)(i,"populateCommonDb")},69412:(e,t,a)=>{a.d(t,{diagram:()=>C});var i=a(73590),l=a(25871),n=a(13226),r=a(67633),s=a(40797),o=a(78731),c=a(70451),p=r.UI.pie,d={sections:new Map,showData:!1,config:p},u=d.sections,g=d.showData,h=structuredClone(p),f=(0,s.K2)(()=>structuredClone(h),"getConfig"),m=(0,s.K2)(()=>{u=new Map,g=d.showData,(0,r.IU)()},"clear"),w=(0,s.K2)(({label:e,value:t})=>{if(t<0)throw new Error(`"${e}" has invalid value: ${t}. Negative values are not allowed in pie charts. All slice values must be >= 0.`);u.has(e)||(u.set(e,t),s.Rm.debug(`added new section: ${e}, with value: ${t}`))},"addSection"),S=(0,s.K2)(()=>u,"getSections"),x=(0,s.K2)(e=>{g=e},"setShowData"),D=(0,s.K2)(()=>g,"getShowData"),T={getConfig:f,clear:m,setDiagramTitle:r.ke,getDiagramTitle:r.ab,setAccTitle:r.SV,getAccTitle:r.iN,setAccDescription:r.EI,getAccDescription:r.m7,addSection:w,getSections:S,setShowData:x,getShowData:D},$=(0,s.K2)((e,t)=>{(0,l.S)(e,t),t.setShowData(e.showData),e.sections.map(t.addSection)},"populateDb"),b={parse:(0,s.K2)(async e=>{const t=await(0,o.qg)("pie",e);s.Rm.debug(t),$(t,T)},"parse")},v=(0,s.K2)(e=>`\n .pieCircle{\n stroke: ${e.pieStrokeColor};\n stroke-width : ${e.pieStrokeWidth};\n opacity : ${e.pieOpacity};\n }\n .pieOuterCircle{\n stroke: ${e.pieOuterStrokeColor};\n stroke-width: ${e.pieOuterStrokeWidth};\n fill: none;\n }\n .pieTitleText {\n text-anchor: middle;\n font-size: ${e.pieTitleTextSize};\n fill: ${e.pieTitleTextColor};\n font-family: ${e.fontFamily};\n }\n .slice {\n font-family: ${e.fontFamily};\n fill: ${e.pieSectionTextColor};\n font-size:${e.pieSectionTextSize};\n // fill: white;\n }\n .legend text {\n fill: ${e.pieLegendTextColor};\n font-family: ${e.fontFamily};\n font-size: ${e.pieLegendTextSize};\n }\n`,"getStyles"),y=(0,s.K2)(e=>{const t=[...e.values()].reduce((e,t)=>e+t,0),a=[...e.entries()].map(([e,t])=>({label:e,value:t})).filter(e=>e.value/t*100>=1).sort((e,t)=>t.value-e.value);return(0,c.rLf)().value(e=>e.value)(a)},"createPieArcs"),C={parser:b,db:T,renderer:{draw:(0,s.K2)((e,t,a,l)=>{s.Rm.debug("rendering pie chart\n"+e);const o=l.db,p=(0,r.D7)(),d=(0,n.$t)(o.getConfig(),p.pie),u=18,g=450,h=g,f=(0,i.D)(t),m=f.append("g");m.attr("transform","translate(225,225)");const{themeVariables:w}=p;let[S]=(0,n.I5)(w.pieOuterStrokeWidth);S??=2;const x=d.textPosition,D=Math.min(h,g)/2-40,T=(0,c.JLW)().innerRadius(0).outerRadius(D),$=(0,c.JLW)().innerRadius(D*x).outerRadius(D*x);m.append("circle").attr("cx",0).attr("cy",0).attr("r",D+S/2).attr("class","pieOuterCircle");const b=o.getSections(),v=y(b),C=[w.pie1,w.pie2,w.pie3,w.pie4,w.pie5,w.pie6,w.pie7,w.pie8,w.pie9,w.pie10,w.pie11,w.pie12];let k=0;b.forEach(e=>{k+=e});const A=v.filter(e=>"0"!==(e.data.value/k*100).toFixed(0)),K=(0,c.UMr)(C);m.selectAll("mySlices").data(A).enter().append("path").attr("d",T).attr("fill",e=>K(e.data.label)).attr("class","pieCircle"),m.selectAll("mySlices").data(A).enter().append("text").text(e=>(e.data.value/k*100).toFixed(0)+"%").attr("transform",e=>"translate("+$.centroid(e)+")").style("text-anchor","middle").attr("class","slice"),m.append("text").text(o.getDiagramTitle()).attr("x",0).attr("y",-200).attr("class","pieTitleText");const R=[...b.entries()].map(([e,t])=>({label:e,value:t})),z=m.selectAll(".legend").data(R).enter().append("g").attr("class","legend").attr("transform",(e,t)=>"translate(216,"+(22*t-22*R.length/2)+")");z.append("rect").attr("width",u).attr("height",u).style("fill",e=>K(e.label)).style("stroke",e=>K(e.label)),z.append("text").attr("x",22).attr("y",14).text(e=>o.getShowData()?`${e.label} [${e.value}]`:e.label);const M=512+Math.max(...z.selectAll("text").nodes().map(e=>e?.getBoundingClientRect().width??0));f.attr("viewBox",`0 0 ${M} 450`),(0,r.a$)(f,g,M,d.useMaxWidth)},"draw")},styles:v}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/9510.4d014fd7.js b/pr-preview/pr-4027/assets/js/9510.4d014fd7.js deleted file mode 100644 index e9a79cb3f..000000000 --- a/pr-preview/pr-4027/assets/js/9510.4d014fd7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9510],{29510:(s,r,a)=>{a.d(r,{diagram:()=>t});var e=a(71746),l=(a(52501),a(89625),a(21152),a(10045),a(5164),a(28698),a(5894),a(63245),a(32387),a(30092),a(13226),a(67633),a(40797)),t={parser:e._$,get db(){return new e.NM},renderer:e.Lh,styles:e.tM,init:(0,l.K2)(s=>{s.class||(s.class={}),s.class.arrowMarkerAbsolute=s.arrowMarkerAbsolute},"init")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/95ca3cf4.101fccad.js b/pr-preview/pr-4027/assets/js/95ca3cf4.101fccad.js deleted file mode 100644 index 9bfe2b2ad..000000000 --- a/pr-preview/pr-4027/assets/js/95ca3cf4.101fccad.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[337],{27574:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Architecture","slug":"/category/architecture","permalink":"/constellation/pr-preview/pr-4027/category/architecture","sidebar":"docs","navigation":{"previous":{"title":"Troubleshooting","permalink":"/constellation/pr-preview/pr-4027/workflows/troubleshooting"},"next":{"title":"Overview","permalink":"/constellation/pr-preview/pr-4027/architecture/overview"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/960959b3.3b66f9f2.js b/pr-preview/pr-4027/assets/js/960959b3.3b66f9f2.js deleted file mode 100644 index 083e2d877..000000000 --- a/pr-preview/pr-4027/assets/js/960959b3.3b66f9f2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[84],{28453:(e,n,r)=>{r.d(n,{R:()=>a,x:()=>i});var s=r(96540);const t={},o=s.createContext(t);function a(e){const n=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),s.createElement(o.Provider,{value:n},e.children)}},97039:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"workflows/upgrade","title":"Upgrade your cluster","description":"Constellation provides an easy way to upgrade all components of your cluster, without disrupting its availability.","source":"@site/docs/workflows/upgrade.md","sourceDirName":"workflows","slug":"/workflows/upgrade","permalink":"/constellation/pr-preview/pr-4027/next/workflows/upgrade","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/workflows/upgrade.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Scale your cluster","permalink":"/constellation/pr-preview/pr-4027/next/workflows/scale"},"next":{"title":"Expose a service","permalink":"/constellation/pr-preview/pr-4027/next/workflows/lb"}}');var t=r(74848),o=r(28453);const a={},i="Upgrade your cluster",l={},c=[{value:"Update the CLI",id:"update-the-cli",level:2},{value:"Migrate the configuration",id:"migrate-the-configuration",level:2},{value:"Check for upgrades",id:"check-for-upgrades",level:2},{value:"Apply the upgrade",id:"apply-the-upgrade",level:2},{value:"Check the status",id:"check-the-status",level:2},{value:"Apply further upgrades",id:"apply-further-upgrades",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"upgrade-your-cluster",children:"Upgrade your cluster"})}),"\n",(0,t.jsxs)(n.p,{children:["Constellation provides an easy way to upgrade all components of your cluster, without disrupting its availability.\nSpecifically, you can upgrade the Kubernetes version, the nodes' image, and the Constellation microservices.\nYou configure the desired versions in your local Constellation configuration and trigger upgrades with the ",(0,t.jsx)(n.code,{children:"apply"})," command.\nTo learn about available versions you use the ",(0,t.jsx)(n.code,{children:"upgrade check"})," command.\nWhich versions are available depends on the CLI version you are using."]}),"\n",(0,t.jsx)(n.h2,{id:"update-the-cli",children:"Update the CLI"}),"\n",(0,t.jsx)(n.p,{children:"Each CLI comes with a set of supported microservice and Kubernetes versions.\nMost importantly, a given CLI version can only upgrade a cluster of the previous minor version, but not older ones.\nThis means that you have to upgrade your CLI and cluster one minor version at a time."}),"\n",(0,t.jsx)(n.p,{children:"For example, if you are currently on CLI version v2.6 and the latest version is v2.8, you should"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"upgrade the CLI to v2.7,"}),"\n",(0,t.jsx)(n.li,{children:"upgrade the cluster to v2.7,"}),"\n",(0,t.jsx)(n.li,{children:"and only then continue upgrading the CLI (and the cluster) to v2.8 after."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Also note that if your current Kubernetes version isn't supported by the next CLI version, use your current CLI to upgrade to a newer Kubernetes version first."}),"\n",(0,t.jsxs)(n.p,{children:["To learn which Kubernetes versions are supported by a particular CLI, run ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/reference/cli#constellation-config-kubernetes-versions",children:"constellation config kubernetes-versions"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"migrate-the-configuration",children:"Migrate the configuration"}),"\n",(0,t.jsxs)(n.p,{children:["The Constellation configuration file is located in the file ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," in your workspace.\nRefer to the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/reference/migration",children:"migration reference"})," to check if you need to update fields in your configuration file.\nUse ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/reference/cli#constellation-config-migrate",children:(0,t.jsx)(n.code,{children:"constellation config migrate"})})," to automatically update an old config file to a new format."]}),"\n",(0,t.jsx)(n.h2,{id:"check-for-upgrades",children:"Check for upgrades"}),"\n",(0,t.jsx)(n.p,{children:"To learn which versions the current CLI can upgrade to and what's installed in your cluster, run:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# Show possible upgrades\nconstellation upgrade check\n\n# Show possible upgrades and write them to config file\nconstellation upgrade check --update-config\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You can either enter the reported target versions into your config manually or run the above command with the ",(0,t.jsx)(n.code,{children:"--update-config"})," flag.\nWhen using this flag, the ",(0,t.jsx)(n.code,{children:"kubernetesVersion"}),", ",(0,t.jsx)(n.code,{children:"image"}),", ",(0,t.jsx)(n.code,{children:"microserviceVersion"}),", and ",(0,t.jsx)(n.code,{children:"attestation"})," fields are overwritten with the smallest available upgrade."]}),"\n",(0,t.jsx)(n.h2,{id:"apply-the-upgrade",children:"Apply the upgrade"}),"\n",(0,t.jsx)(n.p,{children:"Once you updated your config with the desired versions, you can trigger the upgrade with this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation apply\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Microservice upgrades will be finished within a few minutes, depending on the cluster size.\nIf you are interested, you can monitor pods restarting in the ",(0,t.jsx)(n.code,{children:"kube-system"})," namespace with your tool of choice."]}),"\n",(0,t.jsx)(n.p,{children:"Image and Kubernetes upgrades take longer.\nFor each node in your cluster, a new node has to be created and joined.\nThe process usually takes up to ten minutes per node."}),"\n",(0,t.jsxs)(n.p,{children:["When applying an upgrade, the Helm charts for the upgrade as well as backup files of Constellation-managed Custom Resource Definitions, Custom Resources, and Terraform state are created.\nYou can use the Terraform state backup to restore previous resources in case an upgrade misconfigured or erroneously deleted a resource.\nYou can use the Custom Resource (Definition) backup files to restore Custom Resources and Definitions manually (e.g., via ",(0,t.jsx)(n.code,{children:"kubectl apply"}),") if the automatic migration of those resources fails.\nYou can use the Helm charts to manually apply upgrades to the Kubernetes resources, should an upgrade fail."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["For advanced users: the upgrade consists of several phases that can be individually skipped through the ",(0,t.jsx)(n.code,{children:"--skip-phases"})," flag.\nThe phases are ",(0,t.jsx)(n.code,{children:"infrastracture"})," for the cloud resource management through Terraform, ",(0,t.jsx)(n.code,{children:"helm"})," for the chart management of the microservices, ",(0,t.jsx)(n.code,{children:"image"})," for OS image upgrades, and ",(0,t.jsx)(n.code,{children:"k8s"})," for Kubernetes version upgrades."]})}),"\n",(0,t.jsx)(n.h2,{id:"check-the-status",children:"Check the status"}),"\n",(0,t.jsxs)(n.p,{children:["Upgrades are asynchronous operations.\nAfter you run ",(0,t.jsx)(n.code,{children:"apply"}),", it will take a while until the upgrade has completed.\nTo understand if an upgrade is finished, you can run:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation status\n"})}),"\n",(0,t.jsx)(n.p,{children:"This command displays the following information:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The installed services and their versions"}),"\n",(0,t.jsx)(n.li,{children:"The image and Kubernetes version the cluster is expecting on each node"}),"\n",(0,t.jsx)(n.li,{children:"How many nodes are up to date"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here's an example output:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell-session",children:"Target versions:\n Image: v2.6.0\n Kubernetes: v1.25.8\nService versions:\n Cilium: v1.12.1\n cert-manager: v1.10.0\n constellation-operators: v2.6.0\n constellation-services: v2.6.0\nCluster status: Some node versions are out of date\n Image: 23/25\n Kubernetes: 25/25\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This output indicates that the cluster is running Kubernetes version ",(0,t.jsx)(n.code,{children:"1.25.8"}),", and all nodes have the appropriate binaries installed.\n23 out of 25 nodes have already upgraded to the targeted image version of ",(0,t.jsx)(n.code,{children:"2.6.0"}),", while two are still in progress."]}),"\n",(0,t.jsx)(n.h2,{id:"apply-further-upgrades",children:"Apply further upgrades"}),"\n",(0,t.jsxs)(n.p,{children:["After the upgrade is finished, you can run ",(0,t.jsx)(n.code,{children:"constellation upgrade check"})," again to see if there are more upgrades available. If so, repeat the process."]})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/97b147c7.309aa812.js b/pr-preview/pr-4027/assets/js/97b147c7.309aa812.js deleted file mode 100644 index d5c55eb99..000000000 --- a/pr-preview/pr-4027/assets/js/97b147c7.309aa812.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7193],{1316:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_fio_azure_iops-a85caab4031a29df58a3e7175a62b792.png"},1487:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_net_p2svc_gcp-4ae5b9b8d4317ad9d3005c4243d78367.png"},1594:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_net_p2p_azure-fbad5555553d559281f605939f5e26c8.png"},13809:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_fio_gcp_iops-ba4f26c2dd679d3d5e4ad7c7b0c8370e.png"},16796:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"overview/performance/io","title":"I/O performance benchmarks","description":"To assess the overall performance of Constellation, this benchmark evaluates Constellation v2.6.0 in terms of storage I/O using fio and network performance using the Kubernetes Network Benchmark.","source":"@site/versioned_docs/version-2.24/overview/performance/io.md","sourceDirName":"overview/performance","slug":"/overview/performance/io","permalink":"/constellation/pr-preview/pr-4027/overview/performance/io","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/overview/performance/io.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Compute benchmarks","permalink":"/constellation/pr-preview/pr-4027/overview/performance/compute"},"next":{"title":"Application benchmarks","permalink":"/constellation/pr-preview/pr-4027/overview/performance/application"}}');var i=s(74848),o=s(28453);const t={},a="I/O performance benchmarks",l={},c=[{value:"Configurations",id:"configurations",level:2},{value:"Constellation",id:"constellation",level:3},{value:"AKS",id:"aks",level:3},{value:"GKE",id:"gke",level:3},{value:"Results",id:"results",level:2},{value:"Network",id:"network",level:3},{value:"Pod-to-Pod",id:"pod-to-pod",level:4},{value:"Pod-to-Service",id:"pod-to-service",level:4},{value:"Storage I/O",id:"storage-io",level:3},{value:"Conclusion",id:"conclusion",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",mermaid:"mermaid",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"io-performance-benchmarks",children:"I/O performance benchmarks"})}),"\n",(0,i.jsxs)(n.p,{children:["To assess the overall performance of Constellation, this benchmark evaluates Constellation v2.6.0 in terms of storage I/O using ",(0,i.jsx)(n.a,{href:"https://fio.readthedocs.io/en/latest/fio_doc.html",children:(0,i.jsx)(n.code,{children:"fio"})})," and network performance using the ",(0,i.jsx)(n.a,{href:"https://github.com/InfraBuilder/k8s-bench-suite#knb--kubernetes-network-be",children:"Kubernetes Network Benchmark"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"This benchmark tested Constellation on Azure and GCP and compared the results against the managed Kubernetes offerings AKS and GKE."}),"\n",(0,i.jsx)(n.h2,{id:"configurations",children:"Configurations"}),"\n",(0,i.jsx)(n.h3,{id:"constellation",children:"Constellation"}),"\n",(0,i.jsx)(n.p,{children:"The benchmark was conducted with Constellation v2.6.0, Kubernetes v1.25.7, and Cilium v1.12.\nIt ran on the following infrastructure configurations."}),"\n",(0,i.jsx)(n.p,{children:"Constellation on Azure:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Nodes: 3 (1 Control-plane, 2 Worker)"}),"\n",(0,i.jsxs)(n.li,{children:["Machines: ",(0,i.jsx)(n.code,{children:"DC4as_v5"}),": 3rd Generation AMD EPYC 7763v (Milan) processor with 4 Cores, 16 GiB memory"]}),"\n",(0,i.jsxs)(n.li,{children:["CVM: ",(0,i.jsx)(n.code,{children:"true"})]}),"\n",(0,i.jsxs)(n.li,{children:["Region: ",(0,i.jsx)(n.code,{children:"West US"})]}),"\n",(0,i.jsxs)(n.li,{children:["Zone: ",(0,i.jsx)(n.code,{children:"2"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Constellation on GCP:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Nodes: 3 (1 Control-plane, 2 Worker)"}),"\n",(0,i.jsxs)(n.li,{children:["Machines: ",(0,i.jsx)(n.code,{children:"n2d-standard-4"}),": 2nd Generation AMD EPYC (Rome) processor with 4 Cores, 16 GiB of memory"]}),"\n",(0,i.jsxs)(n.li,{children:["CVM: ",(0,i.jsx)(n.code,{children:"true"})]}),"\n",(0,i.jsxs)(n.li,{children:["Zone: ",(0,i.jsx)(n.code,{children:"europe-west3-b"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"aks",children:"AKS"}),"\n",(0,i.jsxs)(n.p,{children:["On AKS, the benchmark used Kubernetes ",(0,i.jsx)(n.code,{children:"v1.24.9"})," and nodes with version ",(0,i.jsx)(n.code,{children:"AKSUbuntu-1804gen2containerd-2023.02.15"}),".\nAKS ran with the ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/concepts-network#kubenet-basic-networking",children:(0,i.jsx)(n.code,{children:"kubenet"})})," CNI and the ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/azure-disk-csi",children:"default CSI driver"})," for Azure Disk."]}),"\n",(0,i.jsx)(n.p,{children:"The following infrastructure configurations was used:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Nodes: 2 (2 Worker)"}),"\n",(0,i.jsxs)(n.li,{children:["Machines: ",(0,i.jsx)(n.code,{children:"D4as_v5"}),": 3rd Generation AMD EPYC 7763v (Milan) processor with 4 Cores, 16 GiB memory"]}),"\n",(0,i.jsxs)(n.li,{children:["CVM: ",(0,i.jsx)(n.code,{children:"false"})]}),"\n",(0,i.jsxs)(n.li,{children:["Region: ",(0,i.jsx)(n.code,{children:"West US"})]}),"\n",(0,i.jsxs)(n.li,{children:["Zone: ",(0,i.jsx)(n.code,{children:"2"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"gke",children:"GKE"}),"\n",(0,i.jsxs)(n.p,{children:["On GKE, the benchmark used Kubernetes ",(0,i.jsx)(n.code,{children:"v1.24.9"})," and nodes with version ",(0,i.jsx)(n.code,{children:"1.24.9-gke.3200"}),".\nGKE ran with the ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/kubernetes-engine/docs/concepts/network-overview",children:(0,i.jsx)(n.code,{children:"kubenet"})})," CNI and the ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/gce-pd-csi-driver",children:"default CSI driver"})," for Compute Engine persistent disk."]}),"\n",(0,i.jsx)(n.p,{children:"The following infrastructure configurations was used:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Nodes: 2 (2 Worker)"}),"\n",(0,i.jsxs)(n.li,{children:["Machines: ",(0,i.jsx)(n.code,{children:"n2d-standard-4"})," 2nd Generation AMD EPYC (Rome) processor with 4 Cores, 16 GiB of memory"]}),"\n",(0,i.jsxs)(n.li,{children:["CVM: ",(0,i.jsx)(n.code,{children:"false"})]}),"\n",(0,i.jsxs)(n.li,{children:["Zone: ",(0,i.jsx)(n.code,{children:"europe-west3-b"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"results",children:"Results"}),"\n",(0,i.jsx)(n.h3,{id:"network",children:"Network"}),"\n",(0,i.jsxs)(n.p,{children:["This section gives a thorough analysis of the network performance of Constellation, specifically focusing on measuring TCP and UDP bandwidth.\nThe benchmark measured the bandwidth of pod-to-pod and pod-to-service connections between two different nodes using ",(0,i.jsx)(n.a,{href:"https://iperf.fr/",children:(0,i.jsx)(n.code,{children:"iperf"})}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["GKE and Constellation on GCP had a maximum network bandwidth of ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/general-purpose-machines#n2d_machines",children:"10 Gbps"}),".\nAKS with ",(0,i.jsx)(n.code,{children:"Standard_D4as_v5"})," machines a maximum network bandwidth of ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/dasv5-dadsv5-series#dasv5-series",children:"12.5 Gbps"}),".\nThe Confidential VM equivalent ",(0,i.jsx)(n.code,{children:"Standard_DC4as_v5"})," currently has a network bandwidth of ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/dcasv5-dcadsv5-series#dcasv5-series-products",children:"1.25 Gbps"}),".\nTherefore, to make the test comparable, both AKS and Constellation on Azure were running with ",(0,i.jsx)(n.code,{children:"Standard_DC4as_v5"})," machines and 1.25 Gbps bandwidth."]}),"\n",(0,i.jsx)(n.p,{children:"Constellation on Azure and AKS used an MTU of 1500.\nConstellation on GCP used an MTU of 8896. GKE used an MTU of 1450."}),"\n",(0,i.jsx)(n.p,{children:"The difference in network bandwidth can largely be attributed to two factors."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Constellation's ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/networking",children:"network encryption"})," via Cilium and WireGuard, which protects data in-transit."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"https://lore.kernel.org/all/20200204193500.GA15564@ashkalra_ubuntu_server/T/",children:"AMD SEV using SWIOTLB bounce buffers"})," for all DMA including network I/O."]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"pod-to-pod",children:"Pod-to-Pod"}),"\n",(0,i.jsx)(n.p,{children:"In this scenario, the client Pod connects directly to the server pod via its IP address."}),"\n",(0,i.jsx)(n.mermaid,{value:"flowchart LR\n subgraph Node A\n Client[Client]\n end\n subgraph Node B\n Server[Server]\n end\n Client ==>|traffic| Server"}),"\n",(0,i.jsx)(n.p,{children:'The results for "Pod-to-Pod" on Azure are as follows:'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Network Pod2Pod Azure benchmark graph",src:s(1594).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:'The results for "Pod-to-Pod" on GCP are as follows:'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Network Pod2Pod GCP benchmark graph",src:s(44477).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.h4,{id:"pod-to-service",children:"Pod-to-Service"}),"\n",(0,i.jsx)(n.p,{children:"In this scenario, the client Pod connects to the server Pod via a ClusterIP service. This is more relevant to real-world use cases."}),"\n",(0,i.jsx)(n.mermaid,{value:"flowchart LR\n subgraph Node A\n Client[Client] ==>|traffic| Service[Service]\n end\n subgraph Node B\n Server[Server]\n end\n Service ==>|traffic| Server"}),"\n",(0,i.jsx)(n.p,{children:'The results for "Pod-to-Pod" on Azure are as follows:'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Network Pod2SVC Azure benchmark graph",src:s(25788).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:'The results for "Pod-to-Pod" on GCP are as follows:'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Network Pod2SVC GCP benchmark graph",src:s(1487).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"In our recent comparison of Constellation on GCP with GKE, Constellation has 58% less TCP bandwidth. However, UDP bandwidth was slightly better with Constellation, thanks to its higher MTU."}),"\n",(0,i.jsx)(n.p,{children:"Similarly, when comparing Constellation on Azure with AKS using CVMs, Constellation achieved approximately 10% less TCP and 40% less UDP bandwidth."}),"\n",(0,i.jsx)(n.h3,{id:"storage-io",children:"Storage I/O"}),"\n",(0,i.jsxs)(n.p,{children:["Azure and GCP offer persistent storage for their Kubernetes services AKS and GKE via the Container Storage Interface (CSI). CSI storage in Kubernetes is available via ",(0,i.jsx)(n.code,{children:"PersistentVolumes"})," (PV) and consumed via ",(0,i.jsx)(n.code,{children:"PersistentVolumeClaims"})," (PVC).\nUpon requesting persistent storage through a PVC, GKE and AKS will provision a PV as defined by a default ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/storage/storage-classes/",children:"storage class"}),".\nConstellation provides persistent storage on Azure and GCP ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/encrypted-storage",children:"that's encrypted on the CSI layer"}),".\nSimilarly, upon a PVC request, Constellation will provision a PV via a default storage class."]}),"\n",(0,i.jsxs)(n.p,{children:["For Constellation on Azure and AKS, the benchmark ran with Azure Disk storage ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/disks-types#standard-ssds",children:"Standard SSD"})," of 400 GiB size.\nThe ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/dasv5-dadsv5-series#dasv5-series",children:"DC4as machine type"})," with four cores provides the following maximum performance:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"6400 (20000 burst) IOPS"}),"\n",(0,i.jsx)(n.li,{children:"144 MB/s (600 MB/s burst) throughput"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["However, the performance is bound by the capabilities of the ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/disks-types#standard-ssds",children:"512 GiB Standard SSD size"})," (the size class of 400 GiB volumes):"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"500 (600 burst) IOPS"}),"\n",(0,i.jsx)(n.li,{children:"60 MB/s (150 MB/s burst) throughput"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["For Constellation on GCP and GKE, the benchmark ran with Compute Engine Persistent Disk Storage ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/disks",children:"pd-balanced"})," of 400 GiB size.\nThe N2D machine type with four cores and pd-balanced provides the following ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/disks/performance#n2d_vms",children:"maximum performance"}),":"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"3,000 read IOPS"}),"\n",(0,i.jsx)(n.li,{children:"15,000 write IOPS"}),"\n",(0,i.jsx)(n.li,{children:"240 MB/s read throughput"}),"\n",(0,i.jsx)(n.li,{children:"240 MB/s write throughput"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["However, the performance is bound by the capabilities of a ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/disks/performance#zonal-persistent-disks",children:(0,i.jsx)(n.code,{children:"Zonal balanced PD"})})," with 400 GiB size:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"2400 read IOPS"}),"\n",(0,i.jsx)(n.li,{children:"2400 write IOPS"}),"\n",(0,i.jsx)(n.li,{children:"112 MB/s read throughput"}),"\n",(0,i.jsx)(n.li,{children:"112 MB/s write throughput"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"https://fio.readthedocs.io/en/latest/fio_doc.html",children:(0,i.jsx)(n.code,{children:"fio"})})," benchmark consists of several tests.\nThe benchmark used ",(0,i.jsx)(n.a,{href:"https://github.com/kastenhq/kubestr",children:(0,i.jsx)(n.code,{children:"Kubestr"})})," to run ",(0,i.jsx)(n.code,{children:"fio"})," in Kubernetes.\nThe default test performs randomized access patterns that accurately depict worst-case I/O scenarios for most applications."]}),"\n",(0,i.jsxs)(n.p,{children:["The following ",(0,i.jsx)(n.code,{children:"fio"})," settings were used:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"No Cloud caching"}),"\n",(0,i.jsx)(n.li,{children:"No OS caching"}),"\n",(0,i.jsx)(n.li,{children:"Single CPU"}),"\n",(0,i.jsx)(n.li,{children:"60 seconds runtime"}),"\n",(0,i.jsx)(n.li,{children:"10 seconds ramp-up time"}),"\n",(0,i.jsx)(n.li,{children:"10 GiB file"}),"\n",(0,i.jsx)(n.li,{children:"IOPS: 4 KB blocks and 128 iodepth"}),"\n",(0,i.jsx)(n.li,{children:"Bandwidth: 1024 KB blocks and 128 iodepth"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["For more details, see the ",(0,i.jsxs)(n.a,{href:"https://github.com/edgelesssys/constellation/blob/main/.github/actions/e2e_benchmark/fio.ini",children:[(0,i.jsx)(n.code,{children:"fio"})," test configuration"]}),"."]}),"\n",(0,i.jsx)(n.p,{children:"The results for IOPS on Azure are as follows:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"I/O IOPS Azure benchmark graph",src:s(1316).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"The results for IOPS on GCP are as follows:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"I/O IOPS GCP benchmark graph",src:s(13809).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"The results for bandwidth on Azure are as follows:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"I/O bandwidth Azure benchmark graph",src:s(78842).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"The results for bandwidth on GCP are as follows:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"I/O bandwidth GCP benchmark graph",src:s(89479).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"On GCP, the results exceed the maximum performance guarantees of the chosen disk type. There are two possible explanations for this. The first is that there may be cloud caching in place that isn't configurable. Alternatively, the underlying provisioned disk size may be larger than what was requested, resulting in higher performance boundaries."}),"\n",(0,i.jsx)(n.p,{children:"When comparing Constellation on GCP with GKE, Constellation has similar bandwidth but about 10% less IOPS performance. On Azure, Constellation has similar IOPS performance compared to AKS, where both likely hit the maximum storage performance. However, Constellation has approximately 15% less read and write bandwidth."}),"\n",(0,i.jsx)(n.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,i.jsxs)(n.p,{children:["Despite the added ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/overview/security-benefits",children:"security benefits"})," that Constellation provides, it only incurs a slight performance overhead when compared to managed Kubernetes offerings such as AKS and GKE. In most compute benchmarks, Constellation is on par with it's alternatives.\nWhile it may be slightly slower in certain I/O scenarios due to network and storage encryption, there is ongoing work to reduce this overhead to single digits."]}),"\n",(0,i.jsxs)(n.p,{children:["For instance, storage encryption only adds between 10% to 15% overhead in terms of bandwidth and IOPS.\nMeanwhile, the biggest performance impact that Constellation currently faces is network encryption, which can incur up to 58% overhead on a 10 Gbps network.\nHowever, the Cilium team has conducted ",(0,i.jsx)(n.a,{href:"https://docs.cilium.io/en/latest/operations/performance/benchmark/#encryption-wireguard-ipsec",children:"benchmarks with Cilium using WireGuard encryption"})," on a 100 Gbps network that yielded over 15 Gbps.\nWe're confident that Constellation will provide a similar level of performance with an upcoming release."]}),"\n",(0,i.jsx)(n.p,{children:"Overall, Constellation strikes a great balance between security and performance, and we're continuously working to improve its performance capabilities while maintaining its high level of security."})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},25788:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_net_p2svc_azure-823916c53e426752564179c0f7147266.png"},28453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>a});var r=s(96540);const i={},o=r.createContext(i);function t(e){const n=r.useContext(o);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),r.createElement(o.Provider,{value:n},e.children)}},44477:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_net_p2p_gcp-8ce759468868272c67b53f5db2a3cf88.png"},78842:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_fio_azure_bw-9294313529fb8cc2c0230b3b581faddb.png"},89479:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_fio_gcp_bw-f8739bb79b0e47f896217bcacba14cdf.png"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/989930da.0bf1c4b6.js b/pr-preview/pr-4027/assets/js/989930da.0bf1c4b6.js deleted file mode 100644 index 0a0ad3147..000000000 --- a/pr-preview/pr-4027/assets/js/989930da.0bf1c4b6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2190],{41287:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Reference","slug":"/category/reference","permalink":"/constellation/pr-preview/pr-4027/2.22/category/reference","sidebar":"docs","navigation":{"previous":{"title":"Observability","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/observability"},"next":{"title":"CLI","permalink":"/constellation/pr-preview/pr-4027/2.22/reference/cli"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/9afa113a.a30bc4f8.js b/pr-preview/pr-4027/assets/js/9afa113a.a30bc4f8.js deleted file mode 100644 index 96dfccf3d..000000000 --- a/pr-preview/pr-4027/assets/js/9afa113a.a30bc4f8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8996],{87171:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Architecture","slug":"/category/architecture","permalink":"/constellation/pr-preview/pr-4027/next/category/architecture","sidebar":"docs","navigation":{"previous":{"title":"Troubleshooting","permalink":"/constellation/pr-preview/pr-4027/next/workflows/troubleshooting"},"next":{"title":"Overview","permalink":"/constellation/pr-preview/pr-4027/next/architecture/overview"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/9b22caeb.35fb7596.js b/pr-preview/pr-4027/assets/js/9b22caeb.35fb7596.js deleted file mode 100644 index 763e33844..000000000 --- a/pr-preview/pr-4027/assets/js/9b22caeb.35fb7596.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4071],{3259:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>c,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"reference/slsa","title":"Supply chain levels for software artifacts (SLSA) adoption","description":"Supply chain Levels for Software Artifacts, or SLSA (salsa) is a framework for improving and grading a project\'s build system and engineering processes. SLSA focuses on security improvements for source code storage as well as build system definition, execution, and observation. SLSA is structured in four levels. This page describes the adoption of SLSA for Constellation.","source":"@site/docs/reference/slsa.md","sourceDirName":"reference","slug":"/reference/slsa","permalink":"/constellation/pr-preview/pr-4027/next/reference/slsa","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/reference/slsa.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Terraform usage","permalink":"/constellation/pr-preview/pr-4027/next/reference/terraform"}}');var t=r(74848),i=r(28453);const o={},a="Supply chain levels for software artifacts (SLSA) adoption",l={},d=[{value:"Level 1 - Adopted",id:"level-1---adopted",level:2},{value:"Level 2 - Adopted",id:"level-2---adopted",level:2},{value:"Level 3 - Adopted",id:"level-3---adopted",level:2},{value:"Level 4 - In Progress",id:"level-4---in-progress",level:2}];function h(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"supply-chain-levels-for-software-artifacts-slsa-adoption",children:"Supply chain levels for software artifacts (SLSA) adoption"})}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"https://slsa.dev/",children:"Supply chain Levels for Software Artifacts, or SLSA (salsa)"})," is a framework for improving and grading a project's build system and engineering processes. SLSA focuses on security improvements for source code storage as well as build system definition, execution, and observation. SLSA is structured in ",(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/levels",children:"four levels"}),". This page describes the adoption of SLSA for Constellation."]}),"\n",(0,t.jsx)(s.admonition,{type:"info",children:(0,t.jsx)(s.p,{children:"SLSA is still in alpha status. The presented levels and their requirements might change in the future. We will adopt any changes into our engineering processes, as they get defined."})}),"\n",(0,t.jsx)(s.h2,{id:"level-1---adopted",children:"Level 1 - Adopted"}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#scripted-build",children:"Build - Scripted"})})}),"\n",(0,t.jsxs)(s.p,{children:["All build steps are automated via ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/tree/main/bazel/ci",children:"Bazel"})," and ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/tree/main/.github",children:"GitHub Actions"}),"."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#available",children:"Provenance - Available"})})}),"\n",(0,t.jsxs)(s.p,{children:["Provenance for the CLI is generated using the ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator",children:"slsa-github-generator"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"level-2---adopted",children:"Level 2 - Adopted"}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#version-controlled",children:"Source - Version Controlled"})})}),"\n",(0,t.jsx)(s.p,{children:"Constellation is hosted on GitHub using git."}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#build-service",children:"Build - Build Service"})})}),"\n",(0,t.jsxs)(s.p,{children:["All builds are carried out by ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/tree/main/.github",children:"GitHub Actions"}),"."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#authenticated",children:"Provenance - Authenticated"})})}),"\n",(0,t.jsxs)(s.p,{children:["Provenance for the CLI is signed using the ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator",children:"slsa-github-generator"}),". Learn ",(0,t.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/verify-cli",children:"how to verify the CLI"})," using the signed provenance, before using it for the first time."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#service-generated",children:"Provenance - Service Generated"})})}),"\n",(0,t.jsxs)(s.p,{children:["Provenance for the CLI is generated using the ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator",children:"slsa-github-generator"})," in GitHub Actions."]}),"\n",(0,t.jsx)(s.h2,{id:"level-3---adopted",children:"Level 3 - Adopted"}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#verified-history",children:"Source - Verified History"})})}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys",children:"Edgeless Systems"})," GitHub organization ",(0,t.jsx)(s.a,{href:"https://docs.github.com/en/organizations/keeping-your-organization-secure/managing-two-factor-authentication-for-your-organization/requiring-two-factor-authentication-in-your-organization",children:"requires two-factor authentication"})," for all members."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#retained-indefinitely",children:"Source - Retained Indefinitely"})})}),"\n",(0,t.jsxs)(s.p,{children:["Since we use GitHub to host the repository, an external person can't modify or delete the history. Before a pull request can be merged, an explicit approval from an ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys",children:"Edgeless Systems"})," team member is required."]}),"\n",(0,t.jsxs)(s.p,{children:["The same holds true for changes proposed by team members. Each change to ",(0,t.jsx)(s.code,{children:"main"})," needs to be proposed via a pull request and requires at least one approval."]}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys",children:"Edgeless Systems"})," GitHub organization admins control these settings and are able to make changes to the repository's history should legal requirements necessitate it. These changes require two-party approval following the obliterate policy."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#build-as-code",children:"Build - Build as Code"})})}),"\n",(0,t.jsxs)(s.p,{children:["All build files for Constellation are stored in ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/tree/main/.github",children:"the same repository"}),"."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#ephemeral-environment",children:"Build - Ephemeral Environment"})})}),"\n",(0,t.jsxs)(s.p,{children:["All GitHub Action workflows are executed on ",(0,t.jsx)(s.a,{href:"https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners",children:"GitHub-hosted runners"}),". These runners are only available during workflow."]}),"\n",(0,t.jsxs)(s.p,{children:["We currently don't use ",(0,t.jsx)(s.a,{href:"https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners",children:"self-hosted runners"}),"."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#isolated",children:"Build - Isolated"})})}),"\n",(0,t.jsx)(s.p,{children:"As outlined in the previous section, we use GitHub-hosted runners, which provide a new, isolated and ephemeral environment for each build."}),"\n",(0,t.jsxs)(s.p,{children:["Additionally, the ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator#generation-of-provenance",children:"SLSA GitHub generator"})," itself is run in an isolated workflow with the artifact hash as defined inputs."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#non-falsifiable",children:"Provenance - Non-falsifiable"})})}),"\n",(0,t.jsxs)(s.p,{children:["As outlined by ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator",children:"SLSA GitHub generator"})," it already fulfills the non-falsifiable requirements for SLSA Level 3. The generated provenance is signed using ",(0,t.jsx)(s.a,{href:"https://sigstore.dev/",children:"sigstore"})," with an OIDC based proof of identity."]}),"\n",(0,t.jsx)(s.h2,{id:"level-4---in-progress",children:"Level 4 - In Progress"}),"\n",(0,t.jsx)(s.p,{children:"We strive to adopt certain aspect of SLSA Level 4 that support our engineering process. At the same time, SLSA is still in alpha status and the biggest changes to SLSA are expected to be around Level 4."})]})}function c(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>o,x:()=>a});var n=r(96540);const t={},i=n.createContext(t);function o(e){const s=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),n.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/9ba5d544.2ed729cc.js b/pr-preview/pr-4027/assets/js/9ba5d544.2ed729cc.js deleted file mode 100644 index a96aa0768..000000000 --- a/pr-preview/pr-4027/assets/js/9ba5d544.2ed729cc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1789],{89673:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Architecture","slug":"/category/architecture","permalink":"/constellation/pr-preview/pr-4027/2.22/category/architecture","sidebar":"docs","navigation":{"previous":{"title":"Troubleshooting","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting"},"next":{"title":"Overview","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/overview"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/9bccdd10.e2550a45.js b/pr-preview/pr-4027/assets/js/9bccdd10.e2550a45.js deleted file mode 100644 index 61c69b827..000000000 --- a/pr-preview/pr-4027/assets/js/9bccdd10.e2550a45.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6067],{28453:(e,s,i)=>{i.d(s,{R:()=>o,x:()=>l});var n=i(96540);const r={},t=n.createContext(r);function o(e){const s=n.useContext(t);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(t.Provider,{value:s},e.children)}},58263:(e,s,i)=>{i.r(s),i.d(s,{assets:()=>d,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"workflows/reproducible-builds","title":"Reproduce released artifacts","description":"Constellation has first-class support for reproducible builds.","source":"@site/versioned_docs/version-2.24/workflows/reproducible-builds.md","sourceDirName":"workflows","slug":"/workflows/reproducible-builds","permalink":"/constellation/pr-preview/pr-4027/workflows/reproducible-builds","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/workflows/reproducible-builds.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Consume SBOMs","permalink":"/constellation/pr-preview/pr-4027/workflows/sbom"},"next":{"title":"Troubleshooting","permalink":"/constellation/pr-preview/pr-4027/workflows/troubleshooting"}}');var r=i(74848),t=i(28453);const o={},l="Reproduce released artifacts",d={},c=[{value:"Build environment prerequisites",id:"build-environment-prerequisites",level:2},{value:"Run the build",id:"run-the-build",level:2},{value:"Feedback",id:"feedback",level:2}];function a(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"reproduce-released-artifacts",children:"Reproduce released artifacts"})}),"\n",(0,r.jsxs)(s.p,{children:["Constellation has first-class support for ",(0,r.jsx)(s.a,{href:"https://reproducible-builds.org",children:"reproducible builds"}),".\nReproducing the released artifacts is an alternative to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/workflows/verify-cli",children:"signature verification"})," that doesn't require trusting Edgeless Systems' release process.\nThe following sections describe how to rebuild an artifact and how Constellation ensures that the rebuild reproduces the artifacts bit-by-bit."]}),"\n",(0,r.jsx)(s.h2,{id:"build-environment-prerequisites",children:"Build environment prerequisites"}),"\n",(0,r.jsxs)(s.p,{children:["The build systems used by Constellation - ",(0,r.jsx)(s.a,{href:"https://bazel.build/",children:"Bazel"})," and ",(0,r.jsx)(s.a,{href:"https://nixos.org",children:"Nix"})," - are designed for deterministic, reproducible builds.\nThese two dependencies should be the only prerequisites for a successful build.\nHowever, it can't be ruled out completely that peculiarities of the host affect the build result.\nThus, we recommend the following host setup for best results:"]}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsx)(s.li,{children:"A Linux operating system not older than v5.4."}),"\n",(0,r.jsxs)(s.li,{children:["The GNU C library not older than v2.31 (avoid ",(0,r.jsx)(s.code,{children:"musl"}),")."]}),"\n",(0,r.jsxs)(s.li,{children:["GNU ",(0,r.jsx)(s.code,{children:"coreutils"})," not older than v8.30 (avoid ",(0,r.jsx)(s.code,{children:"busybox"}),")."]}),"\n",(0,r.jsxs)(s.li,{children:["An ",(0,r.jsx)(s.code,{children:"ext4"})," filesystem for building."]}),"\n",(0,r.jsx)(s.li,{children:"AppArmor turned off."}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"This is given, for example, on an Ubuntu 22.04 system, which is also used for reproducibility tests."}),"\n",(0,r.jsx)(s.admonition,{type:"note",children:(0,r.jsx)(s.p,{children:"To avoid any backwards-compatibility issues, the host software versions should also not be much newer than the Constellation release."})}),"\n",(0,r.jsx)(s.h2,{id:"run-the-build",children:"Run the build"}),"\n",(0,r.jsxs)(s.p,{children:["The following instructions outline qualitatively how to reproduce a build.\nConstellation implements these instructions in the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/actions/workflows/reproducible-builds.yml",children:"Reproducible Builds workflow"}),", which continuously tests for reproducibility.\nThe workflow is a good place to look up specific version numbers and build steps."]}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Check out the Constellation repository at the tag corresponding to the release."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"git clone https://github.com/edgelesssys/constellation.git\ncd constellation\ngit checkout v2.20.0\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"https://bazel.build/install",children:"Install the Bazel release"})," specified in ",(0,r.jsx)(s.code,{children:".bazelversion"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"https://nixos.org/download/",children:"Install Nix"})," (any recent version should do)."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["Run the build with ",(0,r.jsx)(s.code,{children:"bazel build $target"})," for one of the following targets of interest:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-data",children:"//cli:cli_enterprise_darwin_amd64\n//cli:cli_enterprise_darwin_arm64\n//cli:cli_enterprise_linux_amd64\n//cli:cli_enterprise_linux_arm64\n//cli:cli_enterprise_windows_amd64\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Compare the build result with the downloaded release artifact."}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"feedback",children:"Feedback"}),"\n",(0,r.jsxs)(s.p,{children:["Reproduction failures often indicate a bug in the build system or in the build definitions.\nTherefore, we're interested in any reproducibility issues you might encounter.\n",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/issues/new/choose",children:"Start a bug report"})," and describe the details of your build environment.\nMake sure to include your result binary or a ",(0,r.jsx)(s.a,{href:"https://diffoscope.org/",children:(0,r.jsx)(s.code,{children:"diffoscope"})})," report, if possible."]})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/9be9ef65.a4121f91.js b/pr-preview/pr-4027/assets/js/9be9ef65.a4121f91.js deleted file mode 100644 index 27ba7a751..000000000 --- a/pr-preview/pr-4027/assets/js/9be9ef65.a4121f91.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1470],{2337:(e,t,o)=>{o.d(t,{A:()=>n});const n=o.p+"assets/images/example-emojivoto-55d31a6fd0c07e8e44b2b51d55dac60d.jpg"},28453:(e,t,o)=>{o.d(t,{R:()=>a,x:()=>l});var n=o(96540);const s={},i=n.createContext(s);function a(e){const t=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),n.createElement(i.Provider,{value:t},e.children)}},65305:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>r,contentTitle:()=>l,default:()=>p,frontMatter:()=>a,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"getting-started/examples/emojivoto","title":"Emojivoto","description":"Emojivoto is a simple and fun application that\'s well suited to test the basic functionality of your cluster.","source":"@site/docs/getting-started/examples/emojivoto.md","sourceDirName":"getting-started/examples","slug":"/getting-started/examples/emojivoto","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/examples/emojivoto","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/getting-started/examples/emojivoto.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Examples","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/examples"},"next":{"title":"Online Boutique","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/examples/online-boutique"}}');var s=o(74848),i=o(28453);const a={},l="Emojivoto",r={},c=[];function d(e){const t={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"emojivoto",children:"Emojivoto"})}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"Emojivoto"})," is a simple and fun application that's well suited to test the basic functionality of your cluster."]}),"\n",(0,s.jsx)("img",{src:o(2337).A,alt:"emojivoto - Web UI",width:"552"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["Deploy the application:","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["Wait until it becomes available:","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["Forward the web service to your machine:","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"kubectl -n emojivoto port-forward svc/web-svc 8080:80\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["Visit ",(0,s.jsx)(t.a,{href:"http://localhost:8080",children:"http://localhost:8080"})]}),"\n"]})]})}function p(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/9c1ba6d8.45404959.js b/pr-preview/pr-4027/assets/js/9c1ba6d8.45404959.js deleted file mode 100644 index e37908408..000000000 --- a/pr-preview/pr-4027/assets/js/9c1ba6d8.45404959.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8003],{6660:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_fio_azure_bw-9294313529fb8cc2c0230b3b581faddb.png"},8904:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_net_p2p_azure-fbad5555553d559281f605939f5e26c8.png"},24110:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_net_p2svc_azure-823916c53e426752564179c0f7147266.png"},28453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>a});var r=s(96540);const i={},o=r.createContext(i);function t(e){const n=r.useContext(o);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),r.createElement(o.Provider,{value:n},e.children)}},29662:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_fio_azure_iops-a85caab4031a29df58a3e7175a62b792.png"},50419:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_net_p2p_gcp-8ce759468868272c67b53f5db2a3cf88.png"},51257:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_fio_gcp_bw-f8739bb79b0e47f896217bcacba14cdf.png"},79275:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_fio_gcp_iops-ba4f26c2dd679d3d5e4ad7c7b0c8370e.png"},80841:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/benchmark_net_p2svc_gcp-4ae5b9b8d4317ad9d3005c4243d78367.png"},99462:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"overview/performance/io","title":"I/O performance benchmarks","description":"To assess the overall performance of Constellation, this benchmark evaluates Constellation v2.6.0 in terms of storage I/O using fio and network performance using the Kubernetes Network Benchmark.","source":"@site/docs/overview/performance/io.md","sourceDirName":"overview/performance","slug":"/overview/performance/io","permalink":"/constellation/pr-preview/pr-4027/next/overview/performance/io","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/overview/performance/io.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Compute benchmarks","permalink":"/constellation/pr-preview/pr-4027/next/overview/performance/compute"},"next":{"title":"Application benchmarks","permalink":"/constellation/pr-preview/pr-4027/next/overview/performance/application"}}');var i=s(74848),o=s(28453);const t={},a="I/O performance benchmarks",l={},c=[{value:"Configurations",id:"configurations",level:2},{value:"Constellation",id:"constellation",level:3},{value:"AKS",id:"aks",level:3},{value:"GKE",id:"gke",level:3},{value:"Results",id:"results",level:2},{value:"Network",id:"network",level:3},{value:"Pod-to-Pod",id:"pod-to-pod",level:4},{value:"Pod-to-Service",id:"pod-to-service",level:4},{value:"Storage I/O",id:"storage-io",level:3},{value:"Conclusion",id:"conclusion",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",mermaid:"mermaid",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"io-performance-benchmarks",children:"I/O performance benchmarks"})}),"\n",(0,i.jsxs)(n.p,{children:["To assess the overall performance of Constellation, this benchmark evaluates Constellation v2.6.0 in terms of storage I/O using ",(0,i.jsx)(n.a,{href:"https://fio.readthedocs.io/en/latest/fio_doc.html",children:(0,i.jsx)(n.code,{children:"fio"})})," and network performance using the ",(0,i.jsx)(n.a,{href:"https://github.com/InfraBuilder/k8s-bench-suite#knb--kubernetes-network-be",children:"Kubernetes Network Benchmark"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"This benchmark tested Constellation on Azure and GCP and compared the results against the managed Kubernetes offerings AKS and GKE."}),"\n",(0,i.jsx)(n.h2,{id:"configurations",children:"Configurations"}),"\n",(0,i.jsx)(n.h3,{id:"constellation",children:"Constellation"}),"\n",(0,i.jsx)(n.p,{children:"The benchmark was conducted with Constellation v2.6.0, Kubernetes v1.25.7, and Cilium v1.12.\nIt ran on the following infrastructure configurations."}),"\n",(0,i.jsx)(n.p,{children:"Constellation on Azure:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Nodes: 3 (1 Control-plane, 2 Worker)"}),"\n",(0,i.jsxs)(n.li,{children:["Machines: ",(0,i.jsx)(n.code,{children:"DC4as_v5"}),": 3rd Generation AMD EPYC 7763v (Milan) processor with 4 Cores, 16 GiB memory"]}),"\n",(0,i.jsxs)(n.li,{children:["CVM: ",(0,i.jsx)(n.code,{children:"true"})]}),"\n",(0,i.jsxs)(n.li,{children:["Region: ",(0,i.jsx)(n.code,{children:"West US"})]}),"\n",(0,i.jsxs)(n.li,{children:["Zone: ",(0,i.jsx)(n.code,{children:"2"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Constellation on GCP:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Nodes: 3 (1 Control-plane, 2 Worker)"}),"\n",(0,i.jsxs)(n.li,{children:["Machines: ",(0,i.jsx)(n.code,{children:"n2d-standard-4"}),": 2nd Generation AMD EPYC (Rome) processor with 4 Cores, 16 GiB of memory"]}),"\n",(0,i.jsxs)(n.li,{children:["CVM: ",(0,i.jsx)(n.code,{children:"true"})]}),"\n",(0,i.jsxs)(n.li,{children:["Zone: ",(0,i.jsx)(n.code,{children:"europe-west3-b"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"aks",children:"AKS"}),"\n",(0,i.jsxs)(n.p,{children:["On AKS, the benchmark used Kubernetes ",(0,i.jsx)(n.code,{children:"v1.24.9"})," and nodes with version ",(0,i.jsx)(n.code,{children:"AKSUbuntu-1804gen2containerd-2023.02.15"}),".\nAKS ran with the ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/concepts-network#kubenet-basic-networking",children:(0,i.jsx)(n.code,{children:"kubenet"})})," CNI and the ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/azure-disk-csi",children:"default CSI driver"})," for Azure Disk."]}),"\n",(0,i.jsx)(n.p,{children:"The following infrastructure configurations was used:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Nodes: 2 (2 Worker)"}),"\n",(0,i.jsxs)(n.li,{children:["Machines: ",(0,i.jsx)(n.code,{children:"D4as_v5"}),": 3rd Generation AMD EPYC 7763v (Milan) processor with 4 Cores, 16 GiB memory"]}),"\n",(0,i.jsxs)(n.li,{children:["CVM: ",(0,i.jsx)(n.code,{children:"false"})]}),"\n",(0,i.jsxs)(n.li,{children:["Region: ",(0,i.jsx)(n.code,{children:"West US"})]}),"\n",(0,i.jsxs)(n.li,{children:["Zone: ",(0,i.jsx)(n.code,{children:"2"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"gke",children:"GKE"}),"\n",(0,i.jsxs)(n.p,{children:["On GKE, the benchmark used Kubernetes ",(0,i.jsx)(n.code,{children:"v1.24.9"})," and nodes with version ",(0,i.jsx)(n.code,{children:"1.24.9-gke.3200"}),".\nGKE ran with the ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/kubernetes-engine/docs/concepts/network-overview",children:(0,i.jsx)(n.code,{children:"kubenet"})})," CNI and the ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/gce-pd-csi-driver",children:"default CSI driver"})," for Compute Engine persistent disk."]}),"\n",(0,i.jsx)(n.p,{children:"The following infrastructure configurations was used:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Nodes: 2 (2 Worker)"}),"\n",(0,i.jsxs)(n.li,{children:["Machines: ",(0,i.jsx)(n.code,{children:"n2d-standard-4"})," 2nd Generation AMD EPYC (Rome) processor with 4 Cores, 16 GiB of memory"]}),"\n",(0,i.jsxs)(n.li,{children:["CVM: ",(0,i.jsx)(n.code,{children:"false"})]}),"\n",(0,i.jsxs)(n.li,{children:["Zone: ",(0,i.jsx)(n.code,{children:"europe-west3-b"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"results",children:"Results"}),"\n",(0,i.jsx)(n.h3,{id:"network",children:"Network"}),"\n",(0,i.jsxs)(n.p,{children:["This section gives a thorough analysis of the network performance of Constellation, specifically focusing on measuring TCP and UDP bandwidth.\nThe benchmark measured the bandwidth of pod-to-pod and pod-to-service connections between two different nodes using ",(0,i.jsx)(n.a,{href:"https://iperf.fr/",children:(0,i.jsx)(n.code,{children:"iperf"})}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["GKE and Constellation on GCP had a maximum network bandwidth of ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/general-purpose-machines#n2d_machines",children:"10 Gbps"}),".\nAKS with ",(0,i.jsx)(n.code,{children:"Standard_D4as_v5"})," machines a maximum network bandwidth of ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/dasv5-dadsv5-series#dasv5-series",children:"12.5 Gbps"}),".\nThe Confidential VM equivalent ",(0,i.jsx)(n.code,{children:"Standard_DC4as_v5"})," currently has a network bandwidth of ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/dcasv5-dcadsv5-series#dcasv5-series-products",children:"1.25 Gbps"}),".\nTherefore, to make the test comparable, both AKS and Constellation on Azure were running with ",(0,i.jsx)(n.code,{children:"Standard_DC4as_v5"})," machines and 1.25 Gbps bandwidth."]}),"\n",(0,i.jsx)(n.p,{children:"Constellation on Azure and AKS used an MTU of 1500.\nConstellation on GCP used an MTU of 8896. GKE used an MTU of 1450."}),"\n",(0,i.jsx)(n.p,{children:"The difference in network bandwidth can largely be attributed to two factors."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Constellation's ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/networking",children:"network encryption"})," via Cilium and WireGuard, which protects data in-transit."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"https://lore.kernel.org/all/20200204193500.GA15564@ashkalra_ubuntu_server/T/",children:"AMD SEV using SWIOTLB bounce buffers"})," for all DMA including network I/O."]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"pod-to-pod",children:"Pod-to-Pod"}),"\n",(0,i.jsx)(n.p,{children:"In this scenario, the client Pod connects directly to the server pod via its IP address."}),"\n",(0,i.jsx)(n.mermaid,{value:"flowchart LR\n subgraph Node A\n Client[Client]\n end\n subgraph Node B\n Server[Server]\n end\n Client ==>|traffic| Server"}),"\n",(0,i.jsx)(n.p,{children:'The results for "Pod-to-Pod" on Azure are as follows:'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Network Pod2Pod Azure benchmark graph",src:s(8904).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:'The results for "Pod-to-Pod" on GCP are as follows:'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Network Pod2Pod GCP benchmark graph",src:s(50419).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.h4,{id:"pod-to-service",children:"Pod-to-Service"}),"\n",(0,i.jsx)(n.p,{children:"In this scenario, the client Pod connects to the server Pod via a ClusterIP service. This is more relevant to real-world use cases."}),"\n",(0,i.jsx)(n.mermaid,{value:"flowchart LR\n subgraph Node A\n Client[Client] ==>|traffic| Service[Service]\n end\n subgraph Node B\n Server[Server]\n end\n Service ==>|traffic| Server"}),"\n",(0,i.jsx)(n.p,{children:'The results for "Pod-to-Pod" on Azure are as follows:'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Network Pod2SVC Azure benchmark graph",src:s(24110).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:'The results for "Pod-to-Pod" on GCP are as follows:'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Network Pod2SVC GCP benchmark graph",src:s(80841).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"In our recent comparison of Constellation on GCP with GKE, Constellation has 58% less TCP bandwidth. However, UDP bandwidth was slightly better with Constellation, thanks to its higher MTU."}),"\n",(0,i.jsx)(n.p,{children:"Similarly, when comparing Constellation on Azure with AKS using CVMs, Constellation achieved approximately 10% less TCP and 40% less UDP bandwidth."}),"\n",(0,i.jsx)(n.h3,{id:"storage-io",children:"Storage I/O"}),"\n",(0,i.jsxs)(n.p,{children:["Azure and GCP offer persistent storage for their Kubernetes services AKS and GKE via the Container Storage Interface (CSI). CSI storage in Kubernetes is available via ",(0,i.jsx)(n.code,{children:"PersistentVolumes"})," (PV) and consumed via ",(0,i.jsx)(n.code,{children:"PersistentVolumeClaims"})," (PVC).\nUpon requesting persistent storage through a PVC, GKE and AKS will provision a PV as defined by a default ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/storage/storage-classes/",children:"storage class"}),".\nConstellation provides persistent storage on Azure and GCP ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage",children:"that's encrypted on the CSI layer"}),".\nSimilarly, upon a PVC request, Constellation will provision a PV via a default storage class."]}),"\n",(0,i.jsxs)(n.p,{children:["For Constellation on Azure and AKS, the benchmark ran with Azure Disk storage ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/disks-types#standard-ssds",children:"Standard SSD"})," of 400 GiB size.\nThe ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/dasv5-dadsv5-series#dasv5-series",children:"DC4as machine type"})," with four cores provides the following maximum performance:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"6400 (20000 burst) IOPS"}),"\n",(0,i.jsx)(n.li,{children:"144 MB/s (600 MB/s burst) throughput"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["However, the performance is bound by the capabilities of the ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/disks-types#standard-ssds",children:"512 GiB Standard SSD size"})," (the size class of 400 GiB volumes):"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"500 (600 burst) IOPS"}),"\n",(0,i.jsx)(n.li,{children:"60 MB/s (150 MB/s burst) throughput"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["For Constellation on GCP and GKE, the benchmark ran with Compute Engine Persistent Disk Storage ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/disks",children:"pd-balanced"})," of 400 GiB size.\nThe N2D machine type with four cores and pd-balanced provides the following ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/disks/performance#n2d_vms",children:"maximum performance"}),":"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"3,000 read IOPS"}),"\n",(0,i.jsx)(n.li,{children:"15,000 write IOPS"}),"\n",(0,i.jsx)(n.li,{children:"240 MB/s read throughput"}),"\n",(0,i.jsx)(n.li,{children:"240 MB/s write throughput"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["However, the performance is bound by the capabilities of a ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/disks/performance#zonal-persistent-disks",children:(0,i.jsx)(n.code,{children:"Zonal balanced PD"})})," with 400 GiB size:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"2400 read IOPS"}),"\n",(0,i.jsx)(n.li,{children:"2400 write IOPS"}),"\n",(0,i.jsx)(n.li,{children:"112 MB/s read throughput"}),"\n",(0,i.jsx)(n.li,{children:"112 MB/s write throughput"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"https://fio.readthedocs.io/en/latest/fio_doc.html",children:(0,i.jsx)(n.code,{children:"fio"})})," benchmark consists of several tests.\nThe benchmark used ",(0,i.jsx)(n.a,{href:"https://github.com/kastenhq/kubestr",children:(0,i.jsx)(n.code,{children:"Kubestr"})})," to run ",(0,i.jsx)(n.code,{children:"fio"})," in Kubernetes.\nThe default test performs randomized access patterns that accurately depict worst-case I/O scenarios for most applications."]}),"\n",(0,i.jsxs)(n.p,{children:["The following ",(0,i.jsx)(n.code,{children:"fio"})," settings were used:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"No Cloud caching"}),"\n",(0,i.jsx)(n.li,{children:"No OS caching"}),"\n",(0,i.jsx)(n.li,{children:"Single CPU"}),"\n",(0,i.jsx)(n.li,{children:"60 seconds runtime"}),"\n",(0,i.jsx)(n.li,{children:"10 seconds ramp-up time"}),"\n",(0,i.jsx)(n.li,{children:"10 GiB file"}),"\n",(0,i.jsx)(n.li,{children:"IOPS: 4 KB blocks and 128 iodepth"}),"\n",(0,i.jsx)(n.li,{children:"Bandwidth: 1024 KB blocks and 128 iodepth"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["For more details, see the ",(0,i.jsxs)(n.a,{href:"https://github.com/edgelesssys/constellation/blob/main/.github/actions/e2e_benchmark/fio.ini",children:[(0,i.jsx)(n.code,{children:"fio"})," test configuration"]}),"."]}),"\n",(0,i.jsx)(n.p,{children:"The results for IOPS on Azure are as follows:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"I/O IOPS Azure benchmark graph",src:s(29662).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"The results for IOPS on GCP are as follows:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"I/O IOPS GCP benchmark graph",src:s(79275).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"The results for bandwidth on Azure are as follows:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"I/O bandwidth Azure benchmark graph",src:s(6660).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"The results for bandwidth on GCP are as follows:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"I/O bandwidth GCP benchmark graph",src:s(51257).A+"",width:"1000",height:"500"})}),"\n",(0,i.jsx)(n.p,{children:"On GCP, the results exceed the maximum performance guarantees of the chosen disk type. There are two possible explanations for this. The first is that there may be cloud caching in place that isn't configurable. Alternatively, the underlying provisioned disk size may be larger than what was requested, resulting in higher performance boundaries."}),"\n",(0,i.jsx)(n.p,{children:"When comparing Constellation on GCP with GKE, Constellation has similar bandwidth but about 10% less IOPS performance. On Azure, Constellation has similar IOPS performance compared to AKS, where both likely hit the maximum storage performance. However, Constellation has approximately 15% less read and write bandwidth."}),"\n",(0,i.jsx)(n.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,i.jsxs)(n.p,{children:["Despite the added ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/overview/security-benefits",children:"security benefits"})," that Constellation provides, it only incurs a slight performance overhead when compared to managed Kubernetes offerings such as AKS and GKE. In most compute benchmarks, Constellation is on par with it's alternatives.\nWhile it may be slightly slower in certain I/O scenarios due to network and storage encryption, there is ongoing work to reduce this overhead to single digits."]}),"\n",(0,i.jsxs)(n.p,{children:["For instance, storage encryption only adds between 10% to 15% overhead in terms of bandwidth and IOPS.\nMeanwhile, the biggest performance impact that Constellation currently faces is network encryption, which can incur up to 58% overhead on a 10 Gbps network.\nHowever, the Cilium team has conducted ",(0,i.jsx)(n.a,{href:"https://docs.cilium.io/en/latest/operations/performance/benchmark/#encryption-wireguard-ipsec",children:"benchmarks with Cilium using WireGuard encryption"})," on a 100 Gbps network that yielded over 15 Gbps.\nWe're confident that Constellation will provide a similar level of performance with an upcoming release."]}),"\n",(0,i.jsx)(n.p,{children:"Overall, Constellation strikes a great balance between security and performance, and we're continuously working to improve its performance capabilities while maintaining its high level of security."})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/9cbfbb7f.d905e7bc.js b/pr-preview/pr-4027/assets/js/9cbfbb7f.d905e7bc.js deleted file mode 100644 index 1ea3194b0..000000000 --- a/pr-preview/pr-4027/assets/js/9cbfbb7f.d905e7bc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9308],{28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>a});var t=s(96540);const o={},i=t.createContext(o);function r(e){const n=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),t.createElement(i.Provider,{value:n},e.children)}},88528:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"workflows/troubleshooting","title":"Troubleshooting","description":"This section aids you in finding problems when working with Constellation.","source":"@site/versioned_docs/version-2.24/workflows/troubleshooting.md","sourceDirName":"workflows","slug":"/workflows/troubleshooting","permalink":"/constellation/pr-preview/pr-4027/workflows/troubleshooting","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/workflows/troubleshooting.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Reproduce release artifacts","permalink":"/constellation/pr-preview/pr-4027/workflows/reproducible-builds"},"next":{"title":"Architecture","permalink":"/constellation/pr-preview/pr-4027/category/architecture"}}');var o=s(74848),i=s(28453);const r={},a="Troubleshooting",l={},c=[{value:"Common issues",id:"common-issues",level:2},{value:"Issues with creating new clusters",id:"issues-with-creating-new-clusters",level:3},{value:"Azure: Resource Providers can't be registered",id:"azure-resource-providers-cant-be-registered",level:3},{value:"Azure: Can't update attestation policy",id:"azure-cant-update-attestation-policy",level:3},{value:"Nodes fail to join with error <code>untrusted measurement value</code>",id:"nodes-fail-to-join-with-error-untrusted-measurement-value",level:3},{value:"Upgrading Kubernetes resources fails",id:"upgrading-kubernetes-resources-fails",level:3},{value:"Diagnosing issues",id:"diagnosing-issues",level:2},{value:"Logs",id:"logs",level:3},{value:"Node shell access",id:"node-shell-access",level:3},{value:"Emergency SSH access",id:"emergency-ssh-access",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"troubleshooting",children:"Troubleshooting"})}),"\n",(0,o.jsx)(n.p,{children:"This section aids you in finding problems when working with Constellation."}),"\n",(0,o.jsx)(n.h2,{id:"common-issues",children:"Common issues"}),"\n",(0,o.jsx)(n.h3,{id:"issues-with-creating-new-clusters",children:"Issues with creating new clusters"}),"\n",(0,o.jsxs)(n.p,{children:["When you create a new cluster, you should always use the ",(0,o.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/releases/latest",children:"latest release"}),".\nIf something doesn't work, check out the ",(0,o.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"known issues"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"azure-resource-providers-cant-be-registered",children:"Azure: Resource Providers can't be registered"}),"\n",(0,o.jsxs)(n.p,{children:["On Azure, you may receive the following error when running ",(0,o.jsx)(n.code,{children:"apply"})," or ",(0,o.jsx)(n.code,{children:"terminate"})," with limited IAM permissions:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-shell-session",children:"Error: Error ensuring Resource Providers are registered.\n\nTerraform automatically attempts to register the Resource Providers it supports to\nensure it's able to provision resources.\n\nIf you don't have permission to register Resource Providers you may wish to use the\n\"skip_provider_registration\" flag in the Provider block to disable this functionality.\n\n[...]\n"})}),"\n",(0,o.jsxs)(n.p,{children:["To continue, please ensure that the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/getting-started/install#required-permissions",children:"required resource providers"})," have been registered in your subscription by your administrator."]}),"\n",(0,o.jsxs)(n.p,{children:["Afterward, set ",(0,o.jsx)(n.code,{children:"ARM_SKIP_PROVIDER_REGISTRATION=true"})," as an environment variable and either run ",(0,o.jsx)(n.code,{children:"apply"})," or ",(0,o.jsx)(n.code,{children:"terminate"})," again.\nFor example:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"ARM_SKIP_PROVIDER_REGISTRATION=true constellation apply\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Or alternatively, for ",(0,o.jsx)(n.code,{children:"terminate"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"ARM_SKIP_PROVIDER_REGISTRATION=true constellation terminate\n"})}),"\n",(0,o.jsx)(n.h3,{id:"azure-cant-update-attestation-policy",children:"Azure: Can't update attestation policy"}),"\n",(0,o.jsxs)(n.p,{children:["On Azure, you may receive the following error when running ",(0,o.jsx)(n.code,{children:"apply"})," from within an Azure environment, e.g., an Azure VM:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-shell-session",children:"An error occurred: patching policies: updating attestation policy: unexpected status code: 403 Forbidden\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The problem occurs because the Azure SDK we use internally attempts to ",(0,o.jsx)(n.a,{href:"https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#DefaultAzureCredential",children:"authenticate towards the Azure API with the managed identity of your current environment instead of the Azure CLI token"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"We decided not to deviate from this behavior and comply with the ordering of credentials."}),"\n",(0,o.jsxs)(n.p,{children:["A solution is to add the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/getting-started/install#required-permissions",children:"required permissions"})," to the managed identity of your environment. For example, the managed identity of your Azure VM, instead of the account that you've authenticated with in the Azure CLI."]}),"\n",(0,o.jsx)(n.p,{children:"If your setup requires a change in the ordering of credentials, please open an issue and explain your desired behavior."}),"\n",(0,o.jsxs)(n.h3,{id:"nodes-fail-to-join-with-error-untrusted-measurement-value",children:["Nodes fail to join with error ",(0,o.jsx)(n.code,{children:"untrusted measurement value"})]}),"\n",(0,o.jsxs)(n.p,{children:["This error indicates that a node's ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/attestation",children:"attestation statement"})," contains measurements that don't match the trusted values expected by the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#joinservice",children:"JoinService"}),".\nThis may for example happen if the cloud provider updates the VM's firmware such that it influences the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/attestation#runtime-measurements",children:"runtime measurements"})," in an unforeseen way.\nA failed upgrade due to an erroneous attestation config can also cause this error.\nYou can change the expected measurements to resolve the failure."]}),"\n",(0,o.jsx)(n.admonition,{type:"caution",children:(0,o.jsxs)(n.p,{children:["Attestation and trusted measurements are crucial for the security of your cluster.\nBe extra careful when manually changing these settings.\nWhen in doubt, check if the encountered ",(0,o.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"issue is known"})," or ",(0,o.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation#support",children:"contact support"}),"."]})}),"\n",(0,o.jsxs)(n.admonition,{type:"tip",children:[(0,o.jsxs)(n.p,{children:["During an upgrade with modified attestation config, a backup of the current configuration is stored in the ",(0,o.jsx)(n.code,{children:"join-config"})," config map in the ",(0,o.jsx)(n.code,{children:"kube-system"})," namespace under the ",(0,o.jsx)(n.code,{children:"attestationConfig_backup"})," key. To restore the old attestation config after a failed upgrade, replace the value of ",(0,o.jsx)(n.code,{children:"attestationConfig"})," with the value from ",(0,o.jsx)(n.code,{children:"attestationConfig_backup"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'kubectl patch configmaps -n kube-system join-config -p "{\\"data\\":{\\"attestationConfig\\":\\"$(kubectl get configmaps -n kube-system join-config -o "jsonpath={.data.attestationConfig_backup}")\\"}}"\n'})})]}),"\n",(0,o.jsxs)(n.p,{children:["You can use the ",(0,o.jsx)(n.code,{children:"apply"})," command to change measurements of a running cluster:"]}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["Modify the ",(0,o.jsx)(n.code,{children:"measurements"})," key in your local ",(0,o.jsx)(n.code,{children:"constellation-conf.yaml"})," to the expected values."]}),"\n",(0,o.jsxs)(n.li,{children:["Run ",(0,o.jsx)(n.code,{children:"constellation apply"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Keep in mind that running ",(0,o.jsx)(n.code,{children:"apply"})," also applies any version changes from your config to the cluster."]}),"\n",(0,o.jsx)(n.p,{children:"You can run these commands to learn about the versions currently configured in the cluster:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Kubernetes API server version: ",(0,o.jsx)(n.code,{children:"kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.kubernetesClusterVersion"})]}),"\n",(0,o.jsxs)(n.li,{children:["image version: ",(0,o.jsx)(n.code,{children:"kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.imageVersion"})]}),"\n",(0,o.jsxs)(n.li,{children:["microservices versions: ",(0,o.jsx)(n.code,{children:"helm list --filter 'constellation-services' -n kube-system"})]}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"upgrading-kubernetes-resources-fails",children:"Upgrading Kubernetes resources fails"}),"\n",(0,o.jsxs)(n.p,{children:["Constellation manages its Kubernetes resources using Helm.\nWhen applying an upgrade, the charts that are about to be installed, and a values override file ",(0,o.jsx)(n.code,{children:"overrides.yaml"}),",\nare saved to disk in your current workspace under ",(0,o.jsx)(n.code,{children:"constellation-upgrade/upgrade-<timestamp>/helm-charts/"}),".\nIf upgrading the charts using the Constellation CLI fails, you can review these charts and try to manually apply the upgrade."]}),"\n",(0,o.jsx)(n.admonition,{type:"caution",children:(0,o.jsxs)(n.p,{children:["Changing and manually applying the charts may destroy cluster resources and can lead to broken Constellation deployments.\nProceed with caution and when in doubt,\ncheck if the encountered ",(0,o.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"issue is known"})," or ",(0,o.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation#support",children:"contact support"}),"."]})}),"\n",(0,o.jsx)(n.h2,{id:"diagnosing-issues",children:"Diagnosing issues"}),"\n",(0,o.jsx)(n.h3,{id:"logs",children:"Logs"}),"\n",(0,o.jsxs)(n.p,{children:["To get started on diagnosing issues with Constellation, it's often helpful to collect logs from nodes, pods, or other resources in the cluster. Most logs are available through Kubernetes' standard\n",(0,o.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/logging/",children:"logging interfaces"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"To debug issues occurring at boot time of the nodes, you can use the serial console interface of the CSP while the machine boots to get a read-only view of the boot logs."}),"\n",(0,o.jsxs)(n.p,{children:["Apart from that, Constellation also offers further ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/architecture/observability",children:"observability integrations"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"node-shell-access",children:"Node shell access"}),"\n",(0,o.jsxs)(n.p,{children:["Debugging via a shell on a node is ",(0,o.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/debug/debug-application/debug-running-pod/#node-shell-session",children:"directly supported by Kubernetes"}),"."]}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Figure out which node to connect to:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"kubectl get nodes\n# or to see more information, such as IPs:\nkubectl get nodes -o wide\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Connect to the node:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"kubectl debug node/constell-worker-xksa0-000000 -it --image=busybox\n"})}),"\n",(0,o.jsx)(n.p,{children:"You will be presented with a prompt."}),"\n",(0,o.jsxs)(n.p,{children:["The nodes file system is mounted at ",(0,o.jsx)(n.code,{children:"/host"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Once finished, clean up the debug pod:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"kubectl delete pod node-debugger-constell-worker-xksa0-000000-bjthj\n"})}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"emergency-ssh-access",children:"Emergency SSH access"}),"\n",(0,o.jsx)(n.p,{children:"Emergency SSH access to nodes can be useful to diagnose issues or download important data even if the Kubernetes API isn't reachable anymore."}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Enter the ",(0,o.jsx)(n.code,{children:"constellation-terraform"})," directory in your Constellation workspace and enable emergency SSH access to the cluster:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:' cd constellation-terraform\n echo "emergency_ssh = true" >> ./terraform.tfvars\n terraform apply\n'})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Sign an existing SSH key with your master secret:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"cd ../ # go back to your Constellation workspace\nconstellation ssh --key your_public_key.pub\n"})}),"\n",(0,o.jsxs)(n.p,{children:["A certificate is written to ",(0,o.jsx)(n.code,{children:"constellation_cert.pub"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["The certificate is valid for 24 hours and enables you to access your Constellation nodes using\n",(0,o.jsx)(n.a,{href:"https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Certificate-based_Authentication",children:"certificate based authentication"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Now you can connect to any Constellation node using your certificate and your private key."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"ssh -o CertificateFile=constellation_cert.pub -o UserKnownHostsFile=./known_hosts -i <your private key> root@<ip of constellation node>\n"})}),"\n",(0,o.jsx)(n.p,{children:"Normally, you don't have access to the Constellation nodes since they reside in a private network.\nTo access those nodes anyways, you can use your Constellation load balancer as a proxy jump host.\nFor this, use something along the following SSH client configuration:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-text",children:"Host <LB public IP>\n ProxyJump none\n\nHost *\n IdentityFile <your private key>\n PreferredAuthentications publickey\n CertificateFile=constellation_cert.pub\n UserKnownHostsFile=./known_hosts\n User root\n ProxyJump <LB public IP>\n"})}),"\n",(0,o.jsxs)(n.p,{children:["With this configuration you can connect to a Constellation node using ",(0,o.jsx)(n.code,{children:"ssh -F <this config> <private node IP>"}),".\nYou can obtain the private node IP and the public IP of the load balancer using your CSP's web UI. Note that if\nyou use the load balancers domain name, ssh host certificate verification doesn't work, so using the public IP is recommended."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/9d4f835b.c5fd6606.js b/pr-preview/pr-4027/assets/js/9d4f835b.c5fd6606.js deleted file mode 100644 index e85cceca2..000000000 --- a/pr-preview/pr-4027/assets/js/9d4f835b.c5fd6606.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4672],{28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var r=n(96540);const i={},s=r.createContext(i);function o(e){const t=r.useContext(s);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(s.Provider,{value:t},e.children)}},59678:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"overview/confidential-kubernetes","title":"Confidential Kubernetes","description":"We use the term Confidential Kubernetes to refer to the concept of using confidential-computing technology to shield entire Kubernetes clusters from the infrastructure. The three defining properties of this concept are:","source":"@site/versioned_docs/version-2.23/overview/confidential-kubernetes.md","sourceDirName":"overview","slug":"/overview/confidential-kubernetes","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/confidential-kubernetes","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/overview/confidential-kubernetes.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Basics","permalink":"/constellation/pr-preview/pr-4027/2.23/category/basics"},"next":{"title":"Security benefits","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/security-benefits"}}');var i=n(74848),s=n(28453);const o={},a="Confidential Kubernetes",l={},c=[{value:"Constellation security features",id:"constellation-security-features",level:2},{value:"Comparison: Managed Kubernetes with CVMs",id:"comparison-managed-kubernetes-with-cvms",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"confidential-kubernetes",children:"Confidential Kubernetes"})}),"\n",(0,i.jsxs)(t.p,{children:["We use the term ",(0,i.jsx)(t.em,{children:"Confidential Kubernetes"})," to refer to the concept of using confidential-computing technology to shield entire Kubernetes clusters from the infrastructure. The three defining properties of this concept are:"]}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Workload shielding"}),": the confidentiality and integrity of all workload-related data and code are enforced."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Control plane shielding"}),": the confidentiality and integrity of the cluster's control plane, state, and workload configuration are enforced."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Attestation and verifiability"}),": the two properties above can be verified remotely based on hardware-rooted cryptographic certificates."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Each of the above properties is equally important. Only with all three in conjunction, an entire cluster can be shielded without gaps."}),"\n",(0,i.jsx)(t.h2,{id:"constellation-security-features",children:"Constellation security features"}),"\n",(0,i.jsx)(t.p,{children:"Constellation implements the Confidential Kubernetes concept with the following security features."}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Runtime encryption"}),": Constellation runs all Kubernetes nodes inside Confidential VMs (CVMs). This gives runtime encryption for the entire cluster."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Network and storage encryption"}),": Constellation augments this with transparent encryption of the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/networking",children:"network"}),", ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage",children:"persistent storage"}),", and other managed storage like ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage#encrypted-s3-object-storage",children:"AWS S3"}),". Thus, workloads and control plane are truly end-to-end encrypted: at rest, in transit, and at runtime."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Transparent key management"}),": Constellation manages the corresponding ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys",children:"cryptographic keys"})," inside CVMs."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Node attestation and verification"}),": Constellation verifies the integrity of each new CVM-based node using ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation",children:"remote attestation"}),'. Only "good" nodes receive the cryptographic keys required to access the network and storage of a cluster.']}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Confidential computing-optimized images"}),': A node is "good" if it\'s running a signed Constellation ',(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/images",children:"node image"})," inside a CVM and is in the expected state. (Node images are hardware-measured during boot. The measurements are reflected in the attestation statements that are produced by nodes and verified by Constellation.)"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:'"Whole cluster" attestation'}),": Towards the DevOps engineer, Constellation provides a single hardware-rooted certificate from which all of the above can be verified."]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["With the above, Constellation wraps an entire cluster into one coherent and verifiable ",(0,i.jsx)(t.em,{children:"confidential context"}),". The concept is depicted in the following."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Confidential Kubernetes",src:n(91988).A+"",width:"3767",height:"1902"})}),"\n",(0,i.jsx)(t.h2,{id:"comparison-managed-kubernetes-with-cvms",children:"Comparison: Managed Kubernetes with CVMs"}),"\n",(0,i.jsxs)(t.p,{children:["In comparison, managed Kubernetes with CVMs, as it's for example offered in ",(0,i.jsx)(t.a,{href:"https://azure.microsoft.com/en-us/services/kubernetes-service/",children:"AKS"})," and ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/kubernetes-engine",children:"GKE"}),", only provides runtime encryption for certain worker nodes. Here, each worker node is a separate (and typically unverified) confidential context. This only provides limited security benefits as it only prevents direct access to a worker node's memory. The large majority of potential attacks through the infrastructure remain unaffected. This includes attacks through the control plane, access to external key management, and the corruption of worker node images. This leaves many problems unsolved. For instance, ",(0,i.jsx)(t.em,{children:"Node A"})," has no means to verify if ",(0,i.jsx)(t.em,{children:"Node B"}),' is "good" and if it\'s OK to share data with it. Consequently, this approach leaves a large attack surface, as is depicted in the following.']}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Concept: Managed Kubernetes plus CVMs",src:n(74030).A+"",width:"3767",height:"1902"})}),"\n",(0,i.jsx)(t.p,{children:"The following table highlights the key differences in terms of features."}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{}),(0,i.jsx)(t.th,{children:"Managed Kubernetes with CVMs"}),(0,i.jsx)(t.th,{children:"Confidential Kubernetes (Constellation\u2728)"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Runtime encryption"}),(0,i.jsx)(t.td,{children:"Partial (data plane only)"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Node image verification"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Full cluster attestation"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Transparent network encryption"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Transparent storage encryption"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Confidential key management"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Cloud agnostic / multi-cloud"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},74030:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/concept-managed-33482ac199f949182872dc32d69bd3bc.svg"},91988:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/concept-constellation-f869032711a972295d5ddce42c37995c.svg"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/a0c24a7b.92c74a89.js b/pr-preview/pr-4027/assets/js/a0c24a7b.92c74a89.js deleted file mode 100644 index e83c7c12a..000000000 --- a/pr-preview/pr-4027/assets/js/a0c24a7b.92c74a89.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8889],{28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>i});var o=n(96540);const s={},a=o.createContext(s);function r(e){const t=o.useContext(a);return o.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(a.Provider,{value:t},e.children)}},31804:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>r,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"workflows/cert-manager","title":"Install cert-manager","description":"If you want to use cert-manager with Constellation, pay attention to the following to avoid potential pitfalls.","source":"@site/versioned_docs/version-2.24/workflows/cert-manager.md","sourceDirName":"workflows","slug":"/workflows/cert-manager","permalink":"/constellation/pr-preview/pr-4027/workflows/cert-manager","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/workflows/cert-manager.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Expose a service","permalink":"/constellation/pr-preview/pr-4027/workflows/lb"},"next":{"title":"Install s3proxy","permalink":"/constellation/pr-preview/pr-4027/workflows/s3proxy"}}');var s=n(74848),a=n(28453);const r={},i="Install cert-manager",l={},c=[];function d(e){const t={admonition:"admonition",code:"code",h1:"h1",header:"header",p:"p",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"install-cert-manager",children:"Install cert-manager"})}),"\n",(0,s.jsx)(t.admonition,{type:"caution",children:(0,s.jsx)(t.p,{children:"If you want to use cert-manager with Constellation, pay attention to the following to avoid potential pitfalls."})}),"\n",(0,s.jsxs)(t.p,{children:["Constellation ships with cert-manager preinstalled.\nThe default installation is part of the ",(0,s.jsx)(t.code,{children:"kube-system"})," namespace, as all other Constellation-managed microservices.\nYou are free to install more instances of cert-manager into other namespaces.\nHowever, be aware that any new installation needs to use the same version as the one installed with Constellation or rely on the same CRD versions.\nAlso remember to set the ",(0,s.jsx)(t.code,{children:"installCRDs"})," value to ",(0,s.jsx)(t.code,{children:"false"})," when installing new cert-manager instances.\nIt will create problems if you have two installations of cert-manager depending on different versions of the installed CRDs.\nCRDs are cluster-wide resources and cert-manager depends on specific versions of those CRDs for each release."]})]})}function p(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/a3183fd7.fe04cf76.js b/pr-preview/pr-4027/assets/js/a3183fd7.fe04cf76.js deleted file mode 100644 index 9c56bec3c..000000000 --- a/pr-preview/pr-4027/assets/js/a3183fd7.fe04cf76.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[656],{28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>a});var n=r(96540);const i={},s=n.createContext(i);function o(e){const t=n.useContext(s);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),n.createElement(s.Provider,{value:t},e.children)}},79402:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"architecture/encrypted-storage","title":"Encrypted persistent storage","description":"Confidential VMs provide runtime memory encryption to protect data in use.","source":"@site/docs/architecture/encrypted-storage.md","sourceDirName":"architecture","slug":"/architecture/encrypted-storage","permalink":"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/architecture/encrypted-storage.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Keys and cryptographic primitives","permalink":"/constellation/pr-preview/pr-4027/next/architecture/keys"},"next":{"title":"Networking","permalink":"/constellation/pr-preview/pr-4027/next/architecture/networking"}}');var i=r(74848),s=r(28453);const o={},a="Encrypted persistent storage",c={},d=[{value:"Cloud provider-managed encryption",id:"cloud-provider-managed-encryption",level:2},{value:"Constellation-managed encryption",id:"constellation-managed-encryption",level:2},{value:"Cryptographic algorithms",id:"cryptographic-algorithms",level:2},{value:"dm-crypt",id:"dm-crypt",level:3},{value:"dm-integrity",id:"dm-integrity",level:3},{value:"Encrypted S3 object storage",id:"encrypted-s3-object-storage",level:2}];function l(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"encrypted-persistent-storage",children:"Encrypted persistent storage"})}),"\n",(0,i.jsxs)(t.p,{children:["Confidential VMs provide runtime memory encryption to protect data in use.\nIn the context of Kubernetes, this is sufficient for the confidentiality and integrity of stateless services.\nConsider a front-end web server, for example, that keeps all connection information cached in main memory.\nNo sensitive data is ever written to an insecure medium.\nHowever, many real-world applications need some form of state or data-lake service that's connected to a persistent storage device and requires encryption at rest.\nAs described in ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/storage",children:"Use persistent storage"}),", cloud service providers (CSPs) use the container storage interface (CSI) to make their storage solutions available to Kubernetes workloads.\nThese CSI storage solutions often support some sort of encryption.\nFor example, Google Cloud ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/security/encryption/default-encryption",children:"encrypts data at rest by default"}),", without any action required by the customer."]}),"\n",(0,i.jsx)(t.h2,{id:"cloud-provider-managed-encryption",children:"Cloud provider-managed encryption"}),"\n",(0,i.jsx)(t.p,{children:"CSP-managed storage solutions encrypt the data in the cloud backend before writing it physically to disk.\nIn the context of confidential computing and Constellation, the CSP and its managed services aren't trusted.\nHence, cloud provider-managed encryption protects your data from offline hardware access to physical storage devices.\nIt doesn't protect it from anyone with infrastructure-level access to the storage backend or a malicious insider in the cloud platform.\nEven with \"bring your own key\" or similar concepts, the CSP performs the encryption process with access to the keys and plaintext data."}),"\n",(0,i.jsx)(t.p,{children:"In the security model of Constellation, securing persistent storage and thereby data at rest requires that all cryptographic operations are performed inside a trusted execution environment.\nConsequently, using CSP-managed encryption of persistent storage usually isn't an option."}),"\n",(0,i.jsx)(t.h2,{id:"constellation-managed-encryption",children:"Constellation-managed encryption"}),"\n",(0,i.jsxs)(t.p,{children:["Constellation provides CSI drivers for storage solutions in all major clouds with built-in encryption support.\nBlock storage provisioned by the CSP is ",(0,i.jsx)(t.a,{href:"https://guix.gnu.org/manual/en/html_node/Mapped-Devices.html",children:"mapped"})," using the ",(0,i.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-crypt.html",children:"dm-crypt"}),", and optionally the ",(0,i.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-integrity.html",children:"dm-integrity"}),", kernel modules, before it's formatted and accessed by the Kubernetes workloads.\nAll cryptographic operations happen inside the trusted environment of the confidential Constellation node."]}),"\n",(0,i.jsxs)(t.p,{children:["Note that for integrity-protected disks, ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/blog/2018/07/12/resizing-persistent-volumes-using-kubernetes/",children:"volume expansion"})," isn't supported."]}),"\n",(0,i.jsxs)(t.p,{children:["By default the driver uses data encryption keys (DEKs) issued by the Constellation ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#keyservice",children:(0,i.jsx)(t.em,{children:"KeyService"})}),".\nThe DEKs are in turn derived from the Constellation's key encryption key (KEK), which is directly derived from the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys#master-secret",children:"master secret"}),".\nThis is the recommended mode of operation, and also requires the least amount of setup by the cluster administrator."]}),"\n",(0,i.jsx)(t.p,{children:"Alternatively, the driver can be configured to use a key management system to store and access KEKs and DEKs."}),"\n",(0,i.jsxs)(t.p,{children:["Refer to ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys",children:"keys and cryptography"})," for more details on key management in Constellation."]}),"\n",(0,i.jsx)(t.p,{children:"Once deployed and configured, the CSI driver ensures transparent encryption and integrity of all persistent volumes provisioned via its storage class.\nData at rest is secured without any additional actions required by the developer."}),"\n",(0,i.jsx)(t.h2,{id:"cryptographic-algorithms",children:"Cryptographic algorithms"}),"\n",(0,i.jsx)(t.p,{children:"This section gives an overview of the libraries, cryptographic algorithms, and their configurations, used in Constellation's CSI drivers."}),"\n",(0,i.jsx)(t.h3,{id:"dm-crypt",children:"dm-crypt"}),"\n",(0,i.jsxs)(t.p,{children:["To interact with the dm-crypt kernel module, Constellation uses ",(0,i.jsx)(t.a,{href:"https://gitlab.com/cryptsetup/cryptsetup/",children:"libcryptsetup"}),".\nNew devices are formatted as ",(0,i.jsx)(t.a,{href:"https://gitlab.com/cryptsetup/LUKS2-docs/-/tree/master",children:"LUKS2"})," partitions with a sector size of 4096 bytes.\nThe used key derivation function is ",(0,i.jsx)(t.a,{href:"https://datatracker.ietf.org/doc/html/rfc9106",children:"Argon2id"})," with the ",(0,i.jsx)(t.a,{href:"https://datatracker.ietf.org/doc/html/rfc9106#section-7.4",children:"recommended parameters for memory-constrained environments"})," of 3 iterations and 64 MiB of memory, utilizing 4 parallel threads.\nFor encryption Constellation uses AES in XTS-Plain64. The key size is 512 bit."]}),"\n",(0,i.jsx)(t.h3,{id:"dm-integrity",children:"dm-integrity"}),"\n",(0,i.jsxs)(t.p,{children:["To interact with the dm-integrity kernel module, Constellation uses ",(0,i.jsx)(t.a,{href:"https://gitlab.com/cryptsetup/cryptsetup/",children:"libcryptsetup"}),".\nWhen enabled, the used data integrity algorithm is ",(0,i.jsx)(t.a,{href:"https://datatracker.ietf.org/doc/html/rfc2104",children:"HMAC"})," with SHA256 as the hash function.\nThe tag size is 32 Bytes."]}),"\n",(0,i.jsx)(t.h2,{id:"encrypted-s3-object-storage",children:"Encrypted S3 object storage"}),"\n",(0,i.jsxs)(t.p,{children:["Constellation comes with a service that you can use to transparently retrofit client-side encryption to existing applications that use S3 (AWS or compatible) for storage.\nTo learn more, check out the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/s3proxy",children:"s3proxy documentation"}),"."]})]})}function p(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/a39aaf1d.36d99927.js b/pr-preview/pr-4027/assets/js/a39aaf1d.36d99927.js deleted file mode 100644 index 94d4ef433..000000000 --- a/pr-preview/pr-4027/assets/js/a39aaf1d.36d99927.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7227],{28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>r});var t=s(96540);const l={},i=t.createContext(l);function o(e){const n=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:o(e.components),t.createElement(i.Provider,{value:n},e.children)}},75001:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"getting-started/first-steps","title":"First steps with Constellation","description":"The following steps guide you through the process of creating a cluster and deploying a sample app. This example assumes that you have successfully installed and set up Constellation,","source":"@site/docs/getting-started/first-steps.md","sourceDirName":"getting-started","slug":"/getting-started/first-steps","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/first-steps","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/getting-started/first-steps.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Installation","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/install"},"next":{"title":"First steps (local)","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/first-steps-local"}}');var l=s(74848),i=s(28453);const o={},r="First steps with Constellation",a={},c=[{value:"Create a cluster",id:"create-a-cluster",level:2},{value:"Deploy a sample application",id:"deploy-a-sample-application",level:2},{value:"Terminate your cluster",id:"terminate-your-cluster",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components},{TabItem:s,Tabs:t}=n;return s||u("TabItem",!0),t||u("Tabs",!0),(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"first-steps-with-constellation",children:"First steps with Constellation"})}),"\n",(0,l.jsxs)(n.p,{children:["The following steps guide you through the process of creating a cluster and deploying a sample app. This example assumes that you have successfully ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/install",children:"installed and set up Constellation"}),",\nand have access to a cloud subscription."]}),"\n",(0,l.jsx)(n.admonition,{type:"tip",children:(0,l.jsxs)(n.p,{children:["If you don't have a cloud subscription, you can also set up a ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/first-steps-local",children:"local Constellation cluster using virtualization"})," for testing."]})}),"\n",(0,l.jsx)(n.admonition,{type:"note",children:(0,l.jsxs)(n.p,{children:["If you encounter any problem with the following steps, make sure to use the ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/releases/latest",children:"latest release"})," and check out the ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"known issues"}),"."]})}),"\n",(0,l.jsx)(n.h2,{id:"create-a-cluster",children:"Create a cluster"}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Create the ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/config",children:"configuration file"})," and state file for your cloud provider. If you are following the steps of this guide, there is no need to edit the file."]}),"\n",(0,l.jsxs)(t,{groupId:"csp",children:[(0,l.jsx)(s,{value:"aws",label:"AWS",children:(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation config generate aws\n"})})}),(0,l.jsx)(s,{value:"azure",label:"Azure",children:(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation config generate azure\n"})})}),(0,l.jsx)(s,{value:"gcp",label:"GCP",children:(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation config generate gcp\n"})})}),(0,l.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation config generate stackit\n"})})})]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Create your ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/config#creating-an-iam-configuration",children:"IAM configuration"}),"."]}),"\n",(0,l.jsxs)(t,{groupId:"csp",children:[(0,l.jsxs)(s,{value:"aws",label:"AWS",children:[(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation iam create aws --zone=us-east-2a --prefix=constellTest --update-config\n"})}),(0,l.jsxs)(n.p,{children:["This command creates IAM configuration for the AWS zone ",(0,l.jsx)(n.code,{children:"us-east-2a"})," using the prefix ",(0,l.jsx)(n.code,{children:"constellTest"})," for all named resources being created. It also updates the configuration file ",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"})," in your current directory with the IAM values filled in."]}),(0,l.jsxs)(n.p,{children:["Depending on the attestation variant selected on config generation, different regions are available.\nAMD SEV-SNP machines (requires the default attestation variant ",(0,l.jsx)(n.code,{children:"awsSEVSNP"}),") are currently available in the following regions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"eu-west-1"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"us-east-2"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["You can find a list of regions that support AMD SEV-SNP in ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/snp-requirements.html",children:"AWS's documentation"}),"."]}),(0,l.jsxs)(n.p,{children:["NitroTPM machines (requires the attestation variant ",(0,l.jsx)(n.code,{children:"awsNitroTPM"}),") are available in all regions.\nConstellation OS images are currently replicated to the following regions:"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"eu-central-1"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"eu-west-1"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"eu-west-3"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"us-east-2"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"ap-south-1"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+AWS+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),(0,l.jsxs)(n.p,{children:["You can find a list of all ",(0,l.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions",children:"regions in AWS's documentation"}),"."]})]}),(0,l.jsxs)(s,{value:"azure",label:"Azure",children:[(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation iam create azure --subscriptionID 00000000-0000-0000-0000-000000000000 --region=westus --resourceGroup=constellTest --servicePrincipal=spTest --update-config\n"})}),(0,l.jsxs)(n.p,{children:["This command creates IAM configuration on the Azure region ",(0,l.jsx)(n.code,{children:"westus"})," creating a new resource group ",(0,l.jsx)(n.code,{children:"constellTest"})," and a new service principal ",(0,l.jsx)(n.code,{children:"spTest"}),". It also updates the configuration file ",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"})," in your current directory with the IAM values filled in."]}),(0,l.jsx)(n.p,{children:"CVMs are available in several Azure regions. Constellation OS images are currently replicated to the following:"}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"germanywestcentral"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"westus"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"eastus"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"northeurope"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"westeurope"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"southeastasia"})}),"\n"]}),(0,l.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+Azure+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),(0,l.jsxs)(n.p,{children:["You can find a list of all ",(0,l.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/global-infrastructure/services/?products=virtual-machines®ions=all",children:"regions in Azure's documentation"}),"."]})]}),(0,l.jsxs)(s,{value:"gcp",label:"GCP",children:[(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation iam create gcp --projectID=yourproject-12345 --zone=europe-west3-a --prefix=constell-test --update-config\n"})}),(0,l.jsxs)(n.p,{children:["This command creates IAM configuration in the GCP project ",(0,l.jsx)(n.code,{children:"yourproject-12345"})," on the GCP zone ",(0,l.jsx)(n.code,{children:"europe-west3-a"})," creating a new service account ",(0,l.jsx)(n.code,{children:"constell-test"}),". It also updates the configuration file ",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"})," in your current directory with the IAM values filled in."]}),(0,l.jsxs)(n.p,{children:["Note that only regions offering CVMs of the ",(0,l.jsx)(n.code,{children:"C2D"})," or ",(0,l.jsx)(n.code,{children:"N2D"})," series are supported. You can find a ",(0,l.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones#available",children:"list of all regions in Google's documentation"}),", which you can filter by machine type ",(0,l.jsx)(n.code,{children:"C2D"})," or ",(0,l.jsx)(n.code,{children:"N2D"}),"."]})]}),(0,l.jsxs)(s,{value:"stackit",label:"STACKIT",children:[(0,l.jsxs)(n.p,{children:["To use Constellation on STACKIT, the cluster will use the User Access Token (UAT) that's generated ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/getting-started/install",children:"during the install step"}),".\nAfter creating the accounts, fill in the STACKIT details in ",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"})," under ",(0,l.jsx)(n.code,{children:"provider.openstack"}),":"]}),(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"stackitProjectID"}),": STACKIT project id (can be found after login on the ",(0,l.jsx)(n.a,{href:"https://portal.stackit.cloud",children:"STACKIT portal"}),")"]}),"\n"]}),(0,l.jsx)(n.admonition,{type:"caution",children:(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:"stackitProjectID"})," refers to the ID of your STACKIT project. The STACKIT portal also shows the OpenStack ID that's associated with your project in some places. Make sure you insert the STACKIT project ID in the ",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"})," file. It's of the format ",(0,l.jsx)(n.code,{children:"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"}),"."]})})]})]}),"\n",(0,l.jsx)(n.admonition,{type:"tip",children:(0,l.jsxs)(n.p,{children:["To learn about all options you have for managing IAM resources and Constellation configuration, see the ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/config",children:"Configuration workflow"}),"."]})}),"\n"]}),"\n"]}),"\n",(0,l.jsxs)(n.ol,{start:"3",children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Create the cluster. ",(0,l.jsx)(n.code,{children:"constellation apply"})," uses options set in ",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"}),".\nIf you want to manually manage your cloud resources, for example by using ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/reference/terraform",children:"Terraform"}),", follow the corresponding instructions in the ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/create",children:"Create workflow"}),"."]}),"\n",(0,l.jsx)(n.admonition,{type:"tip",children:(0,l.jsx)(n.p,{children:"On Azure, you may need to wait 15+ minutes at this point for role assignments to propagate."})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation apply -y\n"})}),"\n",(0,l.jsx)(n.p,{children:"This should look similar to the following:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:'$ constellation apply -y\nChecking for infrastructure changes\nThe following Constellation cluster will be created:\n 3 control-plane nodes of type n2d-standard-4 will be created.\n 1 worker node of type n2d-standard-4 will be created.\nCreating\nCloud infrastructure created successfully\nYour Constellation master secret was successfully written to ./constellation-mastersecret.json\nConnecting\nInitializing cluster\nInstalling Kubernetes components\nYour Constellation cluster was successfully initialized.\n\nConstellation cluster identifier g6iMP5wRU1b7mpOz2WEISlIYSfdAhB0oNaOg6XEwKFY=\nKubernetes configuration constellation-admin.conf\n\nYou can now connect to your cluster by executing:\n export KUBECONFIG="$PWD/constellation-admin.conf"\n'})}),"\n",(0,l.jsxs)(n.p,{children:["The cluster's identifier will be different in your output.\nKeep ",(0,l.jsx)(n.code,{children:"constellation-mastersecret.json"})," somewhere safe.\nThis will allow you to ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/recovery",children:"recover your cluster"})," in case of a disaster."]}),"\n",(0,l.jsx)(n.admonition,{type:"info",children:(0,l.jsxs)(n.p,{children:["Depending on your CSP and region, ",(0,l.jsx)(n.code,{children:"constellation apply"})," may take 10+ minutes to complete."]})}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Configure kubectl."}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:'export KUBECONFIG="$PWD/constellation-admin.conf"\n'})}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"deploy-a-sample-application",children:"Deploy a sample application"}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Deploy the ",(0,l.jsx)(n.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"emojivoto app"})]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment\n"})}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Expose the frontend service locally"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments\nkubectl -n emojivoto port-forward svc/web-svc 8080:80 &\ncurl http://localhost:8080\nkill %1\n"})}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"terminate-your-cluster",children:"Terminate your cluster"}),"\n",(0,l.jsxs)(n.p,{children:["Use the CLI to terminate your cluster. If you manually used ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/reference/terraform",children:"Terraform"})," to manage your cloud resources, follow the corresponding instructions in the ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/terminate",children:"Terminate workflow"}),"."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation terminate\n"})}),"\n",(0,l.jsx)(n.p,{children:"This should give the following output:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"$ constellation terminate\nYou are about to terminate a Constellation cluster.\nAll of its associated resources will be DESTROYED.\nThis action is irreversible and ALL DATA WILL BE LOST.\nDo you want to continue? [y/n]:\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Confirm with ",(0,l.jsx)(n.code,{children:"y"})," to terminate the cluster:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"Terminating ...\nYour Constellation cluster was terminated successfully.\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Optionally, you can also ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/config#deleting-an-iam-configuration",children:"delete your IAM resources"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}function u(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/a4c009ef.37cd2124.js b/pr-preview/pr-4027/assets/js/a4c009ef.37cd2124.js deleted file mode 100644 index bc03fe033..000000000 --- a/pr-preview/pr-4027/assets/js/a4c009ef.37cd2124.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6257],{93963:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Reference","slug":"/category/reference","permalink":"/constellation/pr-preview/pr-4027/next/category/reference","sidebar":"docs","navigation":{"previous":{"title":"Observability","permalink":"/constellation/pr-preview/pr-4027/next/architecture/observability"},"next":{"title":"CLI","permalink":"/constellation/pr-preview/pr-4027/next/reference/cli"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/a5863201.f48869f7.js b/pr-preview/pr-4027/assets/js/a5863201.f48869f7.js deleted file mode 100644 index 0e6c61cdb..000000000 --- a/pr-preview/pr-4027/assets/js/a5863201.f48869f7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2993],{22705:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"architecture/keys","title":"Key management and cryptographic primitives","description":"Constellation protects and isolates your cluster and workloads.","source":"@site/versioned_docs/version-2.24/architecture/keys.md","sourceDirName":"architecture","slug":"/architecture/keys","permalink":"/constellation/pr-preview/pr-4027/architecture/keys","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/architecture/keys.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Images","permalink":"/constellation/pr-preview/pr-4027/architecture/images"},"next":{"title":"Encrypted persistent storage","permalink":"/constellation/pr-preview/pr-4027/architecture/encrypted-storage"}}');var a=n(74848),i=n(28453);const s={},o="Key management and cryptographic primitives",l={},c=[{value:"Confidential VMs",id:"confidential-vms",level:2},{value:"Master secret",id:"master-secret",level:2},{value:"Cluster identity",id:"cluster-identity",level:2},{value:"Network encryption",id:"network-encryption",level:2},{value:"Storage encryption",id:"storage-encryption",level:2},{value:"Constellation-managed key management",id:"constellation-managed-key-management",level:3},{value:"Key material and key derivation",id:"key-material-and-key-derivation",level:4},{value:"State and storage",id:"state-and-storage",level:4},{value:"Availability",id:"availability",level:4},{value:"Recovery",id:"recovery",level:4},{value:"User-managed key management",id:"user-managed-key-management",level:3},{value:"Recovery and migration",id:"recovery-and-migration",level:4}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"key-management-and-cryptographic-primitives",children:"Key management and cryptographic primitives"})}),"\n",(0,a.jsx)(t.p,{children:"Constellation protects and isolates your cluster and workloads.\nTo that end, cryptography is the foundation that ensures the confidentiality and integrity of all components.\nEvaluating the security and compliance of Constellation requires a precise understanding of the cryptographic primitives and keys used.\nThe following gives an overview of the architecture and explains the technical details."}),"\n",(0,a.jsx)(t.h2,{id:"confidential-vms",children:"Confidential VMs"}),"\n",(0,a.jsx)(t.p,{children:"Confidential VM (CVM) technology comes with hardware and software components for memory encryption, isolation, and remote attestation.\nFor details on the implementations and cryptographic soundness, refer to the hardware vendors' documentation and advisories."}),"\n",(0,a.jsx)(t.h2,{id:"master-secret",children:"Master secret"}),"\n",(0,a.jsxs)(t.p,{children:["The master secret is the cryptographic material used for deriving the ",(0,a.jsx)(t.a,{href:"#cluster-identity",children:(0,a.jsx)(t.em,{children:"clusterID"})})," and the ",(0,a.jsx)(t.em,{children:"key encryption key (KEK)"})," for ",(0,a.jsx)(t.a,{href:"#storage-encryption",children:"storage encryption"}),".\nIt's generated during the bootstrapping of a Constellation cluster.\nIt can either be managed by ",(0,a.jsx)(t.a,{href:"#constellation-managed-key-management",children:"Constellation"})," or an ",(0,a.jsx)(t.a,{href:"#user-managed-key-management",children:"external key management system"}),".\nIn case of ",(0,a.jsx)(t.a,{href:"#recovery-and-migration",children:"recovery"}),", the master secret allows to decrypt the state and recover a Constellation cluster."]}),"\n",(0,a.jsx)(t.h2,{id:"cluster-identity",children:"Cluster identity"}),"\n",(0,a.jsxs)(t.p,{children:["The identity of a Constellation cluster is represented by cryptographic ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/attestation#runtime-measurements",children:"measurements"}),":"]}),"\n",(0,a.jsxs)(t.p,{children:["The ",(0,a.jsx)(t.strong,{children:"base measurements"})," represent the identity of a valid, uninitialized Constellation node.\nThey depend on the node image, but are otherwise the same for every Constellation cluster.\nOn node boot, they're determined using the CVM's attestation mechanism and ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/images",children:"measured boot up to the read-only root filesystem"}),"."]}),"\n",(0,a.jsxs)(t.p,{children:["The ",(0,a.jsx)(t.strong,{children:"clusterID"})," represents the identity of a single initialized Constellation cluster.\nIt's derived from the master secret and a cryptographically random salt and unique for every Constellation cluster.\nThe ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#bootstrapper",children:"Bootstrapper"})," measures the ",(0,a.jsx)(t.em,{children:"clusterID"})," into its own PCR before executing any code not measured as part of the ",(0,a.jsx)(t.em,{children:"base measurements"}),".\nSee ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/attestation#node-attestation",children:"Node attestation"})," for details."]}),"\n",(0,a.jsxs)(t.p,{children:["The remote attestation statement of a Constellation cluster combines the ",(0,a.jsx)(t.em,{children:"base measurements"})," and the ",(0,a.jsx)(t.em,{children:"clusterID"})," for a verifiable, unspoofable, unique identity."]}),"\n",(0,a.jsx)(t.h2,{id:"network-encryption",children:"Network encryption"}),"\n",(0,a.jsxs)(t.p,{children:["Constellation encrypts all cluster network communication using the ",(0,a.jsx)(t.a,{href:"https://github.com/containernetworking/cni",children:"container network interface (CNI)"}),".\nSee ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/networking",children:"network encryption"})," for more details."]}),"\n",(0,a.jsxs)(t.p,{children:["The Cilium agent running on each node establishes a secure ",(0,a.jsx)(t.a,{href:"https://www.wireguard.com/",children:"WireGuard"})," tunnel between it and all other known nodes in the cluster.\nEach node creates its own ",(0,a.jsx)(t.a,{href:"http://cr.yp.to/ecdh.html",children:"Curve25519"})," encryption key pair and distributes its public key via Kubernetes.\nA node uses another node's public key to decrypt and encrypt traffic from and to Cilium-managed endpoints running on that node.\nConnections are always encrypted peer-to-peer using ",(0,a.jsx)(t.a,{href:"http://cr.yp.to/chacha.html",children:"ChaCha20"})," with ",(0,a.jsx)(t.a,{href:"http://cr.yp.to/mac.html",children:"Poly1305"}),".\nWireGuard implements ",(0,a.jsx)(t.a,{href:"https://lists.zx2c4.com/pipermail/wireguard/2017-December/002141.html",children:"forward secrecy with key rotation every 2 minutes"}),"."]}),"\n",(0,a.jsx)(t.h2,{id:"storage-encryption",children:"Storage encryption"}),"\n",(0,a.jsx)(t.p,{children:"Constellation supports transparent encryption of persistent storage.\nThe Linux kernel's device mapper-based encryption features are used to encrypt the data on the block storage level.\nCurrently, the following primitives are used for block storage encryption:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-crypt.html",children:"dm-crypt"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-integrity.html",children:"dm-integrity"})}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["Adding primitives for integrity protection in the CVM attacker model are under active development and will be available in a future version of Constellation.\nSee ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/encrypted-storage",children:"encrypted storage"})," for more details."]}),"\n",(0,a.jsxs)(t.p,{children:["As a cluster administrator, when creating a cluster, you can use the Constellation ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/orchestration",children:"installation program"})," to select one of the following methods for key management:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Constellation-managed key management"}),"\n",(0,a.jsx)(t.li,{children:"User-managed key management"}),"\n"]}),"\n",(0,a.jsx)(t.h3,{id:"constellation-managed-key-management",children:"Constellation-managed key management"}),"\n",(0,a.jsx)(t.h4,{id:"key-material-and-key-derivation",children:"Key material and key derivation"}),"\n",(0,a.jsxs)(t.p,{children:["During the creation of a Constellation cluster, the cluster's master secret is used to derive a KEK.\nThis means creating two clusters with the same master secret will yield the same KEK.\nAny data encryption key (DEK) is derived from the KEK via HKDF.\nNote that the master secret is recommended to be unique for every cluster and shouldn't be reused (except in case of ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/recovery",children:"recovering"})," a cluster)."]}),"\n",(0,a.jsx)(t.h4,{id:"state-and-storage",children:"State and storage"}),"\n",(0,a.jsx)(t.p,{children:"The KEK is derived from the master secret during the initialization.\nSubsequently, all other key material is derived from the KEK.\nGiven the same KEK, any DEK can be derived deterministically from a given identifier.\nHence, there is no need to store DEKs. They can be derived on demand.\nAfter the KEK was derived, it's stored in memory only and never leaves the CVM context."}),"\n",(0,a.jsx)(t.h4,{id:"availability",children:"Availability"}),"\n",(0,a.jsxs)(t.p,{children:["Constellation-managed key management has the same availability as the underlying Kubernetes cluster.\nTherefore, the KEK is stored in the ",(0,a.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/",children:"distributed Kubernetes etcd storage"})," to allow for unexpected but non-fatal (control-plane) node failure.\nThe etcd storage is backed by the encrypted and integrity protected ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/images#state-disk",children:"state disk"})," of the nodes."]}),"\n",(0,a.jsx)(t.h4,{id:"recovery",children:"Recovery"}),"\n",(0,a.jsxs)(t.p,{children:["Constellation clusters can be recovered in the event of a disaster, even when all node machines have been stopped and need to be rebooted.\nFor details on the process see the ",(0,a.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/recovery",children:"recovery workflow"}),"."]}),"\n",(0,a.jsx)(t.h3,{id:"user-managed-key-management",children:"User-managed key management"}),"\n",(0,a.jsx)(t.p,{children:"User-managed key management is under active development and will be available soon.\nIn scenarios where constellation-managed key management isn't an option, this mode allows you to keep full control of your keys.\nFor example, compliance requirements may force you to keep your KEKs in an on-prem key management system (KMS)."}),"\n",(0,a.jsx)(t.p,{children:'During the creation of a Constellation cluster, you specify a KEK present in a remote KMS.\nThis follows the common scheme of "bring your own key" (BYOK).\nConstellation will support several KMSs for managing the storage and access of your KEK.\nInitially, it will support the following KMSs:'}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://aws.amazon.com/kms/",children:"AWS KMS"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://cloud.google.com/security-key-management",children:"GCP KMS"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://azure.microsoft.com/en-us/services/key-vault/#product-overview",children:"Azure Key Vault"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=kmip",children:"KMIP-compatible KMS"})}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Storing the keys in Cloud KMS of AWS, Azure, or GCP binds the key usage to the particular cloud identity access management (IAM).\nIn the future, Constellation will support remote attestation-based access policies for Cloud KMS once available.\nNote that using a Cloud KMS limits the isolation and protection to the guarantees of the particular offering."}),"\n",(0,a.jsx)(t.p,{children:'KMIP support allows you to use your KMIP-compatible on-prem KMS and keep full control over your keys.\nThis follows the common scheme of "hold your own key" (HYOK).'}),"\n",(0,a.jsx)(t.p,{children:'The KEK is used to encrypt per-data "data encryption keys" (DEKs).\nDEKs are generated to encrypt your data before storing it on persistent storage.\nAfter being encrypted by the KEK, the DEKs are stored on dedicated cloud storage for persistence.\nCurrently, Constellation supports the following cloud storage options:'}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://aws.amazon.com/s3/",children:"AWS S3"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://cloud.google.com/storage",children:"GCP Cloud Storage"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://azure.microsoft.com/en-us/services/storage/blobs/#overview",children:"Azure Blob Storage"})}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"The DEKs are only present in plaintext form in the encrypted main memory of the CVMs.\nSimilarly, the cryptographic operations for encrypting data before writing it to persistent storage are performed in the context of the CVMs."}),"\n",(0,a.jsx)(t.h4,{id:"recovery-and-migration",children:"Recovery and migration"}),"\n",(0,a.jsx)(t.p,{children:"In the case of a disaster, the KEK can be used to decrypt the DEKs locally and subsequently use them to decrypt and retrieve the data.\nIn case of migration, configuring the same KEK will provide seamless migration of data.\nThus, only the DEK storage needs to be transferred to the new cluster alongside the encrypted data for seamless migration."})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>o});var r=n(96540);const a={},i=r.createContext(a);function s(e){const t=r.useContext(i);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),r.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/a631f374.cb614d21.js b/pr-preview/pr-4027/assets/js/a631f374.cb614d21.js deleted file mode 100644 index 5d8d721c0..000000000 --- a/pr-preview/pr-4027/assets/js/a631f374.cb614d21.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9770],{28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var r=n(96540);const i={},s=r.createContext(i);function o(e){const t=r.useContext(s);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(s.Provider,{value:t},e.children)}},76978:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"architecture/microservices","title":"Microservices","description":"Constellation takes care of bootstrapping and initializing a Confidential Kubernetes cluster.","source":"@site/versioned_docs/version-2.23/architecture/microservices.md","sourceDirName":"architecture","slug":"/architecture/microservices","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/microservices","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/architecture/microservices.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Versions and support","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/versions"},"next":{"title":"Attestation","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/attestation"}}');var i=n(74848),s=n(28453);const o={},a="Microservices",c={},l=[{value:"Bootstrapper",id:"bootstrapper",level:2},{value:"JoinService",id:"joinservice",level:2},{value:"VerificationService",id:"verificationservice",level:2},{value:"KeyService",id:"keyservice",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",mermaid:"mermaid",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"microservices",children:"Microservices"})}),"\n",(0,i.jsx)(t.p,{children:"Constellation takes care of bootstrapping and initializing a Confidential Kubernetes cluster.\nDuring the lifetime of the cluster, it handles day 2 operations such as key management, remote attestation, and updates.\nThese features are provided by several microservices:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#bootstrapper",children:"Bootstrapper"})," initializes a Constellation node and bootstraps the cluster"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#joinservice",children:"JoinService"})," joins new nodes to an existing cluster"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#verificationservice",children:"VerificationService"})," provides remote attestation functionality"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#keyservice",children:"KeyService"})," manages Constellation-internal keys"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"The relations between microservices are shown in the following diagram:"}),"\n",(0,i.jsx)(t.mermaid,{value:"flowchart LR\n subgraph admin [Admin's machine]\n A[Constellation CLI]\n end\n subgraph img [Constellation OS image]\n B[Constellation OS]\n C[Bootstrapper]\n end\n subgraph Kubernetes\n D[JoinService]\n E[KeyService]\n F[VerificationService]\n end\n A -- deploys --\x3e\n B -- starts --\x3e C\n C -- deploys --\x3e D\n C -- deploys --\x3e E\n C -- deploys --\x3e F"}),"\n",(0,i.jsx)(t.h2,{id:"bootstrapper",children:"Bootstrapper"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"Bootstrapper"})," is the first microservice launched after booting a Constellation node image.\nIt sets up that machine as a Kubernetes node and integrates that node into the Kubernetes cluster.\nTo this end, the ",(0,i.jsx)(t.em,{children:"Bootstrapper"})," first downloads and verifies the ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/overview/components/",children:"Kubernetes components"})," at the configured versions.\nThe ",(0,i.jsx)(t.em,{children:"Bootstrapper"})," tries to find an existing cluster and if successful, communicates with the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#joinservice",children:"JoinService"})," to join the node.\nOtherwise, it waits for an initialization request to create a new Kubernetes cluster."]}),"\n",(0,i.jsx)(t.h2,{id:"joinservice",children:"JoinService"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"JoinService"})," runs as ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/",children:"DaemonSet"})," on each control-plane node.\nNew nodes (at cluster start, or later through autoscaling) send a request to the service over ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation#attested-tls-atls",children:"attested TLS (aTLS)"}),".\nThe ",(0,i.jsx)(t.em,{children:"JoinService"})," verifies the new node's certificate and attestation statement.\nIf attestation is successful, the new node is supplied with an encryption key from the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#keyservice",children:(0,i.jsx)(t.em,{children:"KeyService"})})," for its state disk, and a Kubernetes bootstrap token."]}),"\n",(0,i.jsx)(t.mermaid,{value:"sequenceDiagram\n participant New node\n participant JoinService\n New node->>JoinService: aTLS handshake (server side verification)\n JoinService--\x3e>New node: #\n New node->>+JoinService: IssueJoinTicket(DiskUUID, NodeName, IsControlPlane)\n JoinService->>+KeyService: GetDataKey(DiskUUID)\n KeyService--\x3e>-JoinService: DiskEncryptionKey\n JoinService--\x3e>-New node: DiskEncryptionKey, KubernetesJoinToken, ..."}),"\n",(0,i.jsx)(t.h2,{id:"verificationservice",children:"VerificationService"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"VerificationService"})," runs as DaemonSet on each node.\nIt provides user-facing functionality for remote attestation during the cluster's lifetime via an endpoint for ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation#cluster-attestation",children:"verifying the cluster"}),".\nRead more about the hardware-based ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation",children:"attestation feature"})," of Constellation and how to ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cluster",children:"verify"})," a cluster on the client side."]}),"\n",(0,i.jsx)(t.h2,{id:"keyservice",children:"KeyService"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"KeyService"})," runs as DaemonSet on each control-plane node.\nIt implements the key management for the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys#storage-encryption",children:"storage encryption keys"})," in Constellation. These keys are used for the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/images#state-disk",children:"state disk"})," of each node and the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage",children:"transparently encrypted storage"})," for Kubernetes.\nDepending on wether the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys#constellation-managed-key-management",children:"constellation-managed"})," or ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys#user-managed-key-management",children:"user-managed"})," mode is used, the ",(0,i.jsx)(t.em,{children:"KeyService"})," holds the key encryption key (KEK) directly or calls an external key management service (KMS) for key derivation respectively."]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/a6a7cec0.e9c36e1f.js b/pr-preview/pr-4027/assets/js/a6a7cec0.e9c36e1f.js deleted file mode 100644 index 23c5edb58..000000000 --- a/pr-preview/pr-4027/assets/js/a6a7cec0.e9c36e1f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6599],{28453:(e,t,i)=>{i.d(t,{R:()=>r,x:()=>a});var n=i(96540);const s={},o=n.createContext(s);function r(e){const t=n.useContext(o);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(o.Provider,{value:t},e.children)}},63791:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"architecture/images","title":"Constellation images","description":"Constellation uses a minimal version of Fedora as the operating system running inside confidential VMs. This Linux distribution is optimized for containers and designed to be stateless.","source":"@site/versioned_docs/version-2.22/architecture/images.md","sourceDirName":"architecture","slug":"/architecture/images","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/images","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/architecture/images.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Attestation","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation"},"next":{"title":"Keys and cryptographic primitives","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/keys"}}');var s=i(74848),o=i(28453);const r={},a="Constellation images",d={},l=[{value:"Measured boot",id:"measured-boot",level:2},{value:"Firmware",id:"firmware",level:3},{value:"Bootloader",id:"bootloader",level:3},{value:"initramfs",id:"initramfs",level:3},{value:"State disk",id:"state-disk",level:2},{value:"Kubernetes components",id:"kubernetes-components",level:2}];function c(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",mermaid:"mermaid",p:"p",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"constellation-images",children:"Constellation images"})}),"\n",(0,s.jsx)(t.p,{children:"Constellation uses a minimal version of Fedora as the operating system running inside confidential VMs. This Linux distribution is optimized for containers and designed to be stateless.\nThe Constellation images provide measured boot and an immutable filesystem."}),"\n",(0,s.jsx)(t.h2,{id:"measured-boot",children:"Measured boot"}),"\n",(0,s.jsx)(t.mermaid,{value:"flowchart LR\n Firmware --\x3e Bootloader\n Bootloader --\x3e uki\n subgraph uki[Unified Kernel Image]\n Kernel[Kernel]\n initramfs[Initramfs]\n cmdline[Kernel Command Line]\n end\n uki --\x3e rootfs[Root Filesystem]"}),"\n",(0,s.jsx)(t.p,{children:"Measured boot uses a Trusted Platform Module (TPM) to measure every part of the boot process. This allows for verification of the integrity of a running system at any point in time. To ensure correct measurements of every stage, each stage is responsible to measure the next stage before transitioning."}),"\n",(0,s.jsx)(t.h3,{id:"firmware",children:"Firmware"}),"\n",(0,s.jsx)(t.p,{children:"With confidential VMs, the firmware is the root of trust and is measured automatically at boot. After initialization, the firmware will load and measure the bootloader before executing it."}),"\n",(0,s.jsx)(t.h3,{id:"bootloader",children:"Bootloader"}),"\n",(0,s.jsx)(t.p,{children:"The bootloader is the first modifiable part of the boot chain. The bootloader is tasked with loading the kernel, initramfs and setting the kernel command line. The Constellation bootloader measures these components before starting the kernel."}),"\n",(0,s.jsx)(t.h3,{id:"initramfs",children:"initramfs"}),"\n",(0,s.jsxs)(t.p,{children:["The initramfs is a small filesystem loaded to prepare the actual root filesystem. The Constellation initramfs maps the block device containing the root filesystem with ",(0,s.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"}),". The initramfs then mounts the root filesystem from the mapped block device."]}),"\n",(0,s.jsx)(t.p,{children:"dm-verity provides integrity checking using a cryptographic hash tree. When a block is read, its integrity is checked by verifying the tree against a trusted root hash. The initramfs reads this root hash from the previously measured kernel command line. Thus, if any block of the root filesystem's device is modified on disk, trying to read the modified block will result in a kernel panic at runtime."}),"\n",(0,s.jsxs)(t.p,{children:["After mounting the root filesystem, the initramfs will switch over and start the ",(0,s.jsx)(t.code,{children:"init"})," process of the integrity-protected root filesystem."]}),"\n",(0,s.jsx)(t.h2,{id:"state-disk",children:"State disk"}),"\n",(0,s.jsxs)(t.p,{children:["In addition to the read-only root filesystem, each Constellation node has a disk for storing state data.\nThis disk is mounted readable and writable by the initramfs and contains data that should persist across reboots.\nSuch data can contain sensitive information and, therefore, must be stored securely.\nTo that end, the state disk is protected by authenticated encryption.\nSee the section on ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys#storage-encryption",children:"keys and encryption"})," for more information on the cryptographic primitives in use."]}),"\n",(0,s.jsx)(t.h2,{id:"kubernetes-components",children:"Kubernetes components"}),"\n",(0,s.jsxs)(t.p,{children:["During initialization, the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#bootstrapper",children:(0,s.jsx)(t.em,{children:"Bootstrapper"})})," downloads and verifies the ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/overview/components/",children:"Kubernetes components"})," as configured by the user.\nThey're stored on the state partition and can be updated once new releases need to be installed."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/a7bd4aaa.125c3d24.js b/pr-preview/pr-4027/assets/js/a7bd4aaa.125c3d24.js deleted file mode 100644 index b3aa09a24..000000000 --- a/pr-preview/pr-4027/assets/js/a7bd4aaa.125c3d24.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7098],{22881:(n,s,e)=>{e.r(s),e.d(s,{default:()=>d});e(96540);var o=e(17153),r=e(91704),t=e(73718),i=e(22831),c=e(51210),l=e(74848);function a(n){const{version:s}=n;return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(c.A,{version:s.version,tag:(0,t.k)(s.pluginId,s.version)}),(0,l.jsx)(o.be,{children:s.noIndex&&(0,l.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})]})}function u(n){const{version:s,route:e}=n;return(0,l.jsx)(o.e3,{className:s.className,children:(0,l.jsx)(r.n,{version:s,children:(0,i.v)(e.routes)})})}function d(n){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(a,{...n}),(0,l.jsx)(u,{...n})]})}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/a7be6a84.cd4ab870.js b/pr-preview/pr-4027/assets/js/a7be6a84.cd4ab870.js deleted file mode 100644 index 0cf82a324..000000000 --- a/pr-preview/pr-4027/assets/js/a7be6a84.cd4ab870.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1275],{28453:(e,n,t)=>{t.d(n,{R:()=>l,x:()=>a});var o=t(96540);const s={},i=o.createContext(s);function l(e){const n=o.useContext(i);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),o.createElement(i.Provider,{value:n},e.children)}},64325:(e,n,t)=>{t.d(n,{A:()=>o});const o=t.p+"assets/images/example-online-boutique-c89a9a15b1d4c086d3654bf75843295e.jpg"},99835:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>a,default:()=>u,frontMatter:()=>l,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"getting-started/examples/online-boutique","title":"Online Boutique","description":"Online Boutique is an e-commerce demo application by Google consisting of 11 separate microservices. In this demo, Constellation automatically sets up a load balancer on your CSP, making it easy to expose services from your confidential cluster.","source":"@site/versioned_docs/version-2.22/getting-started/examples/online-boutique.md","sourceDirName":"getting-started/examples","slug":"/getting-started/examples/online-boutique","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/online-boutique","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/getting-started/examples/online-boutique.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Emojivoto","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/emojivoto"},"next":{"title":"Horizontal Pod Autoscaling","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scaling"}}');var s=t(74848),i=t(28453);const l={},a="Online Boutique",r={},c=[];function d(e){const n={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"online-boutique",children:"Online Boutique"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://github.com/GoogleCloudPlatform/microservices-demo",children:"Online Boutique"})," is an e-commerce demo application by Google consisting of 11 separate microservices. In this demo, Constellation automatically sets up a load balancer on your CSP, making it easy to expose services from your confidential cluster."]}),"\n",(0,s.jsx)("img",{src:t(64325).A,alt:"Online Boutique - Web UI",width:"662"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Create a namespace:","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl create ns boutique\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Deploy the application:","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl apply -n boutique -f https://github.com/GoogleCloudPlatform/microservices-demo/raw/main/release/kubernetes-manifests.yaml\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Wait for all services to become available:","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl wait --for=condition=available --timeout=300s -n boutique --all deployments\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Get the frontend's external IP address:","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell-session",children:"$ kubectl get service frontend-external -n boutique | awk '{print $4}'\nEXTERNAL-IP\n<your-ip>\n"})}),"\n","(",(0,s.jsx)(n.code,{children:"<your-ip>"})," is a placeholder for the IP assigned by your CSP.)"]}),"\n",(0,s.jsx)(n.li,{children:"Enter the IP from the result in your browser to browse the online shop."}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/a7cbe781.1cd695b6.js b/pr-preview/pr-4027/assets/js/a7cbe781.1cd695b6.js deleted file mode 100644 index 0a2902302..000000000 --- a/pr-preview/pr-4027/assets/js/a7cbe781.1cd695b6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5757],{357:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/min_latency-87ed51de18ebede26c314ff00d0e8e23.png"},4220:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/mean_latency-4c041d48ebb1b521c92d464040e94031.png"},10171:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/max_latency-ae0fad7be416fae0d31ab35bb8284234.png"},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}},83015:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"overview/performance/application","title":"Application benchmarks","description":"HashiCorp Vault","source":"@site/versioned_docs/version-2.24/overview/performance/application.md","sourceDirName":"overview/performance","slug":"/overview/performance/application","permalink":"/constellation/pr-preview/pr-4027/overview/performance/application","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/overview/performance/application.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"I/O benchmarks","permalink":"/constellation/pr-preview/pr-4027/overview/performance/io"},"next":{"title":"License","permalink":"/constellation/pr-preview/pr-4027/overview/license"}}');var s=t(74848),i=t(28453);const r={},o="Application benchmarks",c={},l=[{value:"HashiCorp Vault",id:"hashicorp-vault",level:2},{value:"Results",id:"results",level:2},{value:"Visualization",id:"visualization",level:3}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components},{Details:a}=n;return a||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"application-benchmarks",children:"Application benchmarks"})}),"\n",(0,s.jsx)(n.h2,{id:"hashicorp-vault",children:"HashiCorp Vault"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://www.vaultproject.io/",children:"HashiCorp Vault"})," is a distributed secrets management software that can be deployed to Kubernetes.\nHashiCorp maintains a benchmarking tool for vault, ",(0,s.jsx)(n.a,{href:"https://github.com/hashicorp/vault-benchmark/",children:"vault-benchmark"}),".\nVault-benchmark generates load on a Vault deployment and measures response times."]}),"\n",(0,s.jsxs)(n.p,{children:["This article describes the results from running vault-benchmark on Constellation, AKS, and GKE.\nYou can find the setup for producing the data discussed in this article in the ",(0,s.jsx)(n.a,{href:"https://github.com/edgelesssys/vault-benchmarks",children:"vault-benchmarks"})," repository."]}),"\n",(0,s.jsxs)(n.p,{children:["The Vault API used during benchmarking is the ",(0,s.jsx)(n.a,{href:"https://developer.hashicorp.com/vault/docs/secrets/transit",children:"transits secret engine"}),".\nThis allows services to send data to Vault for encryption, decryption, signing, and verification."]}),"\n",(0,s.jsx)(n.h2,{id:"results",children:"Results"}),"\n",(0,s.jsx)(n.p,{children:"On each run, vault-benchmark sends requests and measures the latencies.\nThe measured latencies are aggregated through various statistical features.\nAfter running the benchmark n times, the arithmetic mean over a subset of the reported statistics is calculated.\nThe selected features are arithmetic mean, 99th percentile, minimum, and maximum."}),"\n",(0,s.jsx)(n.p,{children:"Arithmetic mean gives a general sense of the latency on each target.\nThe 99th percentile shows performance in (most likely) erroneous states.\nMinimum and maximum mark the range within which latency varies each run."}),"\n",(0,s.jsx)(n.p,{children:"The benchmark was configured with 1300 workers and 10 seconds per run.\nThose numbers were chosen empirically.\nThe latency was stabilizing at 10 seconds runtime, not changing with further increase.\nIncreasing the number of workers beyond 1300 leads to request failures, marking the limit Vault was able to handle in this setup.\nAll results are based on 100 runs."}),"\n",(0,s.jsx)(n.p,{children:"The following data was generated while running five replicas, one primary, and four standby nodes.\nAll numbers are in seconds if not indicated otherwise."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"========== Results AKS ==========\nMean: mean: 1.632200, variance: 0.002057\nP99: mean: 5.480679, variance: 2.263700\nMax: mean: 6.651001, variance: 2.808401\nMin: mean: 0.011415, variance: 0.000133\n========== Results GKE ==========\nMean: mean: 1.656435, variance: 0.003615\nP99: mean: 6.030807, variance: 3.955051\nMax: mean: 7.164843, variance: 3.300004\nMin: mean: 0.010233, variance: 0.000111\n========== Results C11n ==========\nMean: mean: 1.651549, variance: 0.001610\nP99: mean: 5.780422, variance: 3.016106\nMax: mean: 6.942997, variance: 3.075796\nMin: mean: 0.013774, variance: 0.000228\n========== AKS vs C11n ==========\nMean: +1.171577 % (AKS is faster)\nP99: +5.185495 % (AKS is faster)\nMax: +4.205618 % (AKS is faster)\nMin: +17.128781 % (AKS is faster)\n========== GKE vs C11n ==========\nMean: -0.295851 % (GKE is slower)\nP99: -4.331603 % (GKE is slower)\nMax: -3.195248 % (GKE is slower)\nMin: +25.710886 % (GKE is faster)\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Interpretation"}),": Latencies are all within ~5% of each other.\nAKS performs slightly better than GKE and Constellation (C11n) in all cases except minimum latency.\nMinimum latency is the lowest for GKE.\nCompared to GKE, Constellation had slightly lower peak latencies (99th percentile and maximum), indicating that Constellation could have handled slightly more concurrent accesses than GKE.\nOverall, performance is at comparable levels across all three distributions.\nBased on these numbers, you can use a similarly sized Constellation cluster to run your existing Vault deployment."]}),"\n",(0,s.jsx)(n.h3,{id:"visualization",children:"Visualization"}),"\n",(0,s.jsxs)(n.p,{children:["The following plots visualize the data presented above as ",(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Box_plot",children:"box plots"}),".\nThe whiskers denote the minimum and maximum.\nThe box stretches from the 25th to the 75th percentile, with the dividing bar marking the 50th percentile.\nThe circles outside the whiskers denote outliers."]}),"\n",(0,s.jsxs)(a,{children:[(0,s.jsx)("summary",{children:"Mean Latency"}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Mean Latency",src:t(4220).A+"",width:"576",height:"576"})})]}),"\n",(0,s.jsxs)(a,{children:[(0,s.jsx)("summary",{children:"99th Percentile Latency"}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"99th Percentile Latency",src:t(99019).A+"",width:"576",height:"576"})})]}),"\n",(0,s.jsxs)(a,{children:[(0,s.jsx)("summary",{children:"Maximum Latency"}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Maximum Latency",src:t(10171).A+"",width:"576",height:"576"})})]}),"\n",(0,s.jsxs)(a,{children:[(0,s.jsx)("summary",{children:"Minimum Latency"}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Minimum Latency",src:t(357).A+"",width:"576",height:"576"})})]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},99019:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/p99_latency-fd60c7ae80666133370f9b8e47404994.png"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/a7e69b4a.72ef9c11.js b/pr-preview/pr-4027/assets/js/a7e69b4a.72ef9c11.js deleted file mode 100644 index 67d21b4a7..000000000 --- a/pr-preview/pr-4027/assets/js/a7e69b4a.72ef9c11.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8146],{7210:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Getting started","slug":"/category/getting-started","permalink":"/constellation/pr-preview/pr-4027/category/getting-started","sidebar":"docs","navigation":{"previous":{"title":"License","permalink":"/constellation/pr-preview/pr-4027/overview/license"},"next":{"title":"Installation","permalink":"/constellation/pr-preview/pr-4027/getting-started/install"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/a93f81ab.12d75ad1.js b/pr-preview/pr-4027/assets/js/a93f81ab.12d75ad1.js deleted file mode 100644 index 9b4081cdd..000000000 --- a/pr-preview/pr-4027/assets/js/a93f81ab.12d75ad1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7218],{1338:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"overview/product","title":"Product features","description":"Constellation is a Kubernetes engine that aims to provide the best possible data security in combination with enterprise-grade scalability and reliability features---and a smooth user experience.","source":"@site/versioned_docs/version-2.24/overview/product.md","sourceDirName":"overview","slug":"/overview/product","permalink":"/constellation/pr-preview/pr-4027/overview/product","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/overview/product.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Security benefits","permalink":"/constellation/pr-preview/pr-4027/overview/security-benefits"},"next":{"title":"Feature status of clouds","permalink":"/constellation/pr-preview/pr-4027/overview/clouds"}}');var s=r(74848),n=r(28453);const i={},a="Product features",l={},c=[];function u(e){const t={a:"a",h1:"h1",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,n.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"product-features",children:"Product features"})}),"\n",(0,s.jsx)(t.p,{children:"Constellation is a Kubernetes engine that aims to provide the best possible data security in combination with enterprise-grade scalability and reliability features---and a smooth user experience."}),"\n",(0,s.jsxs)(t.p,{children:["From a security perspective, Constellation implements the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/overview/confidential-kubernetes",children:"Confidential Kubernetes"})," concept and corresponding security features, which shield your entire cluster from the underlying infrastructure."]}),"\n",(0,s.jsx)(t.p,{children:"From an operational perspective, Constellation provides the following key features:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Native support for different clouds"}),": Constellation works on Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), and STACKIT. Support for OpenStack-based environments is coming with a future release. Constellation securely interfaces with the cloud infrastructure to provide ",(0,s.jsx)(t.a,{href:"https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler",children:"cluster autoscaling"}),", ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/storage/dynamic-provisioning/",children:"dynamic persistent volumes"}),", and ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer",children:"service load balancing"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"High availability"}),": Constellation uses a ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/",children:"multi-master architecture"})," with a ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/ha-topology/#stacked-etcd-topology",children:"stacked etcd topology"})," to ensure high availability."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Integrated Day-2 operations"}),": Constellation lets you securely ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/upgrade",children:"upgrade"})," your cluster to a new release. It also lets you securely ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/recovery",children:"recover"})," a failed cluster. Both with a single command."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Support for Terraform"}),": Constellation includes a ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/terraform-provider",children:"Terraform provider"})," that lets you manage the full lifecycle of your cluster via Terraform."]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>a});var o=r(96540);const s={},n=o.createContext(s);function i(e){const t=o.useContext(n);return o.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/a94703ab.2a6d89c3.js b/pr-preview/pr-4027/assets/js/a94703ab.2a6d89c3.js deleted file mode 100644 index 0e00bce62..000000000 --- a/pr-preview/pr-4027/assets/js/a94703ab.2a6d89c3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9048],{59818:(e,t,n)=>{n.r(t),n.d(t,{default:()=>ke});var a=n(96540),i=n(34164),o=n(17153),s=n(18630),l=n(45357),r=n(20040),c=n(23230),d=n(24245),u=n(54067);const m={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};var b=n(74848);function h(){const{shown:e,scrollToTop:t}=function({threshold:e}){const[t,n]=(0,a.useState)(!1),i=(0,a.useRef)(!1),{startScroll:o,cancelScroll:s}=(0,d.gk)();return(0,d.Mq)(({scrollY:t},a)=>{const o=a?.scrollY;o&&(i.current?i.current=!1:t>=o?(s(),n(!1)):t<e?n(!1):t+window.innerHeight<document.documentElement.scrollHeight&&n(!0))}),(0,u.$)(e=>{e.location.hash&&(i.current=!0,n(!1))}),{shown:t,scrollToTop:()=>o(0)}}({threshold:300});return(0,b.jsx)("button",{"aria-label":(0,c.T)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,i.A)("clean-btn",s.G.common.backToTopButton,m.backToTopButton,e&&m.backToTopButtonShow),type:"button",onClick:t})}var p=n(36350),x=n(56347),j=n(82216),f=n(86957),_=n(20020);function g(e){return(0,b.jsx)("svg",{width:"20",height:"20","aria-hidden":"true",...e,children:(0,b.jsxs)("g",{fill:"#7a7a7a",children:[(0,b.jsx)("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),(0,b.jsx)("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})]})})}const v="collapseSidebarButton_PEFL",k="collapseSidebarButtonIcon_kv0_";function A({onClick:e}){return(0,b.jsx)("button",{type:"button",title:(0,c.T)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,i.A)("button button--secondary button--outline",v),onClick:e,children:(0,b.jsx)(g,{className:k})})}var C=n(40002),S=n(4799);const T=Symbol("EmptyContext"),N=a.createContext(T);function I({children:e}){const[t,n]=(0,a.useState)(null),i=(0,a.useMemo)(()=>({expandedItem:t,setExpandedItem:n}),[t]);return(0,b.jsx)(N.Provider,{value:i,children:e})}var y=n(94549),B=n(80260),L=n(14783),w=n(11062),E=n(40877),M=n(90716);const H="menuExternalLink_NmtK",P="linkLabel_WmDU";function G({label:e}){return(0,b.jsx)("span",{title:e,className:P,children:e})}function W({item:e,onItemClick:t,activePath:n,level:a,index:o,...r}){const{href:c,label:d,className:u,autoAddBaseUrl:m}=e,h=(0,l.w8)(e,n),p=(0,E.A)(c);return(0,b.jsx)("li",{className:(0,i.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(a),"menu__list-item",u),children:(0,b.jsxs)(L.A,{className:(0,i.A)("menu__link",!p&&H,{"menu__link--active":h}),autoAddBaseUrl:m,"aria-current":h?"page":void 0,to:c,...p&&{onClick:t?()=>t(e):void 0},...r,children:[(0,b.jsx)(G,{label:d}),!p&&(0,b.jsx)(M.A,{})]})},d)}const R="categoryLink_byQd",D="categoryLinkLabel_W154";function U({collapsed:e,categoryLabel:t,onClick:n}){return(0,b.jsx)("button",{"aria-label":e?(0,c.T)({id:"theme.DocSidebarItem.expandCategoryAriaLabel",message:"Expand sidebar category '{label}'",description:"The ARIA label to expand the sidebar category"},{label:t}):(0,c.T)({id:"theme.DocSidebarItem.collapseCategoryAriaLabel",message:"Collapse sidebar category '{label}'",description:"The ARIA label to collapse the sidebar category"},{label:t}),"aria-expanded":!e,type:"button",className:"clean-btn menu__caret",onClick:n})}function F({label:e}){return(0,b.jsx)("span",{title:e,className:D,children:e})}function V(e){return 0===(0,l.Y)(e.item.items,e.activePath).length?(0,b.jsx)(Y,{...e}):(0,b.jsx)(K,{...e})}function Y({item:e,...t}){if("string"!=typeof e.href)return null;const{type:n,collapsed:a,collapsible:i,items:o,linkUnlisted:s,...l}=e,r={type:"link",...l};return(0,b.jsx)(W,{item:r,...t})}function K({item:e,onItemClick:t,activePath:n,level:o,index:r,...c}){const{items:d,label:u,collapsible:m,className:h,href:p}=e,{docs:{sidebar:{autoCollapseCategories:x}}}=(0,f.p)(),j=function(e){const t=(0,w.A)();return(0,a.useMemo)(()=>e.href&&!e.linkUnlisted?e.href:!t&&e.collapsible?(0,l.Nr)(e):void 0,[e,t])}(e),_=(0,l.w8)(e,n),g=(0,B.ys)(p,n),{collapsed:v,setCollapsed:k}=(0,y.u)({initialState:()=>!!m&&(!_&&e.collapsed)}),{expandedItem:A,setExpandedItem:C}=function(){const e=(0,a.useContext)(N);if(e===T)throw new S.dV("DocSidebarItemsExpandedStateProvider");return e}(),I=(e=!v)=>{C(e?null:r),k(e)};!function({isActive:e,collapsed:t,updateCollapsed:n,activePath:i}){const o=(0,S.ZC)(e),s=(0,S.ZC)(i);(0,a.useEffect)(()=>{(e&&!o||e&&o&&i!==s)&&t&&n(!1)},[e,o,t,n,i,s])}({isActive:_,collapsed:v,updateCollapsed:I,activePath:n}),(0,a.useEffect)(()=>{m&&null!=A&&A!==r&&x&&k(!0)},[m,A,r,k,x]);return(0,b.jsxs)("li",{className:(0,i.A)(s.G.docs.docSidebarItemCategory,s.G.docs.docSidebarItemCategoryLevel(o),"menu__list-item",{"menu__list-item--collapsed":v},h),children:[(0,b.jsxs)("div",{className:(0,i.A)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":g}),children:[(0,b.jsx)(L.A,{className:(0,i.A)(R,"menu__link",{"menu__link--sublist":m,"menu__link--sublist-caret":!p&&m,"menu__link--active":_}),onClick:n=>{t?.(e),m&&(p?g?(n.preventDefault(),I()):I(!1):(n.preventDefault(),I()))},"aria-current":g?"page":void 0,role:m&&!p?"button":void 0,"aria-expanded":m&&!p?!v:void 0,href:m?j??"#":j,...c,children:(0,b.jsx)(F,{label:u})}),p&&m&&(0,b.jsx)(U,{collapsed:v,categoryLabel:u,onClick:e=>{e.preventDefault(),I()}})]}),(0,b.jsx)(y.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:v,children:(0,b.jsx)(Z,{items:d,tabIndex:v?-1:0,onItemClick:t,activePath:n,level:o+1})})]})}const z="menuHtmlItem_M9Kj";function q({item:e,level:t,index:n}){const{value:a,defaultStyle:o,className:l}=e;return(0,b.jsx)("li",{className:(0,i.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(t),o&&[z,"menu__list-item"],l),dangerouslySetInnerHTML:{__html:a}},n)}function O({item:e,...t}){switch(e.type){case"category":return(0,b.jsx)(V,{item:e,...t});case"html":return(0,b.jsx)(q,{item:e,...t});default:return(0,b.jsx)(W,{item:e,...t})}}function Q({items:e,...t}){const n=(0,l.Y)(e,t.activePath);return(0,b.jsx)(I,{children:n.map((e,n)=>(0,b.jsx)(O,{item:e,index:n,...t},n))})}const Z=(0,a.memo)(Q),J="menu_SIkG",X="menuWithAnnouncementBar_GW3s";function $({path:e,sidebar:t,className:n}){const o=function(){const{isActive:e}=(0,C.M)(),[t,n]=(0,a.useState)(e);return(0,d.Mq)(({scrollY:t})=>{e&&n(0===t)},[e]),e&&t}();return(0,b.jsx)("nav",{"aria-label":(0,c.T)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,i.A)("menu thin-scrollbar",J,o&&X,n),children:(0,b.jsx)("ul",{className:(0,i.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(Z,{items:t,activePath:e,level:1})})})}const ee="sidebar_njMd",te="sidebarWithHideableNavbar_wUlq",ne="sidebarHidden_VK0M",ae="sidebarLogo_isFc";function ie({path:e,sidebar:t,onCollapse:n,isHidden:a}){const{navbar:{hideOnScroll:o},docs:{sidebar:{hideable:s}}}=(0,f.p)();return(0,b.jsxs)("div",{className:(0,i.A)(ee,o&&te,a&&ne),children:[o&&(0,b.jsx)(_.A,{tabIndex:-1,className:ae}),(0,b.jsx)($,{path:e,sidebar:t}),s&&(0,b.jsx)(A,{onClick:n})]})}const oe=a.memo(ie);var se=n(70763),le=n(61938);const re=({sidebar:e,path:t})=>{const n=(0,le.M)();return(0,b.jsx)("ul",{className:(0,i.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(Z,{items:e,activePath:t,onItemClick:e=>{"category"===e.type&&e.href&&n.toggle(),"link"===e.type&&n.toggle()},level:1})})};function ce(e){return(0,b.jsx)(se.GX,{component:re,props:e})}const de=a.memo(ce);function ue(e){const t=(0,j.l)(),n="desktop"===t||"ssr"===t,a="mobile"===t;return(0,b.jsxs)(b.Fragment,{children:[n&&(0,b.jsx)(oe,{...e}),a&&(0,b.jsx)(de,{...e})]})}const me={expandButton:"expandButton_TmdG",expandButtonIcon:"expandButtonIcon_i1dp"};function be({toggleSidebar:e}){return(0,b.jsx)("div",{className:me.expandButton,title:(0,c.T)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:e,onClick:e,children:(0,b.jsx)(g,{className:me.expandButtonIcon})})}const he={docSidebarContainer:"docSidebarContainer_YfHR",docSidebarContainerHidden:"docSidebarContainerHidden_DPk8",sidebarViewport:"sidebarViewport_aRkj"};function pe({children:e}){const t=(0,r.t)();return(0,b.jsx)(a.Fragment,{children:e},t?.name??"noSidebar")}function xe({sidebar:e,hiddenSidebarContainer:t,setHiddenSidebarContainer:n}){const{pathname:o}=(0,x.zy)(),[l,r]=(0,a.useState)(!1),c=(0,a.useCallback)(()=>{l&&r(!1),!l&&(0,p.O)()&&r(!0),n(e=>!e)},[n,l]);return(0,b.jsx)("aside",{className:(0,i.A)(s.G.docs.docSidebarContainer,he.docSidebarContainer,t&&he.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(he.docSidebarContainer)&&t&&r(!0)},children:(0,b.jsx)(pe,{children:(0,b.jsxs)("div",{className:(0,i.A)(he.sidebarViewport,l&&he.sidebarViewportHidden),children:[(0,b.jsx)(ue,{sidebar:e,path:o,onCollapse:c,isHidden:l}),l&&(0,b.jsx)(be,{toggleSidebar:c})]})})})}const je={docMainContainer:"docMainContainer_TBSr",docMainContainerEnhanced:"docMainContainerEnhanced_lQrH",docItemWrapperEnhanced:"docItemWrapperEnhanced_JWYK"};function fe({hiddenSidebarContainer:e,children:t}){const n=(0,r.t)();return(0,b.jsx)("main",{className:(0,i.A)(je.docMainContainer,(e||!n)&&je.docMainContainerEnhanced),children:(0,b.jsx)("div",{className:(0,i.A)("container padding-top--md padding-bottom--lg",je.docItemWrapper,e&&je.docItemWrapperEnhanced),children:t})})}const _e={docRoot:"docRoot_UBD9",docsWrapper:"docsWrapper_hBAB"};function ge({children:e}){const t=(0,r.t)(),[n,i]=(0,a.useState)(!1);return(0,b.jsxs)("div",{className:_e.docsWrapper,children:[(0,b.jsx)(h,{}),(0,b.jsxs)("div",{className:_e.docRoot,children:[t&&(0,b.jsx)(xe,{sidebar:t.items,hiddenSidebarContainer:n,setHiddenSidebarContainer:i}),(0,b.jsx)(fe,{hiddenSidebarContainer:n,children:e})]})]})}var ve=n(83510);function ke(e){const t=(0,l.B5)(e);if(!t)return(0,b.jsx)(ve.A,{});const{docElement:n,sidebarName:a,sidebarItems:c}=t;return(0,b.jsx)(o.e3,{className:(0,i.A)(s.G.page.docsDocPage),children:(0,b.jsx)(r.V,{name:a,items:c,children:(0,b.jsx)(ge,{children:n})})})}},83510:(e,t,n)=>{n.d(t,{A:()=>l});n(96540);var a=n(34164),i=n(23230),o=n(85225),s=n(74848);function l({className:e}){return(0,s.jsx)("main",{className:(0,a.A)("container margin-vert--xl",e),children:(0,s.jsx)("div",{className:"row",children:(0,s.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,s.jsx)(o.A,{as:"h1",className:"hero__title",children:(0,s.jsx)(i.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,s.jsx)("p",{children:(0,s.jsx)(i.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,s.jsx)("p",{children:(0,s.jsx)(i.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/aba21aa0.7466539b.js b/pr-preview/pr-4027/assets/js/aba21aa0.7466539b.js deleted file mode 100644 index db8aa652f..000000000 --- a/pr-preview/pr-4027/assets/js/aba21aa0.7466539b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5742],{27093:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"default"}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/acced080.7d6c4195.js b/pr-preview/pr-4027/assets/js/acced080.7d6c4195.js deleted file mode 100644 index e4a338c10..000000000 --- a/pr-preview/pr-4027/assets/js/acced080.7d6c4195.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1587],{48609:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Basics","slug":"/category/basics","permalink":"/constellation/pr-preview/pr-4027/2.22/category/basics","sidebar":"docs","navigation":{"previous":{"title":"Introduction","permalink":"/constellation/pr-preview/pr-4027/2.22/"},"next":{"title":"Confidential Kubernetes","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/confidential-kubernetes"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/acf362b0.e0ac5608.js b/pr-preview/pr-4027/assets/js/acf362b0.e0ac5608.js deleted file mode 100644 index 99d27498f..000000000 --- a/pr-preview/pr-4027/assets/js/acf362b0.e0ac5608.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1516],{347:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/concept-constellation-f869032711a972295d5ddce42c37995c.svg"},9127:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"overview/confidential-kubernetes","title":"Confidential Kubernetes","description":"We use the term Confidential Kubernetes to refer to the concept of using confidential-computing technology to shield entire Kubernetes clusters from the infrastructure. The three defining properties of this concept are:","source":"@site/docs/overview/confidential-kubernetes.md","sourceDirName":"overview","slug":"/overview/confidential-kubernetes","permalink":"/constellation/pr-preview/pr-4027/next/overview/confidential-kubernetes","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/overview/confidential-kubernetes.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Basics","permalink":"/constellation/pr-preview/pr-4027/next/category/basics"},"next":{"title":"Security benefits","permalink":"/constellation/pr-preview/pr-4027/next/overview/security-benefits"}}');var i=n(74848),s=n(28453);const o={},a="Confidential Kubernetes",l={},c=[{value:"Constellation security features",id:"constellation-security-features",level:2},{value:"Comparison: Managed Kubernetes with CVMs",id:"comparison-managed-kubernetes-with-cvms",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"confidential-kubernetes",children:"Confidential Kubernetes"})}),"\n",(0,i.jsxs)(t.p,{children:["We use the term ",(0,i.jsx)(t.em,{children:"Confidential Kubernetes"})," to refer to the concept of using confidential-computing technology to shield entire Kubernetes clusters from the infrastructure. The three defining properties of this concept are:"]}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Workload shielding"}),": the confidentiality and integrity of all workload-related data and code are enforced."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Control plane shielding"}),": the confidentiality and integrity of the cluster's control plane, state, and workload configuration are enforced."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Attestation and verifiability"}),": the two properties above can be verified remotely based on hardware-rooted cryptographic certificates."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Each of the above properties is equally important. Only with all three in conjunction, an entire cluster can be shielded without gaps."}),"\n",(0,i.jsx)(t.h2,{id:"constellation-security-features",children:"Constellation security features"}),"\n",(0,i.jsx)(t.p,{children:"Constellation implements the Confidential Kubernetes concept with the following security features."}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Runtime encryption"}),": Constellation runs all Kubernetes nodes inside Confidential VMs (CVMs). This gives runtime encryption for the entire cluster."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Network and storage encryption"}),": Constellation augments this with transparent encryption of the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/networking",children:"network"}),", ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage",children:"persistent storage"}),", and other managed storage like ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage#encrypted-s3-object-storage",children:"AWS S3"}),". Thus, workloads and control plane are truly end-to-end encrypted: at rest, in transit, and at runtime."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Transparent key management"}),": Constellation manages the corresponding ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys",children:"cryptographic keys"})," inside CVMs."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Node attestation and verification"}),": Constellation verifies the integrity of each new CVM-based node using ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/attestation",children:"remote attestation"}),'. Only "good" nodes receive the cryptographic keys required to access the network and storage of a cluster.']}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Confidential computing-optimized images"}),': A node is "good" if it\'s running a signed Constellation ',(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/images",children:"node image"})," inside a CVM and is in the expected state. (Node images are hardware-measured during boot. The measurements are reflected in the attestation statements that are produced by nodes and verified by Constellation.)"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:'"Whole cluster" attestation'}),": Towards the DevOps engineer, Constellation provides a single hardware-rooted certificate from which all of the above can be verified."]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["With the above, Constellation wraps an entire cluster into one coherent and verifiable ",(0,i.jsx)(t.em,{children:"confidential context"}),". The concept is depicted in the following."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Confidential Kubernetes",src:n(347).A+"",width:"3767",height:"1902"})}),"\n",(0,i.jsx)(t.h2,{id:"comparison-managed-kubernetes-with-cvms",children:"Comparison: Managed Kubernetes with CVMs"}),"\n",(0,i.jsxs)(t.p,{children:["In comparison, managed Kubernetes with CVMs, as it's for example offered in ",(0,i.jsx)(t.a,{href:"https://azure.microsoft.com/en-us/services/kubernetes-service/",children:"AKS"})," and ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/kubernetes-engine",children:"GKE"}),", only provides runtime encryption for certain worker nodes. Here, each worker node is a separate (and typically unverified) confidential context. This only provides limited security benefits as it only prevents direct access to a worker node's memory. The large majority of potential attacks through the infrastructure remain unaffected. This includes attacks through the control plane, access to external key management, and the corruption of worker node images. This leaves many problems unsolved. For instance, ",(0,i.jsx)(t.em,{children:"Node A"})," has no means to verify if ",(0,i.jsx)(t.em,{children:"Node B"}),' is "good" and if it\'s OK to share data with it. Consequently, this approach leaves a large attack surface, as is depicted in the following.']}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Concept: Managed Kubernetes plus CVMs",src:n(66309).A+"",width:"3767",height:"1902"})}),"\n",(0,i.jsx)(t.p,{children:"The following table highlights the key differences in terms of features."}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{}),(0,i.jsx)(t.th,{children:"Managed Kubernetes with CVMs"}),(0,i.jsx)(t.th,{children:"Confidential Kubernetes (Constellation\u2728)"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Runtime encryption"}),(0,i.jsx)(t.td,{children:"Partial (data plane only)"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Node image verification"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Full cluster attestation"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Transparent network encryption"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Transparent storage encryption"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Confidential key management"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Cloud agnostic / multi-cloud"}),(0,i.jsx)(t.td,{children:"No"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Yes"})})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var r=n(96540);const i={},s=r.createContext(i);function o(e){const t=r.useContext(s);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(s.Provider,{value:t},e.children)}},66309:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/concept-managed-33482ac199f949182872dc32d69bd3bc.svg"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/adfda302.e01c344d.js b/pr-preview/pr-4027/assets/js/adfda302.e01c344d.js deleted file mode 100644 index b290188fb..000000000 --- a/pr-preview/pr-4027/assets/js/adfda302.e01c344d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6144],{28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>a});var n=r(96540);const s={},i=n.createContext(s);function o(e){const t=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),n.createElement(i.Provider,{value:t},e.children)}},40602:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"architecture/orchestration","title":"Orchestrating Constellation clusters","description":"You can use the CLI to create a cluster on the supported cloud platforms.","source":"@site/versioned_docs/version-2.23/architecture/orchestration.md","sourceDirName":"architecture","slug":"/architecture/orchestration","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/orchestration","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/architecture/orchestration.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/overview"},"next":{"title":"Versions and support","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/versions"}}');var s=r(74848),i=r(28453);const o={},a="Orchestrating Constellation clusters",c={},l=[{value:"Workspaces",id:"workspaces",level:2},{value:"Cluster creation process",id:"cluster-creation-process",level:2},{value:"Creation process details",id:"creation-process-details",level:3},{value:"Post-installation configuration",id:"post-installation-configuration",level:2},{value:"Upgrades",id:"upgrades",level:2},{value:"Attestation of upgrades",id:"attestation-of-upgrades",level:3}];function h(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"orchestrating-constellation-clusters",children:"Orchestrating Constellation clusters"})}),"\n",(0,s.jsx)(t.p,{children:"You can use the CLI to create a cluster on the supported cloud platforms.\nThe CLI provisions the resources in your cloud environment and initiates the initialization of your cluster.\nIt uses a set of parameters and an optional configuration file to manage your cluster installation.\nThe CLI is also used for updating your cluster."}),"\n",(0,s.jsx)(t.h2,{id:"workspaces",children:"Workspaces"}),"\n",(0,s.jsxs)(t.p,{children:["Each Constellation cluster has an associated ",(0,s.jsx)(t.em,{children:"workspace"}),".\nThe workspace is where data such as the Constellation state and config files are stored.\nEach workspace is associated with a single cluster and configuration.\nThe CLI stores state in the local filesystem making the current directory the active workspace.\nMultiple clusters require multiple workspaces, hence, multiple directories.\nNote that every operation on a cluster always has to be performed from the directory associated with its workspace."]}),"\n",(0,s.jsx)(t.p,{children:"You may copy files from the workspace to other locations,\nbut you shouldn't move or delete them while the cluster is still being used.\nThe Constellation CLI takes care of managing the workspace.\nOnly when a cluster was terminated, and you are sure the files aren't needed anymore, should you remove a workspace."}),"\n",(0,s.jsx)(t.h2,{id:"cluster-creation-process",children:"Cluster creation process"}),"\n",(0,s.jsxs)(t.p,{children:["To allow for fine-grained configuration of your cluster and cloud environment, Constellation supports an extensive configuration file with strong defaults. ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/config",children:"Generating the configuration file"})," is typically the first thing you do in the workspace."]}),"\n",(0,s.jsx)(t.p,{children:"Altogether, the following files are generated during the creation of a Constellation cluster and stored in the current workspace:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"a configuration file"}),"\n",(0,s.jsx)(t.li,{children:"a state file"}),"\n",(0,s.jsx)(t.li,{children:"a Base64-encoded master secret"}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/reference/terraform",children:"Terraform artifacts"}),", stored in subdirectories"]}),"\n",(0,s.jsxs)(t.li,{children:["a Kubernetes ",(0,s.jsx)(t.code,{children:"kubeconfig"})," file."]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["After the initialization of your cluster, the CLI will provide you with a Kubernetes ",(0,s.jsx)(t.code,{children:"kubeconfig"})," file.\nThis file grants you access to your Kubernetes cluster and configures the ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/",children:"kubectl"})," tool.\nIn addition, the cluster's ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/orchestration#post-installation-configuration",children:"identifier"})," is returned and stored in the state file."]}),"\n",(0,s.jsx)(t.h3,{id:"creation-process-details",children:"Creation process details"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["The CLI ",(0,s.jsx)(t.code,{children:"apply"})," command first creates the confidential VM (CVM) resources in your cloud environment and configures the network"]}),"\n",(0,s.jsx)(t.li,{children:"Each CVM boots the Constellation node image and measures every component in the boot chain"}),"\n",(0,s.jsxs)(t.li,{children:["The first microservice launched in each node is the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#bootstrapper",children:(0,s.jsx)(t.em,{children:"Bootstrapper"})})]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"Bootstrapper"})," waits until it either receives an initialization request or discovers an initialized cluster"]}),"\n",(0,s.jsxs)(t.li,{children:["The CLI then connects to the ",(0,s.jsx)(t.em,{children:"Bootstrapper"})," of a selected node, sends the configuration, and initiates the initialization of the cluster"]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"Bootstrapper"})," of ",(0,s.jsx)(t.strong,{children:"that"})," node ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#bootstrapper",children:"initializes the Kubernetes cluster"})," and deploys the other Constellation ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices",children:"microservices"})," including the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#joinservice",children:(0,s.jsx)(t.em,{children:"JoinService"})})]}),"\n",(0,s.jsxs)(t.li,{children:["Subsequently, the ",(0,s.jsx)(t.em,{children:"Bootstrappers"})," of the other nodes discover the initialized cluster and send join requests to the ",(0,s.jsx)(t.em,{children:"JoinService"})]}),"\n",(0,s.jsx)(t.li,{children:"As part of the join request each node includes an attestation statement of its boot measurements as authentication"}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"JoinService"})," verifies the attestation statements and joins the nodes to the Kubernetes cluster"]}),"\n",(0,s.jsx)(t.li,{children:"This process is repeated for every node joining the cluster later (e.g., through autoscaling)"}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"post-installation-configuration",children:"Post-installation configuration"}),"\n",(0,s.jsxs)(t.p,{children:["Post-installation the CLI provides a configuration for ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-api/",children:"accessing the cluster using the Kubernetes API"}),".\nThe ",(0,s.jsx)(t.code,{children:"kubeconfig"})," file provides the credentials and configuration for connecting and authenticating to the API server.\nOnce configured, orchestrate the Kubernetes cluster via ",(0,s.jsx)(t.code,{children:"kubectl"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"After the initialization, the CLI will present you with a couple of tokens:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys#master-secret",children:(0,s.jsx)(t.em,{children:"master secret"})})," (stored in the ",(0,s.jsx)(t.code,{children:"constellation-mastersecret.json"})," file by default)"]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys#cluster-identity",children:(0,s.jsx)(t.em,{children:"clusterID"})})," of your cluster in Base64 encoding"]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["You can read more about these values and their meaning in the guide on ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys#cluster-identity",children:"cluster identity"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.em,{children:"master secret"})," must be kept secret and can be used to ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/recovery",children:"recover your cluster"}),".\nInstead of managing this secret manually, you can ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/keys#user-managed-key-management",children:"use your key management solution of choice"})," with Constellation."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.em,{children:"clusterID"})," uniquely identifies a cluster and can be used to ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cluster",children:"verify your cluster"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"upgrades",children:"Upgrades"}),"\n",(0,s.jsxs)(t.p,{children:["Constellation images and microservices may need to be upgraded to new versions during the lifetime of a cluster.\nConstellation implements a rolling update mechanism ensuring no downtime of the control or data plane.\nYou can upgrade a Constellation cluster with a single operation by using the CLI.\nFor step-by-step instructions on how to do this, refer to ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/upgrade",children:"Upgrade your cluster"}),"."]}),"\n",(0,s.jsx)(t.h3,{id:"attestation-of-upgrades",children:"Attestation of upgrades"}),"\n",(0,s.jsxs)(t.p,{children:["With every new image, corresponding measurements are released.\nDuring an update procedure, the CLI provides new measurements to the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#joinservice",children:"JoinService"})," securely.\nNew measurements for an updated image are automatically pulled and verified by the CLI following the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation#chain-of-trust",children:"supply chain security concept"})," of Constellation.\nThe ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation#cluster-facing-attestation",children:"attestation section"})," describes in detail how these measurements are then used by the JoinService for the attestation of nodes."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/ae4682fc.bd09743d.js b/pr-preview/pr-4027/assets/js/ae4682fc.bd09743d.js deleted file mode 100644 index f93806f81..000000000 --- a/pr-preview/pr-4027/assets/js/ae4682fc.bd09743d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[308],{28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>l});var i=n(96540);const r={},t=i.createContext(r);function o(e){const s=i.useContext(t);return i.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(t.Provider,{value:s},e.children)}},56746:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"overview/license","title":"License","description":"Source code","source":"@site/versioned_docs/version-2.22/overview/license.md","sourceDirName":"overview","slug":"/overview/license","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/license","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/overview/license.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Application benchmarks","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/performance/application"},"next":{"title":"Getting started","permalink":"/constellation/pr-preview/pr-4027/2.22/category/getting-started"}}');var r=n(74848),t=n(28453);const o={},l="License",a={},c=[{value:"Source code",id:"source-code",level:2},{value:"Binaries",id:"binaries",level:2},{value:"Terraform provider",id:"terraform-provider",level:2},{value:"Community License",id:"community-license",level:2},{value:"Enterprise License",id:"enterprise-license",level:2},{value:"CSP Marketplaces",id:"csp-marketplaces",level:2}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",strong:"strong",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"license",children:"License"})}),"\n",(0,r.jsx)(s.h2,{id:"source-code",children:"Source code"}),"\n",(0,r.jsxs)(s.p,{children:["Constellation's source code is available on ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation",children:"GitHub"})," under the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/blob/main/LICENSE",children:"GNU Affero General Public License v3.0"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"binaries",children:"Binaries"}),"\n",(0,r.jsxs)(s.p,{children:["Edgeless Systems provides ready-to-use and ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#chain-of-trust",children:"signed"})," binaries of Constellation. This includes the CLI and the ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/images",children:"node images"}),"."]}),"\n",(0,r.jsxs)(s.p,{children:["These binaries may be used free of charge within the bounds of Constellation's ",(0,r.jsx)(s.a,{href:"#community-license",children:(0,r.jsx)(s.strong,{children:"Community License"})}),". An ",(0,r.jsx)(s.a,{href:"#enterprise-license",children:(0,r.jsx)(s.strong,{children:"Enterprise License"})})," can be purchased from Edgeless Systems."]}),"\n",(0,r.jsx)(s.p,{children:"The Constellation CLI displays relevant license information when you initialize your cluster. You are responsible for staying within the bounds of your respective license. Constellation doesn't enforce any limits so as not to endanger your cluster's availability."}),"\n",(0,r.jsx)(s.h2,{id:"terraform-provider",children:"Terraform provider"}),"\n",(0,r.jsxs)(s.p,{children:["Edgeless Systems provides a ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/terraform-provider-constellation/releases",children:"Terraform provider"}),", which may be used free of charge within the bounds of Constellation's ",(0,r.jsx)(s.a,{href:"#community-license",children:(0,r.jsx)(s.strong,{children:"Community License"})}),". An ",(0,r.jsx)(s.a,{href:"#enterprise-license",children:(0,r.jsx)(s.strong,{children:"Enterprise License"})})," can be purchased from Edgeless Systems."]}),"\n",(0,r.jsx)(s.p,{children:"You are responsible for staying within the bounds of your respective license. Constellation doesn't enforce any limits so as not to endanger your cluster's availability."}),"\n",(0,r.jsx)(s.h2,{id:"community-license",children:"Community License"}),"\n",(0,r.jsx)(s.p,{children:"You are free to use the Constellation binaries provided by Edgeless Systems to create services for internal consumption, evaluation purposes, or non-commercial use. You must not use the Constellation binaries to provide commercial hosted services to third parties. Edgeless Systems gives no warranties and offers no support."}),"\n",(0,r.jsx)(s.h2,{id:"enterprise-license",children:"Enterprise License"}),"\n",(0,r.jsxs)(s.p,{children:["Enterprise Licenses don't have the above limitations and come with support and additional features. Find out more at the ",(0,r.jsx)(s.a,{href:"https://www.edgeless.systems/products/constellation/",children:"product website"}),"."]}),"\n",(0,r.jsxs)(s.p,{children:["Once you have received your Enterprise License file, place it in your ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration#workspaces",children:"Constellation workspace"})," in a file named ",(0,r.jsx)(s.code,{children:"constellation.license"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"csp-marketplaces",children:"CSP Marketplaces"}),"\n",(0,r.jsxs)(s.p,{children:["Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please ",(0,r.jsx)(s.a,{href:"https://www.edgeless.systems/enterprise-support/",children:"contact us"}),"."]})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/af08314d.13910ef0.js b/pr-preview/pr-4027/assets/js/af08314d.13910ef0.js deleted file mode 100644 index 5678a5ede..000000000 --- a/pr-preview/pr-4027/assets/js/af08314d.13910ef0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3182],{28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>a});var n=r(96540);const i={},s=n.createContext(i);function o(e){const t=n.useContext(s);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),n.createElement(s.Provider,{value:t},e.children)}},53996:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"architecture/encrypted-storage","title":"Encrypted persistent storage","description":"Confidential VMs provide runtime memory encryption to protect data in use.","source":"@site/versioned_docs/version-2.24/architecture/encrypted-storage.md","sourceDirName":"architecture","slug":"/architecture/encrypted-storage","permalink":"/constellation/pr-preview/pr-4027/architecture/encrypted-storage","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/architecture/encrypted-storage.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Keys and cryptographic primitives","permalink":"/constellation/pr-preview/pr-4027/architecture/keys"},"next":{"title":"Networking","permalink":"/constellation/pr-preview/pr-4027/architecture/networking"}}');var i=r(74848),s=r(28453);const o={},a="Encrypted persistent storage",c={},d=[{value:"Cloud provider-managed encryption",id:"cloud-provider-managed-encryption",level:2},{value:"Constellation-managed encryption",id:"constellation-managed-encryption",level:2},{value:"Cryptographic algorithms",id:"cryptographic-algorithms",level:2},{value:"dm-crypt",id:"dm-crypt",level:3},{value:"dm-integrity",id:"dm-integrity",level:3},{value:"Encrypted S3 object storage",id:"encrypted-s3-object-storage",level:2}];function l(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"encrypted-persistent-storage",children:"Encrypted persistent storage"})}),"\n",(0,i.jsxs)(t.p,{children:["Confidential VMs provide runtime memory encryption to protect data in use.\nIn the context of Kubernetes, this is sufficient for the confidentiality and integrity of stateless services.\nConsider a front-end web server, for example, that keeps all connection information cached in main memory.\nNo sensitive data is ever written to an insecure medium.\nHowever, many real-world applications need some form of state or data-lake service that's connected to a persistent storage device and requires encryption at rest.\nAs described in ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/storage",children:"Use persistent storage"}),", cloud service providers (CSPs) use the container storage interface (CSI) to make their storage solutions available to Kubernetes workloads.\nThese CSI storage solutions often support some sort of encryption.\nFor example, Google Cloud ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/security/encryption/default-encryption",children:"encrypts data at rest by default"}),", without any action required by the customer."]}),"\n",(0,i.jsx)(t.h2,{id:"cloud-provider-managed-encryption",children:"Cloud provider-managed encryption"}),"\n",(0,i.jsx)(t.p,{children:"CSP-managed storage solutions encrypt the data in the cloud backend before writing it physically to disk.\nIn the context of confidential computing and Constellation, the CSP and its managed services aren't trusted.\nHence, cloud provider-managed encryption protects your data from offline hardware access to physical storage devices.\nIt doesn't protect it from anyone with infrastructure-level access to the storage backend or a malicious insider in the cloud platform.\nEven with \"bring your own key\" or similar concepts, the CSP performs the encryption process with access to the keys and plaintext data."}),"\n",(0,i.jsx)(t.p,{children:"In the security model of Constellation, securing persistent storage and thereby data at rest requires that all cryptographic operations are performed inside a trusted execution environment.\nConsequently, using CSP-managed encryption of persistent storage usually isn't an option."}),"\n",(0,i.jsx)(t.h2,{id:"constellation-managed-encryption",children:"Constellation-managed encryption"}),"\n",(0,i.jsxs)(t.p,{children:["Constellation provides CSI drivers for storage solutions in all major clouds with built-in encryption support.\nBlock storage provisioned by the CSP is ",(0,i.jsx)(t.a,{href:"https://guix.gnu.org/manual/en/html_node/Mapped-Devices.html",children:"mapped"})," using the ",(0,i.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-crypt.html",children:"dm-crypt"}),", and optionally the ",(0,i.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-integrity.html",children:"dm-integrity"}),", kernel modules, before it's formatted and accessed by the Kubernetes workloads.\nAll cryptographic operations happen inside the trusted environment of the confidential Constellation node."]}),"\n",(0,i.jsxs)(t.p,{children:["Note that for integrity-protected disks, ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/blog/2018/07/12/resizing-persistent-volumes-using-kubernetes/",children:"volume expansion"})," isn't supported."]}),"\n",(0,i.jsxs)(t.p,{children:["By default the driver uses data encryption keys (DEKs) issued by the Constellation ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#keyservice",children:(0,i.jsx)(t.em,{children:"KeyService"})}),".\nThe DEKs are in turn derived from the Constellation's key encryption key (KEK), which is directly derived from the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys#master-secret",children:"master secret"}),".\nThis is the recommended mode of operation, and also requires the least amount of setup by the cluster administrator."]}),"\n",(0,i.jsx)(t.p,{children:"Alternatively, the driver can be configured to use a key management system to store and access KEKs and DEKs."}),"\n",(0,i.jsxs)(t.p,{children:["Refer to ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/keys",children:"keys and cryptography"})," for more details on key management in Constellation."]}),"\n",(0,i.jsx)(t.p,{children:"Once deployed and configured, the CSI driver ensures transparent encryption and integrity of all persistent volumes provisioned via its storage class.\nData at rest is secured without any additional actions required by the developer."}),"\n",(0,i.jsx)(t.h2,{id:"cryptographic-algorithms",children:"Cryptographic algorithms"}),"\n",(0,i.jsx)(t.p,{children:"This section gives an overview of the libraries, cryptographic algorithms, and their configurations, used in Constellation's CSI drivers."}),"\n",(0,i.jsx)(t.h3,{id:"dm-crypt",children:"dm-crypt"}),"\n",(0,i.jsxs)(t.p,{children:["To interact with the dm-crypt kernel module, Constellation uses ",(0,i.jsx)(t.a,{href:"https://gitlab.com/cryptsetup/cryptsetup/",children:"libcryptsetup"}),".\nNew devices are formatted as ",(0,i.jsx)(t.a,{href:"https://gitlab.com/cryptsetup/LUKS2-docs/-/tree/master",children:"LUKS2"})," partitions with a sector size of 4096 bytes.\nThe used key derivation function is ",(0,i.jsx)(t.a,{href:"https://datatracker.ietf.org/doc/html/rfc9106",children:"Argon2id"})," with the ",(0,i.jsx)(t.a,{href:"https://datatracker.ietf.org/doc/html/rfc9106#section-7.4",children:"recommended parameters for memory-constrained environments"})," of 3 iterations and 64 MiB of memory, utilizing 4 parallel threads.\nFor encryption Constellation uses AES in XTS-Plain64. The key size is 512 bit."]}),"\n",(0,i.jsx)(t.h3,{id:"dm-integrity",children:"dm-integrity"}),"\n",(0,i.jsxs)(t.p,{children:["To interact with the dm-integrity kernel module, Constellation uses ",(0,i.jsx)(t.a,{href:"https://gitlab.com/cryptsetup/cryptsetup/",children:"libcryptsetup"}),".\nWhen enabled, the used data integrity algorithm is ",(0,i.jsx)(t.a,{href:"https://datatracker.ietf.org/doc/html/rfc2104",children:"HMAC"})," with SHA256 as the hash function.\nThe tag size is 32 Bytes."]}),"\n",(0,i.jsx)(t.h2,{id:"encrypted-s3-object-storage",children:"Encrypted S3 object storage"}),"\n",(0,i.jsxs)(t.p,{children:["Constellation comes with a service that you can use to transparently retrofit client-side encryption to existing applications that use S3 (AWS or compatible) for storage.\nTo learn more, check out the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/s3proxy",children:"s3proxy documentation"}),"."]})]})}function p(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/b28da407.5321d36a.js b/pr-preview/pr-4027/assets/js/b28da407.5321d36a.js deleted file mode 100644 index 224a18f7d..000000000 --- a/pr-preview/pr-4027/assets/js/b28da407.5321d36a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1187],{28453:(e,n,o)=>{o.d(n,{R:()=>i,x:()=>c});var r=o(96540);const t={},a=r.createContext(t);function i(e){const n=r.useContext(a);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),r.createElement(a.Provider,{value:n},e.children)}},90447:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>s,contentTitle:()=>c,default:()=>m,frontMatter:()=>i,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"overview/performance/compute","title":"Impact of runtime encryption on compute performance","description":"All nodes in a Constellation cluster are executed inside Confidential VMs (CVMs). Consequently, the performance of Constellation is inherently linked to the performance of these CVMs.","source":"@site/docs/overview/performance/compute.md","sourceDirName":"overview/performance","slug":"/overview/performance/compute","permalink":"/constellation/pr-preview/pr-4027/next/overview/performance/compute","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/overview/performance/compute.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Performance analysis of Constellation","permalink":"/constellation/pr-preview/pr-4027/next/overview/performance/"},"next":{"title":"I/O benchmarks","permalink":"/constellation/pr-preview/pr-4027/next/overview/performance/io"}}');var t=o(74848),a=o(28453);const i={},c="Impact of runtime encryption on compute performance",s={},l=[{value:"AMD and Azure benchmarking",id:"amd-and-azure-benchmarking",level:2},{value:"AMD and Google benchmarking",id:"amd-and-google-benchmarking",level:2}];function d(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"impact-of-runtime-encryption-on-compute-performance",children:"Impact of runtime encryption on compute performance"})}),"\n",(0,t.jsx)(n.p,{children:"All nodes in a Constellation cluster are executed inside Confidential VMs (CVMs). Consequently, the performance of Constellation is inherently linked to the performance of these CVMs."}),"\n",(0,t.jsx)(n.h2,{id:"amd-and-azure-benchmarking",children:"AMD and Azure benchmarking"}),"\n",(0,t.jsxs)(n.p,{children:["AMD and Azure have collectively released a ",(0,t.jsx)(n.a,{href:"https://community.amd.com/t5/business/microsoft-azure-confidential-computing-powered-by-3rd-gen-epyc/ba-p/497796",children:"performance benchmark"})," for CVMs that utilize 3rd Gen AMD EPYC processors (Milan) with SEV-SNP. This benchmark, which included a variety of mostly compute-intensive tests such as SPEC CPU 2017 and CoreMark, demonstrated that CVMs experience only minor performance degradation (ranging from 2% to 8%) when compared to standard VMs. Such results are indicative of the performance that can be expected from compute-intensive workloads running with Constellation on Azure."]}),"\n",(0,t.jsx)(n.h2,{id:"amd-and-google-benchmarking",children:"AMD and Google benchmarking"}),"\n",(0,t.jsxs)(n.p,{children:["Similarly, AMD and Google have jointly released a ",(0,t.jsx)(n.a,{href:"https://www.amd.com/system/files/documents/3rd-gen-epyc-gcp-c2d-conf-compute-perf-brief.pdf",children:"performance benchmark"})," for CVMs employing 3rd Gen AMD EPYC processors (Milan) with SEV-SNP. With high-performance computing workloads such as WRF, NAMD, Ansys CFS, and Ansys LS_DYNA, they observed analogous findings, with only minor performance degradation (between 2% and 4%) compared to standard VMs. These outcomes are reflective of the performance that can be expected for compute-intensive workloads running with Constellation on GCP."]})]})}function m(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/b29fd7c7.bc2a3e28.js b/pr-preview/pr-4027/assets/js/b29fd7c7.bc2a3e28.js deleted file mode 100644 index c1255477d..000000000 --- a/pr-preview/pr-4027/assets/js/b29fd7c7.bc2a3e28.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4591],{28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var r=n(96540);const s={},i=r.createContext(s);function o(e){const t=r.useContext(i);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),r.createElement(i.Provider,{value:t},e.children)}},61795:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"architecture/orchestration","title":"Orchestrating Constellation clusters","description":"You can use the CLI to create a cluster on the supported cloud platforms.","source":"@site/docs/architecture/orchestration.md","sourceDirName":"architecture","slug":"/architecture/orchestration","permalink":"/constellation/pr-preview/pr-4027/next/architecture/orchestration","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/architecture/orchestration.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/constellation/pr-preview/pr-4027/next/architecture/overview"},"next":{"title":"Versions and support","permalink":"/constellation/pr-preview/pr-4027/next/architecture/versions"}}');var s=n(74848),i=n(28453);const o={},a="Orchestrating Constellation clusters",c={},l=[{value:"Workspaces",id:"workspaces",level:2},{value:"Cluster creation process",id:"cluster-creation-process",level:2},{value:"Creation process details",id:"creation-process-details",level:3},{value:"Post-installation configuration",id:"post-installation-configuration",level:2},{value:"Upgrades",id:"upgrades",level:2},{value:"Attestation of upgrades",id:"attestation-of-upgrades",level:3}];function h(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"orchestrating-constellation-clusters",children:"Orchestrating Constellation clusters"})}),"\n",(0,s.jsx)(t.p,{children:"You can use the CLI to create a cluster on the supported cloud platforms.\nThe CLI provisions the resources in your cloud environment and initiates the initialization of your cluster.\nIt uses a set of parameters and an optional configuration file to manage your cluster installation.\nThe CLI is also used for updating your cluster."}),"\n",(0,s.jsx)(t.h2,{id:"workspaces",children:"Workspaces"}),"\n",(0,s.jsxs)(t.p,{children:["Each Constellation cluster has an associated ",(0,s.jsx)(t.em,{children:"workspace"}),".\nThe workspace is where data such as the Constellation state and config files are stored.\nEach workspace is associated with a single cluster and configuration.\nThe CLI stores state in the local filesystem making the current directory the active workspace.\nMultiple clusters require multiple workspaces, hence, multiple directories.\nNote that every operation on a cluster always has to be performed from the directory associated with its workspace."]}),"\n",(0,s.jsx)(t.p,{children:"You may copy files from the workspace to other locations,\nbut you shouldn't move or delete them while the cluster is still being used.\nThe Constellation CLI takes care of managing the workspace.\nOnly when a cluster was terminated, and you are sure the files aren't needed anymore, should you remove a workspace."}),"\n",(0,s.jsx)(t.h2,{id:"cluster-creation-process",children:"Cluster creation process"}),"\n",(0,s.jsxs)(t.p,{children:["To allow for fine-grained configuration of your cluster and cloud environment, Constellation supports an extensive configuration file with strong defaults. ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/config",children:"Generating the configuration file"})," is typically the first thing you do in the workspace."]}),"\n",(0,s.jsx)(t.p,{children:"Altogether, the following files are generated during the creation of a Constellation cluster and stored in the current workspace:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"a configuration file"}),"\n",(0,s.jsx)(t.li,{children:"a state file"}),"\n",(0,s.jsx)(t.li,{children:"a Base64-encoded master secret"}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/reference/terraform",children:"Terraform artifacts"}),", stored in subdirectories"]}),"\n",(0,s.jsxs)(t.li,{children:["a Kubernetes ",(0,s.jsx)(t.code,{children:"kubeconfig"})," file."]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["After the initialization of your cluster, the CLI will provide you with a Kubernetes ",(0,s.jsx)(t.code,{children:"kubeconfig"})," file.\nThis file grants you access to your Kubernetes cluster and configures the ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/",children:"kubectl"})," tool.\nIn addition, the cluster's ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/orchestration#post-installation-configuration",children:"identifier"})," is returned and stored in the state file."]}),"\n",(0,s.jsx)(t.h3,{id:"creation-process-details",children:"Creation process details"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["The CLI ",(0,s.jsx)(t.code,{children:"apply"})," command first creates the confidential VM (CVM) resources in your cloud environment and configures the network"]}),"\n",(0,s.jsx)(t.li,{children:"Each CVM boots the Constellation node image and measures every component in the boot chain"}),"\n",(0,s.jsxs)(t.li,{children:["The first microservice launched in each node is the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#bootstrapper",children:(0,s.jsx)(t.em,{children:"Bootstrapper"})})]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"Bootstrapper"})," waits until it either receives an initialization request or discovers an initialized cluster"]}),"\n",(0,s.jsxs)(t.li,{children:["The CLI then connects to the ",(0,s.jsx)(t.em,{children:"Bootstrapper"})," of a selected node, sends the configuration, and initiates the initialization of the cluster"]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"Bootstrapper"})," of ",(0,s.jsx)(t.strong,{children:"that"})," node ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#bootstrapper",children:"initializes the Kubernetes cluster"})," and deploys the other Constellation ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices",children:"microservices"})," including the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#joinservice",children:(0,s.jsx)(t.em,{children:"JoinService"})})]}),"\n",(0,s.jsxs)(t.li,{children:["Subsequently, the ",(0,s.jsx)(t.em,{children:"Bootstrappers"})," of the other nodes discover the initialized cluster and send join requests to the ",(0,s.jsx)(t.em,{children:"JoinService"})]}),"\n",(0,s.jsx)(t.li,{children:"As part of the join request each node includes an attestation statement of its boot measurements as authentication"}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"JoinService"})," verifies the attestation statements and joins the nodes to the Kubernetes cluster"]}),"\n",(0,s.jsx)(t.li,{children:"This process is repeated for every node joining the cluster later (e.g., through autoscaling)"}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"post-installation-configuration",children:"Post-installation configuration"}),"\n",(0,s.jsxs)(t.p,{children:["Post-installation the CLI provides a configuration for ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-api/",children:"accessing the cluster using the Kubernetes API"}),".\nThe ",(0,s.jsx)(t.code,{children:"kubeconfig"})," file provides the credentials and configuration for connecting and authenticating to the API server.\nOnce configured, orchestrate the Kubernetes cluster via ",(0,s.jsx)(t.code,{children:"kubectl"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"After the initialization, the CLI will present you with a couple of tokens:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys#master-secret",children:(0,s.jsx)(t.em,{children:"master secret"})})," (stored in the ",(0,s.jsx)(t.code,{children:"constellation-mastersecret.json"})," file by default)"]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys#cluster-identity",children:(0,s.jsx)(t.em,{children:"clusterID"})})," of your cluster in Base64 encoding"]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["You can read more about these values and their meaning in the guide on ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys#cluster-identity",children:"cluster identity"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.em,{children:"master secret"})," must be kept secret and can be used to ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/recovery",children:"recover your cluster"}),".\nInstead of managing this secret manually, you can ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys#user-managed-key-management",children:"use your key management solution of choice"})," with Constellation."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.em,{children:"clusterID"})," uniquely identifies a cluster and can be used to ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/verify-cluster",children:"verify your cluster"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"upgrades",children:"Upgrades"}),"\n",(0,s.jsxs)(t.p,{children:["Constellation images and microservices may need to be upgraded to new versions during the lifetime of a cluster.\nConstellation implements a rolling update mechanism ensuring no downtime of the control or data plane.\nYou can upgrade a Constellation cluster with a single operation by using the CLI.\nFor step-by-step instructions on how to do this, refer to ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/upgrade",children:"Upgrade your cluster"}),"."]}),"\n",(0,s.jsx)(t.h3,{id:"attestation-of-upgrades",children:"Attestation of upgrades"}),"\n",(0,s.jsxs)(t.p,{children:["With every new image, corresponding measurements are released.\nDuring an update procedure, the CLI provides new measurements to the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#joinservice",children:"JoinService"})," securely.\nNew measurements for an updated image are automatically pulled and verified by the CLI following the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/attestation#chain-of-trust",children:"supply chain security concept"})," of Constellation.\nThe ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/attestation#cluster-facing-attestation",children:"attestation section"})," describes in detail how these measurements are then used by the JoinService for the attestation of nodes."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/b744c41b.b5d06d0f.js b/pr-preview/pr-4027/assets/js/b744c41b.b5d06d0f.js deleted file mode 100644 index 3e8154102..000000000 --- a/pr-preview/pr-4027/assets/js/b744c41b.b5d06d0f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7317],{9597:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>d,metadata:()=>i,toc:()=>t});const i=JSON.parse('{"id":"reference/migration","title":"Migrations","description":"This document describes breaking changes and migrations between Constellation releases.","source":"@site/versioned_docs/version-2.22/reference/migration.md","sourceDirName":"reference","slug":"/reference/migration","permalink":"/constellation/pr-preview/pr-4027/2.22/reference/migration","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/reference/migration.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"CLI","permalink":"/constellation/pr-preview/pr-4027/2.22/reference/cli"},"next":{"title":"Terraform usage","permalink":"/constellation/pr-preview/pr-4027/2.22/reference/terraform"}}');var s=n(74848),o=n(28453);const d={},l="Migrations",c={},t=[{value:"Migrations to v2.19.1",id:"migrations-to-v2191",level:2},{value:"Azure",id:"azure",level:3},{value:"Migrating from CLI versions before 2.21.1",id:"migrating-from-cli-versions-before-2211",level:2},{value:"AWS",id:"aws",level:3},{value:"Migrating from CLI versions before 2.19.0",id:"migrating-from-cli-versions-before-2190",level:2},{value:"Azure",id:"azure-1",level:3},{value:"Migrating from CLI versions before 2.18.0",id:"migrating-from-cli-versions-before-2180",level:2},{value:"Migrating from CLI versions before 2.10",id:"migrating-from-cli-versions-before-210",level:2},{value:"Migrating from CLI versions before 2.9",id:"migrating-from-cli-versions-before-29",level:2},{value:"Migrating from CLI versions before 2.8",id:"migrating-from-cli-versions-before-28",level:2},{value:"Migrating from CLI versions before 2.3",id:"migrating-from-cli-versions-before-23",level:2}];function a(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components},{Details:n}=r;return n||function(e,r){throw new Error("Expected "+(r?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.header,{children:(0,s.jsx)(r.h1,{id:"migrations",children:"Migrations"})}),"\n",(0,s.jsxs)(r.p,{children:["This document describes breaking changes and migrations between Constellation releases.\nUse ",(0,s.jsx)(r.a,{href:"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-config-migrate",children:(0,s.jsx)(r.code,{children:"constellation config migrate"})})," to automatically update an old config file to a new format."]}),"\n",(0,s.jsx)(r.h2,{id:"migrations-to-v2191",children:"Migrations to v2.19.1"}),"\n",(0,s.jsx)(r.h3,{id:"azure",children:"Azure"}),"\n",(0,s.jsxs)(r.ul,{children:["\n",(0,s.jsx)(r.li,{children:"During the upgrade, security rules are migrated and the old ones need to be cleaned up manually by the user. The below script shows how to delete them through the Azure CLI:"}),"\n"]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:'#!/usr/bin/env bash\nname="<insert>" # the name provided in the config\nuid="<insert>" # the cluster id can be retrieved via `yq \'.infrastructure.uid\' constellation-state.yaml`\nresource_group="<insert>" # the RG can be retrieved via `yq \'.provider.azure.resourceGroup\' constellation-conf.yaml`\n\nrules=(\n "kubernetes"\n "bootstrapper"\n "verify"\n "recovery"\n "join"\n "debugd"\n "konnectivity"\n)\n\nfor rule in "${rules[@]}"; do\n echo "Deleting rule: ${rule}"\n az network nsg rule delete \\\n --resource-group "${resource_group}" \\\n --nsg-name "${name}-${uid}" \\\n --name "${rule}"\ndone\n\necho "All specified rules have been deleted."\n'})}),"\n",(0,s.jsx)(r.h2,{id:"migrating-from-cli-versions-before-2211",children:"Migrating from CLI versions before 2.21.1"}),"\n",(0,s.jsx)(r.h3,{id:"aws",children:"AWS"}),"\n",(0,s.jsxs)(r.ul,{children:["\n",(0,s.jsxs)(r.li,{children:["AWS clusters that use ",(0,s.jsx)(r.code,{children:"LoadBalancer"})," resources require more IAM permissions. Please upgrade your IAM roles using ",(0,s.jsx)(r.code,{children:"constellation iam upgrade apply"}),". This will show necessary changes and apply them, if desired."]}),"\n"]}),"\n",(0,s.jsx)(r.h2,{id:"migrating-from-cli-versions-before-2190",children:"Migrating from CLI versions before 2.19.0"}),"\n",(0,s.jsx)(r.h3,{id:"azure-1",children:"Azure"}),"\n",(0,s.jsxs)(r.ul,{children:["\n",(0,s.jsxs)(r.li,{children:["To allow seamless upgrades on Azure when Kubernetes services of type ",(0,s.jsx)(r.code,{children:"LoadBalancer"})," are deployed, the target\nload balancer in which the ",(0,s.jsx)(r.code,{children:"cloud-controller-manager"})," creates load balancing rules was changed. Instead of using the load balancer\ncreated and maintained by the CLI's Terraform code, the ",(0,s.jsx)(r.code,{children:"cloud-controller-manager"})," now creates its own load balancer in Azure.\nIf your Constellation has services of type ",(0,s.jsx)(r.code,{children:"LoadBalancer"}),", please remove them before the upgrade and re-apply them\nafterward."]}),"\n"]}),"\n",(0,s.jsx)(r.h2,{id:"migrating-from-cli-versions-before-2180",children:"Migrating from CLI versions before 2.18.0"}),"\n",(0,s.jsxs)(r.ul,{children:["\n",(0,s.jsxs)(r.li,{children:["The ",(0,s.jsx)(r.code,{children:"provider.azure.appClientID"})," and ",(0,s.jsx)(r.code,{children:"provider.azure.appClientSecret"})," fields are no longer supported and should be removed."]}),"\n",(0,s.jsxs)(r.li,{children:["To keep using an existing UAMI, add the ",(0,s.jsx)(r.code,{children:"Owner"})," permission with the scope of your ",(0,s.jsx)(r.code,{children:"resourceGroup"}),"."]}),"\n",(0,s.jsxs)(r.li,{children:["Otherwise, simply ",(0,s.jsx)(r.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/config#creating-an-iam-configuration",children:"create new Constellation IAM credentials"})," and use the created UAMI."]}),"\n",(0,s.jsxs)(r.li,{children:["To migrate the authentication for an existing cluster on Azure to an UAMI with the necessary permissions:","\n",(0,s.jsxs)(r.ol,{children:["\n",(0,s.jsxs)(r.li,{children:["Remove the ",(0,s.jsx)(r.code,{children:"aadClientId"})," and ",(0,s.jsx)(r.code,{children:"aadClientSecret"})," from the azureconfig secret."]}),"\n",(0,s.jsxs)(r.li,{children:["Set ",(0,s.jsx)(r.code,{children:"useManagedIdentityExtension"})," to ",(0,s.jsx)(r.code,{children:"true"})," and use the ",(0,s.jsx)(r.code,{children:"userAssignedIdentity"})," from the Constellation config for the value of ",(0,s.jsx)(r.code,{children:"userAssignedIdentityID"}),"."]}),"\n",(0,s.jsx)(r.li,{children:"Restart the CSI driver, cloud controller manager, cluster autoscaler, and Constellation operator pods."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(r.h2,{id:"migrating-from-cli-versions-before-210",children:"Migrating from CLI versions before 2.10"}),"\n",(0,s.jsxs)(r.ul,{children:["\n",(0,s.jsxs)(r.li,{children:["AWS cluster upgrades require additional IAM permissions for the newly introduced ",(0,s.jsx)(r.code,{children:"aws-load-balancer-controller"}),". Please upgrade your IAM roles using ",(0,s.jsx)(r.code,{children:"iam upgrade apply"}),". This will show necessary changes and apply them, if desired."]}),"\n",(0,s.jsxs)(r.li,{children:["The global ",(0,s.jsx)(r.code,{children:"nodeGroups"})," field was added."]}),"\n",(0,s.jsxs)(r.li,{children:["The fields ",(0,s.jsx)(r.code,{children:"instanceType"}),", ",(0,s.jsx)(r.code,{children:"stateDiskSizeGB"}),", and ",(0,s.jsx)(r.code,{children:"stateDiskType"})," for each cloud provider are now part of the configuration of individual node groups."]}),"\n",(0,s.jsxs)(r.li,{children:["The ",(0,s.jsx)(r.code,{children:"constellation create"})," command no longer uses the flags ",(0,s.jsx)(r.code,{children:"--control-plane-count"})," and ",(0,s.jsx)(r.code,{children:"--worker-count"}),". Instead, the initial node count is configured per node group in the ",(0,s.jsx)(r.code,{children:"nodeGroups"})," field."]}),"\n"]}),"\n",(0,s.jsx)(r.h2,{id:"migrating-from-cli-versions-before-29",children:"Migrating from CLI versions before 2.9"}),"\n",(0,s.jsxs)(r.ul,{children:["\n",(0,s.jsxs)(r.li,{children:["The ",(0,s.jsx)(r.code,{children:"provider.azure.appClientID"})," and ",(0,s.jsx)(r.code,{children:"provider.azure.clientSecretValue"})," fields were removed to enforce migration to managed identity authentication"]}),"\n"]}),"\n",(0,s.jsx)(r.h2,{id:"migrating-from-cli-versions-before-28",children:"Migrating from CLI versions before 2.8"}),"\n",(0,s.jsxs)(r.ul,{children:["\n",(0,s.jsxs)(r.li,{children:["The ",(0,s.jsx)(r.code,{children:"measurements"})," field for each cloud service provider was replaced with a global ",(0,s.jsx)(r.code,{children:"attestation"})," field."]}),"\n",(0,s.jsxs)(r.li,{children:["The ",(0,s.jsx)(r.code,{children:"confidentialVM"}),", ",(0,s.jsx)(r.code,{children:"idKeyDigest"}),", and ",(0,s.jsx)(r.code,{children:"enforceIdKeyDigest"})," fields for the Azure cloud service provider were removed in favor of using the global ",(0,s.jsx)(r.code,{children:"attestation"})," field."]}),"\n",(0,s.jsxs)(r.li,{children:["The optional global field ",(0,s.jsx)(r.code,{children:"attestationVariant"})," was replaced by the now required ",(0,s.jsx)(r.code,{children:"attestation"})," field."]}),"\n"]}),"\n",(0,s.jsx)(r.h2,{id:"migrating-from-cli-versions-before-23",children:"Migrating from CLI versions before 2.3"}),"\n",(0,s.jsxs)(r.ul,{children:["\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["The ",(0,s.jsx)(r.code,{children:"sshUsers"})," field was deprecated in v2.2 and has been removed from the configuration in v2.3.\nAs an alternative for SSH, check the workflow section ",(0,s.jsx)(r.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting#node-shell-access",children:"Connect to nodes"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["The ",(0,s.jsx)(r.code,{children:"image"})," field for each cloud service provider has been replaced with a global ",(0,s.jsx)(r.code,{children:"image"})," field. Use the following mapping to migrate your configuration:"]}),"\n",(0,s.jsxs)(n,{children:[(0,s.jsx)("summary",{children:"Show all"}),(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"CSP"}),(0,s.jsx)(r.th,{children:"old image"}),(0,s.jsx)(r.th,{children:"new image"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"AWS"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"ami-06b8cbf4837a0a57c"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"AWS"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"ami-02e96dc04a9e438cd"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"AWS"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"ami-028ead928a9034b2f"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"AWS"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"ami-032ac10dd8d8266e3"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"AWS"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"ami-032e0d57cc4395088"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"AWS"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"ami-053c3e49e19b96bdd"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"AWS"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"ami-0e27ebcefc38f648b"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"AWS"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"ami-098cd37f66523b7c3"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"AWS"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"ami-04a87d302e2509aad"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Azure"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.2"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Azure"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.2"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Azure"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.1"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Azure"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.1"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Azure"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.0"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Azure"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.0"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Azure"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.1.0"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.1.0"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Azure"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.1.0"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.1.0"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Azure"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.0.0"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.0.0"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Azure"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.0.0"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.0.0"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"GCP"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"projects/constellation-images/global/images/constellation-v2-2-2"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.2"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"GCP"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"projects/constellation-images/global/images/constellation-v2-2-1"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.1"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"GCP"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"projects/constellation-images/global/images/constellation-v2-2-0"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.2.0"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"GCP"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"projects/constellation-images/global/images/constellation-v2-1-0"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.1.0"})})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"GCP"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"projects/constellation-images/global/images/constellation-v2-0-0"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"v2.0.0"})})]})]})]})]}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["The ",(0,s.jsx)(r.code,{children:"enforcedMeasurements"})," field has been removed and merged with the ",(0,s.jsx)(r.code,{children:"measurements"})," field."]}),"\n",(0,s.jsxs)(r.ul,{children:["\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["To migrate your config containing a new image (",(0,s.jsx)(r.code,{children:"v2.3"})," or greater), remove the old ",(0,s.jsx)(r.code,{children:"measurements"})," and ",(0,s.jsx)(r.code,{children:"enforcedMeasurements"})," entries from your config and run ",(0,s.jsx)(r.code,{children:"constellation fetch-measurements"})]}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["To migrate your config containing an image older than ",(0,s.jsx)(r.code,{children:"v2.3"}),", remove the ",(0,s.jsx)(r.code,{children:"enforcedMeasurements"})," entry and replace the entries in ",(0,s.jsx)(r.code,{children:"measurements"})," as shown in the example below:"]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-diff",children:"measurements:\n- 0: DzXCFGCNk8em5ornNZtKi+Wg6Z7qkQfs5CfE3qTkOc8=\n+ 0:\n+ expected: DzXCFGCNk8em5ornNZtKi+Wg6Z7qkQfs5CfE3qTkOc8=\n+ warnOnly: true\n- 8: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\n+ 8:\n+ expected: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\n+ warnOnly: false\n-enforcedMeasurements:\n- - 8\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:r}={...(0,o.R)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},28453:(e,r,n)=>{n.d(r,{R:()=>d,x:()=>l});var i=n(96540);const s={},o=i.createContext(s);function d(e){const r=i.useContext(o);return i.useMemo(function(){return"function"==typeof e?e(r):{...r,...e}},[r,e])}function l(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),i.createElement(o.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/b80e9c3d.370d4b83.js b/pr-preview/pr-4027/assets/js/b80e9c3d.370d4b83.js deleted file mode 100644 index e33feacc9..000000000 --- a/pr-preview/pr-4027/assets/js/b80e9c3d.370d4b83.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2829],{42333:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Reference","slug":"/category/reference","permalink":"/constellation/pr-preview/pr-4027/2.23/category/reference","sidebar":"docs","navigation":{"previous":{"title":"Observability","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/observability"},"next":{"title":"CLI","permalink":"/constellation/pr-preview/pr-4027/2.23/reference/cli"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/baf93e4b.fe36f378.js b/pr-preview/pr-4027/assets/js/baf93e4b.fe36f378.js deleted file mode 100644 index 1006fd768..000000000 --- a/pr-preview/pr-4027/assets/js/baf93e4b.fe36f378.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6457],{25946:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>m,frontMatter:()=>i,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"overview/performance/compute","title":"Impact of runtime encryption on compute performance","description":"All nodes in a Constellation cluster are executed inside Confidential VMs (CVMs). Consequently, the performance of Constellation is inherently linked to the performance of these CVMs.","source":"@site/versioned_docs/version-2.22/overview/performance/compute.md","sourceDirName":"overview/performance","slug":"/overview/performance/compute","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/performance/compute","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/overview/performance/compute.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Performance analysis of Constellation","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/performance/"},"next":{"title":"I/O benchmarks","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/performance/io"}}');var t=o(74848),a=o(28453);const i={},s="Impact of runtime encryption on compute performance",c={},l=[{value:"AMD and Azure benchmarking",id:"amd-and-azure-benchmarking",level:2},{value:"AMD and Google benchmarking",id:"amd-and-google-benchmarking",level:2}];function d(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"impact-of-runtime-encryption-on-compute-performance",children:"Impact of runtime encryption on compute performance"})}),"\n",(0,t.jsx)(n.p,{children:"All nodes in a Constellation cluster are executed inside Confidential VMs (CVMs). Consequently, the performance of Constellation is inherently linked to the performance of these CVMs."}),"\n",(0,t.jsx)(n.h2,{id:"amd-and-azure-benchmarking",children:"AMD and Azure benchmarking"}),"\n",(0,t.jsxs)(n.p,{children:["AMD and Azure have collectively released a ",(0,t.jsx)(n.a,{href:"https://community.amd.com/t5/business/microsoft-azure-confidential-computing-powered-by-3rd-gen-epyc/ba-p/497796",children:"performance benchmark"})," for CVMs that utilize 3rd Gen AMD EPYC processors (Milan) with SEV-SNP. This benchmark, which included a variety of mostly compute-intensive tests such as SPEC CPU 2017 and CoreMark, demonstrated that CVMs experience only minor performance degradation (ranging from 2% to 8%) when compared to standard VMs. Such results are indicative of the performance that can be expected from compute-intensive workloads running with Constellation on Azure."]}),"\n",(0,t.jsx)(n.h2,{id:"amd-and-google-benchmarking",children:"AMD and Google benchmarking"}),"\n",(0,t.jsxs)(n.p,{children:["Similarly, AMD and Google have jointly released a ",(0,t.jsx)(n.a,{href:"https://www.amd.com/system/files/documents/3rd-gen-epyc-gcp-c2d-conf-compute-perf-brief.pdf",children:"performance benchmark"})," for CVMs employing 3rd Gen AMD EPYC processors (Milan) with SEV-SNP. With high-performance computing workloads such as WRF, NAMD, Ansys CFS, and Ansys LS_DYNA, they observed analogous findings, with only minor performance degradation (between 2% and 4%) compared to standard VMs. These outcomes are reflective of the performance that can be expected for compute-intensive workloads running with Constellation on GCP."]})]})}function m(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>i,x:()=>s});var r=o(96540);const t={},a=r.createContext(t);function i(e){const n=r.useContext(a);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/bf976132.8fa4d51e.js b/pr-preview/pr-4027/assets/js/bf976132.8fa4d51e.js deleted file mode 100644 index 9609e990c..000000000 --- a/pr-preview/pr-4027/assets/js/bf976132.8fa4d51e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8395],{21668:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"architecture/overview","title":"Overview","description":"Constellation is a cloud-based confidential orchestration platform.","source":"@site/versioned_docs/version-2.22/architecture/overview.md","sourceDirName":"architecture","slug":"/architecture/overview","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/architecture/overview.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Architecture","permalink":"/constellation/pr-preview/pr-4027/2.22/category/architecture"},"next":{"title":"Cluster orchestration","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration"}}');var n=r(74848),o=r(28453);const a={},s="Overview",c={},l=[{value:"About orchestration and updates",id:"about-orchestration-and-updates",level:2},{value:"About microservices and attestation",id:"about-microservices-and-attestation",level:2},{value:"About node images and verified boot",id:"about-node-images-and-verified-boot",level:2},{value:"About key management and cryptographic primitives",id:"about-key-management-and-cryptographic-primitives",level:2},{value:"About observability",id:"about-observability",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,n.jsxs)(t.p,{children:["Constellation is a cloud-based confidential orchestration platform.\nThe foundation of Constellation is Kubernetes and therefore shares the same technology stack and architecture principles.\nTo learn more about Constellation and Kubernetes, see ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/overview/product",children:"product overview"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"about-orchestration-and-updates",children:"About orchestration and updates"}),"\n",(0,n.jsxs)(t.p,{children:["As a cluster administrator, you can use the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration",children:"Constellation CLI"})," to install and deploy a cluster.\nUpdates are provided in accordance with the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/versions",children:"support policy"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"about-microservices-and-attestation",children:"About microservices and attestation"}),"\n",(0,n.jsxs)(t.p,{children:["Constellation manages the nodes and network in your cluster. All nodes are bootstrapped by the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#bootstrapper",children:(0,n.jsx)(t.em,{children:"Bootstrapper"})}),". They're verified and authenticated by the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#joinservice",children:(0,n.jsx)(t.em,{children:"JoinService"})})," before being added to the cluster and the network. Finally, the entire cluster can be verified via the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#verificationservice",children:(0,n.jsx)(t.em,{children:"VerificationService"})})," using ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation",children:"remote attestation"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"about-node-images-and-verified-boot",children:"About node images and verified boot"}),"\n",(0,n.jsxs)(t.p,{children:["Constellation comes with operating system images for Kubernetes control-plane and worker nodes.\nThey're highly optimized for running containerized workloads and specifically prepared for running inside confidential VMs.\nYou can learn more about ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/images",children:"the images"})," and how verified boot ensures their integrity during boot and beyond."]}),"\n",(0,n.jsx)(t.h2,{id:"about-key-management-and-cryptographic-primitives",children:"About key management and cryptographic primitives"}),"\n",(0,n.jsxs)(t.p,{children:["Encryption of data at-rest, in-transit, and in-use is the fundamental building block for confidential computing and Constellation. Learn more about the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys",children:"keys and cryptographic primitives"})," used in Constellation, ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage",children:"encrypted persistent storage"}),", and ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/networking",children:"network encryption"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"about-observability",children:"About observability"}),"\n",(0,n.jsxs)(t.p,{children:["Observability in Kubernetes refers to the capability to troubleshoot issues using telemetry signals such as logs, metrics, and traces.\nIn the realm of Confidential Computing, it's crucial that observability aligns with confidentiality, necessitating careful implementation.\nLearn more about the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/observability",children:"observability capabilities in Constellation"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>a,x:()=>s});var i=r(96540);const n={},o=i.createContext(n);function a(e){const t=i.useContext(o);return i.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/c2af115c.6aae2899.js b/pr-preview/pr-4027/assets/js/c2af115c.6aae2899.js deleted file mode 100644 index 4db612f2f..000000000 --- a/pr-preview/pr-4027/assets/js/c2af115c.6aae2899.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6567],{17020:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"getting-started/first-steps","title":"First steps with Constellation","description":"The following steps guide you through the process of creating a cluster and deploying a sample app. This example assumes that you have successfully installed and set up Constellation,","source":"@site/versioned_docs/version-2.24/getting-started/first-steps.md","sourceDirName":"getting-started","slug":"/getting-started/first-steps","permalink":"/constellation/pr-preview/pr-4027/getting-started/first-steps","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/getting-started/first-steps.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Installation","permalink":"/constellation/pr-preview/pr-4027/getting-started/install"},"next":{"title":"First steps (local)","permalink":"/constellation/pr-preview/pr-4027/getting-started/first-steps-local"}}');var i=s(74848),l=s(28453);const o={},r="First steps with Constellation",a={},c=[{value:"Create a cluster",id:"create-a-cluster",level:2},{value:"Deploy a sample application",id:"deploy-a-sample-application",level:2},{value:"Terminate your cluster",id:"terminate-your-cluster",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,l.R)(),...e.components},{TabItem:s,Tabs:t}=n;return s||u("TabItem",!0),t||u("Tabs",!0),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"first-steps-with-constellation",children:"First steps with Constellation"})}),"\n",(0,i.jsxs)(n.p,{children:["The following steps guide you through the process of creating a cluster and deploying a sample app. This example assumes that you have successfully ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/getting-started/install",children:"installed and set up Constellation"}),",\nand have access to a cloud subscription."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["If you don't have a cloud subscription, you can also set up a ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/getting-started/first-steps-local",children:"local Constellation cluster using virtualization"})," for testing."]})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["If you encounter any problem with the following steps, make sure to use the ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/releases/latest",children:"latest release"})," and check out the ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"known issues"}),"."]})}),"\n",(0,i.jsx)(n.h2,{id:"create-a-cluster",children:"Create a cluster"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Create the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/config",children:"configuration file"})," and state file for your cloud provider. If you are following the steps of this guide, there is no need to edit the file."]}),"\n",(0,i.jsxs)(t,{groupId:"csp",children:[(0,i.jsx)(s,{value:"aws",label:"AWS",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation config generate aws\n"})})}),(0,i.jsx)(s,{value:"azure",label:"Azure",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation config generate azure\n"})})}),(0,i.jsx)(s,{value:"gcp",label:"GCP",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation config generate gcp\n"})})}),(0,i.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation config generate stackit\n"})})})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Create your ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/config#creating-an-iam-configuration",children:"IAM configuration"}),"."]}),"\n",(0,i.jsxs)(t,{groupId:"csp",children:[(0,i.jsxs)(s,{value:"aws",label:"AWS",children:[(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation iam create aws --zone=us-east-2a --prefix=constellTest --update-config\n"})}),(0,i.jsxs)(n.p,{children:["This command creates IAM configuration for the AWS zone ",(0,i.jsx)(n.code,{children:"us-east-2a"})," using the prefix ",(0,i.jsx)(n.code,{children:"constellTest"})," for all named resources being created. It also updates the configuration file ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"})," in your current directory with the IAM values filled in."]}),(0,i.jsxs)(n.p,{children:["Depending on the attestation variant selected on config generation, different regions are available.\nAMD SEV-SNP machines (requires the default attestation variant ",(0,i.jsx)(n.code,{children:"awsSEVSNP"}),") are currently available in the following regions:"]}),(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"eu-west-1"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"us-east-2"})}),"\n"]}),(0,i.jsxs)(n.p,{children:["You can find a list of regions that support AMD SEV-SNP in ",(0,i.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/snp-requirements.html",children:"AWS's documentation"}),"."]}),(0,i.jsxs)(n.p,{children:["NitroTPM machines (requires the attestation variant ",(0,i.jsx)(n.code,{children:"awsNitroTPM"}),") are available in all regions.\nConstellation OS images are currently replicated to the following regions:"]}),(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"eu-central-1"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"eu-west-1"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"eu-west-3"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"us-east-2"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"ap-south-1"})}),"\n"]}),(0,i.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+AWS+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),(0,i.jsxs)(n.p,{children:["You can find a list of all ",(0,i.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions",children:"regions in AWS's documentation"}),"."]})]}),(0,i.jsxs)(s,{value:"azure",label:"Azure",children:[(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation iam create azure --subscriptionID 00000000-0000-0000-0000-000000000000 --region=westus --resourceGroup=constellTest --servicePrincipal=spTest --update-config\n"})}),(0,i.jsxs)(n.p,{children:["This command creates IAM configuration on the Azure region ",(0,i.jsx)(n.code,{children:"westus"})," creating a new resource group ",(0,i.jsx)(n.code,{children:"constellTest"})," and a new service principal ",(0,i.jsx)(n.code,{children:"spTest"}),". It also updates the configuration file ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"})," in your current directory with the IAM values filled in."]}),(0,i.jsx)(n.p,{children:"CVMs are available in several Azure regions. Constellation OS images are currently replicated to the following:"}),(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"germanywestcentral"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"westus"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"eastus"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"northeurope"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"westeurope"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"southeastasia"})}),"\n"]}),(0,i.jsxs)(n.p,{children:["If you require the OS image to be available in another region, ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md&title=Support+new+Azure+image+region:+xx-xxxx-x",children:"let us know"}),"."]}),(0,i.jsxs)(n.p,{children:["You can find a list of all ",(0,i.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/global-infrastructure/services/?products=virtual-machines®ions=all",children:"regions in Azure's documentation"}),"."]})]}),(0,i.jsxs)(s,{value:"gcp",label:"GCP",children:[(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation iam create gcp --projectID=yourproject-12345 --zone=europe-west3-a --prefix=constell-test --update-config\n"})}),(0,i.jsxs)(n.p,{children:["This command creates IAM configuration in the GCP project ",(0,i.jsx)(n.code,{children:"yourproject-12345"})," on the GCP zone ",(0,i.jsx)(n.code,{children:"europe-west3-a"})," creating a new service account ",(0,i.jsx)(n.code,{children:"constell-test"}),". It also updates the configuration file ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"})," in your current directory with the IAM values filled in."]}),(0,i.jsxs)(n.p,{children:["Note that only regions offering CVMs of the ",(0,i.jsx)(n.code,{children:"C2D"})," or ",(0,i.jsx)(n.code,{children:"N2D"})," series are supported. You can find a ",(0,i.jsx)(n.a,{href:"https://cloud.google.com/compute/docs/regions-zones#available",children:"list of all regions in Google's documentation"}),", which you can filter by machine type ",(0,i.jsx)(n.code,{children:"C2D"})," or ",(0,i.jsx)(n.code,{children:"N2D"}),"."]})]}),(0,i.jsxs)(s,{value:"stackit",label:"STACKIT",children:[(0,i.jsxs)(n.p,{children:["To use Constellation on STACKIT, the cluster will use the User Access Token (UAT) that's generated ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/getting-started/install",children:"during the install step"}),".\nAfter creating the accounts, fill in the STACKIT details in ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"})," under ",(0,i.jsx)(n.code,{children:"provider.openstack"}),":"]}),(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"stackitProjectID"}),": STACKIT project id (can be found after login on the ",(0,i.jsx)(n.a,{href:"https://portal.stackit.cloud",children:"STACKIT portal"}),")"]}),"\n"]}),(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"stackitProjectID"})," refers to the ID of your STACKIT project. The STACKIT portal also shows the OpenStack ID that's associated with your project in some places. Make sure you insert the STACKIT project ID in the ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"})," file. It's of the format ",(0,i.jsx)(n.code,{children:"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"}),"."]})})]})]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["To learn about all options you have for managing IAM resources and Constellation configuration, see the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/config",children:"Configuration workflow"}),"."]})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"3",children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Create the cluster. ",(0,i.jsx)(n.code,{children:"constellation apply"})," uses options set in ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"}),".\nIf you want to manually manage your cloud resources, for example by using ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/reference/terraform",children:"Terraform"}),", follow the corresponding instructions in the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/create",children:"Create workflow"}),"."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsx)(n.p,{children:"On Azure, you may need to wait 15+ minutes at this point for role assignments to propagate."})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation apply -y\n"})}),"\n",(0,i.jsx)(n.p,{children:"This should look similar to the following:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell-session",children:'$ constellation apply -y\nChecking for infrastructure changes\nThe following Constellation cluster will be created:\n 3 control-plane nodes of type n2d-standard-4 will be created.\n 1 worker node of type n2d-standard-4 will be created.\nCreating\nCloud infrastructure created successfully\nYour Constellation master secret was successfully written to ./constellation-mastersecret.json\nConnecting\nInitializing cluster\nInstalling Kubernetes components\nYour Constellation cluster was successfully initialized.\n\nConstellation cluster identifier g6iMP5wRU1b7mpOz2WEISlIYSfdAhB0oNaOg6XEwKFY=\nKubernetes configuration constellation-admin.conf\n\nYou can now connect to your cluster by executing:\n export KUBECONFIG="$PWD/constellation-admin.conf"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The cluster's identifier will be different in your output.\nKeep ",(0,i.jsx)(n.code,{children:"constellation-mastersecret.json"})," somewhere safe.\nThis will allow you to ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/recovery",children:"recover your cluster"})," in case of a disaster."]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["Depending on your CSP and region, ",(0,i.jsx)(n.code,{children:"constellation apply"})," may take 10+ minutes to complete."]})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Configure kubectl."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'export KUBECONFIG="$PWD/constellation-admin.conf"\n'})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"deploy-a-sample-application",children:"Deploy a sample application"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Deploy the ",(0,i.jsx)(n.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"emojivoto app"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Expose the frontend service locally"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments\nkubectl -n emojivoto port-forward svc/web-svc 8080:80 &\ncurl http://localhost:8080\nkill %1\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"terminate-your-cluster",children:"Terminate your cluster"}),"\n",(0,i.jsxs)(n.p,{children:["Use the CLI to terminate your cluster. If you manually used ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/reference/terraform",children:"Terraform"})," to manage your cloud resources, follow the corresponding instructions in the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/terminate",children:"Terminate workflow"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"constellation terminate\n"})}),"\n",(0,i.jsx)(n.p,{children:"This should give the following output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell-session",children:"$ constellation terminate\nYou are about to terminate a Constellation cluster.\nAll of its associated resources will be DESTROYED.\nThis action is irreversible and ALL DATA WILL BE LOST.\nDo you want to continue? [y/n]:\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Confirm with ",(0,i.jsx)(n.code,{children:"y"})," to terminate the cluster:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell-session",children:"Terminating ...\nYour Constellation cluster was terminated successfully.\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Optionally, you can also ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/workflows/config#deleting-an-iam-configuration",children:"delete your IAM resources"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}function u(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>r});var t=s(96540);const i={},l=t.createContext(i);function o(e){const n=t.useContext(l);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/c33b0c87.43e2e2a5.js b/pr-preview/pr-4027/assets/js/c33b0c87.43e2e2a5.js deleted file mode 100644 index 3fddea58d..000000000 --- a/pr-preview/pr-4027/assets/js/c33b0c87.43e2e2a5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8518],{8519:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"getting-started/examples/horizontal-scaling","title":"Horizontal Pod Autoscaling","description":"This example demonstrates Constellation\'s autoscaling capabilities. It\'s based on the Kubernetes HorizontalPodAutoscaler Walkthrough. During the following steps, Constellation will spawn new VMs on demand, verify them, add them to the cluster, and delete them again when the load has settled down.","source":"@site/versioned_docs/version-2.22/getting-started/examples/horizontal-scaling.md","sourceDirName":"getting-started/examples","slug":"/getting-started/examples/horizontal-scaling","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scaling","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/getting-started/examples/horizontal-scaling.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Online Boutique","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/online-boutique"},"next":{"title":"Filestash with s3proxy","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/filestash-s3proxy"}}');var a=t(74848),o=t(28453);const i={},r="Horizontal Pod Autoscaling",l={},c=[{value:"Requirements",id:"requirements",level:2},{value:"Setup",id:"setup",level:2},{value:"Monitoring",id:"monitoring",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"horizontal-pod-autoscaling",children:"Horizontal Pod Autoscaling"})}),"\n",(0,a.jsxs)(n.p,{children:["This example demonstrates Constellation's autoscaling capabilities. It's based on the Kubernetes ",(0,a.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/",children:"HorizontalPodAutoscaler Walkthrough"}),". During the following steps, Constellation will spawn new VMs on demand, verify them, add them to the cluster, and delete them again when the load has settled down."]}),"\n",(0,a.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,a.jsxs)(n.p,{children:["The cluster needs to be initialized with Kubernetes 1.23 or later. In addition, ",(0,a.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/scale",children:"autoscaling must be enabled"})," to enable Constellation to assign new nodes dynamically."]}),"\n",(0,a.jsxs)(n.p,{children:["Just for this example specifically, the cluster should have as few worker nodes in the beginning as possible. Start with a small cluster with only ",(0,a.jsx)(n.em,{children:"one"})," low-powered node for the control-plane node and ",(0,a.jsx)(n.em,{children:"one"})," low-powered worker node."]}),"\n",(0,a.jsx)(n.admonition,{type:"info",children:(0,a.jsxs)(n.p,{children:["We tested the example using instances of types ",(0,a.jsx)(n.code,{children:"Standard_DC4as_v5"})," on Azure and ",(0,a.jsx)(n.code,{children:"n2d-standard-4"})," on GCP."]})}),"\n",(0,a.jsx)(n.h2,{id:"setup",children:"Setup"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Install the Kubernetes Metrics Server:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Deploy the HPA example server that's supposed to be scaled under load."}),"\n",(0,a.jsx)(n.p,{children:"This manifest is similar to the one from the Kubernetes HPA walkthrough, but with increased CPU limits and requests to facilitate the triggering of node scaling events."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cat <<EOF | kubectl apply -f -\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: php-apache\nspec:\n selector:\n matchLabels:\n run: php-apache\n replicas: 1\n template:\n metadata:\n labels:\n run: php-apache\n spec:\n containers:\n - name: php-apache\n image: registry.k8s.io/hpa-example\n ports:\n - containerPort: 80\n resources:\n limits:\n cpu: 900m\n requests:\n cpu: 600m\n---\napiVersion: v1\nkind: Service\nmetadata:\n name: php-apache\n labels:\n run: php-apache\nspec:\n ports:\n - port: 80\n selector:\n run: php-apache\nEOF\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Create a HorizontalPodAutoscaler."}),"\n",(0,a.jsxs)(n.p,{children:["Set an average CPU usage across all Pods of 20% to see one additional worker node being created later. Note that the CPU usage isn't related to the host CPU usage, but rather to the requested CPU capacities (20% of 600 milli-cores CPU across all Pods). See the ",(0,a.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#create-horizontal-pod-autoscaler",children:"original tutorial"})," for more information on the HPA configuration."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl autoscale deployment php-apache --cpu-percent=20 --min=1 --max=10\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Create a Pod that generates load on the server:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while true; do wget -q -O- http://php-apache; done"\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["Wait a few minutes until new nodes are added to the cluster. You can ",(0,a.jsx)(n.a,{href:"#monitoring",children:"monitor"})," the state of the HorizontalPodAutoscaler, the list of nodes, and the behavior of the autoscaler."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"To stop the load generator, press CTRL+C and run:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl delete pod load-generator\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"The cluster-autoscaler checks every few minutes if nodes are underutilized. It will taint such candidates for removal and wait additional 10 minutes before the nodes are eventually removed and deallocated. The whole process can take about 20 minutes."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"monitoring",children:"Monitoring"}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsx)(n.p,{children:"For better observability, run the listed commands in different tabs in your terminal."})}),"\n",(0,a.jsx)(n.p,{children:"You can watch the status of the HorizontalPodAutoscaler with the current CPU usage, the target CPU limit, and the number of replicas created with:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl get hpa php-apache --watch\n"})}),"\n",(0,a.jsx)(n.p,{children:"From time to time compare the list of nodes to check the behavior of the autoscaler:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl get nodes\n"})}),"\n",(0,a.jsx)(n.p,{children:"For deeper insights, see the logs of the autoscaler Pod, which contains more details about the scaling decision process:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl logs -f deployment/constellation-cluster-autoscaler -n kube-system\n"})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>r});var s=t(96540);const a={},o=s.createContext(a);function i(e){const n=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/c920f53d.e05afb5e.js b/pr-preview/pr-4027/assets/js/c920f53d.e05afb5e.js deleted file mode 100644 index 5421e1d57..000000000 --- a/pr-preview/pr-4027/assets/js/c920f53d.e05afb5e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1155],{28453:(e,r,n)=>{n.d(r,{R:()=>i,x:()=>a});var o=n(96540);const t={},s=o.createContext(t);function i(e){const r=o.useContext(s);return o.useMemo(function(){return"function"==typeof e?e(r):{...r,...e}},[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),o.createElement(s.Provider,{value:r},e.children)}},52406:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"workflows/terraform-provider","title":"Use the Terraform provider","description":"The Constellation Terraform provider allows to manage the full lifecycle of a Constellation cluster (namely creation, upgrades, and deletion) via Terraform.","source":"@site/versioned_docs/version-2.22/workflows/terraform-provider.md","sourceDirName":"workflows","slug":"/workflows/terraform-provider","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/terraform-provider","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/workflows/terraform-provider.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Use persistent storage","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/storage"},"next":{"title":"Consume SBOMs","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/sbom"}}');var t=n(74848),s=n(28453);const i={},a="Use the Terraform provider",l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Quick setup",id:"quick-setup",level:2},{value:"Bringing your own infrastructure",id:"bringing-your-own-infrastructure",level:2},{value:"Cluster upgrades",id:"cluster-upgrades",level:2}];function d(e){const r={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components},{TabItem:n,Tabs:o}=r;return n||h("TabItem",!0),o||h("Tabs",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.header,{children:(0,t.jsx)(r.h1,{id:"use-the-terraform-provider",children:"Use the Terraform provider"})}),"\n",(0,t.jsxs)(r.p,{children:["The Constellation Terraform provider allows to manage the full lifecycle of a Constellation cluster (namely creation, upgrades, and deletion) via Terraform.\nThe provider is available through the ",(0,t.jsx)(r.a,{href:"https://registry.terraform.io/providers/edgelesssys/constellation/latest",children:"Terraform registry"})," and is released in lock-step with Constellation releases."]}),"\n",(0,t.jsx)(r.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsx)(r.li,{children:"a Linux / Mac operating system (ARM64/AMD64)"}),"\n",(0,t.jsxs)(r.li,{children:["a Terraform installation of version ",(0,t.jsx)(r.code,{children:"v1.4.4"})," or above"]}),"\n"]}),"\n",(0,t.jsx)(r.h2,{id:"quick-setup",children:"Quick setup"}),"\n",(0,t.jsxs)(r.p,{children:["This example shows how to set up a Constellation cluster with the reference IAM and infrastructure setup. This setup is also used when creating a Constellation cluster through the Constellation CLI. You can either consume the IAM / infrastructure modules through a remote source (recommended) or local files. The latter requires downloading the infrastructure and IAM modules for the corresponding CSP from ",(0,t.jsx)(r.code,{children:"terraform-modules.zip"})," on the ",(0,t.jsx)(r.a,{href:"https://github.com/edgelesssys/constellation/releases/latest",children:"Constellation release page"})," and placing them in the Terraform workspace directory."]}),"\n",(0,t.jsxs)(r.ol,{children:["\n",(0,t.jsx)(r.li,{children:"Create a directory (workspace) for your Constellation cluster."}),"\n"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"mkdir constellation-workspace\ncd constellation-workspace\n"})}),"\n",(0,t.jsxs)(r.ol,{start:"2",children:["\n",(0,t.jsxs)(r.li,{children:["Use one of the ",(0,t.jsx)(r.a,{href:"https://github.com/edgelesssys/constellation/tree/main/terraform-provider-constellation/examples/full",children:"example configurations for using the Constellation Terraform provider"})," or create a ",(0,t.jsx)(r.code,{children:"main.tf"})," file and fill it with the resources you want to create. The ",(0,t.jsx)(r.a,{href:"https://registry.terraform.io/providers/edgelesssys/constellation/latest",children:"Constellation Terraform provider documentation"})," offers thorough documentation on the resources and their attributes."]}),"\n",(0,t.jsx)(r.li,{children:"Initialize and apply the Terraform configuration."}),"\n"]}),"\n",(0,t.jsxs)(o,{groupId:"csp",children:[(0,t.jsxs)(n,{value:"aws",label:"AWS",children:[(0,t.jsx)(r.p,{children:"Initialize the providers and apply the configuration."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply\n"})}),(0,t.jsxs)(r.p,{children:["Optionally, you can prefix the ",(0,t.jsx)(r.code,{children:"terraform apply"})," command with ",(0,t.jsx)(r.code,{children:"TF_LOG=INFO"})," to collect ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform logs"})," while applying the configuration. This may provide helpful output in debugging scenarios."]})]}),(0,t.jsxs)(n,{value:"azure",label:"Azure",children:[(0,t.jsxs)(r.admonition,{type:"info",children:[(0,t.jsx)(r.p,{children:"On SEV-SNP, you need to manually patch the policy of the MAA provider before creating the Constellation cluster, as this feature isn't available in Azure's Terraform provider yet. The Constellation CLI provides a utility for patching, but you can also do it manually."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply -target module.azure_iam # adjust resource path if not using the example configuration\nterraform apply -target module.azure_infrastructure # adjust resource path if not using the example configuration\nconstellation maa-patch $(terraform output -raw maa_url) # adjust output path / input if not using the example configuration or manually patch the resource\nterraform apply -target constellation_cluster.azure_example # adjust resource path if not using the example configuration\n"})}),(0,t.jsx)(r.p,{children:"Use the following policy if manually performing the patch."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{children:'version= 1.0;\nauthorizationrules\n{\n [type=="x-ms-azurevm-default-securebootkeysvalidated", value==false] => deny();\n [type=="x-ms-azurevm-debuggersdisabled", value==false] => deny();\n // The line below was edited to use the MAA provider within Constellation. Do not edit manually.\n //[type=="secureboot", value==false] => deny();\n [type=="x-ms-azurevm-signingdisabled", value==false] => deny();\n [type=="x-ms-azurevm-dbvalidated", value==false] => deny();\n [type=="x-ms-azurevm-dbxvalidated", value==false] => deny();\n => permit();\n};\nissuancerules\n{\n};\n'})})]}),(0,t.jsx)(r.p,{children:"Initialize the providers and apply the configuration."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply\n"})}),(0,t.jsxs)(r.p,{children:["Optionally, you can prefix the ",(0,t.jsx)(r.code,{children:"terraform apply"})," command with ",(0,t.jsx)(r.code,{children:"TF_LOG=INFO"})," to collect ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform logs"})," while applying the configuration. This may provide helpful output in debugging scenarios."]})]}),(0,t.jsxs)(n,{value:"gcp",label:"GCP",children:[(0,t.jsx)(r.p,{children:"Initialize the providers and apply the configuration."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply\n"})}),(0,t.jsxs)(r.p,{children:["Optionally, you can prefix the ",(0,t.jsx)(r.code,{children:"terraform apply"})," command with ",(0,t.jsx)(r.code,{children:"TF_LOG=INFO"})," to collect ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform logs"})," while applying the configuration. This may provide helpful output in debugging scenarios."]})]}),(0,t.jsxs)(n,{value:"stackit",label:"STACKIT",children:[(0,t.jsx)(r.p,{children:"Initialize the providers and apply the configuration."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply\n"})}),(0,t.jsxs)(r.p,{children:["Optionally, you can prefix the ",(0,t.jsx)(r.code,{children:"terraform apply"})," command with ",(0,t.jsx)(r.code,{children:"TF_LOG=INFO"})," to collect ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform logs"})," while applying the configuration. This may provide helpful output in debugging scenarios."]})]})]}),"\n",(0,t.jsxs)(r.ol,{start:"4",children:["\n",(0,t.jsx)(r.li,{children:"Connect to the cluster."}),"\n"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform output -raw kubeconfig > constellation-admin.conf\nexport KUBECONFIG=$(realpath constellation-admin.conf)\n"})}),"\n",(0,t.jsx)(r.h2,{id:"bringing-your-own-infrastructure",children:"Bringing your own infrastructure"}),"\n",(0,t.jsxs)(r.p,{children:["Instead of using the example infrastructure used in the ",(0,t.jsx)(r.a,{href:"#quick-setup",children:"quick setup"}),", you can also provide your own infrastructure.\nIf you need a starting point for a custom infrastructure setup, you can download the infrastructure / IAM Terraform modules for the respective CSP from the Constellation ",(0,t.jsx)(r.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub releases"}),". You can modify and extend the modules per your requirements, while keeping the basic functionality intact.\nThe module contains:"]}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsxs)(r.li,{children:[(0,t.jsx)(r.code,{children:"{csp}"}),": cloud resources the cluster runs on"]}),"\n",(0,t.jsxs)(r.li,{children:[(0,t.jsx)(r.code,{children:"iam/{csp}"}),": IAM resources used within the cluster"]}),"\n"]}),"\n",(0,t.jsx)(r.p,{children:"When upgrading your cluster, make sure to check the Constellation release notes for potential breaking changes in the reference infrastructure / IAM modules that need to be considered."}),"\n",(0,t.jsx)(r.h2,{id:"cluster-upgrades",children:"Cluster upgrades"}),"\n",(0,t.jsx)(r.admonition,{type:"tip",children:(0,t.jsxs)(r.p,{children:["Also see the ",(0,t.jsx)(r.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade",children:"general documentation on cluster upgrades"}),"."]})}),"\n",(0,t.jsx)(r.p,{children:"The steps for applying the upgrade are as follows:"}),"\n",(0,t.jsxs)(r.ol,{children:["\n",(0,t.jsxs)(r.li,{children:["Update the version constraint of the Constellation Terraform provider in the ",(0,t.jsx)(r.code,{children:"required_providers"})," block in your Terraform configuration."]}),"\n",(0,t.jsxs)(r.li,{children:["If you explicitly set any of the version attributes of the provider's resources and data sources (e.g. ",(0,t.jsx)(r.code,{children:"image_version"})," or ",(0,t.jsx)(r.code,{children:"constellation_microservice_version"}),"), make sure to update them too. Refer to Constellation's ",(0,t.jsx)(r.a,{href:"https://github.com/edgelesssys/constellation/blob/main/dev-docs/workflows/versions-support.md",children:"version support policy"})," for more information on how each Constellation version and its dependencies are supported."]}),"\n",(0,t.jsxs)(r.li,{children:["Update the IAM / infrastructure configuration.","\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsxs)(r.li,{children:["For ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/language/modules/sources#fetching-archives-over-http",children:"remote addresses as module sources"}),", update the version number inside the address of the ",(0,t.jsx)(r.code,{children:"source"})," field of the infrastructure / IAM module to the target version."]}),"\n",(0,t.jsxs)(r.li,{children:["For ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/language/modules/sources#local-paths",children:"local paths as module sources"})," or when ",(0,t.jsx)(r.a,{href:"#bringing-your-own-infrastructure",children:"providing your own infrastructure"}),", see the changes made in the reference modules since the upgrade's origin version and adjust your infrastructure / IAM configuration accordingly."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(r.li,{children:"Upgrade the Terraform module and provider dependencies and apply the targeted configuration."}),"\n"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:" terraform init -upgrade\n terraform apply\n"})})]})}function u(e={}){const{wrapper:r}={...(0,s.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}function h(e,r){throw new Error("Expected "+(r?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/ca2d12cf.4f360de1.js b/pr-preview/pr-4027/assets/js/ca2d12cf.4f360de1.js deleted file mode 100644 index 9d3da2b78..000000000 --- a/pr-preview/pr-4027/assets/js/ca2d12cf.4f360de1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9343],{28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>l});var s=t(96540);const r={},i=s.createContext(r);function o(e){const n=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:n},e.children)}},50045:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"workflows/verify-cluster","title":"Verify your cluster","description":"Constellation\'s attestation feature allows you, or a third party, to verify the integrity and confidentiality of your Constellation cluster.","source":"@site/docs/workflows/verify-cluster.md","sourceDirName":"workflows","slug":"/workflows/verify-cluster","permalink":"/constellation/pr-preview/pr-4027/next/workflows/verify-cluster","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/workflows/verify-cluster.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Recover your cluster","permalink":"/constellation/pr-preview/pr-4027/next/workflows/recovery"},"next":{"title":"Use persistent storage","permalink":"/constellation/pr-preview/pr-4027/next/workflows/storage"}}');var r=t(74848),i=t(28453);const o={},l="Verify your cluster",a={},c=[{value:"Fetch measurements",id:"fetch-measurements",level:2},{value:"The <em>verify</em> command",id:"the-verify-command",level:2},{value:"Custom arguments",id:"custom-arguments",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"verify-your-cluster",children:"Verify your cluster"})}),"\n",(0,r.jsxs)(n.p,{children:["Constellation's ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/attestation",children:"attestation feature"})," allows you, or a third party, to verify the integrity and confidentiality of your Constellation cluster."]}),"\n",(0,r.jsx)(n.h2,{id:"fetch-measurements",children:"Fetch measurements"}),"\n",(0,r.jsx)(n.p,{children:"To verify the integrity of Constellation you need trusted measurements to verify against. For each node image released by Edgeless Systems, there are signed measurements, which you can download using the CLI:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"constellation config fetch-measurements\n"})}),"\n",(0,r.jsx)(n.p,{children:"This command performs the following steps:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Download the signed measurements for the configured image. By default, this will use Edgeless Systems' public measurement registry."}),"\n",(0,r.jsxs)(n.li,{children:["Verify the signature of the measurements. This will use Edgeless Systems' ",(0,r.jsx)(n.a,{href:"https://edgeless.systems/es.pub",children:"public key"}),"."]}),"\n",(0,r.jsx)(n.li,{children:"Write measurements into configuration file."}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["The configuration file then contains a list of ",(0,r.jsx)(n.code,{children:"measurements"})," similar to the following:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'# ...\nmeasurements:\n 0:\n expected: "0f35c214608d93c7a6e68ae7359b4a8be5a0e99eea9107ece427c4dea4e439cf"\n warnOnly: false\n 4:\n expected: "02c7a67c01ec70ffaf23d73a12f749ab150a8ac6dc529bda2fe1096a98bf42ea"\n warnOnly: false\n 5:\n expected: "e6949026b72e5045706cd1318889b3874480f7a3f7c5c590912391a2d15e6975"\n warnOnly: true\n 8:\n expected: "0000000000000000000000000000000000000000000000000000000000000000"\n warnOnly: false\n 9:\n expected: "f0a6e8601b00e2fdc57195686cd4ef45eb43a556ac1209b8e25d993213d68384"\n warnOnly: false\n 11:\n expected: "0000000000000000000000000000000000000000000000000000000000000000"\n warnOnly: false\n 12:\n expected: "da99eb6cf7c7fbb692067c87fd5ca0b7117dc293578e4fea41f95d3d3d6af5e2"\n warnOnly: false\n 13:\n expected: "0000000000000000000000000000000000000000000000000000000000000000"\n warnOnly: false\n 14:\n expected: "d7c4cc7ff7933022f013e03bdee875b91720b5b86cf1753cad830f95e791926f"\n warnOnly: true\n 15:\n expected: "0000000000000000000000000000000000000000000000000000000000000000"\n warnOnly: false\n# ...\n'})}),"\n",(0,r.jsxs)(n.p,{children:["Each entry specifies the expected value of the Constellation node, and whether the measurement should be enforced (",(0,r.jsx)(n.code,{children:"warnOnly: false"}),"), or only a warning should be logged (",(0,r.jsx)(n.code,{children:"warnOnly: true"}),").\nBy default, the subset of the ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/attestation#runtime-measurements",children:"available measurements"})," that can be locally reproduced and verified is enforced."]}),"\n",(0,r.jsxs)(n.p,{children:["During attestation, the validating side (CLI or ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#joinservice",children:"join service"}),") compares each measurement reported by the issuing side (first node or joining node) individually.\nFor mismatching measurements that have set ",(0,r.jsx)(n.code,{children:"warnOnly"})," to ",(0,r.jsx)(n.code,{children:"true"})," only a warning is emitted.\nFor mismatching measurements that have set ",(0,r.jsx)(n.code,{children:"warnOnly"})," to ",(0,r.jsx)(n.code,{children:"false"})," an error is emitted and attestation fails.\nIf attestation fails for a new node, it isn't permitted to join the cluster."]}),"\n",(0,r.jsxs)(n.h2,{id:"the-verify-command",children:["The ",(0,r.jsx)(n.em,{children:"verify"})," command"]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["The steps below are purely optional. They're automatically executed by ",(0,r.jsx)(n.code,{children:"constellation apply"})," when you initialize your cluster. The ",(0,r.jsx)(n.code,{children:"constellation verify"})," command mostly has an illustrative purpose."]})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"verify"})," command obtains and verifies an attestation statement from a running Constellation cluster."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"constellation verify [--cluster-id ...]\n"})}),"\n",(0,r.jsx)(n.p,{children:"From the attestation statement, the command verifies the following properties:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"The cluster is using the correct Confidential VM (CVM) type."}),"\n",(0,r.jsx)(n.li,{children:"Inside the CVMs, the correct node images are running. The node images are identified through the measurements obtained in the previous step."}),"\n",(0,r.jsxs)(n.li,{children:["The unique ID of the cluster matches the one from your ",(0,r.jsx)(n.code,{children:"constellation-state.yaml"})," file or passed in via ",(0,r.jsx)(n.code,{children:"--cluster-id"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Once the above properties are verified, you know that you are talking to the right Constellation cluster and it's in a good and trustworthy shape."}),"\n",(0,r.jsx)(n.h3,{id:"custom-arguments",children:"Custom arguments"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"verify"})," command also allows you to verify any Constellation deployment that you have network access to. For this you need the following:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The IP address of a running Constellation cluster's ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#verificationservice",children:"VerificationService"}),". The ",(0,r.jsx)(n.code,{children:"VerificationService"})," is exposed via a ",(0,r.jsx)(n.code,{children:"NodePort"})," service using the external IP address of your cluster. Run ",(0,r.jsx)(n.code,{children:"kubectl get nodes -o wide"})," and look for ",(0,r.jsx)(n.code,{children:"EXTERNAL-IP"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["The cluster's ",(0,r.jsx)(n.em,{children:"clusterID"}),". See ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys#cluster-identity",children:"cluster identity"})," for more details."]}),"\n",(0,r.jsxs)(n.li,{children:["A ",(0,r.jsx)(n.code,{children:"constellation-conf.yaml"})," file with the expected measurements of the cluster in your working directory."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"For example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-shell-session",children:"constellation verify -e 192.0.2.1 --cluster-id Q29uc3RlbGxhdGlvbkRvY3VtZW50YXRpb25TZWNyZXQ=\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/ca9f0fb1.84fd3f3c.js b/pr-preview/pr-4027/assets/js/ca9f0fb1.84fd3f3c.js deleted file mode 100644 index cfc431ecb..000000000 --- a/pr-preview/pr-4027/assets/js/ca9f0fb1.84fd3f3c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8255],{28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>s});var t=r(96540);const o={},l=t.createContext(o);function i(e){const n=t.useContext(l);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),t.createElement(l.Provider,{value:n},e.children)}},45488:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>t,toc:()=>a});const t=JSON.parse('{"id":"workflows/recovery","title":"Recover your cluster","description":"Recovery of a Constellation cluster means getting it back into a healthy state after too many concurrent node failures in the control plane.","source":"@site/docs/workflows/recovery.md","sourceDirName":"workflows","slug":"/workflows/recovery","permalink":"/constellation/pr-preview/pr-4027/next/workflows/recovery","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/workflows/recovery.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Terminate your cluster","permalink":"/constellation/pr-preview/pr-4027/next/workflows/terminate"},"next":{"title":"Verify your cluster","permalink":"/constellation/pr-preview/pr-4027/next/workflows/verify-cluster"}}');var o=r(74848),l=r(28453);const i={},s="Recover your cluster",c={},a=[{value:"Identify unhealthy clusters",id:"identify-unhealthy-clusters",level:2},{value:"Recover a cluster",id:"recover-a-cluster",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,l.R)(),...e.components},{TabItem:t,Tabs:i}=n;return t||g("TabItem",!0),i||g("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"recover-your-cluster",children:"Recover your cluster"})}),"\n",(0,o.jsxs)(n.p,{children:["Recovery of a Constellation cluster means getting it back into a healthy state after too many concurrent node failures in the control plane.\nReasons for an unhealthy cluster can vary from a power outage, or planned reboot, to migration of nodes and regions.\nRecovery events are rare, because Constellation is built for high availability and automatically and securely replaces failed nodes. When a node is replaced, Constellation's control plane first verifies the new node before it sends the node the cryptographic keys required to decrypt its ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/images#state-disk",children:"state disk"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Constellation provides a recovery mechanism for cases where the control plane has failed and is unable to replace nodes.\nThe ",(0,o.jsx)(n.code,{children:"constellation recover"})," command securely connects to all nodes in need of recovery using ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/attestation#attested-tls-atls",children:"attested TLS"})," and provides them with the keys to decrypt their state disks and continue booting."]}),"\n",(0,o.jsx)(n.h2,{id:"identify-unhealthy-clusters",children:"Identify unhealthy clusters"}),"\n",(0,o.jsx)(n.p,{children:"The first step to recovery is identifying when a cluster becomes unhealthy.\nUsually, this can be first observed when the Kubernetes API server becomes unresponsive."}),"\n",(0,o.jsx)(n.p,{children:"You can check the health status of the nodes via the cloud service provider (CSP).\nConstellation provides logging information on the boot process and status via serial console output.\nIn the following, you'll find detailed descriptions for identifying clusters stuck in recovery for each CSP."}),"\n",(0,o.jsxs)(i,{groupId:"csp",children:[(0,o.jsxs)(t,{value:"aws",label:"AWS",children:[(0,o.jsxs)(n.p,{children:["First, open the AWS console to view all Auto Scaling Groups (ASGs) in the region of your cluster. Select the ASG of the control plane ",(0,o.jsx)(n.code,{children:"<cluster-name>-<UID>-control-plane"})," and check that enough members are in a ",(0,o.jsx)(n.em,{children:"Running"})," state."]}),(0,o.jsxs)(n.p,{children:["Second, check the boot logs of these ",(0,o.jsx)(n.em,{children:"Instances"}),". In the ASG's ",(0,o.jsx)(n.em,{children:"Instance management"})," view, select each desired instance. In the upper right corner, select ",(0,o.jsx)(n.strong,{children:"Action > Monitor and troubleshoot > Get system log"}),"."]}),(0,o.jsxs)(n.p,{children:["In the serial console output, search for ",(0,o.jsx)(n.code,{children:"Waiting for decryption key"}),".\nSimilar output to the following means your node was restarted and needs to decrypt the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/images#state-disk",children:"state disk"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"gcp"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}\n'})}),(0,o.jsxs)(n.p,{children:["The node will then try to connect to the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#joinservice",children:(0,o.jsx)(n.em,{children:"JoinService"})})," and obtain the decryption key.\nIf this fails due to an unhealthy control plane, you will see log messages similar to the following:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["192.168.178.4:30090","192.168.178.2:30090"]}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.4:30090"}\n{"level":"WARN","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.4:30090: connect: connection refused\\"","endpoint":"192.168.178.4:30090"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.2:30090"}\n{"level":"WARN","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.2:30090: i/o timeout\\"","endpoint":"192.168.178.2:30090"}\n{"level":"ERROR","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}\n'})}),(0,o.jsx)(n.p,{children:"This means that you have to recover the node manually."})]}),(0,o.jsxs)(t,{value:"azure",label:"Azure",children:[(0,o.jsxs)(n.p,{children:["In the Azure portal, find the cluster's resource group.\nInside the resource group, open the control plane ",(0,o.jsx)(n.em,{children:"Virtual machine scale set"})," ",(0,o.jsx)(n.code,{children:"constellation-scale-set-controlplanes-<suffix>"}),".\nOn the left, go to ",(0,o.jsx)(n.strong,{children:"Settings"})," > ",(0,o.jsx)(n.strong,{children:"Instances"})," and check that enough members are in a ",(0,o.jsx)(n.em,{children:"Running"})," state."]}),(0,o.jsxs)(n.p,{children:["Second, check the boot logs of these ",(0,o.jsx)(n.em,{children:"Instances"}),".\nIn the scale set's ",(0,o.jsx)(n.em,{children:"Instances"})," view, open the details page of the desired instance.\nOn the left, go to ",(0,o.jsx)(n.strong,{children:"Support + troubleshooting"})," > ",(0,o.jsx)(n.strong,{children:"Serial console"}),"."]}),(0,o.jsxs)(n.p,{children:["In the serial console output, search for ",(0,o.jsx)(n.code,{children:"Waiting for decryption key"}),".\nSimilar output to the following means your node was restarted and needs to decrypt the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/images#state-disk",children:"state disk"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T09:56:41Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"azure"}\n{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}\n{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}\n{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}\n'})}),(0,o.jsxs)(n.p,{children:["The node will then try to connect to the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#joinservice",children:(0,o.jsx)(n.em,{children:"JoinService"})})," and obtain the decryption key.\nIf this fails due to an unhealthy control plane, you will see log messages similar to the following:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["10.9.0.5:30090","10.9.0.6:30090"]}\n{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"10.9.0.5:30090"}\n{"level":"WARN","ts":"2022-09-08T09:57:03Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 10.9.0.5:30090: i/o timeout\\"","endpoint":"10.9.0.5:30090"}\n{"level":"INFO","ts":"2022-09-08T09:57:03Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"10.9.0.6:30090"}\n{"level":"WARN","ts":"2022-09-08T09:57:23Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 10.9.0.6:30090: i/o timeout\\"","endpoint":"10.9.0.6:30090"}\n{"level":"ERROR","ts":"2022-09-08T09:57:23Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}\n'})}),(0,o.jsx)(n.p,{children:"This means that you have to recover the node manually."})]}),(0,o.jsxs)(t,{value:"gcp",label:"GCP",children:[(0,o.jsxs)(n.p,{children:["First, check that the control plane ",(0,o.jsx)(n.em,{children:"Instance Group"})," has enough members in a ",(0,o.jsx)(n.em,{children:"Ready"})," state.\nIn the GCP Console, go to ",(0,o.jsx)(n.strong,{children:"Instance Groups"})," and check the group for the cluster's control plane ",(0,o.jsx)(n.code,{children:"<cluster-name>-control-plane-<suffix>"}),"."]}),(0,o.jsxs)(n.p,{children:["Second, check the status of the ",(0,o.jsx)(n.em,{children:"VM Instances"}),".\nGo to ",(0,o.jsx)(n.strong,{children:"VM Instances"})," and open the details of the desired instance.\nCheck the serial console output of that instance by opening the ",(0,o.jsx)(n.strong,{children:"Logs"})," > ",(0,o.jsx)(n.strong,{children:"Serial port 1 (console)"})," page:"]}),(0,o.jsx)(n.p,{children:(0,o.jsx)(n.img,{alt:"GCP portal serial console link",src:r(85866).A+"",width:"846",height:"415"})}),(0,o.jsxs)(n.p,{children:["In the serial console output, search for ",(0,o.jsx)(n.code,{children:"Waiting for decryption key"}),".\nSimilar output to the following means your node was restarted and needs to decrypt the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/images#state-disk",children:"state disk"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"gcp"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}\n'})}),(0,o.jsxs)(n.p,{children:["The node will then try to connect to the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#joinservice",children:(0,o.jsx)(n.em,{children:"JoinService"})})," and obtain the decryption key.\nIf this fails due to an unhealthy control plane, you will see log messages similar to the following:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["192.168.178.4:30090","192.168.178.2:30090"]}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.4:30090"}\n{"level":"WARN","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.4:30090: connect: connection refused\\"","endpoint":"192.168.178.4:30090"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.2:30090"}\n{"level":"WARN","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.2:30090: i/o timeout\\"","endpoint":"192.168.178.2:30090"}\n{"level":"ERROR","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}\n'})}),(0,o.jsx)(n.p,{children:"This means that you have to recover the node manually."})]}),(0,o.jsxs)(t,{value:"stackit",label:"STACKIT",children:[(0,o.jsxs)(n.p,{children:["First, open the STACKIT portal to view all servers in your project. Select individual control plane nodes ",(0,o.jsx)(n.code,{children:"<cluster-name>-<UID>-control-plane-<UID>-<index>"})," and check that enough members are in a ",(0,o.jsx)(n.em,{children:"Running"})," state."]}),(0,o.jsxs)(n.p,{children:["Second, check the boot logs of these servers. Click on a server name and select ",(0,o.jsx)(n.strong,{children:"Overview"}),". Find the ",(0,o.jsx)(n.strong,{children:"Machine Setup"})," section and click on ",(0,o.jsx)(n.strong,{children:"Web console"})," > ",(0,o.jsx)(n.strong,{children:"Open console"}),"."]}),(0,o.jsxs)(n.p,{children:["In the serial console output, search for ",(0,o.jsx)(n.code,{children:"Waiting for decryption key"}),".\nSimilar output to the following means your node was restarted and needs to decrypt the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/images#state-disk",children:"state disk"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"gcp"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}\n'})}),(0,o.jsxs)(n.p,{children:["The node will then try to connect to the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#joinservice",children:(0,o.jsx)(n.em,{children:"JoinService"})})," and obtain the decryption key.\nIf this fails due to an unhealthy control plane, you will see log messages similar to the following:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["192.168.178.4:30090","192.168.178.2:30090"]}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.4:30090"}\n{"level":"WARN","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.4:30090: connect: connection refused\\"","endpoint":"192.168.178.4:30090"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.2:30090"}\n{"level":"WARN","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.2:30090: i/o timeout\\"","endpoint":"192.168.178.2:30090"}\n{"level":"ERROR","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}\n'})}),(0,o.jsx)(n.p,{children:"This means that you have to recover the node manually."})]})]}),"\n",(0,o.jsx)(n.h2,{id:"recover-a-cluster",children:"Recover a cluster"}),"\n",(0,o.jsx)(n.p,{children:"Recovering a cluster requires the following parameters:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The ",(0,o.jsx)(n.code,{children:"constellation-state.yaml"})," file in your working directory or the cluster's endpoint"]}),"\n",(0,o.jsx)(n.li,{children:"The master secret of the cluster"}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"A cluster can be recovered like this:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"$ constellation recover\nPushed recovery key.\nPushed recovery key.\nPushed recovery key.\nRecovered 3 control-plane nodes.\n"})}),"\n",(0,o.jsx)(n.p,{children:"In the serial console output of the node you'll see a similar output to the following:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer","caller":"recoveryserver/server.go:93","msg":"Received recover call"}\n{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer","caller":"recoveryserver/server.go:125","msg":"Received state disk key and measurement secret, shutting down server"}\n{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer.gRPC","caller":"zap/server_interceptors.go:61","msg":"finished streaming call with code OK","grpc.start_time":"2022-09-08T10:26:59Z","system":"grpc","span.kind":"server","grpc.service":"recoverproto.API","grpc.method":"Recover","peer.address":"192.0.2.3:41752","grpc.code":"OK","grpc.time_ms":15.701}\n{"level":"INFO","ts":"2022-09-08T10:27:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:87","msg":"RejoinClient stopped"}\n'})})]})}function h(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}function g(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},85866:(e,n,r)=>{r.d(n,{A:()=>t});const t=r.p+"assets/images/recovery-gcp-serial-console-link-d31487c5a5e88fbcde9dcc33e876838d.png"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/cb054e22.1fe4c9a7.js b/pr-preview/pr-4027/assets/js/cb054e22.1fe4c9a7.js deleted file mode 100644 index a6286ba9d..000000000 --- a/pr-preview/pr-4027/assets/js/cb054e22.1fe4c9a7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9032],{28453:(e,s,n)=>{n.d(s,{R:()=>r,x:()=>a});var t=n(96540);const o={},i=t.createContext(o);function r(e){const s=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),t.createElement(i.Provider,{value:s},e.children)}},80233:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"workflows/sbom","title":"Consume software bill of materials (SBOMs)","description":"---","source":"@site/docs/workflows/sbom.md","sourceDirName":"workflows","slug":"/workflows/sbom","permalink":"/constellation/pr-preview/pr-4027/next/workflows/sbom","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/workflows/sbom.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Use the Terraform provider","permalink":"/constellation/pr-preview/pr-4027/next/workflows/terraform-provider"},"next":{"title":"Reproduce release artifacts","permalink":"/constellation/pr-preview/pr-4027/next/workflows/reproducible-builds"}}');var o=n(74848),i=n(28453);const r={},a="Consume software bill of materials (SBOMs)",l={},c=[{value:"Verify and download SBOMs",id:"verify-and-download-sboms",level:2},{value:"Constellation CLI",id:"constellation-cli",level:3},{value:"Container Images",id:"container-images",level:3},{value:"Vulnerability scanning",id:"vulnerability-scanning",level:2},{value:"Grype",id:"grype",level:3},{value:"Dependency Track",id:"dependency-track",level:3}];function d(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",...(0,i.R)(),...e.components},{AsciinemaWidget:n}=s;return n||function(e,s){throw new Error("Expected "+(s?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("AsciinemaWidget",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.header,{children:(0,o.jsx)(s.h1,{id:"consume-software-bill-of-materials-sboms",children:"Consume software bill of materials (SBOMs)"})}),"\n",(0,o.jsx)(n,{src:"/constellation/assets/check-sbom.cast",rows:"20",cols:"112",idleTimeLimit:"3",preload:"true",theme:"edgeless"}),"\n",(0,o.jsx)(s.hr,{}),"\n",(0,o.jsxs)(s.p,{children:["Constellation builds produce a ",(0,o.jsx)(s.a,{href:"https://www.ntia.gov/SBOM",children:"software bill of materials (SBOM)"})," for each generated ",(0,o.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices",children:"artifact"}),".\nYou can use SBOMs to make informed decisions about dependencies and vulnerabilities in a given application. Enterprises rely on SBOMs to maintain an inventory of used applications, which allows them to take data-driven approaches to managing risks related to vulnerabilities."]}),"\n",(0,o.jsxs)(s.p,{children:["SBOMs for Constellation are generated using ",(0,o.jsx)(s.a,{href:"https://github.com/anchore/syft",children:"Syft"}),", signed using ",(0,o.jsx)(s.a,{href:"https://github.com/sigstore/cosign",children:"Cosign"}),", and stored with the produced artifact."]}),"\n",(0,o.jsxs)(s.admonition,{type:"note",children:[(0,o.jsx)(s.p,{children:"The public key for Edgeless Systems' long-term code-signing key is:"}),(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT\nJmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==\n-----END PUBLIC KEY-----\n"})}),(0,o.jsxs)(s.p,{children:["The public key is also available for download at ",(0,o.jsx)(s.a,{href:"https://edgeless.systems/es.pub",children:"https://edgeless.systems/es.pub"})," and in the Twitter profile ",(0,o.jsx)(s.a,{href:"https://twitter.com/EdgelessSystems",children:"@EdgelessSystems"}),"."]}),(0,o.jsxs)(s.p,{children:["Make sure the key is available in a file named ",(0,o.jsx)(s.code,{children:"cosign.pub"})," to execute the following examples."]})]}),"\n",(0,o.jsx)(s.h2,{id:"verify-and-download-sboms",children:"Verify and download SBOMs"}),"\n",(0,o.jsx)(s.p,{children:"The following sections detail how to work with each type of artifact to verify and extract the SBOM."}),"\n",(0,o.jsx)(s.h3,{id:"constellation-cli",children:"Constellation CLI"}),"\n",(0,o.jsxs)(s.p,{children:["The SBOM for Constellation CLI is made available on the ",(0,o.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub release page"}),". The SBOM (",(0,o.jsx)(s.code,{children:"constellation.spdx.sbom"}),") and corresponding signature (",(0,o.jsx)(s.code,{children:"constellation.spdx.sbom.sig"}),") are valid for each Constellation CLI for a given version, regardless of architecture and operating system."]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-bash",children:"curl -LO https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom\ncurl -LO https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom.sig\ncosign verify-blob --key cosign.pub --signature constellation.spdx.sbom.sig constellation.spdx.sbom\n"})}),"\n",(0,o.jsx)(s.h3,{id:"container-images",children:"Container Images"}),"\n",(0,o.jsxs)(s.p,{children:["SBOMs for container images are ",(0,o.jsx)(s.a,{href:"https://docs.sigstore.dev/cosign/signing/other_types/#sboms-software-bill-of-materials",children:"attached to the image using Cosign"})," and uploaded to the same registry."]}),"\n",(0,o.jsx)(s.p,{children:"As a consumer, use cosign to download and verify the SBOM:"}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-bash",children:"# Verify and download the attestation statement\ncosign verify-attestation ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --type 'https://cyclonedx.org/bom' --key cosign.pub --output-file verification-service.att.json\n# Extract SBOM from attestation statement\njq -r .payload verification-service.att.json | base64 -d > verification-service.cyclonedx.sbom\n"})}),"\n",(0,o.jsx)(s.p,{children:"A successful verification should result in similar output:"}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-shell-session",children:"$ cosign verify-attestation ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --type 'https://cyclonedx.org/bom' --key cosign.pub --output-file verification-service.sbom\n\nVerification for ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --\nThe following checks were performed on each of these signatures:\n - The cosign claims were validated\n - The signatures were verified against the specified public key\n$ jq -r .payload verification-service.sbom | base64 -d > verification-service.cyclonedx.sbom\n"})}),"\n",(0,o.jsx)(s.admonition,{type:"note",children:(0,o.jsxs)(s.p,{children:["This example considers only the ",(0,o.jsx)(s.code,{children:"verification-service"}),". The same approach works for all containers in the ",(0,o.jsx)(s.a,{href:"https://github.com/orgs/edgelesssys/packages?repo_name=constellation",children:"Constellation container registry"}),"."]})}),"\n",(0,o.jsx)(s.h2,{id:"vulnerability-scanning",children:"Vulnerability scanning"}),"\n",(0,o.jsxs)(s.p,{children:["You can use a plethora of tools to consume SBOMs. This section provides suggestions for tools that are popular and known to produce reliable results, but any tool that consumes ",(0,o.jsx)(s.a,{href:"https://spdx.dev/",children:"SPDX"})," or ",(0,o.jsx)(s.a,{href:"https://cyclonedx.org/",children:"CycloneDX"})," files should work."]}),"\n",(0,o.jsxs)(s.p,{children:["Syft is able to ",(0,o.jsx)(s.a,{href:"https://github.com/anchore/syft#format-conversion-experimental",children:"convert between the two formats"})," in case you require a specific type."]}),"\n",(0,o.jsx)(s.h3,{id:"grype",children:"Grype"}),"\n",(0,o.jsxs)(s.p,{children:[(0,o.jsx)(s.a,{href:"https://github.com/anchore/grype",children:"Grype"})," is a CLI tool that lends itself well for integration into CI/CD systems or local developer machines. It's also able to consume the signed attestation statement directly and does the verification in one go."]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-bash",children:"grype att:verification-service.sbom --key cosign.pub --add-cpes-if-none -q\n"})}),"\n",(0,o.jsx)(s.h3,{id:"dependency-track",children:"Dependency Track"}),"\n",(0,o.jsxs)(s.p,{children:[(0,o.jsx)(s.a,{href:"https://dependencytrack.org/",children:"Dependency Track"})," is one of the oldest and most mature solutions when it comes to managing software inventory and vulnerabilities. Once imported, it continuously scans SBOMs for new vulnerabilities. It supports the CycloneDX format and provides direct guidance on how to comply with ",(0,o.jsx)(s.a,{href:"https://docs.dependencytrack.org/usage/executive-order-14028/",children:"U.S. Executive Order 14028"}),"."]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/cbcdb048.23aba831.js b/pr-preview/pr-4027/assets/js/cbcdb048.23aba831.js deleted file mode 100644 index 485a72005..000000000 --- a/pr-preview/pr-4027/assets/js/cbcdb048.23aba831.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[2843],{28453:(e,t,o)=>{o.d(t,{R:()=>a,x:()=>l});var n=o(96540);const s={},i=n.createContext(s);function a(e){const t=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),n.createElement(i.Provider,{value:t},e.children)}},44999:(e,t,o)=>{o.d(t,{A:()=>n});const n=o.p+"assets/images/example-emojivoto-55d31a6fd0c07e8e44b2b51d55dac60d.jpg"},61985:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>r,contentTitle:()=>l,default:()=>p,frontMatter:()=>a,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"getting-started/examples/emojivoto","title":"Emojivoto","description":"Emojivoto is a simple and fun application that\'s well suited to test the basic functionality of your cluster.","source":"@site/versioned_docs/version-2.24/getting-started/examples/emojivoto.md","sourceDirName":"getting-started/examples","slug":"/getting-started/examples/emojivoto","permalink":"/constellation/pr-preview/pr-4027/getting-started/examples/emojivoto","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/getting-started/examples/emojivoto.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Examples","permalink":"/constellation/pr-preview/pr-4027/getting-started/examples"},"next":{"title":"Online Boutique","permalink":"/constellation/pr-preview/pr-4027/getting-started/examples/online-boutique"}}');var s=o(74848),i=o(28453);const a={},l="Emojivoto",r={},c=[];function d(e){const t={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"emojivoto",children:"Emojivoto"})}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"Emojivoto"})," is a simple and fun application that's well suited to test the basic functionality of your cluster."]}),"\n",(0,s.jsx)("img",{src:o(44999).A,alt:"emojivoto - Web UI",width:"552"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["Deploy the application:","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["Wait until it becomes available:","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["Forward the web service to your machine:","\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"kubectl -n emojivoto port-forward svc/web-svc 8080:80\n"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["Visit ",(0,s.jsx)(t.a,{href:"http://localhost:8080",children:"http://localhost:8080"})]}),"\n"]})]})}function p(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/cda59bb1.59d1e222.js b/pr-preview/pr-4027/assets/js/cda59bb1.59d1e222.js deleted file mode 100644 index d8a1e6ae5..000000000 --- a/pr-preview/pr-4027/assets/js/cda59bb1.59d1e222.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3526],{24565:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"overview/security-benefits","title":"Security benefits and threat model","description":"Constellation implements the Confidential Kubernetes concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be verified.","source":"@site/versioned_docs/version-2.22/overview/security-benefits.md","sourceDirName":"overview","slug":"/overview/security-benefits","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/security-benefits","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/overview/security-benefits.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential Kubernetes","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/confidential-kubernetes"},"next":{"title":"Product features","permalink":"/constellation/pr-preview/pr-4027/2.22/overview/product"}}');var r=n(74848),i=n(28453);const a={},o="Security benefits and threat model",c={},l=[{value:"Insider access",id:"insider-access",level:2},{value:"Infrastructure-based attacks",id:"infrastructure-based-attacks",level:2},{value:"Supply chain attacks",id:"supply-chain-attacks",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",p:"p",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"security-benefits-and-threat-model",children:"Security benefits and threat model"})}),"\n",(0,r.jsxs)(t.p,{children:["Constellation implements the ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/overview/confidential-kubernetes",children:"Confidential Kubernetes"})," concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the ",(0,r.jsx)(t.em,{children:"cloud & datacenter infrastructure"})," and the ",(0,r.jsx)(t.em,{children:"physical hosts"}),", including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cluster",children:"verified"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"TCB comparison",src:n(56726).A+"",width:"3988",height:"1380"})}),"\n",(0,r.jsx)(t.p,{children:"Given this background, the following describes the concrete threat classes that Constellation addresses."}),"\n",(0,r.jsx)(t.h2,{id:"insider-access",children:"Insider access"}),"\n",(0,r.jsx)(t.p,{children:"Employees and third-party contractors of cloud service providers (CSPs) have access to different layers of the cloud infrastructure.\nThis opens up a large attack surface where workloads and data can be read, copied, or manipulated. With Constellation, Kubernetes deployments are shielded from the infrastructure and thus such accesses are prevented."}),"\n",(0,r.jsx)(t.h2,{id:"infrastructure-based-attacks",children:"Infrastructure-based attacks"}),"\n",(0,r.jsxs)(t.p,{children:['Malicious cloud users ("hackers") may break out of their tenancy and access other tenants\' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. Analogously to the ',(0,r.jsx)(t.em,{children:"insider access"})," scenario, Constellation also prevents access to a deployment's data in this scenario."]}),"\n",(0,r.jsx)(t.h2,{id:"supply-chain-attacks",children:"Supply chain attacks"}),"\n",(0,r.jsxs)(t.p,{children:["Supply chain security is receiving lots of attention recently due to an ",(0,r.jsx)(t.a,{href:"https://www.enisa.europa.eu/news/enisa-news/understanding-the-increase-in-supply-chain-security-attacks",children:"increasing number of recorded attacks"}),". For instance, a malicious actor could attempt to tamper Constellation node images (including Kubernetes and other software) before they're loaded in the confidential VMs of a cluster. Constellation uses ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation",children:"remote attestation"})," in conjunction with public ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli",children:"transparency logs"})," to prevent this."]}),"\n",(0,r.jsx)(t.p,{children:"In the future, Constellation will extend this feature to customer workloads. This will enable cluster owners to create auditable policies that precisely define which containers can run in a given deployment."})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var s=n(96540);const r={},i=s.createContext(r);function a(e){const t=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:t},e.children)}},56726:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/tcb-424516bbf9d20afe12576bc1305ebc29.svg"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/ce803f35.cb1c2349.js b/pr-preview/pr-4027/assets/js/ce803f35.cb1c2349.js deleted file mode 100644 index 703eab31c..000000000 --- a/pr-preview/pr-4027/assets/js/ce803f35.cb1c2349.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7496],{28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>l});var s=t(96540);const r={},i=s.createContext(r);function o(e){const n=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:n},e.children)}},88365:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"workflows/verify-cluster","title":"Verify your cluster","description":"Constellation\'s attestation feature allows you, or a third party, to verify the integrity and confidentiality of your Constellation cluster.","source":"@site/versioned_docs/version-2.22/workflows/verify-cluster.md","sourceDirName":"workflows","slug":"/workflows/verify-cluster","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cluster","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/workflows/verify-cluster.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Recover your cluster","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/recovery"},"next":{"title":"Use persistent storage","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/storage"}}');var r=t(74848),i=t(28453);const o={},l="Verify your cluster",a={},c=[{value:"Fetch measurements",id:"fetch-measurements",level:2},{value:"The <em>verify</em> command",id:"the-verify-command",level:2},{value:"Custom arguments",id:"custom-arguments",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"verify-your-cluster",children:"Verify your cluster"})}),"\n",(0,r.jsxs)(n.p,{children:["Constellation's ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation",children:"attestation feature"})," allows you, or a third party, to verify the integrity and confidentiality of your Constellation cluster."]}),"\n",(0,r.jsx)(n.h2,{id:"fetch-measurements",children:"Fetch measurements"}),"\n",(0,r.jsx)(n.p,{children:"To verify the integrity of Constellation you need trusted measurements to verify against. For each node image released by Edgeless Systems, there are signed measurements, which you can download using the CLI:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"constellation config fetch-measurements\n"})}),"\n",(0,r.jsx)(n.p,{children:"This command performs the following steps:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Download the signed measurements for the configured image. By default, this will use Edgeless Systems' public measurement registry."}),"\n",(0,r.jsxs)(n.li,{children:["Verify the signature of the measurements. This will use Edgeless Systems' ",(0,r.jsx)(n.a,{href:"https://edgeless.systems/es.pub",children:"public key"}),"."]}),"\n",(0,r.jsx)(n.li,{children:"Write measurements into configuration file."}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["The configuration file then contains a list of ",(0,r.jsx)(n.code,{children:"measurements"})," similar to the following:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'# ...\nmeasurements:\n 0:\n expected: "0f35c214608d93c7a6e68ae7359b4a8be5a0e99eea9107ece427c4dea4e439cf"\n warnOnly: false\n 4:\n expected: "02c7a67c01ec70ffaf23d73a12f749ab150a8ac6dc529bda2fe1096a98bf42ea"\n warnOnly: false\n 5:\n expected: "e6949026b72e5045706cd1318889b3874480f7a3f7c5c590912391a2d15e6975"\n warnOnly: true\n 8:\n expected: "0000000000000000000000000000000000000000000000000000000000000000"\n warnOnly: false\n 9:\n expected: "f0a6e8601b00e2fdc57195686cd4ef45eb43a556ac1209b8e25d993213d68384"\n warnOnly: false\n 11:\n expected: "0000000000000000000000000000000000000000000000000000000000000000"\n warnOnly: false\n 12:\n expected: "da99eb6cf7c7fbb692067c87fd5ca0b7117dc293578e4fea41f95d3d3d6af5e2"\n warnOnly: false\n 13:\n expected: "0000000000000000000000000000000000000000000000000000000000000000"\n warnOnly: false\n 14:\n expected: "d7c4cc7ff7933022f013e03bdee875b91720b5b86cf1753cad830f95e791926f"\n warnOnly: true\n 15:\n expected: "0000000000000000000000000000000000000000000000000000000000000000"\n warnOnly: false\n# ...\n'})}),"\n",(0,r.jsxs)(n.p,{children:["Each entry specifies the expected value of the Constellation node, and whether the measurement should be enforced (",(0,r.jsx)(n.code,{children:"warnOnly: false"}),"), or only a warning should be logged (",(0,r.jsx)(n.code,{children:"warnOnly: true"}),").\nBy default, the subset of the ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#runtime-measurements",children:"available measurements"})," that can be locally reproduced and verified is enforced."]}),"\n",(0,r.jsxs)(n.p,{children:["During attestation, the validating side (CLI or ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#joinservice",children:"join service"}),") compares each measurement reported by the issuing side (first node or joining node) individually.\nFor mismatching measurements that have set ",(0,r.jsx)(n.code,{children:"warnOnly"})," to ",(0,r.jsx)(n.code,{children:"true"})," only a warning is emitted.\nFor mismatching measurements that have set ",(0,r.jsx)(n.code,{children:"warnOnly"})," to ",(0,r.jsx)(n.code,{children:"false"})," an error is emitted and attestation fails.\nIf attestation fails for a new node, it isn't permitted to join the cluster."]}),"\n",(0,r.jsxs)(n.h2,{id:"the-verify-command",children:["The ",(0,r.jsx)(n.em,{children:"verify"})," command"]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["The steps below are purely optional. They're automatically executed by ",(0,r.jsx)(n.code,{children:"constellation apply"})," when you initialize your cluster. The ",(0,r.jsx)(n.code,{children:"constellation verify"})," command mostly has an illustrative purpose."]})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"verify"})," command obtains and verifies an attestation statement from a running Constellation cluster."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"constellation verify [--cluster-id ...]\n"})}),"\n",(0,r.jsx)(n.p,{children:"From the attestation statement, the command verifies the following properties:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"The cluster is using the correct Confidential VM (CVM) type."}),"\n",(0,r.jsx)(n.li,{children:"Inside the CVMs, the correct node images are running. The node images are identified through the measurements obtained in the previous step."}),"\n",(0,r.jsxs)(n.li,{children:["The unique ID of the cluster matches the one from your ",(0,r.jsx)(n.code,{children:"constellation-state.yaml"})," file or passed in via ",(0,r.jsx)(n.code,{children:"--cluster-id"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Once the above properties are verified, you know that you are talking to the right Constellation cluster and it's in a good and trustworthy shape."}),"\n",(0,r.jsx)(n.h3,{id:"custom-arguments",children:"Custom arguments"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"verify"})," command also allows you to verify any Constellation deployment that you have network access to. For this you need the following:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The IP address of a running Constellation cluster's ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#verificationservice",children:"VerificationService"}),". The ",(0,r.jsx)(n.code,{children:"VerificationService"})," is exposed via a ",(0,r.jsx)(n.code,{children:"NodePort"})," service using the external IP address of your cluster. Run ",(0,r.jsx)(n.code,{children:"kubectl get nodes -o wide"})," and look for ",(0,r.jsx)(n.code,{children:"EXTERNAL-IP"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["The cluster's ",(0,r.jsx)(n.em,{children:"clusterID"}),". See ",(0,r.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys#cluster-identity",children:"cluster identity"})," for more details."]}),"\n",(0,r.jsxs)(n.li,{children:["A ",(0,r.jsx)(n.code,{children:"constellation-conf.yaml"})," file with the expected measurements of the cluster in your working directory."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"For example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-shell-session",children:"constellation verify -e 192.0.2.1 --cluster-id Q29uc3RlbGxhdGlvbkRvY3VtZW50YXRpb25TZWNyZXQ=\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/cea600d4.27bcd6a1.js b/pr-preview/pr-4027/assets/js/cea600d4.27bcd6a1.js deleted file mode 100644 index 366f51f9e..000000000 --- a/pr-preview/pr-4027/assets/js/cea600d4.27bcd6a1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[234],{637:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Workflows","slug":"/category/workflows","permalink":"/constellation/pr-preview/pr-4027/category/workflows","sidebar":"docs","navigation":{"previous":{"title":"Filestash with s3proxy","permalink":"/constellation/pr-preview/pr-4027/getting-started/examples/filestash-s3proxy"},"next":{"title":"Verify the CLI","permalink":"/constellation/pr-preview/pr-4027/workflows/verify-cli"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/d0929cd6.10e4a498.js b/pr-preview/pr-4027/assets/js/d0929cd6.10e4a498.js deleted file mode 100644 index 4ffc1b69c..000000000 --- a/pr-preview/pr-4027/assets/js/d0929cd6.10e4a498.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8748],{24258:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"getting-started/examples/filestash-s3proxy","title":"Deploying Filestash","description":"Filestash is a web frontend for different storage backends, including S3.","source":"@site/versioned_docs/version-2.24/getting-started/examples/filestash-s3proxy.md","sourceDirName":"getting-started/examples","slug":"/getting-started/examples/filestash-s3proxy","permalink":"/constellation/pr-preview/pr-4027/getting-started/examples/filestash-s3proxy","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/getting-started/examples/filestash-s3proxy.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Horizontal Pod Autoscaling","permalink":"/constellation/pr-preview/pr-4027/getting-started/examples/horizontal-scaling"},"next":{"title":"Workflows","permalink":"/constellation/pr-preview/pr-4027/category/workflows"}}');var o=t(74848),a=t(28453);const r={},i="Deploying Filestash",c={},l=[];function d(e){const s={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.header,{children:(0,o.jsx)(s.h1,{id:"deploying-filestash",children:"Deploying Filestash"})}),"\n",(0,o.jsx)(s.p,{children:"Filestash is a web frontend for different storage backends, including S3.\nIt's a useful application to showcase s3proxy in action."}),"\n",(0,o.jsxs)(s.ol,{children:["\n",(0,o.jsxs)(s.li,{children:["Deploy s3proxy as described in ",(0,o.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/workflows/s3proxy#deployment",children:"Deployment"}),"."]}),"\n",(0,o.jsx)(s.li,{children:"Create a deployment file for Filestash with one pod:"}),"\n"]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-sh",children:'cat << EOF > "deployment-filestash.yaml"\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: filestash\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: filestash\n template:\n metadata:\n labels:\n app: filestash\n spec:\n hostAliases:\n - ip: $(kubectl get svc s3proxy-service -o=jsonpath=\'{.spec.clusterIP}\')\n hostnames:\n - "s3.us-east-1.amazonaws.com"\n - "s3.us-east-2.amazonaws.com"\n - "s3.us-west-1.amazonaws.com"\n - "s3.us-west-2.amazonaws.com"\n - "s3.eu-north-1.amazonaws.com"\n - "s3.eu-south-1.amazonaws.com"\n - "s3.eu-south-2.amazonaws.com"\n - "s3.eu-west-1.amazonaws.com"\n - "s3.eu-west-2.amazonaws.com"\n - "s3.eu-west-3.amazonaws.com"\n - "s3.eu-central-1.amazonaws.com"\n - "s3.eu-central-2.amazonaws.com"\n - "s3.ap-northeast-1.amazonaws.com"\n - "s3.ap-northeast-2.amazonaws.com"\n - "s3.ap-northeast-3.amazonaws.com"\n - "s3.ap-east-1.amazonaws.com"\n - "s3.ap-southeast-1.amazonaws.com"\n - "s3.ap-southeast-2.amazonaws.com"\n - "s3.ap-southeast-3.amazonaws.com"\n - "s3.ap-southeast-4.amazonaws.com"\n - "s3.ap-south-1.amazonaws.com"\n - "s3.ap-south-2.amazonaws.com"\n - "s3.me-south-1.amazonaws.com"\n - "s3.me-central-1.amazonaws.com"\n - "s3.il-central-1.amazonaws.com"\n - "s3.af-south-1.amazonaws.com"\n - "s3.ca-central-1.amazonaws.com"\n - "s3.sa-east-1.amazonaws.com"\n containers:\n - name: filestash\n image: machines/filestash:latest\n ports:\n - containerPort: 8334\n volumeMounts:\n - name: ca-cert\n mountPath: /etc/ssl/certs/kube-ca.crt\n subPath: kube-ca.crt\n volumes:\n - name: ca-cert\n secret:\n secretName: s3proxy-tls\n items:\n - key: ca.crt\n path: kube-ca.crt\nEOF\n'})}),"\n",(0,o.jsxs)(s.p,{children:["The pod spec includes the ",(0,o.jsx)(s.code,{children:"hostAliases"})," key, which adds an entry to the pod's ",(0,o.jsx)(s.code,{children:"/etc/hosts"}),".\nThe entry forwards all requests for any of the currently defined AWS regions to the Kubernetes service ",(0,o.jsx)(s.code,{children:"s3proxy-service"}),".\nIf you followed the s3proxy ",(0,o.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/workflows/s3proxy#deployment",children:"Deployment"})," guide, this service points to a s3proxy pod."]}),"\n",(0,o.jsxs)(s.p,{children:["The deployment specifies all regions explicitly to prevent accidental data leaks.\nIf one of your buckets were located in a region that's not part of the ",(0,o.jsx)(s.code,{children:"hostAliases"})," key, traffic towards those buckets would not be redirected to s3proxy.\nSimilarly, if you want to exclude data for specific regions from going through s3proxy you can remove those regions from the deployment."]}),"\n",(0,o.jsxs)(s.p,{children:["The spec also includes a volume mount for the TLS certificate and adds it to the pod's certificate trust store.\nThe volume is called ",(0,o.jsx)(s.code,{children:"ca-cert"}),".\nThe key ",(0,o.jsx)(s.code,{children:"ca.crt"})," of that volume is mounted to ",(0,o.jsx)(s.code,{children:"/etc/ssl/certs/kube-ca.crt"}),", which is the default certificate trust store location for that container's OpenSSL library.\nNot adding the CA certificate will result in TLS authentication errors."]}),"\n",(0,o.jsxs)(s.ol,{start:"3",children:["\n",(0,o.jsxs)(s.li,{children:["Apply the file: ",(0,o.jsx)(s.code,{children:"kubectl apply -f deployment-filestash.yaml"})]}),"\n"]}),"\n",(0,o.jsxs)(s.p,{children:["Afterward, you can use a port forward to access the Filestash pod:\n",(0,o.jsx)(s.code,{children:"kubectl port-forward pod/$(kubectl get pod --selector='app=filestash' -o=jsonpath='{.items[*].metadata.name}') 8334:8334"})]}),"\n",(0,o.jsxs)(s.ol,{start:"4",children:["\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["After browsing to ",(0,o.jsx)(s.code,{children:"localhost:8443"}),", Filestash will ask you to set an administrator password.\nAfter setting it, you can directly leave the admin area by clicking the blue cloud symbol in the top left corner.\nSubsequently, you can select S3 as storage backend and enter your credentials.\nThis will bring you to an overview of your buckets.\nIf you want to deploy Filestash in production, take a look at its ",(0,o.jsx)(s.a,{href:"https://www.filestash.app/docs/",children:"documentation"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["To see the logs of s3proxy intercepting requests made to S3, run: ",(0,o.jsx)(s.code,{children:"kubectl logs -f pod/$(kubectl get pod --selector='app=s3proxy' -o=jsonpath='{.items[*].metadata.name}')"}),"\nLook out for log messages labeled ",(0,o.jsx)(s.code,{children:"intercepting"}),".\nThere is one such log message for each message that's encrypted, decrypted, or blocked."]}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["Once you have uploaded a file with Filestash, you should be able to view the file in Filestash.\nHowever, if you go to the AWS S3 ",(0,o.jsx)(s.a,{href:"https://s3.console.aws.amazon.com/s3/home",children:"Web UI"})," and download the file you just uploaded in Filestash, you won't be able to read it.\nAnother way to spot encrypted files without downloading them is to click on a file, scroll to the Metadata section, and look for the header named ",(0,o.jsx)(s.code,{children:"x-amz-meta-constellation-encryption"}),".\nThis header holds the encrypted data encryption key of the object and is only present on objects that are encrypted by s3proxy."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>r,x:()=>i});var n=t(96540);const o={},a=n.createContext(o);function r(e){const s=n.useContext(a);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/d12af2ba.d07f7408.js b/pr-preview/pr-4027/assets/js/d12af2ba.d07f7408.js deleted file mode 100644 index 18e17e43b..000000000 --- a/pr-preview/pr-4027/assets/js/d12af2ba.d07f7408.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[946],{28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>r});var t=s(96540);const l={},i=t.createContext(l);function o(e){const n=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:o(e.components),t.createElement(i.Provider,{value:n},e.children)}},85502:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"getting-started/first-steps-local","title":"First steps with a local cluster","description":"A local cluster lets you deploy and test Constellation without a cloud subscription.","source":"@site/versioned_docs/version-2.22/getting-started/first-steps-local.md","sourceDirName":"getting-started","slug":"/getting-started/first-steps-local","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/getting-started/first-steps-local.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"First steps (cloud)","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps"},"next":{"title":"Cloud Marketplaces","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/marketplaces"}}');var l=s(74848),i=s(28453);const o={},r="First steps with a local cluster",a={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Software installation on Ubuntu",id:"software-installation-on-ubuntu",level:3},{value:"Create a cluster",id:"create-a-cluster",level:2},{value:"Connect to the cluster",id:"connect-to-the-cluster",level:2},{value:"Deploy a sample application",id:"deploy-a-sample-application",level:2},{value:"Terminate your cluster",id:"terminate-your-cluster",level:2},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"VMs have no internet access / CLI remains in "Initializing cluster" state",id:"vms-have-no-internet-access--cli-remains-in-initializing-cluster-state",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components},{TabItem:s,Tabs:t}=n;return s||h("TabItem",!0),t||h("Tabs",!0),(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"first-steps-with-a-local-cluster",children:"First steps with a local cluster"})}),"\n",(0,l.jsx)(n.p,{children:"A local cluster lets you deploy and test Constellation without a cloud subscription.\nYou have two options:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Use MiniConstellation to automatically deploy a two-node cluster."}),"\n",(0,l.jsx)(n.li,{children:"For more fine-grained control, create the cluster using the QEMU provider."}),"\n"]}),"\n",(0,l.jsxs)(n.p,{children:["Both options use virtualization to create a local cluster with control-plane nodes and worker nodes. They ",(0,l.jsx)(n.strong,{children:"don't"})," require hardware with Confidential VM (CVM) support. For attestation, they currently use a software-based vTPM provided by KVM/QEMU."]}),"\n",(0,l.jsx)(n.p,{children:"You need an x64 machine with a Linux OS.\nYou can use a VM, but it needs nested virtualization."}),"\n",(0,l.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Machine requirements:","\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"An x86-64 CPU with at least 4 cores (6 cores are recommended)"}),"\n",(0,l.jsx)(n.li,{children:"At least 4 GB RAM (6 GB are recommended)"}),"\n",(0,l.jsx)(n.li,{children:"20 GB of free disk space"}),"\n",(0,l.jsx)(n.li,{children:"Hardware virtualization enabled in the BIOS/UEFI (often referred to as Intel VT-x or AMD-V/SVM) / nested-virtualization support when using a VM"}),"\n"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["Software requirements:","\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Linux OS with ",(0,l.jsx)(n.a,{href:"https://www.linux-kvm.org/page/Main_Page",children:"KVM kernel module"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Recommended: Ubuntu 22.04 LTS"}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://docs.docker.com/engine/install/",children:"Docker"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://gitlab.gnome.org/GNOME/libxslt/-/wikis/home",children:"xsltproc"})}),"\n",(0,l.jsxs)(n.li,{children:["(Optional) ",(0,l.jsx)(n.a,{href:"https://www.libvirt.org/manpages/virsh.html",children:"virsh"})," to observe and access your nodes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"software-installation-on-ubuntu",children:"Software installation on Ubuntu"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:'# install Docker\ncurl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg\necho "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null\nsudo apt update\nsudo apt install docker-ce\n# install other dependencies\nsudo apt install xsltproc\nsudo snap install kubectl --classic\n# install Constellation CLI\ncurl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-amd64\nsudo install constellation-linux-amd64 /usr/local/bin/constellation\n# do not drop forwarded packages\nsudo iptables -P FORWARD ACCEPT\n'})}),"\n",(0,l.jsx)(n.h2,{id:"create-a-cluster",children:"Create a cluster"}),"\n",(0,l.jsxs)(t,{groupId:"csp",children:[(0,l.jsxs)(s,{value:"mini",label:"MiniConstellation",children:[(0,l.jsxs)(n.p,{children:["With the ",(0,l.jsx)(n.code,{children:"constellation mini"})," command, you can deploy and test Constellation locally. This mode is called MiniConstellation. Conceptually, MiniConstellation is similar to ",(0,l.jsx)(n.a,{href:"https://microk8s.io/",children:"MicroK8s"}),", ",(0,l.jsx)(n.a,{href:"https://k3s.io/",children:"K3s"}),", and ",(0,l.jsx)(n.a,{href:"https://minikube.sigs.k8s.io/docs/",children:"minikube"}),"."]}),(0,l.jsx)(n.admonition,{type:"caution",children:(0,l.jsxs)(n.p,{children:["MiniConstellation has specific soft- and hardware requirements such as a Linux OS running on an x86-64 CPU. Pay attention to all ",(0,l.jsx)(n.a,{href:"#prerequisites",children:"prerequisites"})," when setting up."]})}),(0,l.jsx)(n.admonition,{type:"note",children:(0,l.jsx)(n.p,{children:"Since MiniConstellation runs on your local system, cloud features such as load balancing,\nattaching persistent storage, or autoscaling aren't available."})}),(0,l.jsx)(n.p,{children:"The following creates your MiniConstellation cluster (may take up to 10 minutes to complete):"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation mini up\n"})}),(0,l.jsxs)(n.p,{children:["This will configure your current directory as the ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration#workspaces",children:"workspace"})," for this cluster.\nAll ",(0,l.jsx)(n.code,{children:"constellation"})," commands concerning this cluster need to be issued from this directory."]})]}),(0,l.jsxs)(s,{value:"qemu",label:"QEMU",children:[(0,l.jsxs)(n.p,{children:["With the QEMU provider, you can create a local Constellation cluster as if it were in the cloud. The provider uses ",(0,l.jsx)(n.a,{href:"https://www.qemu.org/",children:"QEMU"})," to create multiple VMs for the cluster nodes, which interact with each other."]}),(0,l.jsx)(n.admonition,{type:"caution",children:(0,l.jsxs)(n.p,{children:["Constellation on QEMU has specific soft- and hardware requirements such as a Linux OS running on an x86-64 CPU. Pay attention to all ",(0,l.jsx)(n.a,{href:"#prerequisites",children:"prerequisites"})," when setting up."]})}),(0,l.jsx)(n.admonition,{type:"note",children:(0,l.jsx)(n.p,{children:"Since Constellation on QEMU runs on your local system, cloud features such as load balancing,\nattaching persistent storage, or autoscaling aren't available."})}),(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"To set up your local cluster, you need to create a configuration file for Constellation first."}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation config generate qemu\n"})}),(0,l.jsxs)(n.p,{children:["This creates a ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/config",children:"configuration file"})," for QEMU called ",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"}),". After that, your current folder also becomes your ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration#workspaces",children:"workspace"}),". All ",(0,l.jsx)(n.code,{children:"constellation"})," commands for your cluster need to be executed from this directory."]}),(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsxs)(n.li,{children:["Now you can create your cluster and its nodes. ",(0,l.jsx)(n.code,{children:"constellation apply"})," uses the options set in ",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"}),"."]}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation apply -y\n"})}),(0,l.jsx)(n.p,{children:"The Output should look like the following:"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:'$ constellation apply -y\nChecking for infrastructure changes\nThe following Constellation cluster will be created:\n 3 control-plane nodes of type 2-vCPUs will be created.\n 1 worker node of type 2-vCPUs will be created.\nCreating\nCloud infrastructure created successfully.\nYour Constellation master secret was successfully written to ./constellation-mastersecret.json\nConnecting\nInitializing cluster\nInstalling Kubernetes components\nYour Constellation cluster was successfully initialized.\n\nConstellation cluster identifier g6iMP5wRU1b7mpOz2WEISlIYSfdAhB0oNaOg6XEwKFY=\nKubernetes configuration constellation-admin.conf\n\nYou can now connect to your cluster by executing:\n export KUBECONFIG="$PWD/constellation-admin.conf"\n'})}),(0,l.jsxs)(n.p,{children:["The cluster's identifier will be different in your output.\nKeep ",(0,l.jsx)(n.code,{children:"constellation-mastersecret.json"})," somewhere safe.\nThis will allow you to ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/recovery",children:"recover your cluster"})," in case of a disaster."]}),(0,l.jsx)(n.admonition,{type:"info",children:(0,l.jsxs)(n.p,{children:["Depending on your setup, ",(0,l.jsx)(n.code,{children:"constellation apply"})," may take 10+ minutes to complete."]})}),(0,l.jsxs)(n.ol,{start:"3",children:["\n",(0,l.jsx)(n.li,{children:"Configure kubectl"}),"\n"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:'export KUBECONFIG="$PWD/constellation-admin.conf"\n'})})]})]}),"\n",(0,l.jsx)(n.h2,{id:"connect-to-the-cluster",children:"Connect to the cluster"}),"\n",(0,l.jsx)(n.p,{children:"Your cluster initially consists of a single control-plane node:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"$ kubectl get nodes\nNAME STATUS ROLES AGE VERSION\ncontrol-plane-0 Ready control-plane 66s v1.24.6\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Additional nodes will request to join the cluster shortly. Before each additional node is allowed to join the cluster, its state is verified using remote attestation by the ",(0,l.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#joinservice",children:"JoinService"}),".\nIf verification passes successfully, the new node receives keys and certificates to join the cluster."]}),"\n",(0,l.jsx)(n.p,{children:"You can follow this process by viewing the logs of the JoinService:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:'$ kubectl logs -n kube-system daemonsets/join-service -f\n{"level":"INFO","ts":"2022-10-14T09:32:20Z","caller":"cmd/main.go:48","msg":"Constellation Node Join Service","version":"2.1.0","cloudProvider":"qemu"}\n{"level":"INFO","ts":"2022-10-14T09:32:20Z","logger":"validator","caller":"watcher/validator.go:96","msg":"Updating expected measurements"}\n...\n'})}),"\n",(0,l.jsx)(n.p,{children:"Once all nodes have joined your cluster, it may take a couple of minutes for all resources to become available.\nYou can check on the state of your cluster by running the following:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"$ kubectl get nodes\nNAME STATUS ROLES AGE VERSION\ncontrol-plane-0 Ready control-plane 2m59s v1.24.6\nworker-0 Ready <none> 32s v1.24.6\n"})}),"\n",(0,l.jsx)(n.h2,{id:"deploy-a-sample-application",children:"Deploy a sample application"}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["Deploy the ",(0,l.jsx)(n.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"emojivoto app"})]}),"\n"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment\n"})}),"\n",(0,l.jsxs)(n.ol,{start:"2",children:["\n",(0,l.jsx)(n.li,{children:"Expose the frontend service locally"}),"\n"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments\nkubectl -n emojivoto port-forward svc/web-svc 8080:80 &\ncurl http://localhost:8080\nkill %1\n"})}),"\n",(0,l.jsx)(n.h2,{id:"terminate-your-cluster",children:"Terminate your cluster"}),"\n",(0,l.jsxs)(t,{groupId:"csp",children:[(0,l.jsxs)(s,{value:"mini",label:"MiniConstellation",children:[(0,l.jsx)(n.p,{children:"Once you are done, you can clean up the created resources using the following command:"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation mini down\n"})}),(0,l.jsxs)(n.p,{children:["This will destroy your cluster and clean up your workspace.\nThe VM image and cluster configuration file (",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"}),") will be kept and may be reused to create new clusters."]})]}),(0,l.jsxs)(s,{value:"qemu",label:"QEMU",children:[(0,l.jsx)(n.p,{children:"Once you are done, you can clean up the created resources using the following command:"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"constellation terminate\n"})}),(0,l.jsx)(n.p,{children:"This should give the following output:"}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"$ constellation terminate\nYou are about to terminate a Constellation cluster.\nAll of its associated resources will be DESTROYED.\nThis action is irreversible and ALL DATA WILL BE LOST.\nDo you want to continue? [y/n]:\n"})}),(0,l.jsxs)(n.p,{children:["Confirm with ",(0,l.jsx)(n.code,{children:"y"})," to terminate the cluster:"]}),(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"Terminating ...\nYour Constellation cluster was terminated successfully.\n"})}),(0,l.jsxs)(n.p,{children:["This will destroy your cluster and clean up your workspace.\nThe VM image and cluster configuration file (",(0,l.jsx)(n.code,{children:"constellation-conf.yaml"}),") will be kept and may be reused to create new clusters."]})]})]}),"\n",(0,l.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,l.jsxs)(n.p,{children:["Make sure to use the ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/releases/latest",children:"latest release"})," and check out the ",(0,l.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"known issues"}),"."]}),"\n",(0,l.jsx)(n.h3,{id:"vms-have-no-internet-access--cli-remains-in-initializing-cluster-state",children:'VMs have no internet access / CLI remains in "Initializing cluster" state'}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:"iptables"})," rules may prevent your VMs from accessing the internet.\nMake sure your rules aren't dropping forwarded packages."]}),"\n",(0,l.jsx)(n.p,{children:"List your rules:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo iptables -S\n"})}),"\n",(0,l.jsx)(n.p,{children:"The output may look similar to the following:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-shell-session",children:"-P INPUT ACCEPT\n-P FORWARD DROP\n-P OUTPUT ACCEPT\n-N DOCKER\n-N DOCKER-ISOLATION-STAGE-1\n-N DOCKER-ISOLATION-STAGE-2\n-N DOCKER-USER\n"})}),"\n",(0,l.jsxs)(n.p,{children:["If your ",(0,l.jsx)(n.code,{children:"FORWARD"})," chain is set to ",(0,l.jsx)(n.code,{children:"DROP"}),", you need to update your rules:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"sudo iptables -P FORWARD ACCEPT\n"})})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}function h(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/d17f599b.9b1c9ad5.js b/pr-preview/pr-4027/assets/js/d17f599b.9b1c9ad5.js deleted file mode 100644 index ecbda4edd..000000000 --- a/pr-preview/pr-4027/assets/js/d17f599b.9b1c9ad5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4678],{28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>l});var o=i(96540);const s={},t=o.createContext(s);function r(e){const n=o.useContext(t);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(t.Provider,{value:n},e.children)}},95806:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>p,frontMatter:()=>r,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"reference/cli","title":"CLI reference","description":"Use the Constellation CLI to create and manage your clusters.","source":"@site/versioned_docs/version-2.23/reference/cli.md","sourceDirName":"reference","slug":"/reference/cli","permalink":"/constellation/pr-preview/pr-4027/2.23/reference/cli","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/reference/cli.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Reference","permalink":"/constellation/pr-preview/pr-4027/2.23/category/reference"},"next":{"title":"Configuration migrations","permalink":"/constellation/pr-preview/pr-4027/2.23/reference/migration"}}');var s=i(74848),t=i(28453);const r={},l="CLI reference",a={},c=[{value:"constellation config",id:"constellation-config",level:2},{value:"Synopsis",id:"synopsis",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"constellation config generate",id:"constellation-config-generate",level:2},{value:"Synopsis",id:"synopsis-1",level:3},{value:"Options",id:"options-1",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-1",level:3},{value:"constellation config fetch-measurements",id:"constellation-config-fetch-measurements",level:2},{value:"Synopsis",id:"synopsis-2",level:3},{value:"Options",id:"options-2",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-2",level:3},{value:"constellation config instance-types",id:"constellation-config-instance-types",level:2},{value:"Synopsis",id:"synopsis-3",level:3},{value:"Options",id:"options-3",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-3",level:3},{value:"constellation config kubernetes-versions",id:"constellation-config-kubernetes-versions",level:2},{value:"Synopsis",id:"synopsis-4",level:3},{value:"Options",id:"options-4",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-4",level:3},{value:"constellation config migrate",id:"constellation-config-migrate",level:2},{value:"Synopsis",id:"synopsis-5",level:3},{value:"Options",id:"options-5",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-5",level:3},{value:"constellation create",id:"constellation-create",level:2},{value:"Synopsis",id:"synopsis-6",level:3},{value:"Options",id:"options-6",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-6",level:3},{value:"constellation apply",id:"constellation-apply",level:2},{value:"Synopsis",id:"synopsis-7",level:3},{value:"Options",id:"options-7",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-7",level:3},{value:"constellation mini",id:"constellation-mini",level:2},{value:"Synopsis",id:"synopsis-8",level:3},{value:"Options",id:"options-8",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-8",level:3},{value:"constellation mini up",id:"constellation-mini-up",level:2},{value:"Synopsis",id:"synopsis-9",level:3},{value:"Options",id:"options-9",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-9",level:3},{value:"constellation mini down",id:"constellation-mini-down",level:2},{value:"Synopsis",id:"synopsis-10",level:3},{value:"Options",id:"options-10",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-10",level:3},{value:"constellation status",id:"constellation-status",level:2},{value:"Synopsis",id:"synopsis-11",level:3},{value:"Options",id:"options-11",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-11",level:3},{value:"constellation verify",id:"constellation-verify",level:2},{value:"Synopsis",id:"synopsis-12",level:3},{value:"Options",id:"options-12",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-12",level:3},{value:"constellation upgrade",id:"constellation-upgrade",level:2},{value:"Synopsis",id:"synopsis-13",level:3},{value:"Options",id:"options-13",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-13",level:3},{value:"constellation upgrade check",id:"constellation-upgrade-check",level:2},{value:"Synopsis",id:"synopsis-14",level:3},{value:"Options",id:"options-14",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-14",level:3},{value:"constellation upgrade apply",id:"constellation-upgrade-apply",level:2},{value:"Synopsis",id:"synopsis-15",level:3},{value:"Options",id:"options-15",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-15",level:3},{value:"constellation recover",id:"constellation-recover",level:2},{value:"Synopsis",id:"synopsis-16",level:3},{value:"Options",id:"options-16",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-16",level:3},{value:"constellation terminate",id:"constellation-terminate",level:2},{value:"Synopsis",id:"synopsis-17",level:3},{value:"Options",id:"options-17",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-17",level:3},{value:"constellation iam",id:"constellation-iam",level:2},{value:"Synopsis",id:"synopsis-18",level:3},{value:"Options",id:"options-18",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-18",level:3},{value:"constellation iam create",id:"constellation-iam-create",level:2},{value:"Synopsis",id:"synopsis-19",level:3},{value:"Options",id:"options-19",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-19",level:3},{value:"constellation iam create aws",id:"constellation-iam-create-aws",level:2},{value:"Synopsis",id:"synopsis-20",level:3},{value:"Options",id:"options-20",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-20",level:3},{value:"constellation iam create azure",id:"constellation-iam-create-azure",level:2},{value:"Synopsis",id:"synopsis-21",level:3},{value:"Options",id:"options-21",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-21",level:3},{value:"constellation iam create gcp",id:"constellation-iam-create-gcp",level:2},{value:"Synopsis",id:"synopsis-22",level:3},{value:"Options",id:"options-22",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-22",level:3},{value:"constellation iam destroy",id:"constellation-iam-destroy",level:2},{value:"Synopsis",id:"synopsis-23",level:3},{value:"Options",id:"options-23",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-23",level:3},{value:"constellation iam upgrade",id:"constellation-iam-upgrade",level:2},{value:"Synopsis",id:"synopsis-24",level:3},{value:"Options",id:"options-24",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-24",level:3},{value:"constellation iam upgrade apply",id:"constellation-iam-upgrade-apply",level:2},{value:"Synopsis",id:"synopsis-25",level:3},{value:"Options",id:"options-25",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-25",level:3},{value:"constellation version",id:"constellation-version",level:2},{value:"Synopsis",id:"synopsis-26",level:3},{value:"Options",id:"options-26",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-26",level:3},{value:"constellation init",id:"constellation-init",level:2},{value:"Synopsis",id:"synopsis-27",level:3},{value:"Options",id:"options-27",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-27",level:3},{value:"constellation ssh",id:"constellation-ssh",level:2},{value:"Synopsis",id:"synopsis-28",level:3},{value:"Options",id:"options-28",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-28",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"cli-reference",children:"CLI reference"})}),"\n",(0,s.jsx)(n.p,{children:"Use the Constellation CLI to create and manage your clusters."}),"\n",(0,s.jsx)(n.p,{children:"Usage:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation [command]\n"})}),"\n",(0,s.jsx)(n.p,{children:"Commands:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config",children:"config"}),": Work with the Constellation configuration file","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-generate",children:"generate"}),": Generate a default configuration and state file"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-fetch-measurements",children:"fetch-measurements"}),": Fetch measurements for configured cloud provider and image"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-instance-types",children:"instance-types"}),": Print the supported instance types for all cloud providers"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-kubernetes-versions",children:"kubernetes-versions"}),": Print the Kubernetes versions supported by this CLI"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-migrate",children:"migrate"}),": Migrate a configuration file to a new version"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-create",children:"create"}),": Create instances on a cloud platform for your Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-apply",children:"apply"}),": Apply a configuration to a Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-mini",children:"mini"}),": Manage MiniConstellation clusters","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-mini-up",children:"up"}),": Create and initialize a new MiniConstellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-mini-down",children:"down"}),": Destroy a MiniConstellation cluster"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-status",children:"status"}),": Show status of a Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-verify",children:"verify"}),": Verify the confidential properties of a Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-upgrade",children:"upgrade"}),": Find and apply upgrades to your Constellation cluster","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-upgrade-check",children:"check"}),": Check for possible upgrades"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-upgrade-apply",children:"apply"}),": Apply an upgrade to a Constellation cluster"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-recover",children:"recover"}),": Recover a completely stopped Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-terminate",children:"terminate"}),": Terminate a Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam",children:"iam"}),": Work with the IAM configuration on your cloud provider","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-create",children:"create"}),": Create IAM configuration on a cloud platform for your Constellation cluster","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-create-aws",children:"aws"}),": Create IAM configuration on AWS for your Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-create-azure",children:"azure"}),": Create IAM configuration on Microsoft Azure for your Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-create-gcp",children:"gcp"}),": Create IAM configuration on GCP for your Constellation cluster"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-destroy",children:"destroy"}),": Destroy an IAM configuration and delete local Terraform files"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-upgrade",children:"upgrade"}),": Find and apply upgrades to your IAM profile","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-upgrade-apply",children:"apply"}),": Apply an upgrade to an IAM profile"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-version",children:"version"}),": Display version of this CLI"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-init",children:"init"}),": Initialize the Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-ssh",children:"ssh"}),": Generate a certificate for emergency SSH access"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config",children:"constellation config"}),"\n",(0,s.jsx)(n.p,{children:"Work with the Constellation configuration file"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Work with the Constellation configuration file."}),"\n",(0,s.jsx)(n.h3,{id:"options",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for config\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-generate",children:"constellation config generate"}),"\n",(0,s.jsx)(n.p,{children:"Generate a default configuration and state file"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-1",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Generate a default configuration and state file for your selected cloud provider."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config generate {aws|azure|gcp|openstack|qemu|stackit} [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-1",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' -a, --attestation string attestation variant to use {aws-sev-snp|aws-nitro-tpm|azure-sev-snp|azure-tdx|azure-trustedlaunch|gcp-sev-snp|gcp-sev-es|qemu-vtpm}. If not specified, the default for the cloud provider is used\n -h, --help help for generate\n -k, --kubernetes string Kubernetes version to use in format MAJOR.MINOR (default "v1.30")\n -t, --tags strings additional tags for created resources given a list of key=value\n'})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-1",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-fetch-measurements",children:"constellation config fetch-measurements"}),"\n",(0,s.jsx)(n.p,{children:"Fetch measurements for configured cloud provider and image"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-2",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Fetch measurements for configured cloud provider and image."}),"\n",(0,s.jsx)(n.p,{children:"A config needs to be generated first."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config fetch-measurements [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-2",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for fetch-measurements\n -s, --signature-url string alternative URL to fetch measurements' signature from\n -u, --url string alternative URL to fetch measurements from\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-2",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-instance-types",children:"constellation config instance-types"}),"\n",(0,s.jsx)(n.p,{children:"Print the supported instance types for all cloud providers"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-3",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Print the supported instance types for all cloud providers."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config instance-types [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-3",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for instance-types\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-3",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-kubernetes-versions",children:"constellation config kubernetes-versions"}),"\n",(0,s.jsx)(n.p,{children:"Print the Kubernetes versions supported by this CLI"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-4",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Print the Kubernetes versions supported by this CLI."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config kubernetes-versions [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-4",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for kubernetes-versions\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-4",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-migrate",children:"constellation config migrate"}),"\n",(0,s.jsx)(n.p,{children:"Migrate a configuration file to a new version"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-5",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Migrate a configuration file to a new version."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config migrate [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-5",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for migrate\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-5",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-create",children:"constellation create"}),"\n",(0,s.jsx)(n.p,{children:"Create instances on a cloud platform for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-6",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create instances on a cloud platform for your Constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation create [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-6",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for create\n -y, --yes create the cluster without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-6",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-apply",children:"constellation apply"}),"\n",(0,s.jsx)(n.p,{children:"Apply a configuration to a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-7",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Apply a configuration to a Constellation cluster to initialize or upgrade the cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation apply [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-7",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" --conformance enable conformance mode\n -h, --help help for apply\n --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config\n --skip-helm-wait install helm charts without waiting for deployments to be ready\n --skip-phases strings comma-separated list of upgrade phases to skip\n one or multiple of { infrastructure | init | attestationconfig | certsans | helm | image | k8s }\n -y, --yes run command without further confirmation\n WARNING: the command might delete or update existing resources without additional checks. Please read the docs.\n \n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-7",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-mini",children:"constellation mini"}),"\n",(0,s.jsx)(n.p,{children:"Manage MiniConstellation clusters"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-8",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Manage MiniConstellation clusters."}),"\n",(0,s.jsx)(n.h3,{id:"options-8",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for mini\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-8",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-mini-up",children:"constellation mini up"}),"\n",(0,s.jsx)(n.p,{children:"Create and initialize a new MiniConstellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-9",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create and initialize a new MiniConstellation cluster."}),"\n",(0,s.jsx)(n.p,{children:"A mini cluster consists of a single control-plane and worker node, hosted using QEMU/KVM."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation mini up [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-9",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for up\n --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config (default true)\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-9",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-mini-down",children:"constellation mini down"}),"\n",(0,s.jsx)(n.p,{children:"Destroy a MiniConstellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-10",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Destroy a MiniConstellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation mini down [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-10",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for down\n -y, --yes terminate the cluster without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-10",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-status",children:"constellation status"}),"\n",(0,s.jsx)(n.p,{children:"Show status of a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-11",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Show the status of a constellation cluster."}),"\n",(0,s.jsx)(n.p,{children:"Shows microservice, image, and Kubernetes versions installed in the cluster. Also shows status of current version upgrades."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation status [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-11",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for status\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-11",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-verify",children:"constellation verify"}),"\n",(0,s.jsx)(n.p,{children:"Verify the confidential properties of a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-12",children:"Synopsis"}),"\n",(0,s.jsxs)(n.p,{children:["Verify the confidential properties of a Constellation cluster.\nIf arguments aren't specified, values are read from ",(0,s.jsx)(n.code,{children:"constellation-state.yaml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation verify [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-12",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" --cluster-id string expected cluster identifier\n -h, --help help for verify\n -e, --node-endpoint string endpoint of the node to verify, passed as HOST[:PORT]\n -o, --output string print the attestation document in the output format {json|raw}\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-12",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-upgrade",children:"constellation upgrade"}),"\n",(0,s.jsx)(n.p,{children:"Find and apply upgrades to your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-13",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Find and apply upgrades to your Constellation cluster."}),"\n",(0,s.jsx)(n.h3,{id:"options-13",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for upgrade\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-13",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-upgrade-check",children:"constellation upgrade check"}),"\n",(0,s.jsx)(n.p,{children:"Check for possible upgrades"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-14",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Check which upgrades can be applied to your Constellation Cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation upgrade check [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-14",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' -h, --help help for check\n --ref string the reference to use for querying new versions (default "-")\n --stream string the stream to use for querying new versions (default "stable")\n -u, --update-config update the specified config file with the suggested versions\n'})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-14",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-upgrade-apply",children:"constellation upgrade apply"}),"\n",(0,s.jsx)(n.p,{children:"Apply an upgrade to a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-15",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Apply an upgrade to a Constellation cluster by applying the chosen configuration."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation upgrade apply [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-15",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" --conformance enable conformance mode\n -h, --help help for apply\n --skip-helm-wait install helm charts without waiting for deployments to be ready\n --skip-phases strings comma-separated list of upgrade phases to skip\n one or multiple of { infrastructure | helm | image | k8s }\n -y, --yes run upgrades without further confirmation\n WARNING: might delete your resources in case you are using cert-manager in your cluster. Please read the docs.\n WARNING: might unintentionally overwrite measurements in the running cluster.\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-15",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-recover",children:"constellation recover"}),"\n",(0,s.jsx)(n.p,{children:"Recover a completely stopped Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-16",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Recover a Constellation cluster by sending a recovery key to an instance in the boot stage."}),"\n",(0,s.jsx)(n.p,{children:"This is only required if instances restart without other instances available for bootstrapping."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation recover [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-16",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -e, --endpoint string endpoint of the instance, passed as HOST[:PORT]\n -h, --help help for recover\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-16",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-terminate",children:"constellation terminate"}),"\n",(0,s.jsx)(n.p,{children:"Terminate a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-17",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Terminate a Constellation cluster."}),"\n",(0,s.jsx)(n.p,{children:"The cluster can't be started again, and all persistent storage will be lost."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation terminate [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-17",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for terminate\n -y, --yes terminate the cluster without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-17",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam",children:"constellation iam"}),"\n",(0,s.jsx)(n.p,{children:"Work with the IAM configuration on your cloud provider"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-18",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Work with the IAM configuration on your cloud provider."}),"\n",(0,s.jsx)(n.h3,{id:"options-18",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for iam\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-18",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-create",children:"constellation iam create"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on a cloud platform for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-19",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on a cloud platform for your Constellation cluster."}),"\n",(0,s.jsx)(n.h3,{id:"options-19",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for create\n --update-config update the config file with the specific IAM information\n -y, --yes create the IAM configuration without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-19",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-create-aws",children:"constellation iam create aws"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on AWS for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-20",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on AWS for your Constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam create aws [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-20",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for aws\n --prefix string name prefix for all resources (required)\n --zone string AWS availability zone the resources will be created in, e.g., us-east-2a (required)\n See the Constellation docs for a list of currently supported regions.\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-20",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n --update-config update the config file with the specific IAM information\n -C, --workspace string path to the Constellation workspace\n -y, --yes create the IAM configuration without further confirmation\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-create-azure",children:"constellation iam create azure"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on Microsoft Azure for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-21",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on Microsoft Azure for your Constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam create azure [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-21",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for azure\n --region string region the resources will be created in, e.g., westus (required)\n --resourceGroup string name prefix of the two resource groups your cluster / IAM resources will be created in (required)\n --servicePrincipal string name of the service principal that will be created (required)\n --subscriptionID string subscription ID of the Azure account. Required if the 'ARM_SUBSCRIPTION_ID' environment variable is not set\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-21",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n --update-config update the config file with the specific IAM information\n -C, --workspace string path to the Constellation workspace\n -y, --yes create the IAM configuration without further confirmation\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-create-gcp",children:"constellation iam create gcp"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on GCP for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-22",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on GCP for your Constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam create gcp [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-22",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for gcp\n --prefix string Prefix for the service account ID and VM ID that will be created (required)\n Must be letters, digits, or hyphens.\n --projectID string ID of the GCP project the configuration will be created in (required)\n Find it on the welcome screen of your project: https://console.cloud.google.com/welcome\n --zone string GCP zone the cluster will be deployed in (required)\n Find a list of available zones here: https://cloud.google.com/compute/docs/regions-zones#available\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-22",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n --update-config update the config file with the specific IAM information\n -C, --workspace string path to the Constellation workspace\n -y, --yes create the IAM configuration without further confirmation\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-destroy",children:"constellation iam destroy"}),"\n",(0,s.jsx)(n.p,{children:"Destroy an IAM configuration and delete local Terraform files"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-23",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Destroy an IAM configuration and delete local Terraform files."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam destroy [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-23",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for destroy\n -y, --yes destroy the IAM configuration without asking for confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-23",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-upgrade",children:"constellation iam upgrade"}),"\n",(0,s.jsx)(n.p,{children:"Find and apply upgrades to your IAM profile"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-24",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Find and apply upgrades to your IAM profile."}),"\n",(0,s.jsx)(n.h3,{id:"options-24",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for upgrade\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-24",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-upgrade-apply",children:"constellation iam upgrade apply"}),"\n",(0,s.jsx)(n.p,{children:"Apply an upgrade to an IAM profile"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-25",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Apply an upgrade to an IAM profile."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam upgrade apply [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-25",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for apply\n -y, --yes run upgrades without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-25",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-version",children:"constellation version"}),"\n",(0,s.jsx)(n.p,{children:"Display version of this CLI"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-26",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Display version of this CLI."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation version [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-26",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for version\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-26",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-init",children:"constellation init"}),"\n",(0,s.jsx)(n.p,{children:"Initialize the Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-27",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Initialize the Constellation cluster."}),"\n",(0,s.jsx)(n.p,{children:"Start your confidential Kubernetes."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation init [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-27",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" --conformance enable conformance mode\n -h, --help help for init\n --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config\n --skip-helm-wait install helm charts without waiting for deployments to be ready\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-27",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-ssh",children:"constellation ssh"}),"\n",(0,s.jsx)(n.p,{children:"Generate a certificate for emergency SSH access"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-28",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Generate a certificate for emergency SSH access to your SSH-enabled constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation ssh [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-28",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for ssh\n --key string the path to an existing SSH public key\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-28",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/d2556545.5917dc82.js b/pr-preview/pr-4027/assets/js/d2556545.5917dc82.js deleted file mode 100644 index 57d4918ca..000000000 --- a/pr-preview/pr-4027/assets/js/d2556545.5917dc82.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3405],{28453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>c});var o=s(96540);const l={},r=o.createContext(l);function t(e){const n=o.useContext(r);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:t(e.components),o.createElement(r.Provider,{value:n},e.children)}},59043:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>u,frontMatter:()=>t,metadata:()=>o,toc:()=>a});const o=JSON.parse('{"id":"workflows/scale","title":"Scale your cluster","description":"Constellation provides all features of a Kubernetes cluster including scaling and autoscaling.","source":"@site/versioned_docs/version-2.23/workflows/scale.md","sourceDirName":"workflows","slug":"/workflows/scale","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/scale","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/workflows/scale.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Create your cluster","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/create"},"next":{"title":"Upgrade your cluster","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/upgrade"}}');var l=s(74848),r=s(28453);const t={},c="Scale your cluster",i={},a=[{value:"Worker node scaling",id:"worker-node-scaling",level:2},{value:"Autoscaling",id:"autoscaling",level:3},{value:"Manual scaling",id:"manual-scaling",level:3},{value:"Control-plane node scaling",id:"control-plane-node-scaling",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,r.R)(),...e.components},{TabItem:s,Tabs:o}=n;return s||h("TabItem",!0),o||h("Tabs",!0),(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"scale-your-cluster",children:"Scale your cluster"})}),"\n",(0,l.jsx)(n.p,{children:"Constellation provides all features of a Kubernetes cluster including scaling and autoscaling."}),"\n",(0,l.jsx)(n.h2,{id:"worker-node-scaling",children:"Worker node scaling"}),"\n",(0,l.jsx)(n.h3,{id:"autoscaling",children:"Autoscaling"}),"\n",(0,l.jsx)(n.p,{children:"Constellation comes with autoscaling disabled by default. To enable autoscaling, find the scaling group of\nworker nodes:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:'kubectl get scalinggroups -o json | yq \'.items | .[] | select(.spec.role == "Worker") | [{"name": .metadata.name, "nodeGoupName": .spec.nodeGroupName}]\'\n'})}),"\n",(0,l.jsxs)(n.p,{children:["This will output a list of scaling groups with the corresponding cloud provider name (",(0,l.jsx)(n.code,{children:"name"}),") and the cloud provider agnostic name of the node group (",(0,l.jsx)(n.code,{children:"nodeGroupName"}),")."]}),"\n",(0,l.jsxs)(n.p,{children:["Then, patch the ",(0,l.jsx)(n.code,{children:"autoscaling"})," field of the scaling group resource with the desired ",(0,l.jsx)(n.code,{children:"name"})," to ",(0,l.jsx)(n.code,{children:"true"}),":"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# Replace <name> with the name of the scaling group you want to enable autoscaling for\nworker_group=<name>\nkubectl patch scalinggroups $worker_group --patch '{\"spec\":{\"autoscaling\": true}}' --type='merge'\nkubectl get scalinggroup $worker_group -o jsonpath='{.spec}' | yq -P\n"})}),"\n",(0,l.jsxs)(n.p,{children:["The cluster autoscaler now automatically provisions additional worker nodes so that all pods have a place to run.\nYou can configure the minimum and maximum number of worker nodes in the scaling group by patching the ",(0,l.jsx)(n.code,{children:"min"})," or\n",(0,l.jsx)(n.code,{children:"max"})," fields of the scaling group resource:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl patch scalinggroups $worker_group --patch '{\"spec\":{\"max\": 5}}' --type='merge'\nkubectl get scalinggroup $worker_group -o jsonpath='{.spec}' | yq -P\n"})}),"\n",(0,l.jsx)(n.p,{children:"The cluster autoscaler will now never provision more than 5 worker nodes."}),"\n",(0,l.jsx)(n.p,{children:"If you want to see the autoscaling in action, try to add a deployment with a lot of replicas, like the\nfollowing Nginx deployment. The number of replicas needed to trigger the autoscaling depends on the size of\nand count of your worker nodes. Wait for the rollout of the deployment to finish and compare the number of\nworker nodes before and after the deployment:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl create deployment nginx --image=nginx --replicas 150\nkubectl -n kube-system get nodes\nkubectl rollout status deployment nginx\nkubectl -n kube-system get nodes\n"})}),"\n",(0,l.jsx)(n.h3,{id:"manual-scaling",children:"Manual scaling"}),"\n",(0,l.jsx)(n.p,{children:"Alternatively, you can manually scale your cluster up or down:"}),"\n",(0,l.jsxs)(o,{groupId:"csp",children:[(0,l.jsx)(s,{value:"aws",label:"AWS",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Go to Auto Scaling Groups and select the worker ASG to scale up."}),"\n",(0,l.jsxs)(n.li,{children:["Click ",(0,l.jsx)(n.strong,{children:"Edit"})]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new (increased) ",(0,l.jsx)(n.strong,{children:"Desired capacity"})," and ",(0,l.jsx)(n.strong,{children:"Update"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"azure",label:"Azure",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Find your Constellation resource group."}),"\n",(0,l.jsxs)(n.li,{children:["Select the ",(0,l.jsx)(n.code,{children:"scale-set-workers"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:["Go to ",(0,l.jsx)(n.strong,{children:"settings"})," and ",(0,l.jsx)(n.strong,{children:"scaling"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new ",(0,l.jsx)(n.strong,{children:"instance count"})," and ",(0,l.jsx)(n.strong,{children:"save"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"gcp",label:"GCP",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["In Compute Engine go to ",(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/compute/instanceGroups/",children:"Instance Groups"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Edit"})," the ",(0,l.jsx)(n.strong,{children:"worker"})," instance group."]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new ",(0,l.jsx)(n.strong,{children:"number of instances"})," and ",(0,l.jsx)(n.strong,{children:"save"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,l.jsx)(n.p,{children:"Dynamic cluster scaling isn't yet supported for STACKIT.\nSupport will be introduced in one of the upcoming releases."})})]}),"\n",(0,l.jsx)(n.h2,{id:"control-plane-node-scaling",children:"Control-plane node scaling"}),"\n",(0,l.jsxs)(n.p,{children:["Control-plane nodes can ",(0,l.jsx)(n.strong,{children:"only be scaled manually and only scaled up"}),"!"]}),"\n",(0,l.jsx)(n.p,{children:"To increase the number of control-plane nodes, follow these steps:"}),"\n",(0,l.jsxs)(o,{groupId:"csp",children:[(0,l.jsx)(s,{value:"aws",label:"AWS",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Go to Auto Scaling Groups and select the control-plane ASG to scale up."}),"\n",(0,l.jsxs)(n.li,{children:["Click ",(0,l.jsx)(n.strong,{children:"Edit"})]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new (increased) ",(0,l.jsx)(n.strong,{children:"Desired capacity"})," and ",(0,l.jsx)(n.strong,{children:"Update"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"azure",label:"Azure",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Find your Constellation resource group."}),"\n",(0,l.jsxs)(n.li,{children:["Select the ",(0,l.jsx)(n.code,{children:"scale-set-controlplanes"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:["Go to ",(0,l.jsx)(n.strong,{children:"settings"})," and ",(0,l.jsx)(n.strong,{children:"scaling"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new (increased) ",(0,l.jsx)(n.strong,{children:"instance count"})," and ",(0,l.jsx)(n.strong,{children:"save"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"gcp",label:"GCP",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["In Compute Engine go to ",(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/compute/instanceGroups/",children:"Instance Groups"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Edit"})," the ",(0,l.jsx)(n.strong,{children:"control-plane"})," instance group."]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new (increased) ",(0,l.jsx)(n.strong,{children:"number of instances"})," and ",(0,l.jsx)(n.strong,{children:"save"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,l.jsx)(n.p,{children:"Dynamic cluster scaling isn't yet supported for STACKIT.\nSupport will be introduced in one of the upcoming releases."})})]}),"\n",(0,l.jsxs)(n.p,{children:["If you scale down the number of control-planes nodes, the removed nodes won't be able to exit the ",(0,l.jsx)(n.code,{children:"etcd"})," cluster correctly. This will endanger the quorum that's required to run a stable Kubernetes control plane."]})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}function h(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/d4cfdd56.00a30674.js b/pr-preview/pr-4027/assets/js/d4cfdd56.00a30674.js deleted file mode 100644 index 8116040a0..000000000 --- a/pr-preview/pr-4027/assets/js/d4cfdd56.00a30674.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3101],{28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var r=n(96540);const i={},o=r.createContext(i);function s(e){const t=r.useContext(o);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),r.createElement(o.Provider,{value:t},e.children)}},45069:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>d});const r=JSON.parse('{"id":"architecture/networking","title":"Network encryption","description":"Constellation encrypts all pod communication using the container network interface (CNI).","source":"@site/versioned_docs/version-2.23/architecture/networking.md","sourceDirName":"architecture","slug":"/architecture/networking","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/networking","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/architecture/networking.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Encrypted persistent storage","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage"},"next":{"title":"Observability","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/observability"}}');var i=n(74848),o=n(28453);const s={},c="Network encryption",a={},d=[];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"network-encryption",children:"Network encryption"})}),"\n",(0,i.jsxs)(t.p,{children:["Constellation encrypts all pod communication using the ",(0,i.jsx)(t.a,{href:"https://github.com/containernetworking/cni",children:"container network interface (CNI)"}),".\nTo that end, Constellation deploys, configures, and operates the ",(0,i.jsx)(t.a,{href:"https://cilium.io/",children:"Cilium"})," CNI plugin.\nCilium provides ",(0,i.jsx)(t.a,{href:"https://docs.cilium.io/en/stable/security/network/encryption",children:"transparent encryption"})," for all cluster traffic using either IPSec or ",(0,i.jsx)(t.a,{href:"https://www.wireguard.com/",children:"WireGuard"}),".\nCurrently, Constellation only supports WireGuard as the encryption engine.\nYou can read more about the cryptographic soundness of WireGuard ",(0,i.jsx)(t.a,{href:"https://www.wireguard.com/papers/wireguard.pdf",children:"in their white paper"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["Cilium is actively working on implementing a feature called ",(0,i.jsx)(t.a,{href:"https://github.com/cilium/cilium/pull/19401",children:(0,i.jsx)(t.code,{children:"host-to-host"})})," encryption mode for WireGuard.\nWith ",(0,i.jsx)(t.code,{children:"host-to-host"}),", all traffic between nodes will be tunneled via WireGuard (host-to-host, host-to-pod, pod-to-host, pod-to-pod).\nUntil the ",(0,i.jsx)(t.code,{children:"host-to-host"})," feature is released, Constellation enables ",(0,i.jsx)(t.code,{children:"pod-to-pod"})," encryption.\nThis mode encrypts all traffic between Kubernetes pods using WireGuard tunnels."]}),"\n",(0,i.jsxs)(t.p,{children:["When using Cilium in the default setup but with encryption enabled, there is a ",(0,i.jsx)(t.a,{href:"https://docs.cilium.io/en/v1.12/gettingstarted/encryption/#egress-traffic-to-not-yet-discovered-remote-endpoints-may-be-unencrypted",children:"known issue"}),"\nthat can cause pod-to-pod traffic to be unencrypted.\nTo mitigate this issue, Constellation adds a ",(0,i.jsx)(t.em,{children:"strict"})," mode to Cilium's ",(0,i.jsx)(t.code,{children:"pod-to-pod"})," encryption.\nThis mode changes the default behavior of traffic that's destined for an unknown endpoint to not be send out in plaintext, but instead being dropped.\nThe strict mode distinguishes between traffic that's send to a pod from traffic that's destined for a cluster-external endpoint by considering the pod's CIDR range."]}),"\n",(0,i.jsxs)(t.p,{children:["Traffic originating from hosts isn't encrypted yet.\nThis mainly includes health checks from Kubernetes API server.\nAlso, traffic proxied over the API server via e.g. ",(0,i.jsx)(t.code,{children:"kubectl port-forward"})," isn't encrypted."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/d84515e5.c5d1d300.js b/pr-preview/pr-4027/assets/js/d84515e5.c5d1d300.js deleted file mode 100644 index 7abfe29db..000000000 --- a/pr-preview/pr-4027/assets/js/d84515e5.c5d1d300.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7730],{6032:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>m,frontMatter:()=>i,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"overview/performance/compute","title":"Impact of runtime encryption on compute performance","description":"All nodes in a Constellation cluster are executed inside Confidential VMs (CVMs). Consequently, the performance of Constellation is inherently linked to the performance of these CVMs.","source":"@site/versioned_docs/version-2.24/overview/performance/compute.md","sourceDirName":"overview/performance","slug":"/overview/performance/compute","permalink":"/constellation/pr-preview/pr-4027/overview/performance/compute","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/overview/performance/compute.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Performance analysis of Constellation","permalink":"/constellation/pr-preview/pr-4027/overview/performance/"},"next":{"title":"I/O benchmarks","permalink":"/constellation/pr-preview/pr-4027/overview/performance/io"}}');var t=o(74848),a=o(28453);const i={},s="Impact of runtime encryption on compute performance",c={},l=[{value:"AMD and Azure benchmarking",id:"amd-and-azure-benchmarking",level:2},{value:"AMD and Google benchmarking",id:"amd-and-google-benchmarking",level:2}];function d(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"impact-of-runtime-encryption-on-compute-performance",children:"Impact of runtime encryption on compute performance"})}),"\n",(0,t.jsx)(n.p,{children:"All nodes in a Constellation cluster are executed inside Confidential VMs (CVMs). Consequently, the performance of Constellation is inherently linked to the performance of these CVMs."}),"\n",(0,t.jsx)(n.h2,{id:"amd-and-azure-benchmarking",children:"AMD and Azure benchmarking"}),"\n",(0,t.jsxs)(n.p,{children:["AMD and Azure have collectively released a ",(0,t.jsx)(n.a,{href:"https://community.amd.com/t5/business/microsoft-azure-confidential-computing-powered-by-3rd-gen-epyc/ba-p/497796",children:"performance benchmark"})," for CVMs that utilize 3rd Gen AMD EPYC processors (Milan) with SEV-SNP. This benchmark, which included a variety of mostly compute-intensive tests such as SPEC CPU 2017 and CoreMark, demonstrated that CVMs experience only minor performance degradation (ranging from 2% to 8%) when compared to standard VMs. Such results are indicative of the performance that can be expected from compute-intensive workloads running with Constellation on Azure."]}),"\n",(0,t.jsx)(n.h2,{id:"amd-and-google-benchmarking",children:"AMD and Google benchmarking"}),"\n",(0,t.jsxs)(n.p,{children:["Similarly, AMD and Google have jointly released a ",(0,t.jsx)(n.a,{href:"https://www.amd.com/system/files/documents/3rd-gen-epyc-gcp-c2d-conf-compute-perf-brief.pdf",children:"performance benchmark"})," for CVMs employing 3rd Gen AMD EPYC processors (Milan) with SEV-SNP. With high-performance computing workloads such as WRF, NAMD, Ansys CFS, and Ansys LS_DYNA, they observed analogous findings, with only minor performance degradation (between 2% and 4%) compared to standard VMs. These outcomes are reflective of the performance that can be expected for compute-intensive workloads running with Constellation on GCP."]})]})}function m(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>i,x:()=>s});var r=o(96540);const t={},a=r.createContext(t);function i(e){const n=r.useContext(a);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/d89a6bd5.49be83be.js b/pr-preview/pr-4027/assets/js/d89a6bd5.49be83be.js deleted file mode 100644 index b3ae3ccc5..000000000 --- a/pr-preview/pr-4027/assets/js/d89a6bd5.49be83be.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6516],{28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>o});var i=s(96540);const n={},r=i.createContext(n);function a(e){const t=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),i.createElement(r.Provider,{value:t},e.children)}},67743:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"architecture/observability","title":"Observability","description":"In Kubernetes, observability is the ability to gain insight into the behavior and performance of applications.","source":"@site/versioned_docs/version-2.24/architecture/observability.md","sourceDirName":"architecture","slug":"/architecture/observability","permalink":"/constellation/pr-preview/pr-4027/architecture/observability","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/architecture/observability.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Networking","permalink":"/constellation/pr-preview/pr-4027/architecture/networking"},"next":{"title":"Reference","permalink":"/constellation/pr-preview/pr-4027/category/reference"}}');var n=s(74848),r=s(28453);const a={},o="Observability",l={},c=[{value:"Cloud resource monitoring",id:"cloud-resource-monitoring",level:2},{value:"Metrics",id:"metrics",level:2},{value:"Logs",id:"logs",level:2},{value:"System logs",id:"system-logs",level:3},{value:"Kubernetes logs",id:"kubernetes-logs",level:3},{value:"Traces",id:"traces",level:2},{value:"Integrations",id:"integrations",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"observability",children:"Observability"})}),"\n",(0,n.jsx)(t.p,{children:'In Kubernetes, observability is the ability to gain insight into the behavior and performance of applications.\nIt helps identify and resolve issues more effectively, ensuring stability and performance of Kubernetes workloads, reducing downtime and outages, and improving efficiency.\nThe "three pillars of observability" are logs, metrics, and traces.'}),"\n",(0,n.jsx)(t.p,{children:"In the context of Confidential Computing, observability is a delicate subject and needs to be applied such that it doesn't leak any sensitive information.\nThe following gives an overview of where and how you can apply standard observability tools in Constellation."}),"\n",(0,n.jsx)(t.h2,{id:"cloud-resource-monitoring",children:"Cloud resource monitoring"}),"\n",(0,n.jsx)(t.p,{children:"While inaccessible, Constellation's nodes are still visible as black box VMs to the hypervisor.\nResource consumption, such as memory and CPU utilization, can be monitored from the outside and observed via the cloud platforms directly.\nSimilarly, other resources, such as storage and network and their respective metrics, are visible via the cloud platform."}),"\n",(0,n.jsx)(t.h2,{id:"metrics",children:"Metrics"}),"\n",(0,n.jsx)(t.p,{children:"Metrics are numeric representations of data measured over intervals of time. They're essential for understanding system health and gaining insights using telemetry signals."}),"\n",(0,n.jsxs)(t.p,{children:["By default, Constellation exposes the ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/system-metrics/",children:"metrics for Kubernetes system components"})," inside the cluster.\nSimilarly, the ",(0,n.jsx)(t.a,{href:"https://etcd.io/docs/v3.5/metrics/",children:"etcd metrics"})," endpoints are exposed inside the cluster.\nThese ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/system-metrics/#disabling-metrics",children:"metrics endpoints can be disabled"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["You can collect these cluster-internal metrics via tools such as ",(0,n.jsx)(t.a,{href:"https://prometheus.io/",children:"Prometheus"})," or the ",(0,n.jsx)(t.a,{href:"https://www.elastic.co/de/elastic-stack/",children:"Elastic Stack"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["Constellation's CNI Cilium also supports ",(0,n.jsx)(t.a,{href:"https://docs.cilium.io/en/latest/observability/metrics/",children:"metrics via Prometheus endpoints"}),".\nHowever, in Constellation, they're disabled by default and must be enabled first."]}),"\n",(0,n.jsx)(t.h2,{id:"logs",children:"Logs"}),"\n",(0,n.jsx)(t.p,{children:"Logs represent discrete events that usually describe what's happening with your service.\nThe payload is an actual message emitted from your system along with a metadata section containing a timestamp, labels, and tracking identifiers."}),"\n",(0,n.jsx)(t.h3,{id:"system-logs",children:"System logs"}),"\n",(0,n.jsxs)(t.p,{children:["Detailed system-level logs are accessible via ",(0,n.jsx)(t.code,{children:"/var/log"})," and ",(0,n.jsx)(t.a,{href:"https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html",children:"journald"})," on the nodes directly.\nThey can be collected from there, for example, via ",(0,n.jsx)(t.a,{href:"https://www.elastic.co/guide/en/beats/filebeat/current/logstash-output.html",children:"Filebeat and Logstash"}),", which are tools of the ",(0,n.jsx)(t.a,{href:"https://www.elastic.co/de/elastic-stack/",children:"Elastic Stack"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["In case of an error during the initialization, the CLI automatically collects the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices#bootstrapper",children:"Bootstrapper"})," logs and returns these as a file for ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/workflows/troubleshooting",children:"troubleshooting"}),". Here is an example of such an event:"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell-session",children:'Cluster initialization failed. This error is not recoverable.\nTerminate your cluster and try again.\nFetched bootstrapper logs are stored in "constellation-cluster.log"\n'})}),"\n",(0,n.jsx)(t.h3,{id:"kubernetes-logs",children:"Kubernetes logs"}),"\n",(0,n.jsxs)(t.p,{children:["Constellation supports the ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/logging/",children:"Kubernetes logging architecture"}),".\nBy default, logs are written to the nodes' encrypted state disks.\nThese include the Pod and container logs and the ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/logging/#system-component-logs",children:"system component logs"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/architecture/microservices",children:"Constellation services"})," run as Pods inside the ",(0,n.jsx)(t.code,{children:"kube-system"})," namespace and use the standard container logging mechanism.\nThe same applies for the ",(0,n.jsx)(t.a,{href:"https://docs.cilium.io/en/latest/operations/troubleshooting/#logs",children:"Cilium Pods"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["You can collect logs from within the cluster via tools such as ",(0,n.jsx)(t.a,{href:"https://github.com/fluent/fluentd",children:"Fluentd"}),", ",(0,n.jsx)(t.a,{href:"https://github.com/grafana/loki",children:"Loki"}),", or the ",(0,n.jsx)(t.a,{href:"https://www.elastic.co/de/elastic-stack/",children:"Elastic Stack"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"traces",children:"Traces"}),"\n",(0,n.jsx)(t.p,{children:"Modern systems are implemented as interconnected complex and distributed microservices. Understanding request flows and system communications is challenging, mainly because all systems in a chain need to be modified to propagate tracing information. Distributed tracing is a new approach to increasing observability and understanding performance bottlenecks. A trace represents consecutive events that reflect an end-to-end request path in a distributed system."}),"\n",(0,n.jsxs)(t.p,{children:["Constellation supports ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/system-traces/",children:"traces for Kubernetes system components"}),".\nBy default, they're disabled and need to be enabled first."]}),"\n",(0,n.jsxs)(t.p,{children:["Similarly, Cilium can be enabled to ",(0,n.jsx)(t.a,{href:"https://cilium.io/use-cases/metrics-export/",children:"export traces"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["You can collect these traces via tools such as ",(0,n.jsx)(t.a,{href:"https://www.jaegertracing.io/",children:"Jaeger"})," or ",(0,n.jsx)(t.a,{href:"https://zipkin.io/",children:"Zipkin"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"integrations",children:"Integrations"}),"\n",(0,n.jsx)(t.p,{children:"Platforms and SaaS solutions such as Datadog, logz.io, Dynatrace, or New Relic facilitate the observability challenge for Kubernetes and provide all-in-one SaaS solutions.\nThey install agents into the cluster that collect metrics, logs, and tracing information and upload them into the data lake of the platform.\nTechnically, the agent-based approach is compatible with Constellation, and attaching these platforms is straightforward.\nHowever, you need to evaluate if the exported data might violate Constellation's compliance and privacy guarantees by uploading them to a third-party platform."})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/da6dfe9f.06480c68.js b/pr-preview/pr-4027/assets/js/da6dfe9f.06480c68.js deleted file mode 100644 index b502c1bed..000000000 --- a/pr-preview/pr-4027/assets/js/da6dfe9f.06480c68.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4222],{28453:(e,s,r)=>{r.d(s,{R:()=>o,x:()=>a});var n=r(96540);const t={},i=n.createContext(t);function o(e){const s=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),n.createElement(i.Provider,{value:s},e.children)}},36444:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>c,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"reference/slsa","title":"Supply chain levels for software artifacts (SLSA) adoption","description":"Supply chain Levels for Software Artifacts, or SLSA (salsa) is a framework for improving and grading a project\'s build system and engineering processes. SLSA focuses on security improvements for source code storage as well as build system definition, execution, and observation. SLSA is structured in four levels. This page describes the adoption of SLSA for Constellation.","source":"@site/versioned_docs/version-2.24/reference/slsa.md","sourceDirName":"reference","slug":"/reference/slsa","permalink":"/constellation/pr-preview/pr-4027/reference/slsa","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/reference/slsa.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Terraform usage","permalink":"/constellation/pr-preview/pr-4027/reference/terraform"}}');var t=r(74848),i=r(28453);const o={},a="Supply chain levels for software artifacts (SLSA) adoption",l={},d=[{value:"Level 1 - Adopted",id:"level-1---adopted",level:2},{value:"Level 2 - Adopted",id:"level-2---adopted",level:2},{value:"Level 3 - Adopted",id:"level-3---adopted",level:2},{value:"Level 4 - In Progress",id:"level-4---in-progress",level:2}];function h(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"supply-chain-levels-for-software-artifacts-slsa-adoption",children:"Supply chain levels for software artifacts (SLSA) adoption"})}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"https://slsa.dev/",children:"Supply chain Levels for Software Artifacts, or SLSA (salsa)"})," is a framework for improving and grading a project's build system and engineering processes. SLSA focuses on security improvements for source code storage as well as build system definition, execution, and observation. SLSA is structured in ",(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/levels",children:"four levels"}),". This page describes the adoption of SLSA for Constellation."]}),"\n",(0,t.jsx)(s.admonition,{type:"info",children:(0,t.jsx)(s.p,{children:"SLSA is still in alpha status. The presented levels and their requirements might change in the future. We will adopt any changes into our engineering processes, as they get defined."})}),"\n",(0,t.jsx)(s.h2,{id:"level-1---adopted",children:"Level 1 - Adopted"}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#scripted-build",children:"Build - Scripted"})})}),"\n",(0,t.jsxs)(s.p,{children:["All build steps are automated via ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/tree/main/bazel/ci",children:"Bazel"})," and ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/tree/main/.github",children:"GitHub Actions"}),"."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#available",children:"Provenance - Available"})})}),"\n",(0,t.jsxs)(s.p,{children:["Provenance for the CLI is generated using the ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator",children:"slsa-github-generator"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"level-2---adopted",children:"Level 2 - Adopted"}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#version-controlled",children:"Source - Version Controlled"})})}),"\n",(0,t.jsx)(s.p,{children:"Constellation is hosted on GitHub using git."}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#build-service",children:"Build - Build Service"})})}),"\n",(0,t.jsxs)(s.p,{children:["All builds are carried out by ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/tree/main/.github",children:"GitHub Actions"}),"."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#authenticated",children:"Provenance - Authenticated"})})}),"\n",(0,t.jsxs)(s.p,{children:["Provenance for the CLI is signed using the ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator",children:"slsa-github-generator"}),". Learn ",(0,t.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/workflows/verify-cli",children:"how to verify the CLI"})," using the signed provenance, before using it for the first time."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#service-generated",children:"Provenance - Service Generated"})})}),"\n",(0,t.jsxs)(s.p,{children:["Provenance for the CLI is generated using the ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator",children:"slsa-github-generator"})," in GitHub Actions."]}),"\n",(0,t.jsx)(s.h2,{id:"level-3---adopted",children:"Level 3 - Adopted"}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#verified-history",children:"Source - Verified History"})})}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys",children:"Edgeless Systems"})," GitHub organization ",(0,t.jsx)(s.a,{href:"https://docs.github.com/en/organizations/keeping-your-organization-secure/managing-two-factor-authentication-for-your-organization/requiring-two-factor-authentication-in-your-organization",children:"requires two-factor authentication"})," for all members."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#retained-indefinitely",children:"Source - Retained Indefinitely"})})}),"\n",(0,t.jsxs)(s.p,{children:["Since we use GitHub to host the repository, an external person can't modify or delete the history. Before a pull request can be merged, an explicit approval from an ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys",children:"Edgeless Systems"})," team member is required."]}),"\n",(0,t.jsxs)(s.p,{children:["The same holds true for changes proposed by team members. Each change to ",(0,t.jsx)(s.code,{children:"main"})," needs to be proposed via a pull request and requires at least one approval."]}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys",children:"Edgeless Systems"})," GitHub organization admins control these settings and are able to make changes to the repository's history should legal requirements necessitate it. These changes require two-party approval following the obliterate policy."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#build-as-code",children:"Build - Build as Code"})})}),"\n",(0,t.jsxs)(s.p,{children:["All build files for Constellation are stored in ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/tree/main/.github",children:"the same repository"}),"."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#ephemeral-environment",children:"Build - Ephemeral Environment"})})}),"\n",(0,t.jsxs)(s.p,{children:["All GitHub Action workflows are executed on ",(0,t.jsx)(s.a,{href:"https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners",children:"GitHub-hosted runners"}),". These runners are only available during workflow."]}),"\n",(0,t.jsxs)(s.p,{children:["We currently don't use ",(0,t.jsx)(s.a,{href:"https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners",children:"self-hosted runners"}),"."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#isolated",children:"Build - Isolated"})})}),"\n",(0,t.jsx)(s.p,{children:"As outlined in the previous section, we use GitHub-hosted runners, which provide a new, isolated and ephemeral environment for each build."}),"\n",(0,t.jsxs)(s.p,{children:["Additionally, the ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator#generation-of-provenance",children:"SLSA GitHub generator"})," itself is run in an isolated workflow with the artifact hash as defined inputs."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:(0,t.jsx)(s.a,{href:"https://slsa.dev/spec/v0.1/requirements#non-falsifiable",children:"Provenance - Non-falsifiable"})})}),"\n",(0,t.jsxs)(s.p,{children:["As outlined by ",(0,t.jsx)(s.a,{href:"https://github.com/slsa-framework/slsa-github-generator",children:"SLSA GitHub generator"})," it already fulfills the non-falsifiable requirements for SLSA Level 3. The generated provenance is signed using ",(0,t.jsx)(s.a,{href:"https://sigstore.dev/",children:"sigstore"})," with an OIDC based proof of identity."]}),"\n",(0,t.jsx)(s.h2,{id:"level-4---in-progress",children:"Level 4 - In Progress"}),"\n",(0,t.jsx)(s.p,{children:"We strive to adopt certain aspect of SLSA Level 4 that support our engineering process. At the same time, SLSA is still in alpha status and the biggest changes to SLSA are expected to be around Level 4."})]})}function c(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/dae6bd30.317266e3.js b/pr-preview/pr-4027/assets/js/dae6bd30.317266e3.js deleted file mode 100644 index fb87127e9..000000000 --- a/pr-preview/pr-4027/assets/js/dae6bd30.317266e3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[680],{584:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"reference/terraform","title":"Terraform usage","description":"Terraform is an Infrastructure as Code (IaC) framework to manage cloud resources. This page explains how Constellation uses it internally and how advanced users may manually use it to have more control over the resource creation.","source":"@site/versioned_docs/version-2.22/reference/terraform.md","sourceDirName":"reference","slug":"/reference/terraform","permalink":"/constellation/pr-preview/pr-4027/2.22/reference/terraform","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/reference/terraform.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Configuration migrations","permalink":"/constellation/pr-preview/pr-4027/2.22/reference/migration"},"next":{"title":"SLSA adoption","permalink":"/constellation/pr-preview/pr-4027/2.22/reference/slsa"}}');var o=t(74848),s=t(28453);const i={},a="Terraform usage",l={},c=[{value:"Terraform state files",id:"terraform-state-files",level:2},{value:"Interacting with Terraform manually",id:"interacting-with-terraform-manually",level:2},{value:"Terraform debugging",id:"terraform-debugging",level:2}];function d(e){const r={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(r.header,{children:(0,o.jsx)(r.h1,{id:"terraform-usage",children:"Terraform usage"})}),"\n",(0,o.jsxs)(r.p,{children:[(0,o.jsx)(r.a,{href:"https://www.terraform.io/",children:"Terraform"})," is an Infrastructure as Code (IaC) framework to manage cloud resources. This page explains how Constellation uses it internally and how advanced users may manually use it to have more control over the resource creation."]}),"\n",(0,o.jsx)(r.admonition,{type:"info",children:(0,o.jsxs)(r.p,{children:["Information on this page is intended for users who are familiar with Terraform.\nIt's not required for common usage of Constellation.\nSee the ",(0,o.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/docs",children:"Terraform documentation"})," if you want to learn more about it."]})}),"\n",(0,o.jsx)(r.h2,{id:"terraform-state-files",children:"Terraform state files"}),"\n",(0,o.jsx)(r.p,{children:"Constellation keeps Terraform state files in subdirectories of the workspace together with the corresponding Terraform configuration files and metadata.\nThe subdirectories are created on the first Constellation CLI action that uses Terraform internally."}),"\n",(0,o.jsx)(r.p,{children:"Currently, these subdirectories are:"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.code,{children:"constellation-terraform"})," - Terraform state files for the resources of the Constellation cluster"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.code,{children:"constellation-iam-terraform"})," - Terraform state files for IAM configuration"]}),"\n"]}),"\n",(0,o.jsxs)(r.p,{children:["As with all commands, commands that work with these files (e.g., ",(0,o.jsx)(r.code,{children:"apply"}),", ",(0,o.jsx)(r.code,{children:"terminate"}),", ",(0,o.jsx)(r.code,{children:"iam"}),") have to be executed from the root of the cluster's ",(0,o.jsx)(r.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration#workspaces",children:"workspace directory"}),". You usually don't need and shouldn't manipulate or delete the subdirectories manually."]}),"\n",(0,o.jsx)(r.h2,{id:"interacting-with-terraform-manually",children:"Interacting with Terraform manually"}),"\n",(0,o.jsxs)(r.p,{children:["Manual interaction with Terraform state created by Constellation (i.e., via the Terraform CLI) should only be performed by experienced users. It may lead to unrecoverable loss of cloud resources. For the majority of users and use cases, the interaction done by the ",(0,o.jsx)(r.a,{href:"/constellation/pr-preview/pr-4027/2.22/reference/cli",children:"Constellation CLI"})," is sufficient."]}),"\n",(0,o.jsx)(r.h2,{id:"terraform-debugging",children:"Terraform debugging"}),"\n",(0,o.jsxs)(r.p,{children:["To debug Terraform issues, the Constellation CLI offers the ",(0,o.jsx)(r.code,{children:"tf-log"})," flag. You can set it to any of ",(0,o.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform's log levels"}),":"]}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.code,{children:"JSON"})," (JSON-formatted logs at ",(0,o.jsx)(r.code,{children:"TRACE"})," level)"]}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"TRACE"})}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"DEBUG"})}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"INFO"})}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"WARN"})}),"\n",(0,o.jsx)(r.li,{children:(0,o.jsx)(r.code,{children:"ERROR"})}),"\n"]}),"\n",(0,o.jsxs)(r.p,{children:["The log output is written to the ",(0,o.jsx)(r.code,{children:"terraform.log"})," file in the workspace directory. The output is appended to the file on each run."]})]})}function h(e={}){const{wrapper:r}={...(0,s.R)(),...e.components};return r?(0,o.jsx)(r,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,r,t)=>{t.d(r,{R:()=>i,x:()=>a});var n=t(96540);const o={},s=n.createContext(o);function i(e){const r=n.useContext(s);return n.useMemo(function(){return"function"==typeof e?e(r):{...r,...e}},[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(s.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/db1b10df.841d69f7.js b/pr-preview/pr-4027/assets/js/db1b10df.841d69f7.js deleted file mode 100644 index 26704c36a..000000000 --- a/pr-preview/pr-4027/assets/js/db1b10df.841d69f7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3501],{4628:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"workflows/upgrade","title":"Upgrade your cluster","description":"Constellation provides an easy way to upgrade all components of your cluster, without disrupting its availability.","source":"@site/versioned_docs/version-2.22/workflows/upgrade.md","sourceDirName":"workflows","slug":"/workflows/upgrade","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/workflows/upgrade.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Scale your cluster","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/scale"},"next":{"title":"Expose a service","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/lb"}}');var t=r(74848),o=r(28453);const i={},a="Upgrade your cluster",l={},c=[{value:"Update the CLI",id:"update-the-cli",level:2},{value:"Migrate the configuration",id:"migrate-the-configuration",level:2},{value:"Check for upgrades",id:"check-for-upgrades",level:2},{value:"Apply the upgrade",id:"apply-the-upgrade",level:2},{value:"Check the status",id:"check-the-status",level:2},{value:"Apply further upgrades",id:"apply-further-upgrades",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"upgrade-your-cluster",children:"Upgrade your cluster"})}),"\n",(0,t.jsxs)(n.p,{children:["Constellation provides an easy way to upgrade all components of your cluster, without disrupting its availability.\nSpecifically, you can upgrade the Kubernetes version, the nodes' image, and the Constellation microservices.\nYou configure the desired versions in your local Constellation configuration and trigger upgrades with the ",(0,t.jsx)(n.code,{children:"apply"})," command.\nTo learn about available versions you use the ",(0,t.jsx)(n.code,{children:"upgrade check"})," command.\nWhich versions are available depends on the CLI version you are using."]}),"\n",(0,t.jsx)(n.h2,{id:"update-the-cli",children:"Update the CLI"}),"\n",(0,t.jsx)(n.p,{children:"Each CLI comes with a set of supported microservice and Kubernetes versions.\nMost importantly, a given CLI version can only upgrade a cluster of the previous minor version, but not older ones.\nThis means that you have to upgrade your CLI and cluster one minor version at a time."}),"\n",(0,t.jsx)(n.p,{children:"For example, if you are currently on CLI version v2.6 and the latest version is v2.8, you should"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"upgrade the CLI to v2.7,"}),"\n",(0,t.jsx)(n.li,{children:"upgrade the cluster to v2.7,"}),"\n",(0,t.jsx)(n.li,{children:"and only then continue upgrading the CLI (and the cluster) to v2.8 after."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Also note that if your current Kubernetes version isn't supported by the next CLI version, use your current CLI to upgrade to a newer Kubernetes version first."}),"\n",(0,t.jsxs)(n.p,{children:["To learn which Kubernetes versions are supported by a particular CLI, run ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-config-kubernetes-versions",children:"constellation config kubernetes-versions"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"migrate-the-configuration",children:"Migrate the configuration"}),"\n",(0,t.jsxs)(n.p,{children:["The Constellation configuration file is located in the file ",(0,t.jsx)(n.code,{children:"constellation-conf.yaml"})," in your workspace.\nRefer to the ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/reference/migration",children:"migration reference"})," to check if you need to update fields in your configuration file.\nUse ",(0,t.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-config-migrate",children:(0,t.jsx)(n.code,{children:"constellation config migrate"})})," to automatically update an old config file to a new format."]}),"\n",(0,t.jsx)(n.h2,{id:"check-for-upgrades",children:"Check for upgrades"}),"\n",(0,t.jsx)(n.p,{children:"To learn which versions the current CLI can upgrade to and what's installed in your cluster, run:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# Show possible upgrades\nconstellation upgrade check\n\n# Show possible upgrades and write them to config file\nconstellation upgrade check --update-config\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You can either enter the reported target versions into your config manually or run the above command with the ",(0,t.jsx)(n.code,{children:"--update-config"})," flag.\nWhen using this flag, the ",(0,t.jsx)(n.code,{children:"kubernetesVersion"}),", ",(0,t.jsx)(n.code,{children:"image"}),", ",(0,t.jsx)(n.code,{children:"microserviceVersion"}),", and ",(0,t.jsx)(n.code,{children:"attestation"})," fields are overwritten with the smallest available upgrade."]}),"\n",(0,t.jsx)(n.h2,{id:"apply-the-upgrade",children:"Apply the upgrade"}),"\n",(0,t.jsx)(n.p,{children:"Once you updated your config with the desired versions, you can trigger the upgrade with this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation apply\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Microservice upgrades will be finished within a few minutes, depending on the cluster size.\nIf you are interested, you can monitor pods restarting in the ",(0,t.jsx)(n.code,{children:"kube-system"})," namespace with your tool of choice."]}),"\n",(0,t.jsx)(n.p,{children:"Image and Kubernetes upgrades take longer.\nFor each node in your cluster, a new node has to be created and joined.\nThe process usually takes up to ten minutes per node."}),"\n",(0,t.jsxs)(n.p,{children:["When applying an upgrade, the Helm charts for the upgrade as well as backup files of Constellation-managed Custom Resource Definitions, Custom Resources, and Terraform state are created.\nYou can use the Terraform state backup to restore previous resources in case an upgrade misconfigured or erroneously deleted a resource.\nYou can use the Custom Resource (Definition) backup files to restore Custom Resources and Definitions manually (e.g., via ",(0,t.jsx)(n.code,{children:"kubectl apply"}),") if the automatic migration of those resources fails.\nYou can use the Helm charts to manually apply upgrades to the Kubernetes resources, should an upgrade fail."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["For advanced users: the upgrade consists of several phases that can be individually skipped through the ",(0,t.jsx)(n.code,{children:"--skip-phases"})," flag.\nThe phases are ",(0,t.jsx)(n.code,{children:"infrastracture"})," for the cloud resource management through Terraform, ",(0,t.jsx)(n.code,{children:"helm"})," for the chart management of the microservices, ",(0,t.jsx)(n.code,{children:"image"})," for OS image upgrades, and ",(0,t.jsx)(n.code,{children:"k8s"})," for Kubernetes version upgrades."]})}),"\n",(0,t.jsx)(n.h2,{id:"check-the-status",children:"Check the status"}),"\n",(0,t.jsxs)(n.p,{children:["Upgrades are asynchronous operations.\nAfter you run ",(0,t.jsx)(n.code,{children:"apply"}),", it will take a while until the upgrade has completed.\nTo understand if an upgrade is finished, you can run:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"constellation status\n"})}),"\n",(0,t.jsx)(n.p,{children:"This command displays the following information:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The installed services and their versions"}),"\n",(0,t.jsx)(n.li,{children:"The image and Kubernetes version the cluster is expecting on each node"}),"\n",(0,t.jsx)(n.li,{children:"How many nodes are up to date"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here's an example output:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell-session",children:"Target versions:\n Image: v2.6.0\n Kubernetes: v1.25.8\nService versions:\n Cilium: v1.12.1\n cert-manager: v1.10.0\n constellation-operators: v2.6.0\n constellation-services: v2.6.0\nCluster status: Some node versions are out of date\n Image: 23/25\n Kubernetes: 25/25\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This output indicates that the cluster is running Kubernetes version ",(0,t.jsx)(n.code,{children:"1.25.8"}),", and all nodes have the appropriate binaries installed.\n23 out of 25 nodes have already upgraded to the targeted image version of ",(0,t.jsx)(n.code,{children:"2.6.0"}),", while two are still in progress."]}),"\n",(0,t.jsx)(n.h2,{id:"apply-further-upgrades",children:"Apply further upgrades"}),"\n",(0,t.jsxs)(n.p,{children:["After the upgrade is finished, you can run ",(0,t.jsx)(n.code,{children:"constellation upgrade check"})," again to see if there are more upgrades available. If so, repeat the process."]})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>a});var s=r(96540);const t={},o=s.createContext(t);function i(e){const n=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/dc614479.12c43ec2.js b/pr-preview/pr-4027/assets/js/dc614479.12c43ec2.js deleted file mode 100644 index 94d66823c..000000000 --- a/pr-preview/pr-4027/assets/js/dc614479.12c43ec2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5739],{28453:(e,s,t)=>{t.d(s,{R:()=>o,x:()=>l});var n=t(96540);const r={},i=n.createContext(r);function o(e){const s=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(i.Provider,{value:s},e.children)}},50988:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"workflows/storage","title":"Use persistent storage","description":"Persistent storage in Kubernetes requires cloud-specific configuration.","source":"@site/versioned_docs/version-2.22/workflows/storage.md","sourceDirName":"workflows","slug":"/workflows/storage","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/storage","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/workflows/storage.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Verify your cluster","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cluster"},"next":{"title":"Use the Terraform provider","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/terraform-provider"}}');var r=t(74848),i=t(28453);const o={},l="Use persistent storage",a={},c=[{value:"Confidential storage",id:"confidential-storage",level:2},{value:"CSI drivers",id:"csi-drivers",level:2},{value:"Installation",id:"installation",level:2},{value:"Change the default storage class",id:"change-the-default-storage-class",level:3}];function d(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components},{TabItem:t,Tabs:n}=s;return t||p("TabItem",!0),n||p("Tabs",!0),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"use-persistent-storage",children:"Use persistent storage"})}),"\n",(0,r.jsxs)(s.p,{children:["Persistent storage in Kubernetes requires cloud-specific configuration.\nFor abstraction of container storage, Kubernetes offers ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/volumes/",children:"volumes"}),",\nallowing users to mount storage solutions directly into containers.\nThe ",(0,r.jsx)(s.a,{href:"https://kubernetes-csi.github.io/docs/",children:"Container Storage Interface (CSI)"})," is the standard interface for exposing arbitrary block and file storage systems into containers in Kubernetes.\nCloud service providers (CSPs) offer their own CSI-based solutions for cloud storage."]}),"\n",(0,r.jsx)(s.h2,{id:"confidential-storage",children:"Confidential storage"}),"\n",(0,r.jsxs)(s.p,{children:["Most cloud storage solutions support encryption, such as ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/kubernetes-engine/docs/how-to/using-cmek",children:"GCE Persistent Disks (PD)"}),".\nConstellation supports the available CSI-based storage options for Kubernetes engines in AWS, Azure, GCP, and STACKIT.\nHowever, their encryption takes place in the storage backend and is managed by the CSP.\nThus, using the default CSI drivers for these storage types means trusting the CSP with your persistent data."]}),"\n",(0,r.jsxs)(s.p,{children:["To address this, Constellation provides CSI drivers for AWS EBS, Azure Disk, GCE PD, and OpenStack Cinder, offering ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys#storage-encryption",children:"encryption on the node level"}),". They enable transparent encryption for persistent volumes without needing to trust the cloud backend. Plaintext data never leaves the confidential VM context, offering you confidential storage."]}),"\n",(0,r.jsxs)(s.p,{children:["For more details see ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage",children:"encrypted persistent storage"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"csi-drivers",children:"CSI drivers"}),"\n",(0,r.jsx)(s.p,{children:"Constellation supports the following drivers, which offer node-level encryption and optional integrity protection."}),"\n",(0,r.jsxs)(n,{groupId:"csp",children:[(0,r.jsx)(t,{value:"aws",label:"AWS",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Constellation CSI driver for AWS Elastic Block Store"}),"\nMount ",(0,r.jsx)(s.a,{href:"https://aws.amazon.com/ebs/",children:"Elastic Block Store"})," storage volumes into your Constellation cluster.\nFollow the instructions on how to ",(0,r.jsx)(s.a,{href:"#installation",children:"install the Constellation CSI driver"})," or check out the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation-aws-ebs-csi-driver",children:"repository"})," for more information."]})}),(0,r.jsx)(t,{value:"azure",label:"Azure",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Constellation CSI driver for Azure Disk"}),":\nMount Azure ",(0,r.jsx)(s.a,{href:"https://azure.microsoft.com/en-us/services/storage/disks/#overview",children:"Disk Storage"})," into your Constellation cluster.\nSee the instructions on how to ",(0,r.jsx)(s.a,{href:"#installation",children:"install the Constellation CSI driver"})," or check out the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation-azuredisk-csi-driver",children:"repository"})," for more information.\nSince Azure Disks are mounted as ",(0,r.jsx)(s.code,{children:"ReadWriteOnce"}),", they're only available to a single pod."]})}),(0,r.jsx)(t,{value:"gcp",label:"GCP",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Constellation CSI driver for GCP Persistent Disk"}),":\nMount ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/persistent-disk",children:"Persistent Disk"})," block storage into your Constellation cluster.\nFollow the instructions on how to ",(0,r.jsx)(s.a,{href:"#installation",children:"install the Constellation CSI driver"})," or check out the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation-gcp-compute-persistent-disk-csi-driver",children:"repository"})," for more information."]})}),(0,r.jsx)(t,{value:"stackit",label:"STACKIT",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Constellation CSI driver for STACKIT / OpenStack Cinder"}),"\nMount ",(0,r.jsx)(s.a,{href:"https://docs.openstack.org/cinder/latest/",children:"Cinder"})," block storage volumes into your Constellation cluster.\nFollow the instructions on how to ",(0,r.jsx)(s.a,{href:"#installation",children:"install the Constellation CSI driver"})," or check out the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation-cloud-provider-openstack",children:"repository"})," for more information."]})})]}),"\n",(0,r.jsxs)(s.p,{children:["Note that in case the options above aren't a suitable solution for you, Constellation is compatible with all other CSI-based storage options. For example, you can use ",(0,r.jsx)(s.a,{href:"https://docs.aws.amazon.com/en_en/eks/latest/userguide/efs-csi.html",children:"AWS EFS"}),", ",(0,r.jsx)(s.a,{href:"https://docs.microsoft.com/en-us/azure/storage/files/storage-files-introduction",children:"Azure Files"}),", or ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/filestore",children:"GCP Filestore"})," with Constellation out of the box. Constellation is just not providing transparent encryption on the node level for these storage types yet."]}),"\n",(0,r.jsx)(s.h2,{id:"installation",children:"Installation"}),"\n",(0,r.jsxs)(s.p,{children:["The Constellation CLI automatically installs Constellation's CSI driver for the selected CSP in your cluster.\nIf you don't need a CSI driver or wish to deploy your own, you can disable the automatic installation by setting ",(0,r.jsx)(s.code,{children:"deployCSIDriver"})," to ",(0,r.jsx)(s.code,{children:"false"})," in your Constellation config file."]}),"\n",(0,r.jsxs)(n,{groupId:"csp",children:[(0,r.jsxs)(t,{value:"aws",label:"AWS",children:[(0,r.jsx)(s.p,{children:"AWS comes with two storage classes by default."}),(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsxs)(s.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volume-types.html",children:["SSDs of ",(0,r.jsx)(s.code,{children:"gp3"})," type"]})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsxs)(s.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volume-types.html",children:["SSDs of ",(0,r.jsx)(s.code,{children:"gp3"})," type"]})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n",(0,r.jsx)(s.li,{children:"Integrity protection of data written to disk"}),"\n"]}),"\n"]}),"\n"]}),(0,r.jsxs)(s.p,{children:["For more information on encryption algorithms and key sizes, refer to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage#cryptographic-algorithms",children:"cryptographic algorithms"}),"."]}),(0,r.jsxs)(s.admonition,{type:"info",children:[(0,r.jsxs)(s.p,{children:["The default storage class is set to ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," for performance reasons.\nIf you want integrity-protected storage, set the ",(0,r.jsx)(s.code,{children:"storageClassName"})," parameter of your persistent volume claim to ",(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"."]}),(0,r.jsxs)(s.p,{children:["Alternatively, you can create your own storage class with integrity protection enabled by adding ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: ext4-integrity"})," to the class ",(0,r.jsx)(s.code,{children:"parameters"}),".\nOr use another filesystem by specifying another file system type with the suffix ",(0,r.jsx)(s.code,{children:"-integrity"}),", e.g., ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: xfs-integrity"}),"."]}),(0,r.jsx)(s.p,{children:"Note that volume expansion isn't supported for integrity-protected disks."})]})]}),(0,r.jsxs)(t,{value:"azure",label:"Azure",children:[(0,r.jsx)(s.p,{children:"Azure comes with two storage classes by default."}),(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsx)(s.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/disks-types#standard-ssds",children:"Standard SSDs"})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsx)(s.a,{href:"https://learn.microsoft.com/en-us/azure/virtual-machines/disks-types#premium-ssds",children:"Premium SSDs"})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n",(0,r.jsx)(s.li,{children:"Integrity protection of data written to disk"}),"\n"]}),"\n"]}),"\n"]}),(0,r.jsxs)(s.p,{children:["For more information on encryption algorithms and key sizes, refer to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage#cryptographic-algorithms",children:"cryptographic algorithms"}),"."]}),(0,r.jsxs)(s.admonition,{type:"info",children:[(0,r.jsxs)(s.p,{children:["The default storage class is set to ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," for performance reasons.\nIf you want integrity-protected storage, set the ",(0,r.jsx)(s.code,{children:"storageClassName"})," parameter of your persistent volume claim to ",(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"."]}),(0,r.jsxs)(s.p,{children:["Alternatively, you can create your own storage class with integrity protection enabled by adding ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: ext4-integrity"})," to the class ",(0,r.jsx)(s.code,{children:"parameters"}),".\nOr use another filesystem by specifying another file system type with the suffix ",(0,r.jsx)(s.code,{children:"-integrity"}),", e.g., ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: xfs-integrity"}),"."]}),(0,r.jsx)(s.p,{children:"Note that volume expansion isn't supported for integrity-protected disks."})]})]}),(0,r.jsxs)(t,{value:"gcp",label:"GCP",children:[(0,r.jsx)(s.p,{children:"GCP comes with two storage classes by default."}),(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/compute/docs/disks#pdspecs",children:"standard persistent disks"})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsx)(s.a,{href:"https://cloud.google.com/compute/docs/disks#pdspecs",children:"performance (SSD) persistent disks"})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n",(0,r.jsx)(s.li,{children:"Integrity protection of data written to disk"}),"\n"]}),"\n"]}),"\n"]}),(0,r.jsxs)(s.p,{children:["For more information on encryption algorithms and key sizes, refer to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage#cryptographic-algorithms",children:"cryptographic algorithms"}),"."]}),(0,r.jsxs)(s.admonition,{type:"info",children:[(0,r.jsxs)(s.p,{children:["The default storage class is set to ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," for performance reasons.\nIf you want integrity-protected storage, set the ",(0,r.jsx)(s.code,{children:"storageClassName"})," parameter of your persistent volume claim to ",(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"."]}),(0,r.jsxs)(s.p,{children:["Alternatively, you can create your own storage class with integrity protection enabled by adding ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: ext4-integrity"})," to the class ",(0,r.jsx)(s.code,{children:"parameters"}),".\nOr use another filesystem by specifying another file system type with the suffix ",(0,r.jsx)(s.code,{children:"-integrity"}),", e.g., ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: xfs-integrity"}),"."]}),(0,r.jsx)(s.p,{children:"Note that volume expansion isn't supported for integrity-protected disks."})]})]}),(0,r.jsxs)(t,{value:"stackit",label:"STACKIT",children:[(0,r.jsx)(s.p,{children:"STACKIT comes with two storage classes by default."}),(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsxs)(s.a,{href:"https://docs.stackit.cloud/stackit/en/service-plans-blockstorage-75137974.html",children:["disks of ",(0,r.jsx)(s.code,{children:"storage_premium_perf1"})," type"]})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Uses ",(0,r.jsxs)(s.a,{href:"https://docs.stackit.cloud/stackit/en/service-plans-blockstorage-75137974.html",children:["disks of ",(0,r.jsx)(s.code,{children:"storage_premium_perf1"})," type"]})]}),"\n",(0,r.jsx)(s.li,{children:"ext-4 filesystem"}),"\n",(0,r.jsx)(s.li,{children:"Encryption of all data written to disk"}),"\n",(0,r.jsx)(s.li,{children:"Integrity protection of data written to disk"}),"\n"]}),"\n"]}),"\n"]}),(0,r.jsxs)(s.p,{children:["For more information on encryption algorithms and key sizes, refer to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage#cryptographic-algorithms",children:"cryptographic algorithms"}),"."]}),(0,r.jsxs)(s.admonition,{type:"info",children:[(0,r.jsxs)(s.p,{children:["The default storage class is set to ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," for performance reasons.\nIf you want integrity-protected storage, set the ",(0,r.jsx)(s.code,{children:"storageClassName"})," parameter of your persistent volume claim to ",(0,r.jsx)(s.code,{children:"integrity-encrypted-rwo"}),"."]}),(0,r.jsxs)(s.p,{children:["Alternatively, you can create your own storage class with integrity protection enabled by adding ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: ext4-integrity"})," to the class ",(0,r.jsx)(s.code,{children:"parameters"}),".\nOr use another filesystem by specifying another file system type with the suffix ",(0,r.jsx)(s.code,{children:"-integrity"}),", e.g., ",(0,r.jsx)(s.code,{children:"csi.storage.k8s.io/fstype: xfs-integrity"}),"."]}),(0,r.jsx)(s.p,{children:"Note that volume expansion isn't supported for integrity-protected disks."})]})]})]}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["Create a ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/",children:"persistent volume"})]}),"\n",(0,r.jsxs)(s.p,{children:["A ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims",children:"persistent volume claim"})," is a request for storage with certain properties.\nIt can refer to a storage class.\nThe following creates a persistent volume claim, requesting 20 GB of storage via the ",(0,r.jsx)(s.code,{children:"encrypted-rwo"})," storage class:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"cat <<EOF | kubectl apply -f -\nkind: PersistentVolumeClaim\napiVersion: v1\nmetadata:\n name: pvc-example\n namespace: default\nspec:\n accessModes:\n - ReadWriteOnce\n storageClassName: encrypted-rwo\n resources:\n requests:\n storage: 20Gi\nEOF\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Create a Pod with persistent storage"}),"\n",(0,r.jsx)(s.p,{children:"You can assign a persistent volume claim to an application in need of persistent storage.\nThe mounted volume will persist restarts.\nThe following creates a pod that uses the previously created persistent volume claim:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"cat <<EOF | kubectl apply -f -\napiVersion: v1\nkind: Pod\nmetadata:\n name: web-server\n namespace: default\nspec:\n containers:\n - name: web-server\n image: nginx\n volumeMounts:\n - mountPath: /var/lib/www/html\n name: mypvc\n volumes:\n - name: mypvc\n persistentVolumeClaim:\n claimName: pvc-example\n readOnly: false\nEOF\n"})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"change-the-default-storage-class",children:"Change the default storage class"}),"\n",(0,r.jsxs)(s.p,{children:["The default storage class is responsible for all persistent volume claims that don't explicitly request ",(0,r.jsx)(s.code,{children:"storageClassName"}),".\nConstellation creates a storage class with encryption enabled and sets this as the default class.\nIn case you wish to change it, follow the steps below:"]}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"List the storage classes in your cluster:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"kubectl get storageclass\n"})}),"\n",(0,r.jsx)(s.p,{children:"The output is similar to this:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-shell-session",children:"NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE\nencrypted-rwo (default) {your-csp}.csi.confidential.cloud Delete Immediate true 1d\nintegrity-encrypted-rwo {your-csp}.csi.confidential.cloud Delete Immediate false 1d\n"})}),"\n",(0,r.jsxs)(s.p,{children:["The default storage class is marked by ",(0,r.jsx)(s.code,{children:"(default)"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Mark old default storage class as non default"}),"\n",(0,r.jsx)(s.p,{children:"If you previously used another storage class as the default, you will have to remove that annotation:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:'kubectl patch storageclass encrypted-rwo -p \'{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}\'\n'})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Mark new class as the default"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:'kubectl patch storageclass integrity-encrypted-rwo -p \'{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}\'\n'})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Verify that your chosen storage class is default:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"kubectl get storageclass\n"})}),"\n",(0,r.jsx)(s.p,{children:"The output is similar to this:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-shell-session",children:"NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE\nencrypted-rwo {your-csp}.csi.confidential.cloud Delete Immediate true 1d\nintegrity-encrypted-rwo (default) {your-csp}.csi.confidential.cloud Delete Immediate false 1d\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}function p(e,s){throw new Error("Expected "+(s?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/dcc7f694.211d37d3.js b/pr-preview/pr-4027/assets/js/dcc7f694.211d37d3.js deleted file mode 100644 index 8a443786f..000000000 --- a/pr-preview/pr-4027/assets/js/dcc7f694.211d37d3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4801],{13573:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"architecture/microservices","title":"Microservices","description":"Constellation takes care of bootstrapping and initializing a Confidential Kubernetes cluster.","source":"@site/docs/architecture/microservices.md","sourceDirName":"architecture","slug":"/architecture/microservices","permalink":"/constellation/pr-preview/pr-4027/next/architecture/microservices","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/architecture/microservices.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Versions and support","permalink":"/constellation/pr-preview/pr-4027/next/architecture/versions"},"next":{"title":"Attestation","permalink":"/constellation/pr-preview/pr-4027/next/architecture/attestation"}}');var i=n(74848),s=n(28453);const o={},a="Microservices",c={},l=[{value:"Bootstrapper",id:"bootstrapper",level:2},{value:"JoinService",id:"joinservice",level:2},{value:"VerificationService",id:"verificationservice",level:2},{value:"KeyService",id:"keyservice",level:2}];function h(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",mermaid:"mermaid",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"microservices",children:"Microservices"})}),"\n",(0,i.jsx)(t.p,{children:"Constellation takes care of bootstrapping and initializing a Confidential Kubernetes cluster.\nDuring the lifetime of the cluster, it handles day 2 operations such as key management, remote attestation, and updates.\nThese features are provided by several microservices:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#bootstrapper",children:"Bootstrapper"})," initializes a Constellation node and bootstraps the cluster"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#joinservice",children:"JoinService"})," joins new nodes to an existing cluster"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#verificationservice",children:"VerificationService"})," provides remote attestation functionality"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#keyservice",children:"KeyService"})," manages Constellation-internal keys"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"The relations between microservices are shown in the following diagram:"}),"\n",(0,i.jsx)(t.mermaid,{value:"flowchart LR\n subgraph admin [Admin's machine]\n A[Constellation CLI]\n end\n subgraph img [Constellation OS image]\n B[Constellation OS]\n C[Bootstrapper]\n end\n subgraph Kubernetes\n D[JoinService]\n E[KeyService]\n F[VerificationService]\n end\n A -- deploys --\x3e\n B -- starts --\x3e C\n C -- deploys --\x3e D\n C -- deploys --\x3e E\n C -- deploys --\x3e F"}),"\n",(0,i.jsx)(t.h2,{id:"bootstrapper",children:"Bootstrapper"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"Bootstrapper"})," is the first microservice launched after booting a Constellation node image.\nIt sets up that machine as a Kubernetes node and integrates that node into the Kubernetes cluster.\nTo this end, the ",(0,i.jsx)(t.em,{children:"Bootstrapper"})," first downloads and verifies the ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/overview/components/",children:"Kubernetes components"})," at the configured versions.\nThe ",(0,i.jsx)(t.em,{children:"Bootstrapper"})," tries to find an existing cluster and if successful, communicates with the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#joinservice",children:"JoinService"})," to join the node.\nOtherwise, it waits for an initialization request to create a new Kubernetes cluster."]}),"\n",(0,i.jsx)(t.h2,{id:"joinservice",children:"JoinService"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"JoinService"})," runs as ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/",children:"DaemonSet"})," on each control-plane node.\nNew nodes (at cluster start, or later through autoscaling) send a request to the service over ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/attestation#attested-tls-atls",children:"attested TLS (aTLS)"}),".\nThe ",(0,i.jsx)(t.em,{children:"JoinService"})," verifies the new node's certificate and attestation statement.\nIf attestation is successful, the new node is supplied with an encryption key from the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/microservices#keyservice",children:(0,i.jsx)(t.em,{children:"KeyService"})})," for its state disk, and a Kubernetes bootstrap token."]}),"\n",(0,i.jsx)(t.mermaid,{value:"sequenceDiagram\n participant New node\n participant JoinService\n New node->>JoinService: aTLS handshake (server side verification)\n JoinService--\x3e>New node: #\n New node->>+JoinService: IssueJoinTicket(DiskUUID, NodeName, IsControlPlane)\n JoinService->>+KeyService: GetDataKey(DiskUUID)\n KeyService--\x3e>-JoinService: DiskEncryptionKey\n JoinService--\x3e>-New node: DiskEncryptionKey, KubernetesJoinToken, ..."}),"\n",(0,i.jsx)(t.h2,{id:"verificationservice",children:"VerificationService"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"VerificationService"})," runs as DaemonSet on each node.\nIt provides user-facing functionality for remote attestation during the cluster's lifetime via an endpoint for ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/attestation#cluster-attestation",children:"verifying the cluster"}),".\nRead more about the hardware-based ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/attestation",children:"attestation feature"})," of Constellation and how to ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/verify-cluster",children:"verify"})," a cluster on the client side."]}),"\n",(0,i.jsx)(t.h2,{id:"keyservice",children:"KeyService"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.em,{children:"KeyService"})," runs as DaemonSet on each control-plane node.\nIt implements the key management for the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys#storage-encryption",children:"storage encryption keys"})," in Constellation. These keys are used for the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/images#state-disk",children:"state disk"})," of each node and the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage",children:"transparently encrypted storage"})," for Kubernetes.\nDepending on wether the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys#constellation-managed-key-management",children:"constellation-managed"})," or ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/keys#user-managed-key-management",children:"user-managed"})," mode is used, the ",(0,i.jsx)(t.em,{children:"KeyService"})," holds the key encryption key (KEK) directly or calls an external key management service (KMS) for key derivation respectively."]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var r=n(96540);const i={},s=r.createContext(i);function o(e){const t=r.useContext(s);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/de51a3b8.9944225e.js b/pr-preview/pr-4027/assets/js/de51a3b8.9944225e.js deleted file mode 100644 index 0cf29a330..000000000 --- a/pr-preview/pr-4027/assets/js/de51a3b8.9944225e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1618],{9122:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"workflows/terraform-provider","title":"Use the Terraform provider","description":"The Constellation Terraform provider allows to manage the full lifecycle of a Constellation cluster (namely creation, upgrades, and deletion) via Terraform.","source":"@site/versioned_docs/version-2.23/workflows/terraform-provider.md","sourceDirName":"workflows","slug":"/workflows/terraform-provider","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/terraform-provider","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/workflows/terraform-provider.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Use persistent storage","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/storage"},"next":{"title":"Consume SBOMs","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/sbom"}}');var t=n(74848),s=n(28453);const i={},a="Use the Terraform provider",l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Quick setup",id:"quick-setup",level:2},{value:"Bringing your own infrastructure",id:"bringing-your-own-infrastructure",level:2},{value:"Cluster upgrades",id:"cluster-upgrades",level:2}];function d(e){const r={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components},{TabItem:n,Tabs:o}=r;return n||h("TabItem",!0),o||h("Tabs",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.header,{children:(0,t.jsx)(r.h1,{id:"use-the-terraform-provider",children:"Use the Terraform provider"})}),"\n",(0,t.jsxs)(r.p,{children:["The Constellation Terraform provider allows to manage the full lifecycle of a Constellation cluster (namely creation, upgrades, and deletion) via Terraform.\nThe provider is available through the ",(0,t.jsx)(r.a,{href:"https://registry.terraform.io/providers/edgelesssys/constellation/latest",children:"Terraform registry"})," and is released in lock-step with Constellation releases."]}),"\n",(0,t.jsx)(r.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsx)(r.li,{children:"a Linux / Mac operating system (ARM64/AMD64)"}),"\n",(0,t.jsxs)(r.li,{children:["a Terraform installation of version ",(0,t.jsx)(r.code,{children:"v1.4.4"})," or above"]}),"\n"]}),"\n",(0,t.jsx)(r.h2,{id:"quick-setup",children:"Quick setup"}),"\n",(0,t.jsxs)(r.p,{children:["This example shows how to set up a Constellation cluster with the reference IAM and infrastructure setup. This setup is also used when creating a Constellation cluster through the Constellation CLI. You can either consume the IAM / infrastructure modules through a remote source (recommended) or local files. The latter requires downloading the infrastructure and IAM modules for the corresponding CSP from ",(0,t.jsx)(r.code,{children:"terraform-modules.zip"})," on the ",(0,t.jsx)(r.a,{href:"https://github.com/edgelesssys/constellation/releases/latest",children:"Constellation release page"})," and placing them in the Terraform workspace directory."]}),"\n",(0,t.jsxs)(r.ol,{children:["\n",(0,t.jsx)(r.li,{children:"Create a directory (workspace) for your Constellation cluster."}),"\n"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"mkdir constellation-workspace\ncd constellation-workspace\n"})}),"\n",(0,t.jsxs)(r.ol,{start:"2",children:["\n",(0,t.jsxs)(r.li,{children:["Use one of the ",(0,t.jsx)(r.a,{href:"https://github.com/edgelesssys/constellation/tree/main/terraform-provider-constellation/examples/full",children:"example configurations for using the Constellation Terraform provider"})," or create a ",(0,t.jsx)(r.code,{children:"main.tf"})," file and fill it with the resources you want to create. The ",(0,t.jsx)(r.a,{href:"https://registry.terraform.io/providers/edgelesssys/constellation/latest",children:"Constellation Terraform provider documentation"})," offers thorough documentation on the resources and their attributes."]}),"\n",(0,t.jsx)(r.li,{children:"Initialize and apply the Terraform configuration."}),"\n"]}),"\n",(0,t.jsxs)(o,{groupId:"csp",children:[(0,t.jsxs)(n,{value:"aws",label:"AWS",children:[(0,t.jsx)(r.p,{children:"Initialize the providers and apply the configuration."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply\n"})}),(0,t.jsxs)(r.p,{children:["Optionally, you can prefix the ",(0,t.jsx)(r.code,{children:"terraform apply"})," command with ",(0,t.jsx)(r.code,{children:"TF_LOG=INFO"})," to collect ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform logs"})," while applying the configuration. This may provide helpful output in debugging scenarios."]})]}),(0,t.jsxs)(n,{value:"azure",label:"Azure",children:[(0,t.jsxs)(r.admonition,{type:"info",children:[(0,t.jsx)(r.p,{children:"On SEV-SNP, you need to manually patch the policy of the MAA provider before creating the Constellation cluster, as this feature isn't available in Azure's Terraform provider yet. The Constellation CLI provides a utility for patching, but you can also do it manually."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply -target module.azure_iam # adjust resource path if not using the example configuration\nterraform apply -target module.azure_infrastructure # adjust resource path if not using the example configuration\nconstellation maa-patch $(terraform output -raw maa_url) # adjust output path / input if not using the example configuration or manually patch the resource\nterraform apply -target constellation_cluster.azure_example # adjust resource path if not using the example configuration\n"})}),(0,t.jsx)(r.p,{children:"Use the following policy if manually performing the patch."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{children:'version= 1.0;\nauthorizationrules\n{\n [type=="x-ms-azurevm-default-securebootkeysvalidated", value==false] => deny();\n [type=="x-ms-azurevm-debuggersdisabled", value==false] => deny();\n // The line below was edited to use the MAA provider within Constellation. Do not edit manually.\n //[type=="secureboot", value==false] => deny();\n [type=="x-ms-azurevm-signingdisabled", value==false] => deny();\n [type=="x-ms-azurevm-dbvalidated", value==false] => deny();\n [type=="x-ms-azurevm-dbxvalidated", value==false] => deny();\n => permit();\n};\nissuancerules\n{\n};\n'})})]}),(0,t.jsx)(r.p,{children:"Initialize the providers and apply the configuration."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply\n"})}),(0,t.jsxs)(r.p,{children:["Optionally, you can prefix the ",(0,t.jsx)(r.code,{children:"terraform apply"})," command with ",(0,t.jsx)(r.code,{children:"TF_LOG=INFO"})," to collect ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform logs"})," while applying the configuration. This may provide helpful output in debugging scenarios."]})]}),(0,t.jsxs)(n,{value:"gcp",label:"GCP",children:[(0,t.jsx)(r.p,{children:"Initialize the providers and apply the configuration."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply\n"})}),(0,t.jsxs)(r.p,{children:["Optionally, you can prefix the ",(0,t.jsx)(r.code,{children:"terraform apply"})," command with ",(0,t.jsx)(r.code,{children:"TF_LOG=INFO"})," to collect ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform logs"})," while applying the configuration. This may provide helpful output in debugging scenarios."]})]}),(0,t.jsxs)(n,{value:"stackit",label:"STACKIT",children:[(0,t.jsx)(r.p,{children:"Initialize the providers and apply the configuration."}),(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply\n"})}),(0,t.jsxs)(r.p,{children:["Optionally, you can prefix the ",(0,t.jsx)(r.code,{children:"terraform apply"})," command with ",(0,t.jsx)(r.code,{children:"TF_LOG=INFO"})," to collect ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform logs"})," while applying the configuration. This may provide helpful output in debugging scenarios."]})]})]}),"\n",(0,t.jsxs)(r.ol,{start:"4",children:["\n",(0,t.jsx)(r.li,{children:"Connect to the cluster."}),"\n"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"terraform output -raw kubeconfig > constellation-admin.conf\nexport KUBECONFIG=$(realpath constellation-admin.conf)\n"})}),"\n",(0,t.jsx)(r.h2,{id:"bringing-your-own-infrastructure",children:"Bringing your own infrastructure"}),"\n",(0,t.jsxs)(r.p,{children:["Instead of using the example infrastructure used in the ",(0,t.jsx)(r.a,{href:"#quick-setup",children:"quick setup"}),", you can also provide your own infrastructure.\nIf you need a starting point for a custom infrastructure setup, you can download the infrastructure / IAM Terraform modules for the respective CSP from the Constellation ",(0,t.jsx)(r.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub releases"}),". You can modify and extend the modules per your requirements, while keeping the basic functionality intact.\nThe module contains:"]}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsxs)(r.li,{children:[(0,t.jsx)(r.code,{children:"{csp}"}),": cloud resources the cluster runs on"]}),"\n",(0,t.jsxs)(r.li,{children:[(0,t.jsx)(r.code,{children:"iam/{csp}"}),": IAM resources used within the cluster"]}),"\n"]}),"\n",(0,t.jsx)(r.p,{children:"When upgrading your cluster, make sure to check the Constellation release notes for potential breaking changes in the reference infrastructure / IAM modules that need to be considered."}),"\n",(0,t.jsx)(r.h2,{id:"cluster-upgrades",children:"Cluster upgrades"}),"\n",(0,t.jsx)(r.admonition,{type:"tip",children:(0,t.jsxs)(r.p,{children:["Also see the ",(0,t.jsx)(r.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/upgrade",children:"general documentation on cluster upgrades"}),"."]})}),"\n",(0,t.jsx)(r.p,{children:"The steps for applying the upgrade are as follows:"}),"\n",(0,t.jsxs)(r.ol,{children:["\n",(0,t.jsxs)(r.li,{children:["Update the version constraint of the Constellation Terraform provider in the ",(0,t.jsx)(r.code,{children:"required_providers"})," block in your Terraform configuration."]}),"\n",(0,t.jsxs)(r.li,{children:["If you explicitly set any of the version attributes of the provider's resources and data sources (e.g. ",(0,t.jsx)(r.code,{children:"image_version"})," or ",(0,t.jsx)(r.code,{children:"constellation_microservice_version"}),"), make sure to update them too. Refer to Constellation's ",(0,t.jsx)(r.a,{href:"https://github.com/edgelesssys/constellation/blob/main/dev-docs/workflows/versions-support.md",children:"version support policy"})," for more information on how each Constellation version and its dependencies are supported."]}),"\n",(0,t.jsxs)(r.li,{children:["Update the IAM / infrastructure configuration.","\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsxs)(r.li,{children:["For ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/language/modules/sources#fetching-archives-over-http",children:"remote addresses as module sources"}),", update the version number inside the address of the ",(0,t.jsx)(r.code,{children:"source"})," field of the infrastructure / IAM module to the target version."]}),"\n",(0,t.jsxs)(r.li,{children:["For ",(0,t.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/language/modules/sources#local-paths",children:"local paths as module sources"})," or when ",(0,t.jsx)(r.a,{href:"#bringing-your-own-infrastructure",children:"providing your own infrastructure"}),", see the changes made in the reference modules since the upgrade's origin version and adjust your infrastructure / IAM configuration accordingly."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(r.li,{children:"Upgrade the Terraform module and provider dependencies and apply the targeted configuration."}),"\n"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:" terraform init -upgrade\n terraform apply\n"})})]})}function u(e={}){const{wrapper:r}={...(0,s.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}function h(e,r){throw new Error("Expected "+(r?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,r,n)=>{n.d(r,{R:()=>i,x:()=>a});var o=n(96540);const t={},s=o.createContext(t);function i(e){const r=o.useContext(s);return o.useMemo(function(){return"function"==typeof e?e(r):{...r,...e}},[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),o.createElement(s.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/ded7ff97.f6bb64a4.js b/pr-preview/pr-4027/assets/js/ded7ff97.f6bb64a4.js deleted file mode 100644 index 9ba90a455..000000000 --- a/pr-preview/pr-4027/assets/js/ded7ff97.f6bb64a4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6389],{13749:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"getting-started/examples/filestash-s3proxy","title":"Deploying Filestash","description":"Filestash is a web frontend for different storage backends, including S3.","source":"@site/versioned_docs/version-2.22/getting-started/examples/filestash-s3proxy.md","sourceDirName":"getting-started/examples","slug":"/getting-started/examples/filestash-s3proxy","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/filestash-s3proxy","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/getting-started/examples/filestash-s3proxy.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Horizontal Pod Autoscaling","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scaling"},"next":{"title":"Workflows","permalink":"/constellation/pr-preview/pr-4027/2.22/category/workflows"}}');var o=t(74848),a=t(28453);const r={},i="Deploying Filestash",c={},l=[];function d(e){const s={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.header,{children:(0,o.jsx)(s.h1,{id:"deploying-filestash",children:"Deploying Filestash"})}),"\n",(0,o.jsx)(s.p,{children:"Filestash is a web frontend for different storage backends, including S3.\nIt's a useful application to showcase s3proxy in action."}),"\n",(0,o.jsxs)(s.ol,{children:["\n",(0,o.jsxs)(s.li,{children:["Deploy s3proxy as described in ",(0,o.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/s3proxy#deployment",children:"Deployment"}),"."]}),"\n",(0,o.jsx)(s.li,{children:"Create a deployment file for Filestash with one pod:"}),"\n"]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-sh",children:'cat << EOF > "deployment-filestash.yaml"\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: filestash\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: filestash\n template:\n metadata:\n labels:\n app: filestash\n spec:\n hostAliases:\n - ip: $(kubectl get svc s3proxy-service -o=jsonpath=\'{.spec.clusterIP}\')\n hostnames:\n - "s3.us-east-1.amazonaws.com"\n - "s3.us-east-2.amazonaws.com"\n - "s3.us-west-1.amazonaws.com"\n - "s3.us-west-2.amazonaws.com"\n - "s3.eu-north-1.amazonaws.com"\n - "s3.eu-south-1.amazonaws.com"\n - "s3.eu-south-2.amazonaws.com"\n - "s3.eu-west-1.amazonaws.com"\n - "s3.eu-west-2.amazonaws.com"\n - "s3.eu-west-3.amazonaws.com"\n - "s3.eu-central-1.amazonaws.com"\n - "s3.eu-central-2.amazonaws.com"\n - "s3.ap-northeast-1.amazonaws.com"\n - "s3.ap-northeast-2.amazonaws.com"\n - "s3.ap-northeast-3.amazonaws.com"\n - "s3.ap-east-1.amazonaws.com"\n - "s3.ap-southeast-1.amazonaws.com"\n - "s3.ap-southeast-2.amazonaws.com"\n - "s3.ap-southeast-3.amazonaws.com"\n - "s3.ap-southeast-4.amazonaws.com"\n - "s3.ap-south-1.amazonaws.com"\n - "s3.ap-south-2.amazonaws.com"\n - "s3.me-south-1.amazonaws.com"\n - "s3.me-central-1.amazonaws.com"\n - "s3.il-central-1.amazonaws.com"\n - "s3.af-south-1.amazonaws.com"\n - "s3.ca-central-1.amazonaws.com"\n - "s3.sa-east-1.amazonaws.com"\n containers:\n - name: filestash\n image: machines/filestash:latest\n ports:\n - containerPort: 8334\n volumeMounts:\n - name: ca-cert\n mountPath: /etc/ssl/certs/kube-ca.crt\n subPath: kube-ca.crt\n volumes:\n - name: ca-cert\n secret:\n secretName: s3proxy-tls\n items:\n - key: ca.crt\n path: kube-ca.crt\nEOF\n'})}),"\n",(0,o.jsxs)(s.p,{children:["The pod spec includes the ",(0,o.jsx)(s.code,{children:"hostAliases"})," key, which adds an entry to the pod's ",(0,o.jsx)(s.code,{children:"/etc/hosts"}),".\nThe entry forwards all requests for any of the currently defined AWS regions to the Kubernetes service ",(0,o.jsx)(s.code,{children:"s3proxy-service"}),".\nIf you followed the s3proxy ",(0,o.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/s3proxy#deployment",children:"Deployment"})," guide, this service points to a s3proxy pod."]}),"\n",(0,o.jsxs)(s.p,{children:["The deployment specifies all regions explicitly to prevent accidental data leaks.\nIf one of your buckets were located in a region that's not part of the ",(0,o.jsx)(s.code,{children:"hostAliases"})," key, traffic towards those buckets would not be redirected to s3proxy.\nSimilarly, if you want to exclude data for specific regions from going through s3proxy you can remove those regions from the deployment."]}),"\n",(0,o.jsxs)(s.p,{children:["The spec also includes a volume mount for the TLS certificate and adds it to the pod's certificate trust store.\nThe volume is called ",(0,o.jsx)(s.code,{children:"ca-cert"}),".\nThe key ",(0,o.jsx)(s.code,{children:"ca.crt"})," of that volume is mounted to ",(0,o.jsx)(s.code,{children:"/etc/ssl/certs/kube-ca.crt"}),", which is the default certificate trust store location for that container's OpenSSL library.\nNot adding the CA certificate will result in TLS authentication errors."]}),"\n",(0,o.jsxs)(s.ol,{start:"3",children:["\n",(0,o.jsxs)(s.li,{children:["Apply the file: ",(0,o.jsx)(s.code,{children:"kubectl apply -f deployment-filestash.yaml"})]}),"\n"]}),"\n",(0,o.jsxs)(s.p,{children:["Afterward, you can use a port forward to access the Filestash pod:\n",(0,o.jsx)(s.code,{children:"kubectl port-forward pod/$(kubectl get pod --selector='app=filestash' -o=jsonpath='{.items[*].metadata.name}') 8334:8334"})]}),"\n",(0,o.jsxs)(s.ol,{start:"4",children:["\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["After browsing to ",(0,o.jsx)(s.code,{children:"localhost:8443"}),", Filestash will ask you to set an administrator password.\nAfter setting it, you can directly leave the admin area by clicking the blue cloud symbol in the top left corner.\nSubsequently, you can select S3 as storage backend and enter your credentials.\nThis will bring you to an overview of your buckets.\nIf you want to deploy Filestash in production, take a look at its ",(0,o.jsx)(s.a,{href:"https://www.filestash.app/docs/",children:"documentation"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["To see the logs of s3proxy intercepting requests made to S3, run: ",(0,o.jsx)(s.code,{children:"kubectl logs -f pod/$(kubectl get pod --selector='app=s3proxy' -o=jsonpath='{.items[*].metadata.name}')"}),"\nLook out for log messages labeled ",(0,o.jsx)(s.code,{children:"intercepting"}),".\nThere is one such log message for each message that's encrypted, decrypted, or blocked."]}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["Once you have uploaded a file with Filestash, you should be able to view the file in Filestash.\nHowever, if you go to the AWS S3 ",(0,o.jsx)(s.a,{href:"https://s3.console.aws.amazon.com/s3/home",children:"Web UI"})," and download the file you just uploaded in Filestash, you won't be able to read it.\nAnother way to spot encrypted files without downloading them is to click on a file, scroll to the Metadata section, and look for the header named ",(0,o.jsx)(s.code,{children:"x-amz-meta-constellation-encryption"}),".\nThis header holds the encrypted data encryption key of the object and is only present on objects that are encrypted by s3proxy."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>r,x:()=>i});var n=t(96540);const o={},a=n.createContext(o);function r(e){const s=n.useContext(a);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/dfb82530.9fdb1b02.js b/pr-preview/pr-4027/assets/js/dfb82530.9fdb1b02.js deleted file mode 100644 index 0f701e862..000000000 --- a/pr-preview/pr-4027/assets/js/dfb82530.9fdb1b02.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8585],{28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>s});var t=r(96540);const o={},l=t.createContext(o);function i(e){const n=t.useContext(l);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),t.createElement(l.Provider,{value:n},e.children)}},60270:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>t,toc:()=>a});const t=JSON.parse('{"id":"workflows/recovery","title":"Recover your cluster","description":"Recovery of a Constellation cluster means getting it back into a healthy state after too many concurrent node failures in the control plane.","source":"@site/versioned_docs/version-2.23/workflows/recovery.md","sourceDirName":"workflows","slug":"/workflows/recovery","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/recovery","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/workflows/recovery.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Terminate your cluster","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/terminate"},"next":{"title":"Verify your cluster","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cluster"}}');var o=r(74848),l=r(28453);const i={},s="Recover your cluster",c={},a=[{value:"Identify unhealthy clusters",id:"identify-unhealthy-clusters",level:2},{value:"Recover a cluster",id:"recover-a-cluster",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,l.R)(),...e.components},{TabItem:t,Tabs:i}=n;return t||g("TabItem",!0),i||g("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"recover-your-cluster",children:"Recover your cluster"})}),"\n",(0,o.jsxs)(n.p,{children:["Recovery of a Constellation cluster means getting it back into a healthy state after too many concurrent node failures in the control plane.\nReasons for an unhealthy cluster can vary from a power outage, or planned reboot, to migration of nodes and regions.\nRecovery events are rare, because Constellation is built for high availability and automatically and securely replaces failed nodes. When a node is replaced, Constellation's control plane first verifies the new node before it sends the node the cryptographic keys required to decrypt its ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/images#state-disk",children:"state disk"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Constellation provides a recovery mechanism for cases where the control plane has failed and is unable to replace nodes.\nThe ",(0,o.jsx)(n.code,{children:"constellation recover"})," command securely connects to all nodes in need of recovery using ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation#attested-tls-atls",children:"attested TLS"})," and provides them with the keys to decrypt their state disks and continue booting."]}),"\n",(0,o.jsx)(n.h2,{id:"identify-unhealthy-clusters",children:"Identify unhealthy clusters"}),"\n",(0,o.jsx)(n.p,{children:"The first step to recovery is identifying when a cluster becomes unhealthy.\nUsually, this can be first observed when the Kubernetes API server becomes unresponsive."}),"\n",(0,o.jsx)(n.p,{children:"You can check the health status of the nodes via the cloud service provider (CSP).\nConstellation provides logging information on the boot process and status via serial console output.\nIn the following, you'll find detailed descriptions for identifying clusters stuck in recovery for each CSP."}),"\n",(0,o.jsxs)(i,{groupId:"csp",children:[(0,o.jsxs)(t,{value:"aws",label:"AWS",children:[(0,o.jsxs)(n.p,{children:["First, open the AWS console to view all Auto Scaling Groups (ASGs) in the region of your cluster. Select the ASG of the control plane ",(0,o.jsx)(n.code,{children:"<cluster-name>-<UID>-control-plane"})," and check that enough members are in a ",(0,o.jsx)(n.em,{children:"Running"})," state."]}),(0,o.jsxs)(n.p,{children:["Second, check the boot logs of these ",(0,o.jsx)(n.em,{children:"Instances"}),". In the ASG's ",(0,o.jsx)(n.em,{children:"Instance management"})," view, select each desired instance. In the upper right corner, select ",(0,o.jsx)(n.strong,{children:"Action > Monitor and troubleshoot > Get system log"}),"."]}),(0,o.jsxs)(n.p,{children:["In the serial console output, search for ",(0,o.jsx)(n.code,{children:"Waiting for decryption key"}),".\nSimilar output to the following means your node was restarted and needs to decrypt the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/images#state-disk",children:"state disk"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"gcp"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}\n'})}),(0,o.jsxs)(n.p,{children:["The node will then try to connect to the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#joinservice",children:(0,o.jsx)(n.em,{children:"JoinService"})})," and obtain the decryption key.\nIf this fails due to an unhealthy control plane, you will see log messages similar to the following:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["192.168.178.4:30090","192.168.178.2:30090"]}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.4:30090"}\n{"level":"WARN","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.4:30090: connect: connection refused\\"","endpoint":"192.168.178.4:30090"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.2:30090"}\n{"level":"WARN","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.2:30090: i/o timeout\\"","endpoint":"192.168.178.2:30090"}\n{"level":"ERROR","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}\n'})}),(0,o.jsx)(n.p,{children:"This means that you have to recover the node manually."})]}),(0,o.jsxs)(t,{value:"azure",label:"Azure",children:[(0,o.jsxs)(n.p,{children:["In the Azure portal, find the cluster's resource group.\nInside the resource group, open the control plane ",(0,o.jsx)(n.em,{children:"Virtual machine scale set"})," ",(0,o.jsx)(n.code,{children:"constellation-scale-set-controlplanes-<suffix>"}),".\nOn the left, go to ",(0,o.jsx)(n.strong,{children:"Settings"})," > ",(0,o.jsx)(n.strong,{children:"Instances"})," and check that enough members are in a ",(0,o.jsx)(n.em,{children:"Running"})," state."]}),(0,o.jsxs)(n.p,{children:["Second, check the boot logs of these ",(0,o.jsx)(n.em,{children:"Instances"}),".\nIn the scale set's ",(0,o.jsx)(n.em,{children:"Instances"})," view, open the details page of the desired instance.\nOn the left, go to ",(0,o.jsx)(n.strong,{children:"Support + troubleshooting"})," > ",(0,o.jsx)(n.strong,{children:"Serial console"}),"."]}),(0,o.jsxs)(n.p,{children:["In the serial console output, search for ",(0,o.jsx)(n.code,{children:"Waiting for decryption key"}),".\nSimilar output to the following means your node was restarted and needs to decrypt the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/images#state-disk",children:"state disk"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T09:56:41Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"azure"}\n{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}\n{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}\n{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}\n'})}),(0,o.jsxs)(n.p,{children:["The node will then try to connect to the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#joinservice",children:(0,o.jsx)(n.em,{children:"JoinService"})})," and obtain the decryption key.\nIf this fails due to an unhealthy control plane, you will see log messages similar to the following:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["10.9.0.5:30090","10.9.0.6:30090"]}\n{"level":"INFO","ts":"2022-09-08T09:56:43Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"10.9.0.5:30090"}\n{"level":"WARN","ts":"2022-09-08T09:57:03Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 10.9.0.5:30090: i/o timeout\\"","endpoint":"10.9.0.5:30090"}\n{"level":"INFO","ts":"2022-09-08T09:57:03Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"10.9.0.6:30090"}\n{"level":"WARN","ts":"2022-09-08T09:57:23Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 10.9.0.6:30090: i/o timeout\\"","endpoint":"10.9.0.6:30090"}\n{"level":"ERROR","ts":"2022-09-08T09:57:23Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}\n'})}),(0,o.jsx)(n.p,{children:"This means that you have to recover the node manually."})]}),(0,o.jsxs)(t,{value:"gcp",label:"GCP",children:[(0,o.jsxs)(n.p,{children:["First, check that the control plane ",(0,o.jsx)(n.em,{children:"Instance Group"})," has enough members in a ",(0,o.jsx)(n.em,{children:"Ready"})," state.\nIn the GCP Console, go to ",(0,o.jsx)(n.strong,{children:"Instance Groups"})," and check the group for the cluster's control plane ",(0,o.jsx)(n.code,{children:"<cluster-name>-control-plane-<suffix>"}),"."]}),(0,o.jsxs)(n.p,{children:["Second, check the status of the ",(0,o.jsx)(n.em,{children:"VM Instances"}),".\nGo to ",(0,o.jsx)(n.strong,{children:"VM Instances"})," and open the details of the desired instance.\nCheck the serial console output of that instance by opening the ",(0,o.jsx)(n.strong,{children:"Logs"})," > ",(0,o.jsx)(n.strong,{children:"Serial port 1 (console)"})," page:"]}),(0,o.jsx)(n.p,{children:(0,o.jsx)(n.img,{alt:"GCP portal serial console link",src:r(79471).A+"",width:"846",height:"415"})}),(0,o.jsxs)(n.p,{children:["In the serial console output, search for ",(0,o.jsx)(n.code,{children:"Waiting for decryption key"}),".\nSimilar output to the following means your node was restarted and needs to decrypt the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/images#state-disk",children:"state disk"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"gcp"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}\n'})}),(0,o.jsxs)(n.p,{children:["The node will then try to connect to the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#joinservice",children:(0,o.jsx)(n.em,{children:"JoinService"})})," and obtain the decryption key.\nIf this fails due to an unhealthy control plane, you will see log messages similar to the following:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["192.168.178.4:30090","192.168.178.2:30090"]}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.4:30090"}\n{"level":"WARN","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.4:30090: connect: connection refused\\"","endpoint":"192.168.178.4:30090"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.2:30090"}\n{"level":"WARN","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.2:30090: i/o timeout\\"","endpoint":"192.168.178.2:30090"}\n{"level":"ERROR","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}\n'})}),(0,o.jsx)(n.p,{children:"This means that you have to recover the node manually."})]}),(0,o.jsxs)(t,{value:"stackit",label:"STACKIT",children:[(0,o.jsxs)(n.p,{children:["First, open the STACKIT portal to view all servers in your project. Select individual control plane nodes ",(0,o.jsx)(n.code,{children:"<cluster-name>-<UID>-control-plane-<UID>-<index>"})," and check that enough members are in a ",(0,o.jsx)(n.em,{children:"Running"})," state."]}),(0,o.jsxs)(n.p,{children:["Second, check the boot logs of these servers. Click on a server name and select ",(0,o.jsx)(n.strong,{children:"Overview"}),". Find the ",(0,o.jsx)(n.strong,{children:"Machine Setup"})," section and click on ",(0,o.jsx)(n.strong,{children:"Web console"})," > ",(0,o.jsx)(n.strong,{children:"Open console"}),"."]}),(0,o.jsxs)(n.p,{children:["In the serial console output, search for ",(0,o.jsx)(n.code,{children:"Waiting for decryption key"}),".\nSimilar output to the following means your node was restarted and needs to decrypt the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/images#state-disk",children:"state disk"}),":"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"gcp"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}\n'})}),(0,o.jsxs)(n.p,{children:["The node will then try to connect to the ",(0,o.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#joinservice",children:(0,o.jsx)(n.em,{children:"JoinService"})})," and obtain the decryption key.\nIf this fails due to an unhealthy control plane, you will see log messages similar to the following:"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["192.168.178.4:30090","192.168.178.2:30090"]}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.4:30090"}\n{"level":"WARN","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.4:30090: connect: connection refused\\"","endpoint":"192.168.178.4:30090"}\n{"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.2:30090"}\n{"level":"WARN","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \\"transport: Error while dialing dial tcp 192.168.178.2:30090: i/o timeout\\"","endpoint":"192.168.178.2:30090"}\n{"level":"ERROR","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}\n'})}),(0,o.jsx)(n.p,{children:"This means that you have to recover the node manually."})]})]}),"\n",(0,o.jsx)(n.h2,{id:"recover-a-cluster",children:"Recover a cluster"}),"\n",(0,o.jsx)(n.p,{children:"Recovering a cluster requires the following parameters:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The ",(0,o.jsx)(n.code,{children:"constellation-state.yaml"})," file in your working directory or the cluster's endpoint"]}),"\n",(0,o.jsx)(n.li,{children:"The master secret of the cluster"}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"A cluster can be recovered like this:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"$ constellation recover\nPushed recovery key.\nPushed recovery key.\nPushed recovery key.\nRecovered 3 control-plane nodes.\n"})}),"\n",(0,o.jsx)(n.p,{children:"In the serial console output of the node you'll see a similar output to the following:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer","caller":"recoveryserver/server.go:93","msg":"Received recover call"}\n{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer","caller":"recoveryserver/server.go:125","msg":"Received state disk key and measurement secret, shutting down server"}\n{"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer.gRPC","caller":"zap/server_interceptors.go:61","msg":"finished streaming call with code OK","grpc.start_time":"2022-09-08T10:26:59Z","system":"grpc","span.kind":"server","grpc.service":"recoverproto.API","grpc.method":"Recover","peer.address":"192.0.2.3:41752","grpc.code":"OK","grpc.time_ms":15.701}\n{"level":"INFO","ts":"2022-09-08T10:27:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:87","msg":"RejoinClient stopped"}\n'})})]})}function h(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}function g(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},79471:(e,n,r)=>{r.d(n,{A:()=>t});const t=r.p+"assets/images/recovery-gcp-serial-console-link-d31487c5a5e88fbcde9dcc33e876838d.png"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/dfb8a45d.047a71dd.js b/pr-preview/pr-4027/assets/js/dfb8a45d.047a71dd.js deleted file mode 100644 index a53dd2480..000000000 --- a/pr-preview/pr-4027/assets/js/dfb8a45d.047a71dd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[5267],{28161:(e,s,i)=>{i.r(s),i.d(s,{assets:()=>d,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"workflows/reproducible-builds","title":"Reproduce released artifacts","description":"Constellation has first-class support for reproducible builds.","source":"@site/versioned_docs/version-2.23/workflows/reproducible-builds.md","sourceDirName":"workflows","slug":"/workflows/reproducible-builds","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/reproducible-builds","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/workflows/reproducible-builds.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Consume SBOMs","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/sbom"},"next":{"title":"Troubleshooting","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/troubleshooting"}}');var r=i(74848),t=i(28453);const o={},l="Reproduce released artifacts",d={},c=[{value:"Build environment prerequisites",id:"build-environment-prerequisites",level:2},{value:"Run the build",id:"run-the-build",level:2},{value:"Feedback",id:"feedback",level:2}];function a(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"reproduce-released-artifacts",children:"Reproduce released artifacts"})}),"\n",(0,r.jsxs)(s.p,{children:["Constellation has first-class support for ",(0,r.jsx)(s.a,{href:"https://reproducible-builds.org",children:"reproducible builds"}),".\nReproducing the released artifacts is an alternative to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cli",children:"signature verification"})," that doesn't require trusting Edgeless Systems' release process.\nThe following sections describe how to rebuild an artifact and how Constellation ensures that the rebuild reproduces the artifacts bit-by-bit."]}),"\n",(0,r.jsx)(s.h2,{id:"build-environment-prerequisites",children:"Build environment prerequisites"}),"\n",(0,r.jsxs)(s.p,{children:["The build systems used by Constellation - ",(0,r.jsx)(s.a,{href:"https://bazel.build/",children:"Bazel"})," and ",(0,r.jsx)(s.a,{href:"https://nixos.org",children:"Nix"})," - are designed for deterministic, reproducible builds.\nThese two dependencies should be the only prerequisites for a successful build.\nHowever, it can't be ruled out completely that peculiarities of the host affect the build result.\nThus, we recommend the following host setup for best results:"]}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsx)(s.li,{children:"A Linux operating system not older than v5.4."}),"\n",(0,r.jsxs)(s.li,{children:["The GNU C library not older than v2.31 (avoid ",(0,r.jsx)(s.code,{children:"musl"}),")."]}),"\n",(0,r.jsxs)(s.li,{children:["GNU ",(0,r.jsx)(s.code,{children:"coreutils"})," not older than v8.30 (avoid ",(0,r.jsx)(s.code,{children:"busybox"}),")."]}),"\n",(0,r.jsxs)(s.li,{children:["An ",(0,r.jsx)(s.code,{children:"ext4"})," filesystem for building."]}),"\n",(0,r.jsx)(s.li,{children:"AppArmor turned off."}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"This is given, for example, on an Ubuntu 22.04 system, which is also used for reproducibility tests."}),"\n",(0,r.jsx)(s.admonition,{type:"note",children:(0,r.jsx)(s.p,{children:"To avoid any backwards-compatibility issues, the host software versions should also not be much newer than the Constellation release."})}),"\n",(0,r.jsx)(s.h2,{id:"run-the-build",children:"Run the build"}),"\n",(0,r.jsxs)(s.p,{children:["The following instructions outline qualitatively how to reproduce a build.\nConstellation implements these instructions in the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/actions/workflows/reproducible-builds.yml",children:"Reproducible Builds workflow"}),", which continuously tests for reproducibility.\nThe workflow is a good place to look up specific version numbers and build steps."]}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Check out the Constellation repository at the tag corresponding to the release."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"git clone https://github.com/edgelesssys/constellation.git\ncd constellation\ngit checkout v2.20.0\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"https://bazel.build/install",children:"Install the Bazel release"})," specified in ",(0,r.jsx)(s.code,{children:".bazelversion"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"https://nixos.org/download/",children:"Install Nix"})," (any recent version should do)."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["Run the build with ",(0,r.jsx)(s.code,{children:"bazel build $target"})," for one of the following targets of interest:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-data",children:"//cli:cli_enterprise_darwin_amd64\n//cli:cli_enterprise_darwin_arm64\n//cli:cli_enterprise_linux_amd64\n//cli:cli_enterprise_linux_arm64\n//cli:cli_enterprise_windows_amd64\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Compare the build result with the downloaded release artifact."}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"feedback",children:"Feedback"}),"\n",(0,r.jsxs)(s.p,{children:["Reproduction failures often indicate a bug in the build system or in the build definitions.\nTherefore, we're interested in any reproducibility issues you might encounter.\n",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/issues/new/choose",children:"Start a bug report"})," and describe the details of your build environment.\nMake sure to include your result binary or a ",(0,r.jsx)(s.a,{href:"https://diffoscope.org/",children:(0,r.jsx)(s.code,{children:"diffoscope"})})," report, if possible."]})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},28453:(e,s,i)=>{i.d(s,{R:()=>o,x:()=>l});var n=i(96540);const r={},t=n.createContext(r);function o(e){const s=n.useContext(t);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/e0c6aa40.9043ab1e.js b/pr-preview/pr-4027/assets/js/e0c6aa40.9043ab1e.js deleted file mode 100644 index d51ceb528..000000000 --- a/pr-preview/pr-4027/assets/js/e0c6aa40.9043ab1e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9529],{28453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>c});var o=s(96540);const l={},r=o.createContext(l);function t(e){const n=o.useContext(r);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:t(e.components),o.createElement(r.Provider,{value:n},e.children)}},30312:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>u,frontMatter:()=>t,metadata:()=>o,toc:()=>a});const o=JSON.parse('{"id":"workflows/scale","title":"Scale your cluster","description":"Constellation provides all features of a Kubernetes cluster including scaling and autoscaling.","source":"@site/versioned_docs/version-2.24/workflows/scale.md","sourceDirName":"workflows","slug":"/workflows/scale","permalink":"/constellation/pr-preview/pr-4027/workflows/scale","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/workflows/scale.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Create your cluster","permalink":"/constellation/pr-preview/pr-4027/workflows/create"},"next":{"title":"Upgrade your cluster","permalink":"/constellation/pr-preview/pr-4027/workflows/upgrade"}}');var l=s(74848),r=s(28453);const t={},c="Scale your cluster",i={},a=[{value:"Worker node scaling",id:"worker-node-scaling",level:2},{value:"Autoscaling",id:"autoscaling",level:3},{value:"Manual scaling",id:"manual-scaling",level:3},{value:"Control-plane node scaling",id:"control-plane-node-scaling",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,r.R)(),...e.components},{TabItem:s,Tabs:o}=n;return s||h("TabItem",!0),o||h("Tabs",!0),(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"scale-your-cluster",children:"Scale your cluster"})}),"\n",(0,l.jsx)(n.p,{children:"Constellation provides all features of a Kubernetes cluster including scaling and autoscaling."}),"\n",(0,l.jsx)(n.h2,{id:"worker-node-scaling",children:"Worker node scaling"}),"\n",(0,l.jsx)(n.h3,{id:"autoscaling",children:"Autoscaling"}),"\n",(0,l.jsx)(n.p,{children:"Constellation comes with autoscaling disabled by default. To enable autoscaling, find the scaling group of\nworker nodes:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:'kubectl get scalinggroups -o json | yq \'.items | .[] | select(.spec.role == "Worker") | [{"name": .metadata.name, "nodeGoupName": .spec.nodeGroupName}]\'\n'})}),"\n",(0,l.jsxs)(n.p,{children:["This will output a list of scaling groups with the corresponding cloud provider name (",(0,l.jsx)(n.code,{children:"name"}),") and the cloud provider agnostic name of the node group (",(0,l.jsx)(n.code,{children:"nodeGroupName"}),")."]}),"\n",(0,l.jsxs)(n.p,{children:["Then, patch the ",(0,l.jsx)(n.code,{children:"autoscaling"})," field of the scaling group resource with the desired ",(0,l.jsx)(n.code,{children:"name"})," to ",(0,l.jsx)(n.code,{children:"true"}),":"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# Replace <name> with the name of the scaling group you want to enable autoscaling for\nworker_group=<name>\nkubectl patch scalinggroups $worker_group --patch '{\"spec\":{\"autoscaling\": true}}' --type='merge'\nkubectl get scalinggroup $worker_group -o jsonpath='{.spec}' | yq -P\n"})}),"\n",(0,l.jsxs)(n.p,{children:["The cluster autoscaler now automatically provisions additional worker nodes so that all pods have a place to run.\nYou can configure the minimum and maximum number of worker nodes in the scaling group by patching the ",(0,l.jsx)(n.code,{children:"min"})," or\n",(0,l.jsx)(n.code,{children:"max"})," fields of the scaling group resource:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl patch scalinggroups $worker_group --patch '{\"spec\":{\"max\": 5}}' --type='merge'\nkubectl get scalinggroup $worker_group -o jsonpath='{.spec}' | yq -P\n"})}),"\n",(0,l.jsx)(n.p,{children:"The cluster autoscaler will now never provision more than 5 worker nodes."}),"\n",(0,l.jsx)(n.p,{children:"If you want to see the autoscaling in action, try to add a deployment with a lot of replicas, like the\nfollowing Nginx deployment. The number of replicas needed to trigger the autoscaling depends on the size of\nand count of your worker nodes. Wait for the rollout of the deployment to finish and compare the number of\nworker nodes before and after the deployment:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"kubectl create deployment nginx --image=nginx --replicas 150\nkubectl -n kube-system get nodes\nkubectl rollout status deployment nginx\nkubectl -n kube-system get nodes\n"})}),"\n",(0,l.jsx)(n.h3,{id:"manual-scaling",children:"Manual scaling"}),"\n",(0,l.jsx)(n.p,{children:"Alternatively, you can manually scale your cluster up or down:"}),"\n",(0,l.jsxs)(o,{groupId:"csp",children:[(0,l.jsx)(s,{value:"aws",label:"AWS",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Go to Auto Scaling Groups and select the worker ASG to scale up."}),"\n",(0,l.jsxs)(n.li,{children:["Click ",(0,l.jsx)(n.strong,{children:"Edit"})]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new (increased) ",(0,l.jsx)(n.strong,{children:"Desired capacity"})," and ",(0,l.jsx)(n.strong,{children:"Update"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"azure",label:"Azure",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Find your Constellation resource group."}),"\n",(0,l.jsxs)(n.li,{children:["Select the ",(0,l.jsx)(n.code,{children:"scale-set-workers"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:["Go to ",(0,l.jsx)(n.strong,{children:"settings"})," and ",(0,l.jsx)(n.strong,{children:"scaling"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new ",(0,l.jsx)(n.strong,{children:"instance count"})," and ",(0,l.jsx)(n.strong,{children:"save"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"gcp",label:"GCP",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["In Compute Engine go to ",(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/compute/instanceGroups/",children:"Instance Groups"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Edit"})," the ",(0,l.jsx)(n.strong,{children:"worker"})," instance group."]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new ",(0,l.jsx)(n.strong,{children:"number of instances"})," and ",(0,l.jsx)(n.strong,{children:"save"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,l.jsx)(n.p,{children:"Dynamic cluster scaling isn't yet supported for STACKIT.\nSupport will be introduced in one of the upcoming releases."})})]}),"\n",(0,l.jsx)(n.h2,{id:"control-plane-node-scaling",children:"Control-plane node scaling"}),"\n",(0,l.jsxs)(n.p,{children:["Control-plane nodes can ",(0,l.jsx)(n.strong,{children:"only be scaled manually and only scaled up"}),"!"]}),"\n",(0,l.jsx)(n.p,{children:"To increase the number of control-plane nodes, follow these steps:"}),"\n",(0,l.jsxs)(o,{groupId:"csp",children:[(0,l.jsx)(s,{value:"aws",label:"AWS",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Go to Auto Scaling Groups and select the control-plane ASG to scale up."}),"\n",(0,l.jsxs)(n.li,{children:["Click ",(0,l.jsx)(n.strong,{children:"Edit"})]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new (increased) ",(0,l.jsx)(n.strong,{children:"Desired capacity"})," and ",(0,l.jsx)(n.strong,{children:"Update"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"azure",label:"Azure",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Find your Constellation resource group."}),"\n",(0,l.jsxs)(n.li,{children:["Select the ",(0,l.jsx)(n.code,{children:"scale-set-controlplanes"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:["Go to ",(0,l.jsx)(n.strong,{children:"settings"})," and ",(0,l.jsx)(n.strong,{children:"scaling"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new (increased) ",(0,l.jsx)(n.strong,{children:"instance count"})," and ",(0,l.jsx)(n.strong,{children:"save"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"gcp",label:"GCP",children:(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["In Compute Engine go to ",(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/compute/instanceGroups/",children:"Instance Groups"}),"."]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Edit"})," the ",(0,l.jsx)(n.strong,{children:"control-plane"})," instance group."]}),"\n",(0,l.jsxs)(n.li,{children:["Set the new (increased) ",(0,l.jsx)(n.strong,{children:"number of instances"})," and ",(0,l.jsx)(n.strong,{children:"save"}),"."]}),"\n"]})}),(0,l.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,l.jsx)(n.p,{children:"Dynamic cluster scaling isn't yet supported for STACKIT.\nSupport will be introduced in one of the upcoming releases."})})]}),"\n",(0,l.jsxs)(n.p,{children:["If you scale down the number of control-planes nodes, the removed nodes won't be able to exit the ",(0,l.jsx)(n.code,{children:"etcd"})," cluster correctly. This will endanger the quorum that's required to run a stable Kubernetes control plane."]})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}function h(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/e0f39c0b.4e546576.js b/pr-preview/pr-4027/assets/js/e0f39c0b.4e546576.js deleted file mode 100644 index cc6764e2c..000000000 --- a/pr-preview/pr-4027/assets/js/e0f39c0b.4e546576.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1279],{28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>a});var n=r(96540);const i={},s=n.createContext(i);function o(e){const t=n.useContext(s);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),n.createElement(s.Provider,{value:t},e.children)}},71882:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"architecture/encrypted-storage","title":"Encrypted persistent storage","description":"Confidential VMs provide runtime memory encryption to protect data in use.","source":"@site/versioned_docs/version-2.22/architecture/encrypted-storage.md","sourceDirName":"architecture","slug":"/architecture/encrypted-storage","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/architecture/encrypted-storage.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Keys and cryptographic primitives","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/keys"},"next":{"title":"Networking","permalink":"/constellation/pr-preview/pr-4027/2.22/architecture/networking"}}');var i=r(74848),s=r(28453);const o={},a="Encrypted persistent storage",c={},d=[{value:"Cloud provider-managed encryption",id:"cloud-provider-managed-encryption",level:2},{value:"Constellation-managed encryption",id:"constellation-managed-encryption",level:2},{value:"Cryptographic algorithms",id:"cryptographic-algorithms",level:2},{value:"dm-crypt",id:"dm-crypt",level:3},{value:"dm-integrity",id:"dm-integrity",level:3},{value:"Encrypted S3 object storage",id:"encrypted-s3-object-storage",level:2}];function l(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"encrypted-persistent-storage",children:"Encrypted persistent storage"})}),"\n",(0,i.jsxs)(t.p,{children:["Confidential VMs provide runtime memory encryption to protect data in use.\nIn the context of Kubernetes, this is sufficient for the confidentiality and integrity of stateless services.\nConsider a front-end web server, for example, that keeps all connection information cached in main memory.\nNo sensitive data is ever written to an insecure medium.\nHowever, many real-world applications need some form of state or data-lake service that's connected to a persistent storage device and requires encryption at rest.\nAs described in ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/storage",children:"Use persistent storage"}),", cloud service providers (CSPs) use the container storage interface (CSI) to make their storage solutions available to Kubernetes workloads.\nThese CSI storage solutions often support some sort of encryption.\nFor example, Google Cloud ",(0,i.jsx)(t.a,{href:"https://cloud.google.com/security/encryption/default-encryption",children:"encrypts data at rest by default"}),", without any action required by the customer."]}),"\n",(0,i.jsx)(t.h2,{id:"cloud-provider-managed-encryption",children:"Cloud provider-managed encryption"}),"\n",(0,i.jsx)(t.p,{children:"CSP-managed storage solutions encrypt the data in the cloud backend before writing it physically to disk.\nIn the context of confidential computing and Constellation, the CSP and its managed services aren't trusted.\nHence, cloud provider-managed encryption protects your data from offline hardware access to physical storage devices.\nIt doesn't protect it from anyone with infrastructure-level access to the storage backend or a malicious insider in the cloud platform.\nEven with \"bring your own key\" or similar concepts, the CSP performs the encryption process with access to the keys and plaintext data."}),"\n",(0,i.jsx)(t.p,{children:"In the security model of Constellation, securing persistent storage and thereby data at rest requires that all cryptographic operations are performed inside a trusted execution environment.\nConsequently, using CSP-managed encryption of persistent storage usually isn't an option."}),"\n",(0,i.jsx)(t.h2,{id:"constellation-managed-encryption",children:"Constellation-managed encryption"}),"\n",(0,i.jsxs)(t.p,{children:["Constellation provides CSI drivers for storage solutions in all major clouds with built-in encryption support.\nBlock storage provisioned by the CSP is ",(0,i.jsx)(t.a,{href:"https://guix.gnu.org/manual/en/html_node/Mapped-Devices.html",children:"mapped"})," using the ",(0,i.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-crypt.html",children:"dm-crypt"}),", and optionally the ",(0,i.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-integrity.html",children:"dm-integrity"}),", kernel modules, before it's formatted and accessed by the Kubernetes workloads.\nAll cryptographic operations happen inside the trusted environment of the confidential Constellation node."]}),"\n",(0,i.jsxs)(t.p,{children:["Note that for integrity-protected disks, ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/blog/2018/07/12/resizing-persistent-volumes-using-kubernetes/",children:"volume expansion"})," isn't supported."]}),"\n",(0,i.jsxs)(t.p,{children:["By default the driver uses data encryption keys (DEKs) issued by the Constellation ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#keyservice",children:(0,i.jsx)(t.em,{children:"KeyService"})}),".\nThe DEKs are in turn derived from the Constellation's key encryption key (KEK), which is directly derived from the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys#master-secret",children:"master secret"}),".\nThis is the recommended mode of operation, and also requires the least amount of setup by the cluster administrator."]}),"\n",(0,i.jsx)(t.p,{children:"Alternatively, the driver can be configured to use a key management system to store and access KEKs and DEKs."}),"\n",(0,i.jsxs)(t.p,{children:["Refer to ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/architecture/keys",children:"keys and cryptography"})," for more details on key management in Constellation."]}),"\n",(0,i.jsx)(t.p,{children:"Once deployed and configured, the CSI driver ensures transparent encryption and integrity of all persistent volumes provisioned via its storage class.\nData at rest is secured without any additional actions required by the developer."}),"\n",(0,i.jsx)(t.h2,{id:"cryptographic-algorithms",children:"Cryptographic algorithms"}),"\n",(0,i.jsx)(t.p,{children:"This section gives an overview of the libraries, cryptographic algorithms, and their configurations, used in Constellation's CSI drivers."}),"\n",(0,i.jsx)(t.h3,{id:"dm-crypt",children:"dm-crypt"}),"\n",(0,i.jsxs)(t.p,{children:["To interact with the dm-crypt kernel module, Constellation uses ",(0,i.jsx)(t.a,{href:"https://gitlab.com/cryptsetup/cryptsetup/",children:"libcryptsetup"}),".\nNew devices are formatted as ",(0,i.jsx)(t.a,{href:"https://gitlab.com/cryptsetup/LUKS2-docs/-/tree/master",children:"LUKS2"})," partitions with a sector size of 4096 bytes.\nThe used key derivation function is ",(0,i.jsx)(t.a,{href:"https://datatracker.ietf.org/doc/html/rfc9106",children:"Argon2id"})," with the ",(0,i.jsx)(t.a,{href:"https://datatracker.ietf.org/doc/html/rfc9106#section-7.4",children:"recommended parameters for memory-constrained environments"})," of 3 iterations and 64 MiB of memory, utilizing 4 parallel threads.\nFor encryption Constellation uses AES in XTS-Plain64. The key size is 512 bit."]}),"\n",(0,i.jsx)(t.h3,{id:"dm-integrity",children:"dm-integrity"}),"\n",(0,i.jsxs)(t.p,{children:["To interact with the dm-integrity kernel module, Constellation uses ",(0,i.jsx)(t.a,{href:"https://gitlab.com/cryptsetup/cryptsetup/",children:"libcryptsetup"}),".\nWhen enabled, the used data integrity algorithm is ",(0,i.jsx)(t.a,{href:"https://datatracker.ietf.org/doc/html/rfc2104",children:"HMAC"})," with SHA256 as the hash function.\nThe tag size is 32 Bytes."]}),"\n",(0,i.jsx)(t.h2,{id:"encrypted-s3-object-storage",children:"Encrypted S3 object storage"}),"\n",(0,i.jsxs)(t.p,{children:["Constellation comes with a service that you can use to transparently retrofit client-side encryption to existing applications that use S3 (AWS or compatible) for storage.\nTo learn more, check out the ",(0,i.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/s3proxy",children:"s3proxy documentation"}),"."]})]})}function p(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/e12b18ba.4cd83c4c.js b/pr-preview/pr-4027/assets/js/e12b18ba.4cd83c4c.js deleted file mode 100644 index f2afdf37e..000000000 --- a/pr-preview/pr-4027/assets/js/e12b18ba.4cd83c4c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[6065],{28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>i});var o=s(96540);const t={},r=o.createContext(t);function a(e){const n=o.useContext(r);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),o.createElement(r.Provider,{value:n},e.children)}},72309:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"workflows/lb","title":"Expose a service","description":"Constellation integrates the native load balancers of each CSP. Therefore, to expose a service simply create a service of type LoadBalancer.","source":"@site/versioned_docs/version-2.23/workflows/lb.md","sourceDirName":"workflows","slug":"/workflows/lb","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/lb","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/workflows/lb.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Upgrade your cluster","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/upgrade"},"next":{"title":"Install cert-manager","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/cert-manager"}}');var t=s(74848),r=s(28453);const a={},i="Expose a service",c={},l=[{value:"Internet-facing LB service on AWS",id:"internet-facing-lb-service-on-aws",level:2},{value:"Ingress on AWS",id:"ingress-on-aws",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"expose-a-service",children:"Expose a service"})}),"\n",(0,t.jsxs)(n.p,{children:["Constellation integrates the native load balancers of each CSP. Therefore, to expose a service simply ",(0,t.jsxs)(n.a,{href:"https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer",children:["create a service of type ",(0,t.jsx)(n.code,{children:"LoadBalancer"})]}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"internet-facing-lb-service-on-aws",children:"Internet-facing LB service on AWS"}),"\n",(0,t.jsxs)(n.p,{children:["To expose your application service externally you might want to use a Kubernetes Service of type ",(0,t.jsx)(n.code,{children:"LoadBalancer"}),". On AWS, load-balancing is achieved through the ",(0,t.jsx)(n.a,{href:"https://kubernetes-sigs.github.io/aws-load-balancer-controller",children:"AWS Load Balancer Controller"})," as in the managed EKS."]}),"\n",(0,t.jsxs)(n.p,{children:["Since recent versions, the controller deploy an internal LB by default requiring to set an annotation ",(0,t.jsx)(n.code,{children:"service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing"})," to have an internet-facing LB. For more details, see the ",(0,t.jsx)(n.a,{href:"https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.7/guide/service/nlb/",children:"official docs"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["For general information on LB with AWS see ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/eks/latest/userguide/network-load-balancing.html",children:"Network load balancing on Amazon EKS"}),"."]}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsx)(n.p,{children:"Before terminating the cluster, all LB backed services should be deleted, so that the controller can cleanup the related resources."})}),"\n",(0,t.jsx)(n.h2,{id:"ingress-on-aws",children:"Ingress on AWS"}),"\n",(0,t.jsxs)(n.p,{children:["The AWS Load Balancer Controller also provisions ",(0,t.jsx)(n.code,{children:"Ingress"})," resources of class ",(0,t.jsx)(n.code,{children:"alb"}),".\nAWS Application Load Balancers (ALBs) can be configured with a ",(0,t.jsx)(n.a,{href:"https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.7/guide/ingress/annotations/#target-type",children:(0,t.jsx)(n.code,{children:"target-type"})}),".\nThe target type ",(0,t.jsx)(n.code,{children:"ip"})," requires using the EKS container network solution, which makes it incompatible with Constellation.\nIf a service can be exposed on a ",(0,t.jsx)(n.code,{children:"NodePort"}),", the target type ",(0,t.jsx)(n.code,{children:"instance"})," can be used."]}),"\n",(0,t.jsxs)(n.p,{children:["See ",(0,t.jsx)(n.a,{href:"https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html",children:"Application load balancing on Amazon EKS"})," for more information."]}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsx)(n.p,{children:"Ingress handlers backed by AWS ALBs reside outside the Constellation cluster, so they shouldn't be handling sensitive traffic!"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/e19825b3.868862f3.js b/pr-preview/pr-4027/assets/js/e19825b3.868862f3.js deleted file mode 100644 index fb2332a66..000000000 --- a/pr-preview/pr-4027/assets/js/e19825b3.868862f3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7284],{12927:(e,s,i)=>{i.r(s),i.d(s,{assets:()=>d,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"workflows/reproducible-builds","title":"Reproduce released artifacts","description":"Constellation has first-class support for reproducible builds.","source":"@site/versioned_docs/version-2.22/workflows/reproducible-builds.md","sourceDirName":"workflows","slug":"/workflows/reproducible-builds","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/reproducible-builds","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/workflows/reproducible-builds.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"Consume SBOMs","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/sbom"},"next":{"title":"Troubleshooting","permalink":"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting"}}');var r=i(74848),t=i(28453);const o={},l="Reproduce released artifacts",d={},c=[{value:"Build environment prerequisites",id:"build-environment-prerequisites",level:2},{value:"Run the build",id:"run-the-build",level:2},{value:"Feedback",id:"feedback",level:2}];function a(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"reproduce-released-artifacts",children:"Reproduce released artifacts"})}),"\n",(0,r.jsxs)(s.p,{children:["Constellation has first-class support for ",(0,r.jsx)(s.a,{href:"https://reproducible-builds.org",children:"reproducible builds"}),".\nReproducing the released artifacts is an alternative to ",(0,r.jsx)(s.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli",children:"signature verification"})," that doesn't require trusting Edgeless Systems' release process.\nThe following sections describe how to rebuild an artifact and how Constellation ensures that the rebuild reproduces the artifacts bit-by-bit."]}),"\n",(0,r.jsx)(s.h2,{id:"build-environment-prerequisites",children:"Build environment prerequisites"}),"\n",(0,r.jsxs)(s.p,{children:["The build systems used by Constellation - ",(0,r.jsx)(s.a,{href:"https://bazel.build/",children:"Bazel"})," and ",(0,r.jsx)(s.a,{href:"https://nixos.org",children:"Nix"})," - are designed for deterministic, reproducible builds.\nThese two dependencies should be the only prerequisites for a successful build.\nHowever, it can't be ruled out completely that peculiarities of the host affect the build result.\nThus, we recommend the following host setup for best results:"]}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsx)(s.li,{children:"A Linux operating system not older than v5.4."}),"\n",(0,r.jsxs)(s.li,{children:["The GNU C library not older than v2.31 (avoid ",(0,r.jsx)(s.code,{children:"musl"}),")."]}),"\n",(0,r.jsxs)(s.li,{children:["GNU ",(0,r.jsx)(s.code,{children:"coreutils"})," not older than v8.30 (avoid ",(0,r.jsx)(s.code,{children:"busybox"}),")."]}),"\n",(0,r.jsxs)(s.li,{children:["An ",(0,r.jsx)(s.code,{children:"ext4"})," filesystem for building."]}),"\n",(0,r.jsx)(s.li,{children:"AppArmor turned off."}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"This is given, for example, on an Ubuntu 22.04 system, which is also used for reproducibility tests."}),"\n",(0,r.jsx)(s.admonition,{type:"note",children:(0,r.jsx)(s.p,{children:"To avoid any backwards-compatibility issues, the host software versions should also not be much newer than the Constellation release."})}),"\n",(0,r.jsx)(s.h2,{id:"run-the-build",children:"Run the build"}),"\n",(0,r.jsxs)(s.p,{children:["The following instructions outline qualitatively how to reproduce a build.\nConstellation implements these instructions in the ",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/actions/workflows/reproducible-builds.yml",children:"Reproducible Builds workflow"}),", which continuously tests for reproducibility.\nThe workflow is a good place to look up specific version numbers and build steps."]}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Check out the Constellation repository at the tag corresponding to the release."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"git clone https://github.com/edgelesssys/constellation.git\ncd constellation\ngit checkout v2.20.0\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"https://bazel.build/install",children:"Install the Bazel release"})," specified in ",(0,r.jsx)(s.code,{children:".bazelversion"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"https://nixos.org/download/",children:"Install Nix"})," (any recent version should do)."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["Run the build with ",(0,r.jsx)(s.code,{children:"bazel build $target"})," for one of the following targets of interest:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-data",children:"//cli:cli_enterprise_darwin_amd64\n//cli:cli_enterprise_darwin_arm64\n//cli:cli_enterprise_linux_amd64\n//cli:cli_enterprise_linux_arm64\n//cli:cli_enterprise_windows_amd64\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Compare the build result with the downloaded release artifact."}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"feedback",children:"Feedback"}),"\n",(0,r.jsxs)(s.p,{children:["Reproduction failures often indicate a bug in the build system or in the build definitions.\nTherefore, we're interested in any reproducibility issues you might encounter.\n",(0,r.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/issues/new/choose",children:"Start a bug report"})," and describe the details of your build environment.\nMake sure to include your result binary or a ",(0,r.jsx)(s.a,{href:"https://diffoscope.org/",children:(0,r.jsx)(s.code,{children:"diffoscope"})})," report, if possible."]})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},28453:(e,s,i)=>{i.d(s,{R:()=>o,x:()=>l});var n=i(96540);const r={},t=n.createContext(r);function o(e){const s=n.useContext(t);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/e344aa3d.4b5c7ca5.js b/pr-preview/pr-4027/assets/js/e344aa3d.4b5c7ca5.js deleted file mode 100644 index eaf821401..000000000 --- a/pr-preview/pr-4027/assets/js/e344aa3d.4b5c7ca5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3884],{28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}},56465:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"overview/clouds","title":"Feature status of clouds","description":"What works on which cloud? Currently, Confidential VMs (CVMs) are available in varying quality on the different clouds and software stacks.","source":"@site/versioned_docs/version-2.23/overview/clouds.md","sourceDirName":"overview","slug":"/overview/clouds","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/clouds","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/overview/clouds.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Product features","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/product"},"next":{"title":"Performance analysis of Constellation","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/performance/"}}');var r=n(74848),i=n(28453);const o={},a="Feature status of clouds",l={},d=[{value:"Amazon Web Services (AWS)",id:"amazon-web-services-aws",level:2},{value:"Microsoft Azure",id:"microsoft-azure",level:2},{value:"Google Cloud Platform (GCP)",id:"google-cloud-platform-gcp",level:2},{value:"STACKIT",id:"stackit",level:2},{value:"OpenStack",id:"openstack",level:2},{value:"Conclusion",id:"conclusion",level:2}];function c(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"feature-status-of-clouds",children:"Feature status of clouds"})}),"\n",(0,r.jsx)(t.p,{children:"What works on which cloud? Currently, Confidential VMs (CVMs) are available in varying quality on the different clouds and software stacks."}),"\n",(0,r.jsx)(t.p,{children:"For Constellation, the ideal environment provides the following:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"Ability to run arbitrary software and images inside CVMs"}),"\n",(0,r.jsx)(t.li,{children:"CVMs based on AMD SEV-SNP (available in EPYC CPUs since the Milan generation) or Intel TDX (available in Xeon CPUs since the Sapphire Rapids generation)"}),"\n",(0,r.jsx)(t.li,{children:"Ability for CVM guests to obtain raw hardware attestation statements"}),"\n",(0,r.jsx)(t.li,{children:"Reviewable, open-source firmware inside CVMs"}),"\n",(0,r.jsx)(t.li,{children:"Capability of the firmware to attest the integrity of the code it passes control to, e.g., with an embedded virtual TPM (vTPM)"}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"(1) is a functional must-have. (2)--(5) are required for remote attestation that fully keeps the infrastructure/cloud out. Constellation can work without them or with approximations, but won't protect against certain privileged attackers anymore."}),"\n",(0,r.jsx)(t.p,{children:"The following table summarizes the state of features for different infrastructures."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"Feature"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"AWS"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"Azure"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"GCP"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"STACKIT"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"OpenStack (Yoga)"})})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"1. Custom images"})}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"2. SEV-SNP or TDX"})}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Depends on kernel/HV"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"3. Raw guest attestation"})}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Depends on kernel/HV"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"4. Reviewable firmware"})}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"No*"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Depends on kernel/HV"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"5. Confidential measured boot"})}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Depends on kernel/HV"})]})]})]}),"\n",(0,r.jsx)(t.h2,{id:"amazon-web-services-aws",children:"Amazon Web Services (AWS)"}),"\n",(0,r.jsxs)(t.p,{children:["Amazon EC2 ",(0,r.jsx)(t.a,{href:"https://aws.amazon.com/de/about-aws/whats-new/2023/04/amazon-ec2-amd-sev-snp/",children:"supports AMD SEV-SNP"}),".\nRegarding (3), AWS provides direct access to attestation statements.\nHowever, regarding (5), attestation is partially based on the ",(0,r.jsx)(t.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nitrotpm.html",children:"NitroTPM"})," for ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation#measured-boot",children:"measured boot"}),", which is a vTPM managed by the Nitro hypervisor.\nHence, the hypervisor is currently part of Constellation's TCB.\nRegarding (4), the ",(0,r.jsx)(t.a,{href:"https://github.com/aws/uefi",children:"firmware is open source"})," and can be reproducibly built."]}),"\n",(0,r.jsx)(t.h2,{id:"microsoft-azure",children:"Microsoft Azure"}),"\n",(0,r.jsxs)(t.p,{children:["With its ",(0,r.jsx)(t.a,{href:"https://docs.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview",children:"CVM offering"}),", Azure provides the best foundations for Constellation.\nRegarding (3), Azure provides direct access to attestation statements.\nThe firmware runs in an isolated domain inside the CVM and exposes a vTPM (5), but it's closed source (4).\nOn SEV-SNP, Azure uses VM Privilege Level (VMPL) isolation for the separation of firmware and the rest of the VM; on TDX, they use TD partitioning.\nThis firmware is signed by Azure.\nThe signature is reflected in the attestation statements of CVMs.\nThus, the Azure closed-source firmware becomes part of Constellation's trusted computing base (TCB)."]}),"\n",(0,r.jsxs)(t.p,{children:["* Recently, ",(0,r.jsx)(t.a,{href:"https://techcommunity.microsoft.com/blog/windowsosplatform/openhcl-the-new-open-source-paravisor/4273172",children:"Azure announced the open source paravisor OpenHCL"}),". It's the foundation for fully open source and verifiable CVM firmware. Once Azure provides their CVM firmware with reproducible builds based on OpenHCL, (4) switches from ",(0,r.jsx)(t.em,{children:"No"})," to ",(0,r.jsx)(t.em,{children:"Yes"}),". Constellation will support OpenHCL based firmware on Azure in the future."]}),"\n",(0,r.jsx)(t.h2,{id:"google-cloud-platform-gcp",children:"Google Cloud Platform (GCP)"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"https://cloud.google.com/confidential-computing/confidential-vm/docs/confidential-vm-overview#technologies",children:"CVMs Generally Available in GCP"})," are based on AMD SEV-ES or SEV-SNP.\nRegarding (3), with their SEV-SNP offering Google provides direct access to attestation statements.\nHowever, regarding (5), attestation is partially based on the ",(0,r.jsx)(t.a,{href:"https://cloud.google.com/compute/shielded-vm/docs/shielded-vm#vtpm",children:"Shielded VM vTPM"})," for ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation#measured-boot",children:"measured boot"}),", which is a vTPM managed by Google's hypervisor.\nHence, the hypervisor is currently part of Constellation's TCB.\nRegarding (4), the CVMs still include closed-source firmware."]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://cloud.google.com/blog/products/identity-security/confidential-vms-on-intel-cpus-your-datas-new-intelligent-defense",children:"TDX on Google"})," is in public preview.\nWith it, Constellation would have a similar TCB and attestation flow as with the current SEV-SNP offering."]}),"\n",(0,r.jsx)(t.h2,{id:"stackit",children:"STACKIT"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://www.stackit.de/en/product/stackit-compute-engine/",children:"STACKIT Compute Engine"})," supports AMD SEV-ES. A vTPM is used for measured boot, which is a vTPM managed by STACKIT's hypervisor. Hence, the hypervisor is currently part of Constellation's TCB."]}),"\n",(0,r.jsx)(t.h2,{id:"openstack",children:"OpenStack"}),"\n",(0,r.jsxs)(t.p,{children:["OpenStack is an open-source cloud and infrastructure management software. It's used by many smaller CSPs and datacenters. In the latest ",(0,r.jsx)(t.em,{children:"Yoga"})," version, OpenStack has basic support for CVMs. However, much depends on the employed kernel and hypervisor. Features (2)--(4) are likely to be a ",(0,r.jsx)(t.em,{children:"Yes"})," with Linux kernel version 6.2. Thus, going forward, OpenStack on corresponding AMD or Intel hardware will be a viable underpinning for Constellation."]}),"\n",(0,r.jsx)(t.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,r.jsx)(t.p,{children:"The different clouds and software like the Linux kernel and OpenStack are in the process of building out their support for state-of-the-art CVMs. Azure has already most features in place. For Constellation, the status quo means that the TCB has different shapes on different infrastructures. With broad SEV-SNP support coming to the Linux kernel, we soon expect a normalization of features across infrastructures."})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/e61948c8.95e47401.js b/pr-preview/pr-4027/assets/js/e61948c8.95e47401.js deleted file mode 100644 index 94558fabb..000000000 --- a/pr-preview/pr-4027/assets/js/e61948c8.95e47401.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9341],{26058:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"getting-started/examples/horizontal-scaling","title":"Horizontal Pod Autoscaling","description":"This example demonstrates Constellation\'s autoscaling capabilities. It\'s based on the Kubernetes HorizontalPodAutoscaler Walkthrough. During the following steps, Constellation will spawn new VMs on demand, verify them, add them to the cluster, and delete them again when the load has settled down.","source":"@site/docs/getting-started/examples/horizontal-scaling.md","sourceDirName":"getting-started/examples","slug":"/getting-started/examples/horizontal-scaling","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/examples/horizontal-scaling","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/getting-started/examples/horizontal-scaling.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Online Boutique","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/examples/online-boutique"},"next":{"title":"Filestash with s3proxy","permalink":"/constellation/pr-preview/pr-4027/next/getting-started/examples/filestash-s3proxy"}}');var a=t(74848),o=t(28453);const i={},r="Horizontal Pod Autoscaling",l={},c=[{value:"Requirements",id:"requirements",level:2},{value:"Setup",id:"setup",level:2},{value:"Monitoring",id:"monitoring",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"horizontal-pod-autoscaling",children:"Horizontal Pod Autoscaling"})}),"\n",(0,a.jsxs)(n.p,{children:["This example demonstrates Constellation's autoscaling capabilities. It's based on the Kubernetes ",(0,a.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/",children:"HorizontalPodAutoscaler Walkthrough"}),". During the following steps, Constellation will spawn new VMs on demand, verify them, add them to the cluster, and delete them again when the load has settled down."]}),"\n",(0,a.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,a.jsxs)(n.p,{children:["The cluster needs to be initialized with Kubernetes 1.23 or later. In addition, ",(0,a.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/scale",children:"autoscaling must be enabled"})," to enable Constellation to assign new nodes dynamically."]}),"\n",(0,a.jsxs)(n.p,{children:["Just for this example specifically, the cluster should have as few worker nodes in the beginning as possible. Start with a small cluster with only ",(0,a.jsx)(n.em,{children:"one"})," low-powered node for the control-plane node and ",(0,a.jsx)(n.em,{children:"one"})," low-powered worker node."]}),"\n",(0,a.jsx)(n.admonition,{type:"info",children:(0,a.jsxs)(n.p,{children:["We tested the example using instances of types ",(0,a.jsx)(n.code,{children:"Standard_DC4as_v5"})," on Azure and ",(0,a.jsx)(n.code,{children:"n2d-standard-4"})," on GCP."]})}),"\n",(0,a.jsx)(n.h2,{id:"setup",children:"Setup"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Install the Kubernetes Metrics Server:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Deploy the HPA example server that's supposed to be scaled under load."}),"\n",(0,a.jsx)(n.p,{children:"This manifest is similar to the one from the Kubernetes HPA walkthrough, but with increased CPU limits and requests to facilitate the triggering of node scaling events."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cat <<EOF | kubectl apply -f -\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: php-apache\nspec:\n selector:\n matchLabels:\n run: php-apache\n replicas: 1\n template:\n metadata:\n labels:\n run: php-apache\n spec:\n containers:\n - name: php-apache\n image: registry.k8s.io/hpa-example\n ports:\n - containerPort: 80\n resources:\n limits:\n cpu: 900m\n requests:\n cpu: 600m\n---\napiVersion: v1\nkind: Service\nmetadata:\n name: php-apache\n labels:\n run: php-apache\nspec:\n ports:\n - port: 80\n selector:\n run: php-apache\nEOF\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Create a HorizontalPodAutoscaler."}),"\n",(0,a.jsxs)(n.p,{children:["Set an average CPU usage across all Pods of 20% to see one additional worker node being created later. Note that the CPU usage isn't related to the host CPU usage, but rather to the requested CPU capacities (20% of 600 milli-cores CPU across all Pods). See the ",(0,a.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#create-horizontal-pod-autoscaler",children:"original tutorial"})," for more information on the HPA configuration."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl autoscale deployment php-apache --cpu-percent=20 --min=1 --max=10\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Create a Pod that generates load on the server:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while true; do wget -q -O- http://php-apache; done"\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["Wait a few minutes until new nodes are added to the cluster. You can ",(0,a.jsx)(n.a,{href:"#monitoring",children:"monitor"})," the state of the HorizontalPodAutoscaler, the list of nodes, and the behavior of the autoscaler."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"To stop the load generator, press CTRL+C and run:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl delete pod load-generator\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"The cluster-autoscaler checks every few minutes if nodes are underutilized. It will taint such candidates for removal and wait additional 10 minutes before the nodes are eventually removed and deallocated. The whole process can take about 20 minutes."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"monitoring",children:"Monitoring"}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsx)(n.p,{children:"For better observability, run the listed commands in different tabs in your terminal."})}),"\n",(0,a.jsx)(n.p,{children:"You can watch the status of the HorizontalPodAutoscaler with the current CPU usage, the target CPU limit, and the number of replicas created with:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl get hpa php-apache --watch\n"})}),"\n",(0,a.jsx)(n.p,{children:"From time to time compare the list of nodes to check the behavior of the autoscaler:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl get nodes\n"})}),"\n",(0,a.jsx)(n.p,{children:"For deeper insights, see the logs of the autoscaler Pod, which contains more details about the scaling decision process:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl logs -f deployment/constellation-cluster-autoscaler -n kube-system\n"})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>r});var s=t(96540);const a={},o=s.createContext(a);function i(e){const n=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/e7c02e82.81e18f1c.js b/pr-preview/pr-4027/assets/js/e7c02e82.81e18f1c.js deleted file mode 100644 index ffb6ee8c3..000000000 --- a/pr-preview/pr-4027/assets/js/e7c02e82.81e18f1c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3939],{28453:(e,n,o)=>{o.d(n,{R:()=>i,x:()=>s});var r=o(96540);const t={},a=r.createContext(t);function i(e){const n=r.useContext(a);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),r.createElement(a.Provider,{value:n},e.children)}},91015:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>m,frontMatter:()=>i,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"overview/performance/compute","title":"Impact of runtime encryption on compute performance","description":"All nodes in a Constellation cluster are executed inside Confidential VMs (CVMs). Consequently, the performance of Constellation is inherently linked to the performance of these CVMs.","source":"@site/versioned_docs/version-2.23/overview/performance/compute.md","sourceDirName":"overview/performance","slug":"/overview/performance/compute","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/performance/compute","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/overview/performance/compute.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Performance analysis of Constellation","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/performance/"},"next":{"title":"I/O benchmarks","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/performance/io"}}');var t=o(74848),a=o(28453);const i={},s="Impact of runtime encryption on compute performance",c={},l=[{value:"AMD and Azure benchmarking",id:"amd-and-azure-benchmarking",level:2},{value:"AMD and Google benchmarking",id:"amd-and-google-benchmarking",level:2}];function d(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"impact-of-runtime-encryption-on-compute-performance",children:"Impact of runtime encryption on compute performance"})}),"\n",(0,t.jsx)(n.p,{children:"All nodes in a Constellation cluster are executed inside Confidential VMs (CVMs). Consequently, the performance of Constellation is inherently linked to the performance of these CVMs."}),"\n",(0,t.jsx)(n.h2,{id:"amd-and-azure-benchmarking",children:"AMD and Azure benchmarking"}),"\n",(0,t.jsxs)(n.p,{children:["AMD and Azure have collectively released a ",(0,t.jsx)(n.a,{href:"https://community.amd.com/t5/business/microsoft-azure-confidential-computing-powered-by-3rd-gen-epyc/ba-p/497796",children:"performance benchmark"})," for CVMs that utilize 3rd Gen AMD EPYC processors (Milan) with SEV-SNP. This benchmark, which included a variety of mostly compute-intensive tests such as SPEC CPU 2017 and CoreMark, demonstrated that CVMs experience only minor performance degradation (ranging from 2% to 8%) when compared to standard VMs. Such results are indicative of the performance that can be expected from compute-intensive workloads running with Constellation on Azure."]}),"\n",(0,t.jsx)(n.h2,{id:"amd-and-google-benchmarking",children:"AMD and Google benchmarking"}),"\n",(0,t.jsxs)(n.p,{children:["Similarly, AMD and Google have jointly released a ",(0,t.jsx)(n.a,{href:"https://www.amd.com/system/files/documents/3rd-gen-epyc-gcp-c2d-conf-compute-perf-brief.pdf",children:"performance benchmark"})," for CVMs employing 3rd Gen AMD EPYC processors (Milan) with SEV-SNP. With high-performance computing workloads such as WRF, NAMD, Ansys CFS, and Ansys LS_DYNA, they observed analogous findings, with only minor performance degradation (between 2% and 4%) compared to standard VMs. These outcomes are reflective of the performance that can be expected for compute-intensive workloads running with Constellation on GCP."]})]})}function m(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/e8feb497.3097bda1.js b/pr-preview/pr-4027/assets/js/e8feb497.3097bda1.js deleted file mode 100644 index cbb324242..000000000 --- a/pr-preview/pr-4027/assets/js/e8feb497.3097bda1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9673],{28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>a});var t=s(96540);const i={},o=t.createContext(i);function r(e){const n=t.useContext(o);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),t.createElement(o.Provider,{value:n},e.children)}},83158:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"workflows/troubleshooting","title":"Troubleshooting","description":"This section aids you in finding problems when working with Constellation.","source":"@site/versioned_docs/version-2.23/workflows/troubleshooting.md","sourceDirName":"workflows","slug":"/workflows/troubleshooting","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/troubleshooting","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/workflows/troubleshooting.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Reproduce release artifacts","permalink":"/constellation/pr-preview/pr-4027/2.23/workflows/reproducible-builds"},"next":{"title":"Architecture","permalink":"/constellation/pr-preview/pr-4027/2.23/category/architecture"}}');var i=s(74848),o=s(28453);const r={},a="Troubleshooting",l={},c=[{value:"Common issues",id:"common-issues",level:2},{value:"Issues with creating new clusters",id:"issues-with-creating-new-clusters",level:3},{value:"Azure: Resource Providers can't be registered",id:"azure-resource-providers-cant-be-registered",level:3},{value:"Azure: Can't update attestation policy",id:"azure-cant-update-attestation-policy",level:3},{value:"Nodes fail to join with error <code>untrusted measurement value</code>",id:"nodes-fail-to-join-with-error-untrusted-measurement-value",level:3},{value:"Upgrading Kubernetes resources fails",id:"upgrading-kubernetes-resources-fails",level:3},{value:"Diagnosing issues",id:"diagnosing-issues",level:2},{value:"Logs",id:"logs",level:3},{value:"Node shell access",id:"node-shell-access",level:3},{value:"Emergency SSH access",id:"emergency-ssh-access",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"troubleshooting",children:"Troubleshooting"})}),"\n",(0,i.jsx)(n.p,{children:"This section aids you in finding problems when working with Constellation."}),"\n",(0,i.jsx)(n.h2,{id:"common-issues",children:"Common issues"}),"\n",(0,i.jsx)(n.h3,{id:"issues-with-creating-new-clusters",children:"Issues with creating new clusters"}),"\n",(0,i.jsxs)(n.p,{children:["When you create a new cluster, you should always use the ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/releases/latest",children:"latest release"}),".\nIf something doesn't work, check out the ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"known issues"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"azure-resource-providers-cant-be-registered",children:"Azure: Resource Providers can't be registered"}),"\n",(0,i.jsxs)(n.p,{children:["On Azure, you may receive the following error when running ",(0,i.jsx)(n.code,{children:"apply"})," or ",(0,i.jsx)(n.code,{children:"terminate"})," with limited IAM permissions:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell-session",children:"Error: Error ensuring Resource Providers are registered.\n\nTerraform automatically attempts to register the Resource Providers it supports to\nensure it's able to provision resources.\n\nIf you don't have permission to register Resource Providers you may wish to use the\n\"skip_provider_registration\" flag in the Provider block to disable this functionality.\n\n[...]\n"})}),"\n",(0,i.jsxs)(n.p,{children:["To continue, please ensure that the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/install#required-permissions",children:"required resource providers"})," have been registered in your subscription by your administrator."]}),"\n",(0,i.jsxs)(n.p,{children:["Afterward, set ",(0,i.jsx)(n.code,{children:"ARM_SKIP_PROVIDER_REGISTRATION=true"})," as an environment variable and either run ",(0,i.jsx)(n.code,{children:"apply"})," or ",(0,i.jsx)(n.code,{children:"terminate"})," again.\nFor example:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"ARM_SKIP_PROVIDER_REGISTRATION=true constellation apply\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Or alternatively, for ",(0,i.jsx)(n.code,{children:"terminate"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"ARM_SKIP_PROVIDER_REGISTRATION=true constellation terminate\n"})}),"\n",(0,i.jsx)(n.h3,{id:"azure-cant-update-attestation-policy",children:"Azure: Can't update attestation policy"}),"\n",(0,i.jsxs)(n.p,{children:["On Azure, you may receive the following error when running ",(0,i.jsx)(n.code,{children:"apply"})," from within an Azure environment, e.g., an Azure VM:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell-session",children:"An error occurred: patching policies: updating attestation policy: unexpected status code: 403 Forbidden\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The problem occurs because the Azure SDK we use internally attempts to ",(0,i.jsx)(n.a,{href:"https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#DefaultAzureCredential",children:"authenticate towards the Azure API with the managed identity of your current environment instead of the Azure CLI token"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"We decided not to deviate from this behavior and comply with the ordering of credentials."}),"\n",(0,i.jsxs)(n.p,{children:["A solution is to add the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/getting-started/install#required-permissions",children:"required permissions"})," to the managed identity of your environment. For example, the managed identity of your Azure VM, instead of the account that you've authenticated with in the Azure CLI."]}),"\n",(0,i.jsx)(n.p,{children:"If your setup requires a change in the ordering of credentials, please open an issue and explain your desired behavior."}),"\n",(0,i.jsxs)(n.h3,{id:"nodes-fail-to-join-with-error-untrusted-measurement-value",children:["Nodes fail to join with error ",(0,i.jsx)(n.code,{children:"untrusted measurement value"})]}),"\n",(0,i.jsxs)(n.p,{children:["This error indicates that a node's ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation",children:"attestation statement"})," contains measurements that don't match the trusted values expected by the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#joinservice",children:"JoinService"}),".\nThis may for example happen if the cloud provider updates the VM's firmware such that it influences the ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation#runtime-measurements",children:"runtime measurements"})," in an unforeseen way.\nA failed upgrade due to an erroneous attestation config can also cause this error.\nYou can change the expected measurements to resolve the failure."]}),"\n",(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsxs)(n.p,{children:["Attestation and trusted measurements are crucial for the security of your cluster.\nBe extra careful when manually changing these settings.\nWhen in doubt, check if the encountered ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"issue is known"})," or ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation#support",children:"contact support"}),"."]})}),"\n",(0,i.jsxs)(n.admonition,{type:"tip",children:[(0,i.jsxs)(n.p,{children:["During an upgrade with modified attestation config, a backup of the current configuration is stored in the ",(0,i.jsx)(n.code,{children:"join-config"})," config map in the ",(0,i.jsx)(n.code,{children:"kube-system"})," namespace under the ",(0,i.jsx)(n.code,{children:"attestationConfig_backup"})," key. To restore the old attestation config after a failed upgrade, replace the value of ",(0,i.jsx)(n.code,{children:"attestationConfig"})," with the value from ",(0,i.jsx)(n.code,{children:"attestationConfig_backup"}),":"]}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'kubectl patch configmaps -n kube-system join-config -p "{\\"data\\":{\\"attestationConfig\\":\\"$(kubectl get configmaps -n kube-system join-config -o "jsonpath={.data.attestationConfig_backup}")\\"}}"\n'})})]}),"\n",(0,i.jsxs)(n.p,{children:["You can use the ",(0,i.jsx)(n.code,{children:"apply"})," command to change measurements of a running cluster:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Modify the ",(0,i.jsx)(n.code,{children:"measurements"})," key in your local ",(0,i.jsx)(n.code,{children:"constellation-conf.yaml"})," to the expected values."]}),"\n",(0,i.jsxs)(n.li,{children:["Run ",(0,i.jsx)(n.code,{children:"constellation apply"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Keep in mind that running ",(0,i.jsx)(n.code,{children:"apply"})," also applies any version changes from your config to the cluster."]}),"\n",(0,i.jsx)(n.p,{children:"You can run these commands to learn about the versions currently configured in the cluster:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Kubernetes API server version: ",(0,i.jsx)(n.code,{children:"kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.kubernetesClusterVersion"})]}),"\n",(0,i.jsxs)(n.li,{children:["image version: ",(0,i.jsx)(n.code,{children:"kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.imageVersion"})]}),"\n",(0,i.jsxs)(n.li,{children:["microservices versions: ",(0,i.jsx)(n.code,{children:"helm list --filter 'constellation-services' -n kube-system"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"upgrading-kubernetes-resources-fails",children:"Upgrading Kubernetes resources fails"}),"\n",(0,i.jsxs)(n.p,{children:["Constellation manages its Kubernetes resources using Helm.\nWhen applying an upgrade, the charts that are about to be installed, and a values override file ",(0,i.jsx)(n.code,{children:"overrides.yaml"}),",\nare saved to disk in your current workspace under ",(0,i.jsx)(n.code,{children:"constellation-upgrade/upgrade-<timestamp>/helm-charts/"}),".\nIf upgrading the charts using the Constellation CLI fails, you can review these charts and try to manually apply the upgrade."]}),"\n",(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsxs)(n.p,{children:["Changing and manually applying the charts may destroy cluster resources and can lead to broken Constellation deployments.\nProceed with caution and when in doubt,\ncheck if the encountered ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22",children:"issue is known"})," or ",(0,i.jsx)(n.a,{href:"https://github.com/edgelesssys/constellation#support",children:"contact support"}),"."]})}),"\n",(0,i.jsx)(n.h2,{id:"diagnosing-issues",children:"Diagnosing issues"}),"\n",(0,i.jsx)(n.h3,{id:"logs",children:"Logs"}),"\n",(0,i.jsxs)(n.p,{children:["To get started on diagnosing issues with Constellation, it's often helpful to collect logs from nodes, pods, or other resources in the cluster. Most logs are available through Kubernetes' standard\n",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/logging/",children:"logging interfaces"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"To debug issues occurring at boot time of the nodes, you can use the serial console interface of the CSP while the machine boots to get a read-only view of the boot logs."}),"\n",(0,i.jsxs)(n.p,{children:["Apart from that, Constellation also offers further ",(0,i.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/observability",children:"observability integrations"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"node-shell-access",children:"Node shell access"}),"\n",(0,i.jsxs)(n.p,{children:["Debugging via a shell on a node is ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/debug/debug-application/debug-running-pod/#node-shell-session",children:"directly supported by Kubernetes"}),"."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Figure out which node to connect to:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl get nodes\n# or to see more information, such as IPs:\nkubectl get nodes -o wide\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Connect to the node:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl debug node/constell-worker-xksa0-000000 -it --image=busybox\n"})}),"\n",(0,i.jsx)(n.p,{children:"You will be presented with a prompt."}),"\n",(0,i.jsxs)(n.p,{children:["The nodes file system is mounted at ",(0,i.jsx)(n.code,{children:"/host"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Once finished, clean up the debug pod:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl delete pod node-debugger-constell-worker-xksa0-000000-bjthj\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"emergency-ssh-access",children:"Emergency SSH access"}),"\n",(0,i.jsx)(n.p,{children:"Emergency SSH access to nodes can be useful to diagnose issues or download important data even if the Kubernetes API isn't reachable anymore."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Enter the ",(0,i.jsx)(n.code,{children:"constellation-terraform"})," directory in your Constellation workspace and enable emergency SSH access to the cluster:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:' cd constellation-terraform\n echo "emergency_ssh = true" >> ./terraform.tfvars\n terraform apply\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Sign an existing SSH key with your master secret:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd ../ # go back to your Constellation workspace\nconstellation ssh --key your_public_key.pub\n"})}),"\n",(0,i.jsxs)(n.p,{children:["A certificate is written to ",(0,i.jsx)(n.code,{children:"constellation_cert.pub"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The certificate is valid for 24 hours and enables you to access your Constellation nodes using\n",(0,i.jsx)(n.a,{href:"https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Certificate-based_Authentication",children:"certificate based authentication"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Now you can connect to any Constellation node using your certificate and your private key."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"ssh -o CertificateFile=constellation_cert.pub -i <your private key> root@<ip of constellation node>\n"})}),"\n",(0,i.jsx)(n.p,{children:"Normally, you don't have access to the Constellation nodes since they reside in a private network.\nTo access those nodes anyways, you can use your Constellation load balancer as a proxy jump host.\nFor this, use something along the following SSH client configuration:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-text",children:"Host <LB domain name>\n ProxyJump none\n\nHost *\n IdentityFile <your private key>\n PreferredAuthentications publickey\n CertificateFile=constellation_cert.pub\n User root\n ProxyJump <LB domain name>\n"})}),"\n",(0,i.jsxs)(n.p,{children:["With this configuration you can connect to a Constellation node using ",(0,i.jsx)(n.code,{children:"ssh -F <this config> <private node IP>"}),".\nYou can obtain the private node IP and the domain name of the load balancer using your CSP's web UI."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/e91da414.45776acc.js b/pr-preview/pr-4027/assets/js/e91da414.45776acc.js deleted file mode 100644 index 09f185ff0..000000000 --- a/pr-preview/pr-4027/assets/js/e91da414.45776acc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1610],{16572:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"overview/product","title":"Product features","description":"Constellation is a Kubernetes engine that aims to provide the best possible data security in combination with enterprise-grade scalability and reliability features---and a smooth user experience.","source":"@site/versioned_docs/version-2.23/overview/product.md","sourceDirName":"overview","slug":"/overview/product","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/product","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/overview/product.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Security benefits","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/security-benefits"},"next":{"title":"Feature status of clouds","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/clouds"}}');var s=r(74848),n=r(28453);const i={},a="Product features",l={},c=[];function u(e){const t={a:"a",h1:"h1",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,n.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"product-features",children:"Product features"})}),"\n",(0,s.jsx)(t.p,{children:"Constellation is a Kubernetes engine that aims to provide the best possible data security in combination with enterprise-grade scalability and reliability features---and a smooth user experience."}),"\n",(0,s.jsxs)(t.p,{children:["From a security perspective, Constellation implements the ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/overview/confidential-kubernetes",children:"Confidential Kubernetes"})," concept and corresponding security features, which shield your entire cluster from the underlying infrastructure."]}),"\n",(0,s.jsx)(t.p,{children:"From an operational perspective, Constellation provides the following key features:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Native support for different clouds"}),": Constellation works on Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), and STACKIT. Support for OpenStack-based environments is coming with a future release. Constellation securely interfaces with the cloud infrastructure to provide ",(0,s.jsx)(t.a,{href:"https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler",children:"cluster autoscaling"}),", ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/storage/dynamic-provisioning/",children:"dynamic persistent volumes"}),", and ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer",children:"service load balancing"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"High availability"}),": Constellation uses a ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/",children:"multi-master architecture"})," with a ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/ha-topology/#stacked-etcd-topology",children:"stacked etcd topology"})," to ensure high availability."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Integrated Day-2 operations"}),": Constellation lets you securely ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/upgrade",children:"upgrade"})," your cluster to a new release. It also lets you securely ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/recovery",children:"recover"})," a failed cluster. Both with a single command."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Support for Terraform"}),": Constellation includes a ",(0,s.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/terraform-provider",children:"Terraform provider"})," that lets you manage the full lifecycle of your cluster via Terraform."]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>a});var o=r(96540);const s={},n=o.createContext(s);function i(e){const t=o.useContext(n);return o.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/e97075f3.f1e5a2f5.js b/pr-preview/pr-4027/assets/js/e97075f3.f1e5a2f5.js deleted file mode 100644 index 5b3bf6e15..000000000 --- a/pr-preview/pr-4027/assets/js/e97075f3.f1e5a2f5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[853],{1397:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"architecture/observability","title":"Observability","description":"In Kubernetes, observability is the ability to gain insight into the behavior and performance of applications.","source":"@site/versioned_docs/version-2.23/architecture/observability.md","sourceDirName":"architecture","slug":"/architecture/observability","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/observability","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/architecture/observability.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Networking","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/networking"},"next":{"title":"Reference","permalink":"/constellation/pr-preview/pr-4027/2.23/category/reference"}}');var n=s(74848),r=s(28453);const a={},o="Observability",l={},c=[{value:"Cloud resource monitoring",id:"cloud-resource-monitoring",level:2},{value:"Metrics",id:"metrics",level:2},{value:"Logs",id:"logs",level:2},{value:"System logs",id:"system-logs",level:3},{value:"Kubernetes logs",id:"kubernetes-logs",level:3},{value:"Traces",id:"traces",level:2},{value:"Integrations",id:"integrations",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"observability",children:"Observability"})}),"\n",(0,n.jsx)(t.p,{children:'In Kubernetes, observability is the ability to gain insight into the behavior and performance of applications.\nIt helps identify and resolve issues more effectively, ensuring stability and performance of Kubernetes workloads, reducing downtime and outages, and improving efficiency.\nThe "three pillars of observability" are logs, metrics, and traces.'}),"\n",(0,n.jsx)(t.p,{children:"In the context of Confidential Computing, observability is a delicate subject and needs to be applied such that it doesn't leak any sensitive information.\nThe following gives an overview of where and how you can apply standard observability tools in Constellation."}),"\n",(0,n.jsx)(t.h2,{id:"cloud-resource-monitoring",children:"Cloud resource monitoring"}),"\n",(0,n.jsx)(t.p,{children:"While inaccessible, Constellation's nodes are still visible as black box VMs to the hypervisor.\nResource consumption, such as memory and CPU utilization, can be monitored from the outside and observed via the cloud platforms directly.\nSimilarly, other resources, such as storage and network and their respective metrics, are visible via the cloud platform."}),"\n",(0,n.jsx)(t.h2,{id:"metrics",children:"Metrics"}),"\n",(0,n.jsx)(t.p,{children:"Metrics are numeric representations of data measured over intervals of time. They're essential for understanding system health and gaining insights using telemetry signals."}),"\n",(0,n.jsxs)(t.p,{children:["By default, Constellation exposes the ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/system-metrics/",children:"metrics for Kubernetes system components"})," inside the cluster.\nSimilarly, the ",(0,n.jsx)(t.a,{href:"https://etcd.io/docs/v3.5/metrics/",children:"etcd metrics"})," endpoints are exposed inside the cluster.\nThese ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/system-metrics/#disabling-metrics",children:"metrics endpoints can be disabled"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["You can collect these cluster-internal metrics via tools such as ",(0,n.jsx)(t.a,{href:"https://prometheus.io/",children:"Prometheus"})," or the ",(0,n.jsx)(t.a,{href:"https://www.elastic.co/de/elastic-stack/",children:"Elastic Stack"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["Constellation's CNI Cilium also supports ",(0,n.jsx)(t.a,{href:"https://docs.cilium.io/en/latest/observability/metrics/",children:"metrics via Prometheus endpoints"}),".\nHowever, in Constellation, they're disabled by default and must be enabled first."]}),"\n",(0,n.jsx)(t.h2,{id:"logs",children:"Logs"}),"\n",(0,n.jsx)(t.p,{children:"Logs represent discrete events that usually describe what's happening with your service.\nThe payload is an actual message emitted from your system along with a metadata section containing a timestamp, labels, and tracking identifiers."}),"\n",(0,n.jsx)(t.h3,{id:"system-logs",children:"System logs"}),"\n",(0,n.jsxs)(t.p,{children:["Detailed system-level logs are accessible via ",(0,n.jsx)(t.code,{children:"/var/log"})," and ",(0,n.jsx)(t.a,{href:"https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html",children:"journald"})," on the nodes directly.\nThey can be collected from there, for example, via ",(0,n.jsx)(t.a,{href:"https://www.elastic.co/guide/en/beats/filebeat/current/logstash-output.html",children:"Filebeat and Logstash"}),", which are tools of the ",(0,n.jsx)(t.a,{href:"https://www.elastic.co/de/elastic-stack/",children:"Elastic Stack"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["In case of an error during the initialization, the CLI automatically collects the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices#bootstrapper",children:"Bootstrapper"})," logs and returns these as a file for ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/troubleshooting",children:"troubleshooting"}),". Here is an example of such an event:"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell-session",children:'Cluster initialization failed. This error is not recoverable.\nTerminate your cluster and try again.\nFetched bootstrapper logs are stored in "constellation-cluster.log"\n'})}),"\n",(0,n.jsx)(t.h3,{id:"kubernetes-logs",children:"Kubernetes logs"}),"\n",(0,n.jsxs)(t.p,{children:["Constellation supports the ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/logging/",children:"Kubernetes logging architecture"}),".\nBy default, logs are written to the nodes' encrypted state disks.\nThese include the Pod and container logs and the ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/logging/#system-component-logs",children:"system component logs"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices",children:"Constellation services"})," run as Pods inside the ",(0,n.jsx)(t.code,{children:"kube-system"})," namespace and use the standard container logging mechanism.\nThe same applies for the ",(0,n.jsx)(t.a,{href:"https://docs.cilium.io/en/latest/operations/troubleshooting/#logs",children:"Cilium Pods"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["You can collect logs from within the cluster via tools such as ",(0,n.jsx)(t.a,{href:"https://github.com/fluent/fluentd",children:"Fluentd"}),", ",(0,n.jsx)(t.a,{href:"https://github.com/grafana/loki",children:"Loki"}),", or the ",(0,n.jsx)(t.a,{href:"https://www.elastic.co/de/elastic-stack/",children:"Elastic Stack"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"traces",children:"Traces"}),"\n",(0,n.jsx)(t.p,{children:"Modern systems are implemented as interconnected complex and distributed microservices. Understanding request flows and system communications is challenging, mainly because all systems in a chain need to be modified to propagate tracing information. Distributed tracing is a new approach to increasing observability and understanding performance bottlenecks. A trace represents consecutive events that reflect an end-to-end request path in a distributed system."}),"\n",(0,n.jsxs)(t.p,{children:["Constellation supports ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/system-traces/",children:"traces for Kubernetes system components"}),".\nBy default, they're disabled and need to be enabled first."]}),"\n",(0,n.jsxs)(t.p,{children:["Similarly, Cilium can be enabled to ",(0,n.jsx)(t.a,{href:"https://cilium.io/use-cases/metrics-export/",children:"export traces"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["You can collect these traces via tools such as ",(0,n.jsx)(t.a,{href:"https://www.jaegertracing.io/",children:"Jaeger"})," or ",(0,n.jsx)(t.a,{href:"https://zipkin.io/",children:"Zipkin"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"integrations",children:"Integrations"}),"\n",(0,n.jsx)(t.p,{children:"Platforms and SaaS solutions such as Datadog, logz.io, Dynatrace, or New Relic facilitate the observability challenge for Kubernetes and provide all-in-one SaaS solutions.\nThey install agents into the cluster that collect metrics, logs, and tracing information and upload them into the data lake of the platform.\nTechnically, the agent-based approach is compatible with Constellation, and attaching these platforms is straightforward.\nHowever, you need to evaluate if the exported data might violate Constellation's compliance and privacy guarantees by uploading them to a third-party platform."})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>o});var i=s(96540);const n={},r=i.createContext(n);function a(e){const t=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/eae38991.c73f15f5.js b/pr-preview/pr-4027/assets/js/eae38991.c73f15f5.js deleted file mode 100644 index 059c20da6..000000000 --- a/pr-preview/pr-4027/assets/js/eae38991.c73f15f5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7570],{28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>r});var s=t(96540);const a={},o=s.createContext(a);function i(e){const n=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),s.createElement(o.Provider,{value:n},e.children)}},60621:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"getting-started/examples/horizontal-scaling","title":"Horizontal Pod Autoscaling","description":"This example demonstrates Constellation\'s autoscaling capabilities. It\'s based on the Kubernetes HorizontalPodAutoscaler Walkthrough. During the following steps, Constellation will spawn new VMs on demand, verify them, add them to the cluster, and delete them again when the load has settled down.","source":"@site/versioned_docs/version-2.23/getting-started/examples/horizontal-scaling.md","sourceDirName":"getting-started/examples","slug":"/getting-started/examples/horizontal-scaling","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/horizontal-scaling","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/getting-started/examples/horizontal-scaling.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Online Boutique","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/online-boutique"},"next":{"title":"Filestash with s3proxy","permalink":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/filestash-s3proxy"}}');var a=t(74848),o=t(28453);const i={},r="Horizontal Pod Autoscaling",l={},c=[{value:"Requirements",id:"requirements",level:2},{value:"Setup",id:"setup",level:2},{value:"Monitoring",id:"monitoring",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"horizontal-pod-autoscaling",children:"Horizontal Pod Autoscaling"})}),"\n",(0,a.jsxs)(n.p,{children:["This example demonstrates Constellation's autoscaling capabilities. It's based on the Kubernetes ",(0,a.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/",children:"HorizontalPodAutoscaler Walkthrough"}),". During the following steps, Constellation will spawn new VMs on demand, verify them, add them to the cluster, and delete them again when the load has settled down."]}),"\n",(0,a.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,a.jsxs)(n.p,{children:["The cluster needs to be initialized with Kubernetes 1.23 or later. In addition, ",(0,a.jsx)(n.a,{href:"/constellation/pr-preview/pr-4027/2.23/workflows/scale",children:"autoscaling must be enabled"})," to enable Constellation to assign new nodes dynamically."]}),"\n",(0,a.jsxs)(n.p,{children:["Just for this example specifically, the cluster should have as few worker nodes in the beginning as possible. Start with a small cluster with only ",(0,a.jsx)(n.em,{children:"one"})," low-powered node for the control-plane node and ",(0,a.jsx)(n.em,{children:"one"})," low-powered worker node."]}),"\n",(0,a.jsx)(n.admonition,{type:"info",children:(0,a.jsxs)(n.p,{children:["We tested the example using instances of types ",(0,a.jsx)(n.code,{children:"Standard_DC4as_v5"})," on Azure and ",(0,a.jsx)(n.code,{children:"n2d-standard-4"})," on GCP."]})}),"\n",(0,a.jsx)(n.h2,{id:"setup",children:"Setup"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Install the Kubernetes Metrics Server:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Deploy the HPA example server that's supposed to be scaled under load."}),"\n",(0,a.jsx)(n.p,{children:"This manifest is similar to the one from the Kubernetes HPA walkthrough, but with increased CPU limits and requests to facilitate the triggering of node scaling events."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cat <<EOF | kubectl apply -f -\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: php-apache\nspec:\n selector:\n matchLabels:\n run: php-apache\n replicas: 1\n template:\n metadata:\n labels:\n run: php-apache\n spec:\n containers:\n - name: php-apache\n image: registry.k8s.io/hpa-example\n ports:\n - containerPort: 80\n resources:\n limits:\n cpu: 900m\n requests:\n cpu: 600m\n---\napiVersion: v1\nkind: Service\nmetadata:\n name: php-apache\n labels:\n run: php-apache\nspec:\n ports:\n - port: 80\n selector:\n run: php-apache\nEOF\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Create a HorizontalPodAutoscaler."}),"\n",(0,a.jsxs)(n.p,{children:["Set an average CPU usage across all Pods of 20% to see one additional worker node being created later. Note that the CPU usage isn't related to the host CPU usage, but rather to the requested CPU capacities (20% of 600 milli-cores CPU across all Pods). See the ",(0,a.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#create-horizontal-pod-autoscaler",children:"original tutorial"})," for more information on the HPA configuration."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl autoscale deployment php-apache --cpu-percent=20 --min=1 --max=10\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Create a Pod that generates load on the server:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while true; do wget -q -O- http://php-apache; done"\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["Wait a few minutes until new nodes are added to the cluster. You can ",(0,a.jsx)(n.a,{href:"#monitoring",children:"monitor"})," the state of the HorizontalPodAutoscaler, the list of nodes, and the behavior of the autoscaler."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"To stop the load generator, press CTRL+C and run:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl delete pod load-generator\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"The cluster-autoscaler checks every few minutes if nodes are underutilized. It will taint such candidates for removal and wait additional 10 minutes before the nodes are eventually removed and deallocated. The whole process can take about 20 minutes."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"monitoring",children:"Monitoring"}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsx)(n.p,{children:"For better observability, run the listed commands in different tabs in your terminal."})}),"\n",(0,a.jsx)(n.p,{children:"You can watch the status of the HorizontalPodAutoscaler with the current CPU usage, the target CPU limit, and the number of replicas created with:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl get hpa php-apache --watch\n"})}),"\n",(0,a.jsx)(n.p,{children:"From time to time compare the list of nodes to check the behavior of the autoscaler:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl get nodes\n"})}),"\n",(0,a.jsx)(n.p,{children:"For deeper insights, see the logs of the autoscaler Pod, which contains more details about the scaling decision process:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl logs -f deployment/constellation-cluster-autoscaler -n kube-system\n"})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/ec7c7126.e5eb60ab.js b/pr-preview/pr-4027/assets/js/ec7c7126.e5eb60ab.js deleted file mode 100644 index ebd3dfcb3..000000000 --- a/pr-preview/pr-4027/assets/js/ec7c7126.e5eb60ab.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[4425],{28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}},74776:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"overview/clouds","title":"Feature status of clouds","description":"What works on which cloud? Currently, Confidential VMs (CVMs) are available in varying quality on the different clouds and software stacks.","source":"@site/docs/overview/clouds.md","sourceDirName":"overview","slug":"/overview/clouds","permalink":"/constellation/pr-preview/pr-4027/next/overview/clouds","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/overview/clouds.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Product features","permalink":"/constellation/pr-preview/pr-4027/next/overview/product"},"next":{"title":"Performance analysis of Constellation","permalink":"/constellation/pr-preview/pr-4027/next/overview/performance/"}}');var r=n(74848),i=n(28453);const o={},a="Feature status of clouds",l={},d=[{value:"Amazon Web Services (AWS)",id:"amazon-web-services-aws",level:2},{value:"Microsoft Azure",id:"microsoft-azure",level:2},{value:"Google Cloud Platform (GCP)",id:"google-cloud-platform-gcp",level:2},{value:"STACKIT",id:"stackit",level:2},{value:"OpenStack",id:"openstack",level:2},{value:"Conclusion",id:"conclusion",level:2}];function c(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"feature-status-of-clouds",children:"Feature status of clouds"})}),"\n",(0,r.jsx)(t.p,{children:"What works on which cloud? Currently, Confidential VMs (CVMs) are available in varying quality on the different clouds and software stacks."}),"\n",(0,r.jsx)(t.p,{children:"For Constellation, the ideal environment provides the following:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"Ability to run arbitrary software and images inside CVMs"}),"\n",(0,r.jsx)(t.li,{children:"CVMs based on AMD SEV-SNP (available in EPYC CPUs since the Milan generation) or Intel TDX (available in Xeon CPUs since the Sapphire Rapids generation)"}),"\n",(0,r.jsx)(t.li,{children:"Ability for CVM guests to obtain raw hardware attestation statements"}),"\n",(0,r.jsx)(t.li,{children:"Reviewable, open-source firmware inside CVMs"}),"\n",(0,r.jsx)(t.li,{children:"Capability of the firmware to attest the integrity of the code it passes control to, e.g., with an embedded virtual TPM (vTPM)"}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"(1) is a functional must-have. (2)--(5) are required for remote attestation that fully keeps the infrastructure/cloud out. Constellation can work without them or with approximations, but won't protect against certain privileged attackers anymore."}),"\n",(0,r.jsx)(t.p,{children:"The following table summarizes the state of features for different infrastructures."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"Feature"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"AWS"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"Azure"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"GCP"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"STACKIT"})}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.strong,{children:"OpenStack (Yoga)"})})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"1. Custom images"})}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"2. SEV-SNP or TDX"})}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Depends on kernel/HV"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"3. Raw guest attestation"})}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Depends on kernel/HV"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"4. Reviewable firmware"})}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"No*"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Depends on kernel/HV"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"5. Confidential measured boot"})}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Yes"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:"Depends on kernel/HV"})]})]})]}),"\n",(0,r.jsx)(t.h2,{id:"amazon-web-services-aws",children:"Amazon Web Services (AWS)"}),"\n",(0,r.jsxs)(t.p,{children:["Amazon EC2 ",(0,r.jsx)(t.a,{href:"https://aws.amazon.com/de/about-aws/whats-new/2023/04/amazon-ec2-amd-sev-snp/",children:"supports AMD SEV-SNP"}),".\nRegarding (3), AWS provides direct access to attestation statements.\nHowever, regarding (5), attestation is partially based on the ",(0,r.jsx)(t.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nitrotpm.html",children:"NitroTPM"})," for ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/attestation#measured-boot",children:"measured boot"}),", which is a vTPM managed by the Nitro hypervisor.\nHence, the hypervisor is currently part of Constellation's TCB.\nRegarding (4), the ",(0,r.jsx)(t.a,{href:"https://github.com/aws/uefi",children:"firmware is open source"})," and can be reproducibly built."]}),"\n",(0,r.jsx)(t.h2,{id:"microsoft-azure",children:"Microsoft Azure"}),"\n",(0,r.jsxs)(t.p,{children:["With its ",(0,r.jsx)(t.a,{href:"https://docs.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview",children:"CVM offering"}),", Azure provides the best foundations for Constellation.\nRegarding (3), Azure provides direct access to attestation statements.\nThe firmware runs in an isolated domain inside the CVM and exposes a vTPM (5), but it's closed source (4).\nOn SEV-SNP, Azure uses VM Privilege Level (VMPL) isolation for the separation of firmware and the rest of the VM; on TDX, they use TD partitioning.\nThis firmware is signed by Azure.\nThe signature is reflected in the attestation statements of CVMs.\nThus, the Azure closed-source firmware becomes part of Constellation's trusted computing base (TCB)."]}),"\n",(0,r.jsxs)(t.p,{children:["* Recently, ",(0,r.jsx)(t.a,{href:"https://techcommunity.microsoft.com/blog/windowsosplatform/openhcl-the-new-open-source-paravisor/4273172",children:"Azure announced the open source paravisor OpenHCL"}),". It's the foundation for fully open source and verifiable CVM firmware. Once Azure provides their CVM firmware with reproducible builds based on OpenHCL, (4) switches from ",(0,r.jsx)(t.em,{children:"No"})," to ",(0,r.jsx)(t.em,{children:"Yes"}),". Constellation will support OpenHCL based firmware on Azure in the future."]}),"\n",(0,r.jsx)(t.h2,{id:"google-cloud-platform-gcp",children:"Google Cloud Platform (GCP)"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"https://cloud.google.com/confidential-computing/confidential-vm/docs/confidential-vm-overview#technologies",children:"CVMs Generally Available in GCP"})," are based on AMD SEV-ES or SEV-SNP.\nRegarding (3), with their SEV-SNP offering Google provides direct access to attestation statements.\nHowever, regarding (5), attestation is partially based on the ",(0,r.jsx)(t.a,{href:"https://cloud.google.com/compute/shielded-vm/docs/shielded-vm#vtpm",children:"Shielded VM vTPM"})," for ",(0,r.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/next/architecture/attestation#measured-boot",children:"measured boot"}),", which is a vTPM managed by Google's hypervisor.\nHence, the hypervisor is currently part of Constellation's TCB.\nRegarding (4), the CVMs still include closed-source firmware."]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://cloud.google.com/blog/products/identity-security/confidential-vms-on-intel-cpus-your-datas-new-intelligent-defense",children:"TDX on Google"})," is in public preview.\nWith it, Constellation would have a similar TCB and attestation flow as with the current SEV-SNP offering."]}),"\n",(0,r.jsx)(t.h2,{id:"stackit",children:"STACKIT"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://www.stackit.de/en/product/stackit-compute-engine/",children:"STACKIT Compute Engine"})," supports AMD SEV-ES. A vTPM is used for measured boot, which is a vTPM managed by STACKIT's hypervisor. Hence, the hypervisor is currently part of Constellation's TCB."]}),"\n",(0,r.jsx)(t.h2,{id:"openstack",children:"OpenStack"}),"\n",(0,r.jsxs)(t.p,{children:["OpenStack is an open-source cloud and infrastructure management software. It's used by many smaller CSPs and datacenters. In the latest ",(0,r.jsx)(t.em,{children:"Yoga"})," version, OpenStack has basic support for CVMs. However, much depends on the employed kernel and hypervisor. Features (2)--(4) are likely to be a ",(0,r.jsx)(t.em,{children:"Yes"})," with Linux kernel version 6.2. Thus, going forward, OpenStack on corresponding AMD or Intel hardware will be a viable underpinning for Constellation."]}),"\n",(0,r.jsx)(t.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,r.jsx)(t.p,{children:"The different clouds and software like the Linux kernel and OpenStack are in the process of building out their support for state-of-the-art CVMs. Azure has already most features in place. For Constellation, the status quo means that the TCB has different shapes on different infrastructures. With broad SEV-SNP support coming to the Linux kernel, we soon expect a normalization of features across infrastructures."})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/f03f4c5d.387e7682.js b/pr-preview/pr-4027/assets/js/f03f4c5d.387e7682.js deleted file mode 100644 index 31d8a704a..000000000 --- a/pr-preview/pr-4027/assets/js/f03f4c5d.387e7682.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[7726],{28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}},39334:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/max_latency-ae0fad7be416fae0d31ab35bb8284234.png"},56591:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/mean_latency-4c041d48ebb1b521c92d464040e94031.png"},70238:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/p99_latency-fd60c7ae80666133370f9b8e47404994.png"},77259:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"overview/performance/application","title":"Application benchmarks","description":"HashiCorp Vault","source":"@site/versioned_docs/version-2.23/overview/performance/application.md","sourceDirName":"overview/performance","slug":"/overview/performance/application","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/performance/application","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/overview/performance/application.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"I/O benchmarks","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/performance/io"},"next":{"title":"License","permalink":"/constellation/pr-preview/pr-4027/2.23/overview/license"}}');var s=t(74848),i=t(28453);const r={},o="Application benchmarks",c={},l=[{value:"HashiCorp Vault",id:"hashicorp-vault",level:2},{value:"Results",id:"results",level:2},{value:"Visualization",id:"visualization",level:3}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components},{Details:a}=n;return a||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"application-benchmarks",children:"Application benchmarks"})}),"\n",(0,s.jsx)(n.h2,{id:"hashicorp-vault",children:"HashiCorp Vault"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://www.vaultproject.io/",children:"HashiCorp Vault"})," is a distributed secrets management software that can be deployed to Kubernetes.\nHashiCorp maintains a benchmarking tool for vault, ",(0,s.jsx)(n.a,{href:"https://github.com/hashicorp/vault-benchmark/",children:"vault-benchmark"}),".\nVault-benchmark generates load on a Vault deployment and measures response times."]}),"\n",(0,s.jsxs)(n.p,{children:["This article describes the results from running vault-benchmark on Constellation, AKS, and GKE.\nYou can find the setup for producing the data discussed in this article in the ",(0,s.jsx)(n.a,{href:"https://github.com/edgelesssys/vault-benchmarks",children:"vault-benchmarks"})," repository."]}),"\n",(0,s.jsxs)(n.p,{children:["The Vault API used during benchmarking is the ",(0,s.jsx)(n.a,{href:"https://developer.hashicorp.com/vault/docs/secrets/transit",children:"transits secret engine"}),".\nThis allows services to send data to Vault for encryption, decryption, signing, and verification."]}),"\n",(0,s.jsx)(n.h2,{id:"results",children:"Results"}),"\n",(0,s.jsx)(n.p,{children:"On each run, vault-benchmark sends requests and measures the latencies.\nThe measured latencies are aggregated through various statistical features.\nAfter running the benchmark n times, the arithmetic mean over a subset of the reported statistics is calculated.\nThe selected features are arithmetic mean, 99th percentile, minimum, and maximum."}),"\n",(0,s.jsx)(n.p,{children:"Arithmetic mean gives a general sense of the latency on each target.\nThe 99th percentile shows performance in (most likely) erroneous states.\nMinimum and maximum mark the range within which latency varies each run."}),"\n",(0,s.jsx)(n.p,{children:"The benchmark was configured with 1300 workers and 10 seconds per run.\nThose numbers were chosen empirically.\nThe latency was stabilizing at 10 seconds runtime, not changing with further increase.\nIncreasing the number of workers beyond 1300 leads to request failures, marking the limit Vault was able to handle in this setup.\nAll results are based on 100 runs."}),"\n",(0,s.jsx)(n.p,{children:"The following data was generated while running five replicas, one primary, and four standby nodes.\nAll numbers are in seconds if not indicated otherwise."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"========== Results AKS ==========\nMean: mean: 1.632200, variance: 0.002057\nP99: mean: 5.480679, variance: 2.263700\nMax: mean: 6.651001, variance: 2.808401\nMin: mean: 0.011415, variance: 0.000133\n========== Results GKE ==========\nMean: mean: 1.656435, variance: 0.003615\nP99: mean: 6.030807, variance: 3.955051\nMax: mean: 7.164843, variance: 3.300004\nMin: mean: 0.010233, variance: 0.000111\n========== Results C11n ==========\nMean: mean: 1.651549, variance: 0.001610\nP99: mean: 5.780422, variance: 3.016106\nMax: mean: 6.942997, variance: 3.075796\nMin: mean: 0.013774, variance: 0.000228\n========== AKS vs C11n ==========\nMean: +1.171577 % (AKS is faster)\nP99: +5.185495 % (AKS is faster)\nMax: +4.205618 % (AKS is faster)\nMin: +17.128781 % (AKS is faster)\n========== GKE vs C11n ==========\nMean: -0.295851 % (GKE is slower)\nP99: -4.331603 % (GKE is slower)\nMax: -3.195248 % (GKE is slower)\nMin: +25.710886 % (GKE is faster)\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Interpretation"}),": Latencies are all within ~5% of each other.\nAKS performs slightly better than GKE and Constellation (C11n) in all cases except minimum latency.\nMinimum latency is the lowest for GKE.\nCompared to GKE, Constellation had slightly lower peak latencies (99th percentile and maximum), indicating that Constellation could have handled slightly more concurrent accesses than GKE.\nOverall, performance is at comparable levels across all three distributions.\nBased on these numbers, you can use a similarly sized Constellation cluster to run your existing Vault deployment."]}),"\n",(0,s.jsx)(n.h3,{id:"visualization",children:"Visualization"}),"\n",(0,s.jsxs)(n.p,{children:["The following plots visualize the data presented above as ",(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Box_plot",children:"box plots"}),".\nThe whiskers denote the minimum and maximum.\nThe box stretches from the 25th to the 75th percentile, with the dividing bar marking the 50th percentile.\nThe circles outside the whiskers denote outliers."]}),"\n",(0,s.jsxs)(a,{children:[(0,s.jsx)("summary",{children:"Mean Latency"}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Mean Latency",src:t(56591).A+"",width:"576",height:"576"})})]}),"\n",(0,s.jsxs)(a,{children:[(0,s.jsx)("summary",{children:"99th Percentile Latency"}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"99th Percentile Latency",src:t(70238).A+"",width:"576",height:"576"})})]}),"\n",(0,s.jsxs)(a,{children:[(0,s.jsx)("summary",{children:"Maximum Latency"}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Maximum Latency",src:t(39334).A+"",width:"576",height:"576"})})]}),"\n",(0,s.jsxs)(a,{children:[(0,s.jsx)("summary",{children:"Minimum Latency"}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Minimum Latency",src:t(91224).A+"",width:"576",height:"576"})})]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},91224:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/min_latency-87ed51de18ebede26c314ff00d0e8e23.png"}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/f402a94e.b74542ad.js b/pr-preview/pr-4027/assets/js/f402a94e.b74542ad.js deleted file mode 100644 index de77259ca..000000000 --- a/pr-preview/pr-4027/assets/js/f402a94e.b74542ad.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[1220],{28453:(e,s,r)=>{r.d(s,{R:()=>i,x:()=>l});var n=r(96540);const t={},o=n.createContext(t);function i(e){const s=n.useContext(o);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),n.createElement(o.Provider,{value:s},e.children)}},50955:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>c,contentTitle:()=>l,default:()=>p,frontMatter:()=>i,metadata:()=>n,toc:()=>a});const n=JSON.parse('{"id":"architecture/versions","title":"Versions and support policy","description":"All components of Constellation use a three-digit version number of the form v...","source":"@site/versioned_docs/version-2.23/architecture/versions.md","sourceDirName":"architecture","slug":"/architecture/versions","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/versions","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.23/architecture/versions.md","tags":[],"version":"2.23","frontMatter":{},"sidebar":"docs","previous":{"title":"Cluster orchestration","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/orchestration"},"next":{"title":"Microservices","permalink":"/constellation/pr-preview/pr-4027/2.23/architecture/microservices"}}');var t=r(74848),o=r(28453);const i={},l="Versions and support policy",c={},a=[{value:"Kubernetes support policy",id:"kubernetes-support-policy",level:2}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"versions-and-support-policy",children:"Versions and support policy"})}),"\n",(0,t.jsxs)(s.p,{children:["All components of Constellation use a three-digit version number of the form ",(0,t.jsx)(s.code,{children:"v<MAJOR>.<MINOR>.<PATCH>"}),".\nThe components are released in lock step, usually on the first Tuesday of every month. This release primarily introduces new features, but may also include security or performance improvements. The ",(0,t.jsx)(s.code,{children:"MINOR"})," version will be incremented as part of this release."]}),"\n",(0,t.jsxs)(s.p,{children:["Additional ",(0,t.jsx)(s.code,{children:"PATCH"})," releases may be created on demand, to fix security issues or bugs before the next ",(0,t.jsx)(s.code,{children:"MINOR"})," release window."]}),"\n",(0,t.jsxs)(s.p,{children:["New releases are published on ",(0,t.jsx)(s.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"kubernetes-support-policy",children:"Kubernetes support policy"}),"\n",(0,t.jsxs)(s.p,{children:["Constellation is aligned to the ",(0,t.jsx)(s.a,{href:"https://kubernetes.io/releases/version-skew-policy/#supported-versions",children:"version support policy of Kubernetes"}),", and therefore usually supports the most recent three minor versions.\nWhen a new minor version of Kubernetes is released, support is added to the next Constellation release, and that version then supports four Kubernetes versions.\nSubsequent Constellation releases drop support for the oldest (and deprecated) Kubernetes version."]}),"\n",(0,t.jsx)(s.p,{children:"The following Kubernetes versions are currently supported:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"v1.29.15"}),"\n",(0,t.jsx)(s.li,{children:"v1.30.12"}),"\n",(0,t.jsx)(s.li,{children:"v1.31.8"}),"\n"]})]})}function p(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/f8c8aa36.3ddbab78.js b/pr-preview/pr-4027/assets/js/f8c8aa36.3ddbab78.js deleted file mode 100644 index d88884ab0..000000000 --- a/pr-preview/pr-4027/assets/js/f8c8aa36.3ddbab78.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3465],{3028:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"workflows/terraform-provider","title":"Use the Terraform provider","description":"The Constellation Terraform provider allows to manage the full lifecycle of a Constellation cluster (namely creation, upgrades, and deletion) via Terraform.","source":"@site/docs/workflows/terraform-provider.md","sourceDirName":"workflows","slug":"/workflows/terraform-provider","permalink":"/constellation/pr-preview/pr-4027/next/workflows/terraform-provider","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/docs/workflows/terraform-provider.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Use persistent storage","permalink":"/constellation/pr-preview/pr-4027/next/workflows/storage"},"next":{"title":"Consume SBOMs","permalink":"/constellation/pr-preview/pr-4027/next/workflows/sbom"}}');var o=n(74848),s=n(28453);const i={},a="Use the Terraform provider",l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Quick setup",id:"quick-setup",level:2},{value:"Bringing your own infrastructure",id:"bringing-your-own-infrastructure",level:2},{value:"Cluster upgrades",id:"cluster-upgrades",level:2}];function d(e){const r={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components},{TabItem:n,Tabs:t}=r;return n||h("TabItem",!0),t||h("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(r.header,{children:(0,o.jsx)(r.h1,{id:"use-the-terraform-provider",children:"Use the Terraform provider"})}),"\n",(0,o.jsxs)(r.p,{children:["The Constellation Terraform provider allows to manage the full lifecycle of a Constellation cluster (namely creation, upgrades, and deletion) via Terraform.\nThe provider is available through the ",(0,o.jsx)(r.a,{href:"https://registry.terraform.io/providers/edgelesssys/constellation/latest",children:"Terraform registry"})," and is released in lock-step with Constellation releases."]}),"\n",(0,o.jsx)(r.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsx)(r.li,{children:"a Linux / Mac operating system (ARM64/AMD64)"}),"\n",(0,o.jsxs)(r.li,{children:["a Terraform installation of version ",(0,o.jsx)(r.code,{children:"v1.4.4"})," or above"]}),"\n"]}),"\n",(0,o.jsx)(r.h2,{id:"quick-setup",children:"Quick setup"}),"\n",(0,o.jsxs)(r.p,{children:["This example shows how to set up a Constellation cluster with the reference IAM and infrastructure setup. This setup is also used when creating a Constellation cluster through the Constellation CLI. You can either consume the IAM / infrastructure modules through a remote source (recommended) or local files. The latter requires downloading the infrastructure and IAM modules for the corresponding CSP from ",(0,o.jsx)(r.code,{children:"terraform-modules.zip"})," on the ",(0,o.jsx)(r.a,{href:"https://github.com/edgelesssys/constellation/releases/latest",children:"Constellation release page"})," and placing them in the Terraform workspace directory."]}),"\n",(0,o.jsxs)(r.ol,{children:["\n",(0,o.jsx)(r.li,{children:"Create a directory (workspace) for your Constellation cluster."}),"\n"]}),"\n",(0,o.jsx)(r.pre,{children:(0,o.jsx)(r.code,{className:"language-bash",children:"mkdir constellation-workspace\ncd constellation-workspace\n"})}),"\n",(0,o.jsxs)(r.ol,{start:"2",children:["\n",(0,o.jsxs)(r.li,{children:["Use one of the ",(0,o.jsx)(r.a,{href:"https://github.com/edgelesssys/constellation/tree/main/terraform-provider-constellation/examples/full",children:"example configurations for using the Constellation Terraform provider"})," or create a ",(0,o.jsx)(r.code,{children:"main.tf"})," file and fill it with the resources you want to create. The ",(0,o.jsx)(r.a,{href:"https://registry.terraform.io/providers/edgelesssys/constellation/latest",children:"Constellation Terraform provider documentation"})," offers thorough documentation on the resources and their attributes."]}),"\n",(0,o.jsx)(r.li,{children:"Initialize and apply the Terraform configuration."}),"\n"]}),"\n",(0,o.jsxs)(t,{groupId:"csp",children:[(0,o.jsxs)(n,{value:"aws",label:"AWS",children:[(0,o.jsx)(r.p,{children:"Initialize the providers and apply the configuration."}),(0,o.jsx)(r.pre,{children:(0,o.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply\n"})}),(0,o.jsxs)(r.p,{children:["Optionally, you can prefix the ",(0,o.jsx)(r.code,{children:"terraform apply"})," command with ",(0,o.jsx)(r.code,{children:"TF_LOG=INFO"})," to collect ",(0,o.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform logs"})," while applying the configuration. This may provide helpful output in debugging scenarios."]})]}),(0,o.jsxs)(n,{value:"azure",label:"Azure",children:[(0,o.jsxs)(r.admonition,{type:"info",children:[(0,o.jsx)(r.p,{children:"On SEV-SNP, you need to manually patch the policy of the MAA provider before creating the Constellation cluster, as this feature isn't available in Azure's Terraform provider yet. The Constellation CLI provides a utility for patching, but you can also do it manually."}),(0,o.jsx)(r.pre,{children:(0,o.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply -target module.azure_iam # adjust resource path if not using the example configuration\nterraform apply -target module.azure_infrastructure # adjust resource path if not using the example configuration\nconstellation maa-patch $(terraform output -raw maa_url) # adjust output path / input if not using the example configuration or manually patch the resource\nterraform apply -target constellation_cluster.azure_example # adjust resource path if not using the example configuration\n"})}),(0,o.jsx)(r.p,{children:"Use the following policy if manually performing the patch."}),(0,o.jsx)(r.pre,{children:(0,o.jsx)(r.code,{children:'version= 1.0;\nauthorizationrules\n{\n [type=="x-ms-azurevm-default-securebootkeysvalidated", value==false] => deny();\n [type=="x-ms-azurevm-debuggersdisabled", value==false] => deny();\n // The line below was edited to use the MAA provider within Constellation. Do not edit manually.\n //[type=="secureboot", value==false] => deny();\n [type=="x-ms-azurevm-signingdisabled", value==false] => deny();\n [type=="x-ms-azurevm-dbvalidated", value==false] => deny();\n [type=="x-ms-azurevm-dbxvalidated", value==false] => deny();\n => permit();\n};\nissuancerules\n{\n};\n'})})]}),(0,o.jsx)(r.p,{children:"Initialize the providers and apply the configuration."}),(0,o.jsx)(r.pre,{children:(0,o.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply\n"})}),(0,o.jsxs)(r.p,{children:["Optionally, you can prefix the ",(0,o.jsx)(r.code,{children:"terraform apply"})," command with ",(0,o.jsx)(r.code,{children:"TF_LOG=INFO"})," to collect ",(0,o.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform logs"})," while applying the configuration. This may provide helpful output in debugging scenarios."]})]}),(0,o.jsxs)(n,{value:"gcp",label:"GCP",children:[(0,o.jsx)(r.p,{children:"Initialize the providers and apply the configuration."}),(0,o.jsx)(r.pre,{children:(0,o.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply\n"})}),(0,o.jsxs)(r.p,{children:["Optionally, you can prefix the ",(0,o.jsx)(r.code,{children:"terraform apply"})," command with ",(0,o.jsx)(r.code,{children:"TF_LOG=INFO"})," to collect ",(0,o.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform logs"})," while applying the configuration. This may provide helpful output in debugging scenarios."]})]}),(0,o.jsxs)(n,{value:"stackit",label:"STACKIT",children:[(0,o.jsx)(r.p,{children:"Initialize the providers and apply the configuration."}),(0,o.jsx)(r.pre,{children:(0,o.jsx)(r.code,{className:"language-bash",children:"terraform init\nterraform apply\n"})}),(0,o.jsxs)(r.p,{children:["Optionally, you can prefix the ",(0,o.jsx)(r.code,{children:"terraform apply"})," command with ",(0,o.jsx)(r.code,{children:"TF_LOG=INFO"})," to collect ",(0,o.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/internals/debugging",children:"Terraform logs"})," while applying the configuration. This may provide helpful output in debugging scenarios."]})]})]}),"\n",(0,o.jsxs)(r.ol,{start:"4",children:["\n",(0,o.jsx)(r.li,{children:"Connect to the cluster."}),"\n"]}),"\n",(0,o.jsx)(r.pre,{children:(0,o.jsx)(r.code,{className:"language-bash",children:"terraform output -raw kubeconfig > constellation-admin.conf\nexport KUBECONFIG=$(realpath constellation-admin.conf)\n"})}),"\n",(0,o.jsx)(r.h2,{id:"bringing-your-own-infrastructure",children:"Bringing your own infrastructure"}),"\n",(0,o.jsxs)(r.p,{children:["Instead of using the example infrastructure used in the ",(0,o.jsx)(r.a,{href:"#quick-setup",children:"quick setup"}),", you can also provide your own infrastructure.\nIf you need a starting point for a custom infrastructure setup, you can download the infrastructure / IAM Terraform modules for the respective CSP from the Constellation ",(0,o.jsx)(r.a,{href:"https://github.com/edgelesssys/constellation/releases",children:"GitHub releases"}),". You can modify and extend the modules per your requirements, while keeping the basic functionality intact.\nThe module contains:"]}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.code,{children:"{csp}"}),": cloud resources the cluster runs on"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.code,{children:"iam/{csp}"}),": IAM resources used within the cluster"]}),"\n"]}),"\n",(0,o.jsx)(r.p,{children:"When upgrading your cluster, make sure to check the Constellation release notes for potential breaking changes in the reference infrastructure / IAM modules that need to be considered."}),"\n",(0,o.jsx)(r.h2,{id:"cluster-upgrades",children:"Cluster upgrades"}),"\n",(0,o.jsx)(r.admonition,{type:"tip",children:(0,o.jsxs)(r.p,{children:["Also see the ",(0,o.jsx)(r.a,{href:"/constellation/pr-preview/pr-4027/next/workflows/upgrade",children:"general documentation on cluster upgrades"}),"."]})}),"\n",(0,o.jsx)(r.p,{children:"The steps for applying the upgrade are as follows:"}),"\n",(0,o.jsxs)(r.ol,{children:["\n",(0,o.jsxs)(r.li,{children:["Update the version constraint of the Constellation Terraform provider in the ",(0,o.jsx)(r.code,{children:"required_providers"})," block in your Terraform configuration."]}),"\n",(0,o.jsxs)(r.li,{children:["If you explicitly set any of the version attributes of the provider's resources and data sources (e.g. ",(0,o.jsx)(r.code,{children:"image_version"})," or ",(0,o.jsx)(r.code,{children:"constellation_microservice_version"}),"), make sure to update them too. Refer to Constellation's ",(0,o.jsx)(r.a,{href:"https://github.com/edgelesssys/constellation/blob/main/dev-docs/workflows/versions-support.md",children:"version support policy"})," for more information on how each Constellation version and its dependencies are supported."]}),"\n",(0,o.jsxs)(r.li,{children:["Update the IAM / infrastructure configuration.","\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:["For ",(0,o.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/language/modules/sources#fetching-archives-over-http",children:"remote addresses as module sources"}),", update the version number inside the address of the ",(0,o.jsx)(r.code,{children:"source"})," field of the infrastructure / IAM module to the target version."]}),"\n",(0,o.jsxs)(r.li,{children:["For ",(0,o.jsx)(r.a,{href:"https://developer.hashicorp.com/terraform/language/modules/sources#local-paths",children:"local paths as module sources"})," or when ",(0,o.jsx)(r.a,{href:"#bringing-your-own-infrastructure",children:"providing your own infrastructure"}),", see the changes made in the reference modules since the upgrade's origin version and adjust your infrastructure / IAM configuration accordingly."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(r.li,{children:"Upgrade the Terraform module and provider dependencies and apply the targeted configuration."}),"\n"]}),"\n",(0,o.jsx)(r.pre,{children:(0,o.jsx)(r.code,{className:"language-bash",children:" terraform init -upgrade\n terraform apply\n"})})]})}function u(e={}){const{wrapper:r}={...(0,s.R)(),...e.components};return r?(0,o.jsx)(r,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}function h(e,r){throw new Error("Expected "+(r?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,r,n)=>{n.d(r,{R:()=>i,x:()=>a});var t=n(96540);const o={},s=t.createContext(o);function i(e){const r=t.useContext(s);return t.useMemo(function(){return"function"==typeof e?e(r):{...r,...e}},[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),t.createElement(s.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/fb5790ab.c2bf914e.js b/pr-preview/pr-4027/assets/js/fb5790ab.c2bf914e.js deleted file mode 100644 index 7671fed81..000000000 --- a/pr-preview/pr-4027/assets/js/fb5790ab.c2bf914e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[9361],{21601:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>c});const a=JSON.parse('{"id":"getting-started/marketplaces","title":"Using Constellation via Cloud Marketplaces","description":"Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please contact us.","source":"@site/versioned_docs/version-2.22/getting-started/marketplaces.md","sourceDirName":"getting-started","slug":"/getting-started/marketplaces","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/marketplaces","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.22/getting-started/marketplaces.md","tags":[],"version":"2.22","frontMatter":{},"sidebar":"docs","previous":{"title":"First steps (local)","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local"},"next":{"title":"Examples","permalink":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples"}}');var n=s(74848),l=s(28453);const o={},r="Using Constellation via Cloud Marketplaces",i={},c=[];function p(e){const t={a:"a",code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,l.R)(),...e.components},{TabItem:s,Tabs:a}=t;return s||h("TabItem",!0),a||h("Tabs",!0),(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"using-constellation-via-cloud-marketplaces",children:"Using Constellation via Cloud Marketplaces"})}),"\n",(0,n.jsxs)(t.p,{children:["Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please ",(0,n.jsx)(t.a,{href:"https://www.edgeless.systems/enterprise-support/",children:"contact us"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"This document explains how to run Constellation with the dynamically billed cloud marketplace images."}),"\n",(0,n.jsxs)(a,{groupId:"csp",children:[(0,n.jsxs)(s,{value:"aws",label:"AWS",children:[(0,n.jsxs)(t.p,{children:["To use Constellation's marketplace images, ensure that you are subscribed to the ",(0,n.jsx)(t.a,{href:"https://aws.amazon.com/marketplace/pp/prodview-2mbn65nv57oys",children:"marketplace offering"})," through the web portal."]}),(0,n.jsxs)(t.p,{children:["Then, enable the use of marketplace images in your Constellation ",(0,n.jsx)(t.code,{children:"constellation-conf.yaml"})," ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/config",children:"config file"}),":"]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:'yq eval -i ".provider.aws.useMarketplaceImage = true" constellation-conf.yaml\n'})})]}),(0,n.jsxs)(s,{value:"azure",label:"Azure",children:[(0,n.jsxs)(t.p,{children:["Constellation has a private marketplace plan. Please ",(0,n.jsx)(t.a,{href:"https://www.edgeless.systems/enterprise-support/",children:"contact us"})," to gain access."]}),(0,n.jsxs)(t.p,{children:["To use a marketplace image, you need to accept the marketplace image's terms once for your subscription with the ",(0,n.jsx)(t.a,{href:"https://learn.microsoft.com/en-us/cli/azure/vm/image/terms?view=azure-cli-latest",children:"Azure CLI"}),":"]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"az vm image terms accept --publisher edgelesssystems --offer constellation --plan constellation\n"})}),(0,n.jsxs)(t.p,{children:["Then, enable the use of marketplace images in your Constellation ",(0,n.jsx)(t.code,{children:"constellation-conf.yaml"})," ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/config",children:"config file"}),":"]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:'yq eval -i ".provider.azure.useMarketplaceImage = true" constellation-conf.yaml\n'})})]}),(0,n.jsxs)(s,{value:"gcp",label:"GCP",children:[(0,n.jsxs)(t.p,{children:["To use a marketplace image, ensure that the account is entitled to use marketplace images by Edgeless Systems by accepting the terms through the ",(0,n.jsx)(t.a,{href:"https://console.cloud.google.com/marketplace/vm/config/edgeless-systems-public/constellation",children:"web portal"}),"."]}),(0,n.jsxs)(t.p,{children:["Then, enable the use of marketplace images in your Constellation ",(0,n.jsx)(t.code,{children:"constellation-conf.yaml"})," ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/config",children:"config file"}),":"]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:'yq eval -i ".provider.gcp.useMarketplaceImage = true" constellation-conf.yaml\n'})})]}),(0,n.jsx)(s,{value:"stackit",label:"STACKIT",children:(0,n.jsx)(t.p,{children:"On STACKIT, the selected Constellation image is always a marketplace image. You can find more information on the STACKIT portal."})})]}),"\n",(0,n.jsxs)(t.p,{children:["Ensure that the cluster uses an official release image version (i.e., ",(0,n.jsx)(t.code,{children:".image=vX.Y.Z"})," in the ",(0,n.jsx)(t.code,{children:"constellation-conf.yaml"})," file)."]}),"\n",(0,n.jsxs)(t.p,{children:["From there, you can proceed with the ",(0,n.jsx)(t.a,{href:"/constellation/pr-preview/pr-4027/2.22/workflows/create",children:"cluster creation"})," as usual."]})]})}function d(e={}){const{wrapper:t}={...(0,l.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}function h(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>r});var a=s(96540);const n={},l=a.createContext(n);function o(e){const t=a.useContext(l);return a.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),a.createElement(l.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/fd1d3864.4d1ac871.js b/pr-preview/pr-4027/assets/js/fd1d3864.4d1ac871.js deleted file mode 100644 index f21eb3dd6..000000000 --- a/pr-preview/pr-4027/assets/js/fd1d3864.4d1ac871.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[3289],{26064:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>p,frontMatter:()=>r,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"reference/cli","title":"CLI reference","description":"Use the Constellation CLI to create and manage your clusters.","source":"@site/versioned_docs/version-2.24/reference/cli.md","sourceDirName":"reference","slug":"/reference/cli","permalink":"/constellation/pr-preview/pr-4027/reference/cli","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/constellation/edit/main/docs/versioned_docs/version-2.24/reference/cli.md","tags":[],"version":"2.24","frontMatter":{},"sidebar":"docs","previous":{"title":"Reference","permalink":"/constellation/pr-preview/pr-4027/category/reference"},"next":{"title":"Configuration migrations","permalink":"/constellation/pr-preview/pr-4027/reference/migration"}}');var s=i(74848),t=i(28453);const r={},l="CLI reference",a={},c=[{value:"constellation config",id:"constellation-config",level:2},{value:"Synopsis",id:"synopsis",level:3},{value:"Options",id:"options",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands",level:3},{value:"constellation config generate",id:"constellation-config-generate",level:2},{value:"Synopsis",id:"synopsis-1",level:3},{value:"Options",id:"options-1",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-1",level:3},{value:"constellation config fetch-measurements",id:"constellation-config-fetch-measurements",level:2},{value:"Synopsis",id:"synopsis-2",level:3},{value:"Options",id:"options-2",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-2",level:3},{value:"constellation config instance-types",id:"constellation-config-instance-types",level:2},{value:"Synopsis",id:"synopsis-3",level:3},{value:"Options",id:"options-3",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-3",level:3},{value:"constellation config kubernetes-versions",id:"constellation-config-kubernetes-versions",level:2},{value:"Synopsis",id:"synopsis-4",level:3},{value:"Options",id:"options-4",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-4",level:3},{value:"constellation config migrate",id:"constellation-config-migrate",level:2},{value:"Synopsis",id:"synopsis-5",level:3},{value:"Options",id:"options-5",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-5",level:3},{value:"constellation create",id:"constellation-create",level:2},{value:"Synopsis",id:"synopsis-6",level:3},{value:"Options",id:"options-6",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-6",level:3},{value:"constellation apply",id:"constellation-apply",level:2},{value:"Synopsis",id:"synopsis-7",level:3},{value:"Options",id:"options-7",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-7",level:3},{value:"constellation mini",id:"constellation-mini",level:2},{value:"Synopsis",id:"synopsis-8",level:3},{value:"Options",id:"options-8",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-8",level:3},{value:"constellation mini up",id:"constellation-mini-up",level:2},{value:"Synopsis",id:"synopsis-9",level:3},{value:"Options",id:"options-9",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-9",level:3},{value:"constellation mini down",id:"constellation-mini-down",level:2},{value:"Synopsis",id:"synopsis-10",level:3},{value:"Options",id:"options-10",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-10",level:3},{value:"constellation status",id:"constellation-status",level:2},{value:"Synopsis",id:"synopsis-11",level:3},{value:"Options",id:"options-11",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-11",level:3},{value:"constellation verify",id:"constellation-verify",level:2},{value:"Synopsis",id:"synopsis-12",level:3},{value:"Options",id:"options-12",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-12",level:3},{value:"constellation upgrade",id:"constellation-upgrade",level:2},{value:"Synopsis",id:"synopsis-13",level:3},{value:"Options",id:"options-13",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-13",level:3},{value:"constellation upgrade check",id:"constellation-upgrade-check",level:2},{value:"Synopsis",id:"synopsis-14",level:3},{value:"Options",id:"options-14",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-14",level:3},{value:"constellation upgrade apply",id:"constellation-upgrade-apply",level:2},{value:"Synopsis",id:"synopsis-15",level:3},{value:"Options",id:"options-15",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-15",level:3},{value:"constellation recover",id:"constellation-recover",level:2},{value:"Synopsis",id:"synopsis-16",level:3},{value:"Options",id:"options-16",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-16",level:3},{value:"constellation terminate",id:"constellation-terminate",level:2},{value:"Synopsis",id:"synopsis-17",level:3},{value:"Options",id:"options-17",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-17",level:3},{value:"constellation iam",id:"constellation-iam",level:2},{value:"Synopsis",id:"synopsis-18",level:3},{value:"Options",id:"options-18",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-18",level:3},{value:"constellation iam create",id:"constellation-iam-create",level:2},{value:"Synopsis",id:"synopsis-19",level:3},{value:"Options",id:"options-19",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-19",level:3},{value:"constellation iam create aws",id:"constellation-iam-create-aws",level:2},{value:"Synopsis",id:"synopsis-20",level:3},{value:"Options",id:"options-20",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-20",level:3},{value:"constellation iam create azure",id:"constellation-iam-create-azure",level:2},{value:"Synopsis",id:"synopsis-21",level:3},{value:"Options",id:"options-21",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-21",level:3},{value:"constellation iam create gcp",id:"constellation-iam-create-gcp",level:2},{value:"Synopsis",id:"synopsis-22",level:3},{value:"Options",id:"options-22",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-22",level:3},{value:"constellation iam destroy",id:"constellation-iam-destroy",level:2},{value:"Synopsis",id:"synopsis-23",level:3},{value:"Options",id:"options-23",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-23",level:3},{value:"constellation iam upgrade",id:"constellation-iam-upgrade",level:2},{value:"Synopsis",id:"synopsis-24",level:3},{value:"Options",id:"options-24",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-24",level:3},{value:"constellation iam upgrade apply",id:"constellation-iam-upgrade-apply",level:2},{value:"Synopsis",id:"synopsis-25",level:3},{value:"Options",id:"options-25",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-25",level:3},{value:"constellation version",id:"constellation-version",level:2},{value:"Synopsis",id:"synopsis-26",level:3},{value:"Options",id:"options-26",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-26",level:3},{value:"constellation init",id:"constellation-init",level:2},{value:"Synopsis",id:"synopsis-27",level:3},{value:"Options",id:"options-27",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-27",level:3},{value:"constellation ssh",id:"constellation-ssh",level:2},{value:"Synopsis",id:"synopsis-28",level:3},{value:"Options",id:"options-28",level:3},{value:"Options inherited from parent commands",id:"options-inherited-from-parent-commands-28",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"cli-reference",children:"CLI reference"})}),"\n",(0,s.jsx)(n.p,{children:"Use the Constellation CLI to create and manage your clusters."}),"\n",(0,s.jsx)(n.p,{children:"Usage:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation [command]\n"})}),"\n",(0,s.jsx)(n.p,{children:"Commands:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config",children:"config"}),": Work with the Constellation configuration file","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-generate",children:"generate"}),": Generate a default configuration and state file"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-fetch-measurements",children:"fetch-measurements"}),": Fetch measurements for configured cloud provider and image"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-instance-types",children:"instance-types"}),": Print the supported instance types for all cloud providers"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-kubernetes-versions",children:"kubernetes-versions"}),": Print the Kubernetes versions supported by this CLI"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-config-migrate",children:"migrate"}),": Migrate a configuration file to a new version"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-create",children:"create"}),": Create instances on a cloud platform for your Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-apply",children:"apply"}),": Apply a configuration to a Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-mini",children:"mini"}),": Manage MiniConstellation clusters","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-mini-up",children:"up"}),": Create and initialize a new MiniConstellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-mini-down",children:"down"}),": Destroy a MiniConstellation cluster"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-status",children:"status"}),": Show status of a Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-verify",children:"verify"}),": Verify the confidential properties of a Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-upgrade",children:"upgrade"}),": Find and apply upgrades to your Constellation cluster","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-upgrade-check",children:"check"}),": Check for possible upgrades"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-upgrade-apply",children:"apply"}),": Apply an upgrade to a Constellation cluster"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-recover",children:"recover"}),": Recover a completely stopped Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-terminate",children:"terminate"}),": Terminate a Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam",children:"iam"}),": Work with the IAM configuration on your cloud provider","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-create",children:"create"}),": Create IAM configuration on a cloud platform for your Constellation cluster","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-create-aws",children:"aws"}),": Create IAM configuration on AWS for your Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-create-azure",children:"azure"}),": Create IAM configuration on Microsoft Azure for your Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-create-gcp",children:"gcp"}),": Create IAM configuration on GCP for your Constellation cluster"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-destroy",children:"destroy"}),": Destroy an IAM configuration and delete local Terraform files"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-upgrade",children:"upgrade"}),": Find and apply upgrades to your IAM profile","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-iam-upgrade-apply",children:"apply"}),": Apply an upgrade to an IAM profile"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-version",children:"version"}),": Display version of this CLI"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-init",children:"init"}),": Initialize the Constellation cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#constellation-ssh",children:"ssh"}),": Generate a certificate for emergency SSH access"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config",children:"constellation config"}),"\n",(0,s.jsx)(n.p,{children:"Work with the Constellation configuration file"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Work with the Constellation configuration file."}),"\n",(0,s.jsx)(n.h3,{id:"options",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for config\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-generate",children:"constellation config generate"}),"\n",(0,s.jsx)(n.p,{children:"Generate a default configuration and state file"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-1",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Generate a default configuration and state file for your selected cloud provider."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config generate {aws|azure|gcp|openstack|qemu|stackit} [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-1",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' -a, --attestation string attestation variant to use {aws-sev-snp|aws-nitro-tpm|azure-sev-snp|azure-tdx|azure-trustedlaunch|gcp-sev-snp|gcp-sev-es|qemu-vtpm}. If not specified, the default for the cloud provider is used\n -h, --help help for generate\n -k, --kubernetes string Kubernetes version to use in format MAJOR.MINOR (default "v1.31")\n -t, --tags strings additional tags for created resources given a list of key=value\n'})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-1",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-fetch-measurements",children:"constellation config fetch-measurements"}),"\n",(0,s.jsx)(n.p,{children:"Fetch measurements for configured cloud provider and image"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-2",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Fetch measurements for configured cloud provider and image."}),"\n",(0,s.jsx)(n.p,{children:"A config needs to be generated first."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config fetch-measurements [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-2",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for fetch-measurements\n -s, --signature-url string alternative URL to fetch measurements' signature from\n -u, --url string alternative URL to fetch measurements from\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-2",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-instance-types",children:"constellation config instance-types"}),"\n",(0,s.jsx)(n.p,{children:"Print the supported instance types for all cloud providers"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-3",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Print the supported instance types for all cloud providers."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config instance-types [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-3",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for instance-types\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-3",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-kubernetes-versions",children:"constellation config kubernetes-versions"}),"\n",(0,s.jsx)(n.p,{children:"Print the Kubernetes versions supported by this CLI"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-4",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Print the Kubernetes versions supported by this CLI."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config kubernetes-versions [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-4",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for kubernetes-versions\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-4",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-config-migrate",children:"constellation config migrate"}),"\n",(0,s.jsx)(n.p,{children:"Migrate a configuration file to a new version"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-5",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Migrate a configuration file to a new version."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation config migrate [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-5",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for migrate\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-5",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-create",children:"constellation create"}),"\n",(0,s.jsx)(n.p,{children:"Create instances on a cloud platform for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-6",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create instances on a cloud platform for your Constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation create [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-6",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for create\n -y, --yes create the cluster without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-6",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-apply",children:"constellation apply"}),"\n",(0,s.jsx)(n.p,{children:"Apply a configuration to a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-7",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Apply a configuration to a Constellation cluster to initialize or upgrade the cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation apply [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-7",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" --conformance enable conformance mode\n -h, --help help for apply\n --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config\n --skip-helm-wait install helm charts without waiting for deployments to be ready\n --skip-phases strings comma-separated list of upgrade phases to skip\n one or multiple of { infrastructure | init | attestationconfig | certsans | helm | image | k8s }\n -y, --yes run command without further confirmation\n WARNING: the command might delete or update existing resources without additional checks. Please read the docs.\n \n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-7",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-mini",children:"constellation mini"}),"\n",(0,s.jsx)(n.p,{children:"Manage MiniConstellation clusters"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-8",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Manage MiniConstellation clusters."}),"\n",(0,s.jsx)(n.h3,{id:"options-8",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for mini\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-8",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-mini-up",children:"constellation mini up"}),"\n",(0,s.jsx)(n.p,{children:"Create and initialize a new MiniConstellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-9",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create and initialize a new MiniConstellation cluster."}),"\n",(0,s.jsx)(n.p,{children:"A mini cluster consists of a single control-plane and worker node, hosted using QEMU/KVM."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation mini up [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-9",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for up\n --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config (default true)\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-9",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-mini-down",children:"constellation mini down"}),"\n",(0,s.jsx)(n.p,{children:"Destroy a MiniConstellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-10",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Destroy a MiniConstellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation mini down [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-10",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for down\n -y, --yes terminate the cluster without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-10",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-status",children:"constellation status"}),"\n",(0,s.jsx)(n.p,{children:"Show status of a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-11",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Show the status of a constellation cluster."}),"\n",(0,s.jsx)(n.p,{children:"Shows microservice, image, and Kubernetes versions installed in the cluster. Also shows status of current version upgrades."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation status [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-11",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for status\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-11",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-verify",children:"constellation verify"}),"\n",(0,s.jsx)(n.p,{children:"Verify the confidential properties of a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-12",children:"Synopsis"}),"\n",(0,s.jsxs)(n.p,{children:["Verify the confidential properties of a Constellation cluster.\nIf arguments aren't specified, values are read from ",(0,s.jsx)(n.code,{children:"constellation-state.yaml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation verify [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-12",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" --cluster-id string expected cluster identifier\n -h, --help help for verify\n -e, --node-endpoint string endpoint of the node to verify, passed as HOST[:PORT]\n -o, --output string print the attestation document in the output format {json|raw}\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-12",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-upgrade",children:"constellation upgrade"}),"\n",(0,s.jsx)(n.p,{children:"Find and apply upgrades to your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-13",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Find and apply upgrades to your Constellation cluster."}),"\n",(0,s.jsx)(n.h3,{id:"options-13",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for upgrade\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-13",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-upgrade-check",children:"constellation upgrade check"}),"\n",(0,s.jsx)(n.p,{children:"Check for possible upgrades"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-14",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Check which upgrades can be applied to your Constellation Cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation upgrade check [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-14",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' -h, --help help for check\n --ref string the reference to use for querying new versions (default "-")\n --stream string the stream to use for querying new versions (default "stable")\n -u, --update-config update the specified config file with the suggested versions\n'})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-14",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-upgrade-apply",children:"constellation upgrade apply"}),"\n",(0,s.jsx)(n.p,{children:"Apply an upgrade to a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-15",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Apply an upgrade to a Constellation cluster by applying the chosen configuration."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation upgrade apply [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-15",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" --conformance enable conformance mode\n -h, --help help for apply\n --skip-helm-wait install helm charts without waiting for deployments to be ready\n --skip-phases strings comma-separated list of upgrade phases to skip\n one or multiple of { infrastructure | helm | image | k8s }\n -y, --yes run upgrades without further confirmation\n WARNING: might delete your resources in case you are using cert-manager in your cluster. Please read the docs.\n WARNING: might unintentionally overwrite measurements in the running cluster.\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-15",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-recover",children:"constellation recover"}),"\n",(0,s.jsx)(n.p,{children:"Recover a completely stopped Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-16",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Recover a Constellation cluster by sending a recovery key to an instance in the boot stage."}),"\n",(0,s.jsx)(n.p,{children:"This is only required if instances restart without other instances available for bootstrapping."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation recover [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-16",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -e, --endpoint string endpoint of the instance, passed as HOST[:PORT]\n -h, --help help for recover\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-16",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-terminate",children:"constellation terminate"}),"\n",(0,s.jsx)(n.p,{children:"Terminate a Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-17",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Terminate a Constellation cluster."}),"\n",(0,s.jsx)(n.p,{children:"The cluster can't be started again, and all persistent storage will be lost."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation terminate [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-17",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for terminate\n -y, --yes terminate the cluster without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-17",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam",children:"constellation iam"}),"\n",(0,s.jsx)(n.p,{children:"Work with the IAM configuration on your cloud provider"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-18",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Work with the IAM configuration on your cloud provider."}),"\n",(0,s.jsx)(n.h3,{id:"options-18",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for iam\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-18",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-create",children:"constellation iam create"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on a cloud platform for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-19",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on a cloud platform for your Constellation cluster."}),"\n",(0,s.jsx)(n.h3,{id:"options-19",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for create\n --update-config update the config file with the specific IAM information\n -y, --yes create the IAM configuration without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-19",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-create-aws",children:"constellation iam create aws"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on AWS for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-20",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on AWS for your Constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam create aws [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-20",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for aws\n --prefix string name prefix for all resources (required)\n --zone string AWS availability zone the resources will be created in, e.g., us-east-2a (required)\n See the Constellation docs for a list of currently supported regions.\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-20",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n --update-config update the config file with the specific IAM information\n -C, --workspace string path to the Constellation workspace\n -y, --yes create the IAM configuration without further confirmation\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-create-azure",children:"constellation iam create azure"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on Microsoft Azure for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-21",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on Microsoft Azure for your Constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam create azure [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-21",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for azure\n --region string region the resources will be created in, e.g., westus (required)\n --resourceGroup string name prefix of the two resource groups your cluster / IAM resources will be created in (required)\n --servicePrincipal string name of the service principal that will be created (required)\n --subscriptionID string subscription ID of the Azure account. Required if the 'ARM_SUBSCRIPTION_ID' environment variable is not set\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-21",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n --update-config update the config file with the specific IAM information\n -C, --workspace string path to the Constellation workspace\n -y, --yes create the IAM configuration without further confirmation\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-create-gcp",children:"constellation iam create gcp"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on GCP for your Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-22",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Create IAM configuration on GCP for your Constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam create gcp [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-22",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for gcp\n --prefix string Prefix for the service account ID and VM ID that will be created (required)\n Must be letters, digits, or hyphens.\n --projectID string ID of the GCP project the configuration will be created in (required)\n Find it on the welcome screen of your project: https://console.cloud.google.com/welcome\n --zone string GCP zone the cluster will be deployed in (required)\n Find a list of available zones here: https://cloud.google.com/compute/docs/regions-zones#available\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-22",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n --update-config update the config file with the specific IAM information\n -C, --workspace string path to the Constellation workspace\n -y, --yes create the IAM configuration without further confirmation\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-destroy",children:"constellation iam destroy"}),"\n",(0,s.jsx)(n.p,{children:"Destroy an IAM configuration and delete local Terraform files"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-23",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Destroy an IAM configuration and delete local Terraform files."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam destroy [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-23",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for destroy\n -y, --yes destroy the IAM configuration without asking for confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-23",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-upgrade",children:"constellation iam upgrade"}),"\n",(0,s.jsx)(n.p,{children:"Find and apply upgrades to your IAM profile"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-24",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Find and apply upgrades to your IAM profile."}),"\n",(0,s.jsx)(n.h3,{id:"options-24",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for upgrade\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-24",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-iam-upgrade-apply",children:"constellation iam upgrade apply"}),"\n",(0,s.jsx)(n.p,{children:"Apply an upgrade to an IAM profile"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-25",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Apply an upgrade to an IAM profile."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation iam upgrade apply [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-25",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for apply\n -y, --yes run upgrades without further confirmation\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-25",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-version",children:"constellation version"}),"\n",(0,s.jsx)(n.p,{children:"Display version of this CLI"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-26",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Display version of this CLI."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation version [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-26",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for version\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-26",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-init",children:"constellation init"}),"\n",(0,s.jsx)(n.p,{children:"Initialize the Constellation cluster"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-27",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Initialize the Constellation cluster."}),"\n",(0,s.jsx)(n.p,{children:"Start your confidential Kubernetes."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation init [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-27",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" --conformance enable conformance mode\n -h, --help help for init\n --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config\n --skip-helm-wait install helm charts without waiting for deployments to be ready\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-27",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})}),"\n",(0,s.jsx)(n.h2,{id:"constellation-ssh",children:"constellation ssh"}),"\n",(0,s.jsx)(n.p,{children:"Generate a certificate for emergency SSH access"}),"\n",(0,s.jsx)(n.h3,{id:"synopsis-28",children:"Synopsis"}),"\n",(0,s.jsx)(n.p,{children:"Generate a certificate for emergency SSH access to your SSH-enabled constellation cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"constellation ssh [flags]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-28",children:"Options"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" -h, --help help for ssh\n --key string the path to an existing SSH public key\n"})}),"\n",(0,s.jsx)(n.h3,{id:"options-inherited-from-parent-commands-28",children:"Options inherited from parent commands"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:' --debug enable debug logging\n --force disable version compatibility checks - might result in corrupted clusters\n --tf-log string Terraform log level (default "NONE")\n -C, --workspace string path to the Constellation workspace\n'})})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>l});var o=i(96540);const s={},t=o.createContext(s);function r(e){const n=o.useContext(t);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/main.6a3f64be.js b/pr-preview/pr-4027/assets/js/main.6a3f64be.js deleted file mode 100644 index 1ddd8e235..000000000 --- a/pr-preview/pr-4027/assets/js/main.6a3f64be.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see main.6a3f64be.js.LICENSE.txt */ -(globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[]).push([[8792],{689:function(e){e.exports=function(){"use strict";var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},t=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},n=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),r=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},o=function(){function e(n){var r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:5e3;t(this,e),this.ctx=n,this.iframes=r,this.exclude=o,this.iframesTimeout=i}return n(e,[{key:"getContexts",value:function(){var e=[];return(void 0!==this.ctx&&this.ctx?NodeList.prototype.isPrototypeOf(this.ctx)?Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?this.ctx:"string"==typeof this.ctx?Array.prototype.slice.call(document.querySelectorAll(this.ctx)):[this.ctx]:[]).forEach(function(t){var n=e.filter(function(e){return e.contains(t)}).length>0;-1!==e.indexOf(t)||n||e.push(t)}),e}},{key:"getIframeContents",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){},r=void 0;try{var o=e.contentWindow;if(r=o.document,!o||!r)throw new Error("iframe inaccessible")}catch(i){n()}r&&t(r)}},{key:"isIframeBlank",value:function(e){var t="about:blank",n=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&n!==t&&n}},{key:"observeIframeLoad",value:function(e,t,n){var r=this,o=!1,i=null,a=function a(){if(!o){o=!0,clearTimeout(i);try{r.isIframeBlank(e)||(e.removeEventListener("load",a),r.getIframeContents(e,t,n))}catch(s){n()}}};e.addEventListener("load",a),i=setTimeout(a,this.iframesTimeout)}},{key:"onIframeReady",value:function(e,t,n){try{"complete"===e.contentWindow.document.readyState?this.isIframeBlank(e)?this.observeIframeLoad(e,t,n):this.getIframeContents(e,t,n):this.observeIframeLoad(e,t,n)}catch(r){n()}}},{key:"waitForIframes",value:function(e,t){var n=this,r=0;this.forEachIframe(e,function(){return!0},function(e){r++,n.waitForIframes(e.querySelector("html"),function(){--r||t()})},function(e){e||t()})}},{key:"forEachIframe",value:function(t,n,r){var o=this,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},a=t.querySelectorAll("iframe"),s=a.length,l=0;a=Array.prototype.slice.call(a);var c=function(){--s<=0&&i(l)};s||c(),a.forEach(function(t){e.matches(t,o.exclude)?c():o.onIframeReady(t,function(e){n(t)&&(l++,r(e)),c()},c)})}},{key:"createIterator",value:function(e,t,n){return document.createNodeIterator(e,t,n,!1)}},{key:"createInstanceOnIframe",value:function(t){return new e(t.querySelector("html"),this.iframes)}},{key:"compareNodeIframe",value:function(e,t,n){if(e.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_PRECEDING){if(null===t)return!0;if(t.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_FOLLOWING)return!0}return!1}},{key:"getIteratorNode",value:function(e){var t=e.previousNode();return{prevNode:t,node:(null===t||e.nextNode())&&e.nextNode()}}},{key:"checkIframeFilter",value:function(e,t,n,r){var o=!1,i=!1;return r.forEach(function(e,t){e.val===n&&(o=t,i=e.handled)}),this.compareNodeIframe(e,t,n)?(!1!==o||i?!1===o||i||(r[o].handled=!0):r.push({val:n,handled:!0}),!0):(!1===o&&r.push({val:n,handled:!1}),!1)}},{key:"handleOpenIframes",value:function(e,t,n,r){var o=this;e.forEach(function(e){e.handled||o.getIframeContents(e.val,function(e){o.createInstanceOnIframe(e).forEachNode(t,n,r)})})}},{key:"iterateThroughNodes",value:function(e,t,n,r,o){for(var i=this,a=this.createIterator(t,e,r),s=[],l=[],c=void 0,u=void 0,p=function(){var e=i.getIteratorNode(a);return u=e.prevNode,c=e.node};p();)this.iframes&&this.forEachIframe(t,function(e){return i.checkIframeFilter(c,u,e,s)},function(t){i.createInstanceOnIframe(t).forEachNode(e,function(e){return l.push(e)},r)}),l.push(c);l.forEach(function(e){n(e)}),this.iframes&&this.handleOpenIframes(s,e,n,r),o()}},{key:"forEachNode",value:function(e,t,n){var r=this,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},i=this.getContexts(),a=i.length;a||o(),i.forEach(function(i){var s=function(){r.iterateThroughNodes(e,i,t,n,function(){--a<=0&&o()})};r.iframes?r.waitForIframes(i,s):s()})}}],[{key:"matches",value:function(e,t){var n="string"==typeof t?[t]:t,r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(r){var o=!1;return n.every(function(t){return!r.call(e,t)||(o=!0,!1)}),o}return!1}}]),e}(),i=function(){function i(e){t(this,i),this.ctx=e,this.ie=!1;var n=window.navigator.userAgent;(n.indexOf("MSIE")>-1||n.indexOf("Trident")>-1)&&(this.ie=!0)}return n(i,[{key:"log",value:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"debug",r=this.opt.log;this.opt.debug&&"object"===(void 0===r?"undefined":e(r))&&"function"==typeof r[n]&&r[n]("mark.js: "+t)}},{key:"escapeStr",value:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}},{key:"createRegExp",value:function(e){return"disabled"!==this.opt.wildcards&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),"disabled"!==this.opt.wildcards&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e)}},{key:"createSynonymsRegExp",value:function(e){var t=this.opt.synonyms,n=this.opt.caseSensitive?"":"i",r=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(var o in t)if(t.hasOwnProperty(o)){var i=t[o],a="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(o):this.escapeStr(o),s="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(i):this.escapeStr(i);""!==a&&""!==s&&(e=e.replace(new RegExp("("+this.escapeStr(a)+"|"+this.escapeStr(s)+")","gm"+n),r+"("+this.processSynomyms(a)+"|"+this.processSynomyms(s)+")"+r))}return e}},{key:"processSynomyms",value:function(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}},{key:"setupWildcardsRegExp",value:function(e){return(e=e.replace(/(?:\\)*\?/g,function(e){return"\\"===e.charAt(0)?"?":"\x01"})).replace(/(?:\\)*\*/g,function(e){return"\\"===e.charAt(0)?"*":"\x02"})}},{key:"createWildcardsRegExp",value:function(e){var t="withSpaces"===this.opt.wildcards;return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}},{key:"setupIgnoreJoinersRegExp",value:function(e){return e.replace(/[^(|)\\]/g,function(e,t,n){var r=n.charAt(t+1);return/[(|)\\]/.test(r)||""===r?e:e+"\0"})}},{key:"createJoinersRegExp",value:function(e){var t=[],n=this.opt.ignorePunctuation;return Array.isArray(n)&&n.length&&t.push(this.escapeStr(n.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join("["+t.join("")+"]*"):e}},{key:"createDiacriticsRegExp",value:function(e){var t=this.opt.caseSensitive?"":"i",n=this.opt.caseSensitive?["a\xe0\xe1\u1ea3\xe3\u1ea1\u0103\u1eb1\u1eaf\u1eb3\u1eb5\u1eb7\xe2\u1ea7\u1ea5\u1ea9\u1eab\u1ead\xe4\xe5\u0101\u0105","A\xc0\xc1\u1ea2\xc3\u1ea0\u0102\u1eb0\u1eae\u1eb2\u1eb4\u1eb6\xc2\u1ea6\u1ea4\u1ea8\u1eaa\u1eac\xc4\xc5\u0100\u0104","c\xe7\u0107\u010d","C\xc7\u0106\u010c","d\u0111\u010f","D\u0110\u010e","e\xe8\xe9\u1ebb\u1ebd\u1eb9\xea\u1ec1\u1ebf\u1ec3\u1ec5\u1ec7\xeb\u011b\u0113\u0119","E\xc8\xc9\u1eba\u1ebc\u1eb8\xca\u1ec0\u1ebe\u1ec2\u1ec4\u1ec6\xcb\u011a\u0112\u0118","i\xec\xed\u1ec9\u0129\u1ecb\xee\xef\u012b","I\xcc\xcd\u1ec8\u0128\u1eca\xce\xcf\u012a","l\u0142","L\u0141","n\xf1\u0148\u0144","N\xd1\u0147\u0143","o\xf2\xf3\u1ecf\xf5\u1ecd\xf4\u1ed3\u1ed1\u1ed5\u1ed7\u1ed9\u01a1\u1edf\u1ee1\u1edb\u1edd\u1ee3\xf6\xf8\u014d","O\xd2\xd3\u1ece\xd5\u1ecc\xd4\u1ed2\u1ed0\u1ed4\u1ed6\u1ed8\u01a0\u1ede\u1ee0\u1eda\u1edc\u1ee2\xd6\xd8\u014c","r\u0159","R\u0158","s\u0161\u015b\u0219\u015f","S\u0160\u015a\u0218\u015e","t\u0165\u021b\u0163","T\u0164\u021a\u0162","u\xf9\xfa\u1ee7\u0169\u1ee5\u01b0\u1eeb\u1ee9\u1eed\u1eef\u1ef1\xfb\xfc\u016f\u016b","U\xd9\xda\u1ee6\u0168\u1ee4\u01af\u1eea\u1ee8\u1eec\u1eee\u1ef0\xdb\xdc\u016e\u016a","y\xfd\u1ef3\u1ef7\u1ef9\u1ef5\xff","Y\xdd\u1ef2\u1ef6\u1ef8\u1ef4\u0178","z\u017e\u017c\u017a","Z\u017d\u017b\u0179"]:["a\xe0\xe1\u1ea3\xe3\u1ea1\u0103\u1eb1\u1eaf\u1eb3\u1eb5\u1eb7\xe2\u1ea7\u1ea5\u1ea9\u1eab\u1ead\xe4\xe5\u0101\u0105A\xc0\xc1\u1ea2\xc3\u1ea0\u0102\u1eb0\u1eae\u1eb2\u1eb4\u1eb6\xc2\u1ea6\u1ea4\u1ea8\u1eaa\u1eac\xc4\xc5\u0100\u0104","c\xe7\u0107\u010dC\xc7\u0106\u010c","d\u0111\u010fD\u0110\u010e","e\xe8\xe9\u1ebb\u1ebd\u1eb9\xea\u1ec1\u1ebf\u1ec3\u1ec5\u1ec7\xeb\u011b\u0113\u0119E\xc8\xc9\u1eba\u1ebc\u1eb8\xca\u1ec0\u1ebe\u1ec2\u1ec4\u1ec6\xcb\u011a\u0112\u0118","i\xec\xed\u1ec9\u0129\u1ecb\xee\xef\u012bI\xcc\xcd\u1ec8\u0128\u1eca\xce\xcf\u012a","l\u0142L\u0141","n\xf1\u0148\u0144N\xd1\u0147\u0143","o\xf2\xf3\u1ecf\xf5\u1ecd\xf4\u1ed3\u1ed1\u1ed5\u1ed7\u1ed9\u01a1\u1edf\u1ee1\u1edb\u1edd\u1ee3\xf6\xf8\u014dO\xd2\xd3\u1ece\xd5\u1ecc\xd4\u1ed2\u1ed0\u1ed4\u1ed6\u1ed8\u01a0\u1ede\u1ee0\u1eda\u1edc\u1ee2\xd6\xd8\u014c","r\u0159R\u0158","s\u0161\u015b\u0219\u015fS\u0160\u015a\u0218\u015e","t\u0165\u021b\u0163T\u0164\u021a\u0162","u\xf9\xfa\u1ee7\u0169\u1ee5\u01b0\u1eeb\u1ee9\u1eed\u1eef\u1ef1\xfb\xfc\u016f\u016bU\xd9\xda\u1ee6\u0168\u1ee4\u01af\u1eea\u1ee8\u1eec\u1eee\u1ef0\xdb\xdc\u016e\u016a","y\xfd\u1ef3\u1ef7\u1ef9\u1ef5\xffY\xdd\u1ef2\u1ef6\u1ef8\u1ef4\u0178","z\u017e\u017c\u017aZ\u017d\u017b\u0179"],r=[];return e.split("").forEach(function(o){n.every(function(n){if(-1!==n.indexOf(o)){if(r.indexOf(n)>-1)return!1;e=e.replace(new RegExp("["+n+"]","gm"+t),"["+n+"]"),r.push(n)}return!0})}),e}},{key:"createMergedBlanksRegExp",value:function(e){return e.replace(/[\s]+/gim,"[\\s]+")}},{key:"createAccuracyRegExp",value:function(e){var t=this,n="!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~\xa1\xbf",r=this.opt.accuracy,o="string"==typeof r?r:r.value,i="string"==typeof r?[]:r.limiters,a="";switch(i.forEach(function(e){a+="|"+t.escapeStr(e)}),o){case"partially":default:return"()("+e+")";case"complementary":return"()([^"+(a="\\s"+(a||this.escapeStr(n)))+"]*"+e+"[^"+a+"]*)";case"exactly":return"(^|\\s"+a+")("+e+")(?=$|\\s"+a+")"}}},{key:"getSeparatedKeywords",value:function(e){var t=this,n=[];return e.forEach(function(e){t.opt.separateWordSearch?e.split(" ").forEach(function(e){e.trim()&&-1===n.indexOf(e)&&n.push(e)}):e.trim()&&-1===n.indexOf(e)&&n.push(e)}),{keywords:n.sort(function(e,t){return t.length-e.length}),length:n.length}}},{key:"isNumeric",value:function(e){return Number(parseFloat(e))==e}},{key:"checkRanges",value:function(e){var t=this;if(!Array.isArray(e)||"[object Object]"!==Object.prototype.toString.call(e[0]))return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];var n=[],r=0;return e.sort(function(e,t){return e.start-t.start}).forEach(function(e){var o=t.callNoMatchOnInvalidRanges(e,r),i=o.start,a=o.end;o.valid&&(e.start=i,e.length=a-i,n.push(e),r=a)}),n}},{key:"callNoMatchOnInvalidRanges",value:function(e,t){var n=void 0,r=void 0,o=!1;return e&&void 0!==e.start?(r=(n=parseInt(e.start,10))+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&r-t>0&&r-n>0?o=!0:(this.log("Ignoring invalid or overlapping range: "+JSON.stringify(e)),this.opt.noMatch(e))):(this.log("Ignoring invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:n,end:r,valid:o}}},{key:"checkWhitespaceRanges",value:function(e,t,n){var r=void 0,o=!0,i=n.length,a=t-i,s=parseInt(e.start,10)-a;return(r=(s=s>i?i:s)+parseInt(e.length,10))>i&&(r=i,this.log("End range automatically set to the max value of "+i)),s<0||r-s<0||s>i||r>i?(o=!1,this.log("Invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)):""===n.substring(s,r).replace(/\s+/g,"")&&(o=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:s,end:r,valid:o}}},{key:"getTextNodes",value:function(e){var t=this,n="",r=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,function(e){r.push({start:n.length,end:(n+=e.textContent).length,node:e})},function(e){return t.matchesExclude(e.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},function(){e({value:n,nodes:r})})}},{key:"matchesExclude",value:function(e){return o.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}},{key:"wrapRangeInTextNode",value:function(e,t,n){var r=this.opt.element?this.opt.element:"mark",o=e.splitText(t),i=o.splitText(n-t),a=document.createElement(r);return a.setAttribute("data-markjs","true"),this.opt.className&&a.setAttribute("class",this.opt.className),a.textContent=o.textContent,o.parentNode.replaceChild(a,o),i}},{key:"wrapRangeInMappedTextNode",value:function(e,t,n,r,o){var i=this;e.nodes.every(function(a,s){var l=e.nodes[s+1];if(void 0===l||l.start>t){if(!r(a.node))return!1;var c=t-a.start,u=(n>a.end?a.end:n)-a.start,p=e.value.substr(0,a.start),d=e.value.substr(u+a.start);if(a.node=i.wrapRangeInTextNode(a.node,c,u),e.value=p+d,e.nodes.forEach(function(t,n){n>=s&&(e.nodes[n].start>0&&n!==s&&(e.nodes[n].start-=u),e.nodes[n].end-=u)}),n-=u,o(a.node.previousSibling,a.start),!(n>a.end))return!1;t=a.end}return!0})}},{key:"wrapMatches",value:function(e,t,n,r,o){var i=this,a=0===t?0:t+1;this.getTextNodes(function(t){t.nodes.forEach(function(t){t=t.node;for(var o=void 0;null!==(o=e.exec(t.textContent))&&""!==o[a];)if(n(o[a],t)){var s=o.index;if(0!==a)for(var l=1;l<a;l++)s+=o[l].length;t=i.wrapRangeInTextNode(t,s,s+o[a].length),r(t.previousSibling),e.lastIndex=0}}),o()})}},{key:"wrapMatchesAcrossElements",value:function(e,t,n,r,o){var i=this,a=0===t?0:t+1;this.getTextNodes(function(t){for(var s=void 0;null!==(s=e.exec(t.value))&&""!==s[a];){var l=s.index;if(0!==a)for(var c=1;c<a;c++)l+=s[c].length;var u=l+s[a].length;i.wrapRangeInMappedTextNode(t,l,u,function(e){return n(s[a],e)},function(t,n){e.lastIndex=n,r(t)})}o()})}},{key:"wrapRangeFromIndex",value:function(e,t,n,r){var o=this;this.getTextNodes(function(i){var a=i.value.length;e.forEach(function(e,r){var s=o.checkWhitespaceRanges(e,a,i.value),l=s.start,c=s.end;s.valid&&o.wrapRangeInMappedTextNode(i,l,c,function(n){return t(n,e,i.value.substring(l,c),r)},function(t){n(t,e)})}),r()})}},{key:"unwrapMatches",value:function(e){for(var t=e.parentNode,n=document.createDocumentFragment();e.firstChild;)n.appendChild(e.removeChild(e.firstChild));t.replaceChild(n,e),this.ie?this.normalizeTextNode(t):t.normalize()}},{key:"normalizeTextNode",value:function(e){if(e){if(3===e.nodeType)for(;e.nextSibling&&3===e.nextSibling.nodeType;)e.nodeValue+=e.nextSibling.nodeValue,e.parentNode.removeChild(e.nextSibling);else this.normalizeTextNode(e.firstChild);this.normalizeTextNode(e.nextSibling)}}},{key:"markRegExp",value:function(e,t){var n=this;this.opt=t,this.log('Searching with expression "'+e+'"');var r=0,o="wrapMatches",i=function(e){r++,n.opt.each(e)};this.opt.acrossElements&&(o="wrapMatchesAcrossElements"),this[o](e,this.opt.ignoreGroups,function(e,t){return n.opt.filter(t,e,r)},i,function(){0===r&&n.opt.noMatch(e),n.opt.done(r)})}},{key:"mark",value:function(e,t){var n=this;this.opt=t;var r=0,o="wrapMatches",i=this.getSeparatedKeywords("string"==typeof e?[e]:e),a=i.keywords,s=i.length,l=this.opt.caseSensitive?"":"i",c=function e(t){var i=new RegExp(n.createRegExp(t),"gm"+l),c=0;n.log('Searching with expression "'+i+'"'),n[o](i,1,function(e,o){return n.opt.filter(o,t,r,c)},function(e){c++,r++,n.opt.each(e)},function(){0===c&&n.opt.noMatch(t),a[s-1]===t?n.opt.done(r):e(a[a.indexOf(t)+1])})};this.opt.acrossElements&&(o="wrapMatchesAcrossElements"),0===s?this.opt.done(r):c(a[0])}},{key:"markRanges",value:function(e,t){var n=this;this.opt=t;var r=0,o=this.checkRanges(e);o&&o.length?(this.log("Starting to mark with the following ranges: "+JSON.stringify(o)),this.wrapRangeFromIndex(o,function(e,t,r,o){return n.opt.filter(e,t,r,o)},function(e,t){r++,n.opt.each(e,t)},function(){n.opt.done(r)})):this.opt.done(r)}},{key:"unmark",value:function(e){var t=this;this.opt=e;var n=this.opt.element?this.opt.element:"*";n+="[data-markjs]",this.opt.className&&(n+="."+this.opt.className),this.log('Removal selector "'+n+'"'),this.iterator.forEachNode(NodeFilter.SHOW_ELEMENT,function(e){t.unwrapMatches(e)},function(e){var r=o.matches(e,n),i=t.matchesExclude(e);return!r||i?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},this.opt.done)}},{key:"opt",set:function(e){this._opt=r({},{element:"",className:"",exclude:[],iframes:!1,iframesTimeout:5e3,separateWordSearch:!0,diacritics:!0,synonyms:{},accuracy:"partially",acrossElements:!1,caseSensitive:!1,ignoreJoiners:!1,ignoreGroups:0,ignorePunctuation:[],wildcards:"disabled",each:function(){},noMatch:function(){},filter:function(){return!0},done:function(){},debug:!1,log:window.console},e)},get:function(){return this._opt}},{key:"iterator",get:function(){return new o(this.ctx,this.opt.iframes,this.opt.exclude,this.opt.iframesTimeout)}}]),i}();function a(e){var t=this,n=new i(e);return this.mark=function(e,r){return n.mark(e,r),t},this.markRegExp=function(e,r){return n.markRegExp(e,r),t},this.markRanges=function(e,r){return n.markRanges(e,r),t},this.unmark=function(e){return n.unmark(e),t},this}return a}()},2098:(e,t,n)=>{"use strict";n.d(t,{o:()=>a});var r=n(97639),o=n(56347),i=n(64609);function a(){const{siteConfig:{baseUrl:e,trailingSlash:t},i18n:{localeConfigs:n}}=(0,r.A)(),{pathname:a}=(0,o.zy)(),s=(0,i.Ks)(a,{trailingSlash:t,baseUrl:e}).replace(e,"");return{createUrl:function({locale:e,fullyQualified:t}){const r=function(e){const t=n[e];if(!t)throw new Error(`Unexpected Docusaurus bug, no locale config found for locale=${e}`);return t}(e);return`${`${t?r.url:""}`}${r.baseUrl}${s}`}}}},2117:(e,t,n)=>{"use strict";var r=n(96540),o=n(5338),i=n(80545),a=n(54625),s=n(4784),l=n(31712);const c=[n(85300),n(74753),n(75729),n(58252)];var u=n(92413),p=n(56347),d=n(22831),f=n(74848);function m({children:e}){return(0,f.jsx)(f.Fragment,{children:e})}var h=n(84030);const v=e=>e.defaultFormatter(e);function g({children:e}){return(0,f.jsx)(h.AL,{formatter:v,children:e})}function b({children:e}){return(0,f.jsx)(g,{children:e})}var y=n(21141),w=n(97639),x=n(98180),k=n(86957),_=n(17153),S=n(2098),E=n(19503),O=n(61482),j=n(64609),P=n(51210);function C(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,w.A)(),r=(0,S.o)(),o=n[e].htmlLang,i=e=>e.replace("-","_");return(0,f.jsxs)(y.A,{children:[Object.entries(n).map(([e,{htmlLang:t}])=>(0,f.jsx)("link",{rel:"alternate",href:r.createUrl({locale:e,fullyQualified:!0}),hrefLang:t},e)),(0,f.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,f.jsx)("meta",{property:"og:locale",content:i(o)}),Object.values(n).filter(e=>o!==e.htmlLang).map(e=>(0,f.jsx)("meta",{property:"og:locale:alternate",content:i(e.htmlLang)},`meta-og-${e.htmlLang}`))]})}function A({permalink:e}){const{siteConfig:{url:t}}=(0,w.A)(),n=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,w.A)(),{pathname:r}=(0,p.zy)();return e+(0,j.Ks)((0,x.Ay)(r),{trailingSlash:n,baseUrl:t})}(),r=e?`${t}${e}`:n;return(0,f.jsxs)(y.A,{children:[(0,f.jsx)("meta",{property:"og:url",content:r}),(0,f.jsx)("link",{rel:"canonical",href:r})]})}function T(){const{i18n:{currentLocale:e}}=(0,w.A)(),{metadata:t,image:n}=(0,k.p)();return(0,f.jsxs)(f.Fragment,{children:[(0,f.jsxs)(y.A,{children:[(0,f.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,f.jsx)("body",{className:E.w})]}),n&&(0,f.jsx)(_.be,{image:n}),(0,f.jsx)(A,{}),(0,f.jsx)(C,{}),(0,f.jsx)(P.A,{tag:O.C,locale:e}),(0,f.jsx)(y.A,{children:t.map((e,t)=>(0,f.jsx)("meta",{...e},t))})]})}const I=new Map;var N=n(48848),L=n(53366),R=n(36494);function D(e,...t){const n=c.map(n=>{const r=n.default?.[e]??n[e];return r?.(...t)});return()=>n.forEach(e=>e?.())}const F=function({children:e,location:t,previousLocation:n}){return(0,R.A)(()=>{n!==t&&(!function({location:e,previousLocation:t}){if(!t)return;const n=e.pathname===t.pathname,r=e.hash===t.hash,o=e.search===t.search;if(n&&r&&!o)return;const{hash:i}=e;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:t,previousLocation:n}),D("onRouteDidUpdate",{previousLocation:n,location:t}))},[n,t]),e};function M(e){const t=Array.from(new Set([e,decodeURI(e)])).map(e=>(0,d.u)(u.A,e)).flat();return Promise.all(t.map(e=>e.route.component.preload?.()))}class B extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=l.A.canUseDOM?D("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=D("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),M(n.pathname).then(()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})}).catch(e=>{console.warn(e),window.location.reload()}),!1}render(){const{children:e,location:t}=this.props;return(0,f.jsx)(F,{previousLocation:this.previousLocation,location:t,children:(0,f.jsx)(p.qh,{location:t,render:()=>e})})}}const z=B,$="__docusaurus-base-url-issue-banner-suggestion-container";function U(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '__docusaurus-base-url-issue-banner-container';\n var bannerHtml = ${JSON.stringify(function(e){return`\n<div id="__docusaurus-base-url-issue-banner" style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">\n <p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>\n <p>A very common reason is a wrong site <a href="https://docusaurus.io/docs/docusaurus.config.js/#baseUrl" style="font-weight: bold;">baseUrl configuration</a>.</p>\n <p>Current configured baseUrl = <span style="font-weight: bold; color: red;">${e}</span> ${"/"===e?" (default value)":""}</p>\n <p>We suggest trying baseUrl = <span id="${$}" style="font-weight: bold; color: green;"></span></p>\n</div>\n`}(e)).replace(/</g,"\\<")};\n bannerContainer.innerHTML = bannerHtml;\n document.body.prepend(bannerContainer);\n var suggestionContainer = document.getElementById('${$}');\n var actualHomePagePath = window.location.pathname;\n var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'\n ? actualHomePagePath\n : actualHomePagePath + '/';\n suggestionContainer.innerHTML = suggestedBaseUrl;\n}\n`}function V(){const{siteConfig:{baseUrl:e}}=(0,w.A)();return(0,f.jsx)(f.Fragment,{children:!l.A.canUseDOM&&(0,f.jsx)(y.A,{children:(0,f.jsx)("script",{children:U(e)})})})}function Q(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,w.A)(),{pathname:n}=(0,p.zy)();return t&&n===e?(0,f.jsx)(V,{}):null}function H(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:r,localeConfigs:o}}=(0,w.A)(),i=(0,x.Ay)(e),{htmlLang:a,direction:s}=o[r];return(0,f.jsxs)(y.A,{children:[(0,f.jsx)("html",{lang:a,dir:s}),(0,f.jsx)("title",{children:t}),(0,f.jsx)("meta",{property:"og:title",content:t}),(0,f.jsx)("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&(0,f.jsx)("meta",{name:"robots",content:"noindex, nofollow"}),e&&(0,f.jsx)("link",{rel:"icon",href:i})]})}var W=n(33832),q=n(11062);function G(){const e=(0,q.A)();return(0,f.jsx)(y.A,{children:(0,f.jsx)("html",{"data-has-hydrated":e})})}const K=(0,d.v)(u.A);function Y(){const e=function(e){if(I.has(e.pathname))return{...e,pathname:I.get(e.pathname)};if((0,d.u)(u.A,e.pathname).some(({route:e})=>!0===e.exact))return I.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return I.set(e.pathname,t),{...e,pathname:t}}((0,p.zy)());return(0,f.jsx)(z,{location:e,children:K})}function Z(){return(0,f.jsx)(W.A,{children:(0,f.jsx)(L.l,{children:(0,f.jsxs)(N.x,{children:[(0,f.jsx)(m,{children:(0,f.jsxs)(b,{children:[(0,f.jsx)(H,{}),(0,f.jsx)(T,{}),(0,f.jsx)(Q,{}),(0,f.jsx)(Y,{})]})}),(0,f.jsx)(G,{})]})})})}var J=n(84054);const X=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const o=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;o?.appendChild(r)})}:function(e){return new Promise((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)})};var ee=n(81604);const te=new Set,ne=new Set,re=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,oe={prefetch:e=>{if(!(e=>!re()&&!ne.has(e)&&!te.has(e))(e))return!1;te.add(e);const t=(0,d.u)(u.A,e).flatMap(e=>{return t=e.route.path,Object.entries(J).filter(([e])=>e.replace(/-[^-]+$/,"")===t).flatMap(([,e])=>Object.values((0,ee.A)(e)));var t});return Promise.all(t.map(e=>{const t=n.gca(e);return t&&!t.includes("undefined")?X(t).catch(()=>{}):Promise.resolve()}))},preload:e=>!!(e=>!re()&&!ne.has(e))(e)&&(ne.add(e),M(e))},ie=Object.freeze(oe);function ae({children:e}){return"hash"===s.A.future.experimental_router?(0,f.jsx)(a.I9,{children:e}):(0,f.jsx)(a.Kd,{children:e})}const se=Boolean(!0);if(l.A.canUseDOM){window.docusaurus=ie;const e=document.getElementById("__docusaurus"),t=(0,f.jsx)(i.vd,{children:(0,f.jsx)(ae,{children:(0,f.jsx)(Z,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},a=()=>{if(window.docusaurusRoot)window.docusaurusRoot.render(t);else if(se)window.docusaurusRoot=o.hydrateRoot(e,t,{onRecoverableError:n});else{const r=o.createRoot(e,{onRecoverableError:n});r.render(t),window.docusaurusRoot=r}};M(window.location.pathname).then(()=>{(0,r.startTransition)(a)})}},2694:(e,t,n)=>{"use strict";var r=n(6925);function o(){}function i(){}i.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,i,a){if(a!==r){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:i,resetWarningCache:o};return n.PropTypes=n,n}},2833:e=>{e.exports=function(e,t,n,r){var o=n?n.call(r,e,t):void 0;if(void 0!==o)return!!o;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var i=Object.keys(e),a=Object.keys(t);if(i.length!==a.length)return!1;for(var s=Object.prototype.hasOwnProperty.bind(t),l=0;l<i.length;l++){var c=i[l];if(!s(c))return!1;var u=e[c],p=t[c];if(!1===(o=n?n.call(r,u,p,c):void 0)||void 0===o&&u!==p)return!1}return!0}},4146:(e,t,n)=>{"use strict";var r=n(44363),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},i={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},a={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function l(e){return r.isMemo(e)?a:s[e.$$typeof]||o}s[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[r.Memo]=a;var c=Object.defineProperty,u=Object.getOwnPropertyNames,p=Object.getOwnPropertySymbols,d=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var o=f(n);o&&o!==m&&e(t,o,r)}var a=u(n);p&&(a=a.concat(p(n)));for(var s=l(t),h=l(n),v=0;v<a.length;++v){var g=a[v];if(!(i[g]||r&&r[g]||h&&h[g]||s&&s[g])){var b=d(n,g);try{c(t,g,b)}catch(y){}}}}return t}},4784:(e,t,n)=>{"use strict";n.d(t,{A:()=>r});const r={title:"Constellation",tagline:"Constellation: The world's most secure Kubernetes",url:"https://docs.edgeless.systems",baseUrl:"/constellation/pr-preview/pr-4027/",onBrokenLinks:"throw",onBrokenAnchors:"throw",favicon:"img/favicon.ico",organizationName:"Edgeless Systems",projectName:"Constellation",scripts:[{src:"/constellation/gtagman.js",async:!0,"data-cookieconsent":"ignore"}],i18n:{defaultLocale:"en",locales:["en"],path:"i18n",localeConfigs:{}},markdown:{mermaid:!0,hooks:{onBrokenMarkdownLinks:"throw",onBrokenMarkdownImages:"throw"},format:"mdx",emoji:!0,mdx1Compat:{comments:!0,admonitions:!0,headingIds:!0},anchors:{maintainCase:!1}},themes:["@docusaurus/theme-mermaid"],presets:[["classic",{docs:{sidebarPath:"/home/runner/work/constellation/constellation/docs/sidebars.js",editUrl:"https://github.com/edgelesssys/constellation/edit/main/docs",routeBasePath:"/"},blog:!1,theme:{customCss:"/home/runner/work/constellation/constellation/docs/src/css/custom.css"}}]],themeConfig:{navbar:{hideOnScroll:!1,logo:{alt:"Constellation Logo",src:"img/logos/constellation_oneline.svg"},items:[{type:"docsVersionDropdown",position:"right",dropdownItemsBefore:[],dropdownItemsAfter:[]},{href:"https://github.com/edgelesssys/constellation",position:"right",className:"header-github-link"}]},colorMode:{defaultMode:"light",disableSwitch:!0,respectPrefersColorScheme:!1},announcementBar:{content:'If you like Constellation, give it a star on <a target="_blank" rel="noopener noreferrer" href="https://github.com/edgelesssys/constellation">GitHub</a> \u2b50\ufe0f',backgroundColor:"#E7E6E6",id:"announcement-bar",isCloseable:!0},footer:{style:"dark",links:[{title:"Learn",items:[{label:"Confidential Kubernetes",to:"/overview/confidential-kubernetes"},{label:"Install",to:"/getting-started/install"},{label:"First steps",to:"/getting-started/first-steps"}]},{title:"Community",items:[{label:"GitHub",href:"https://github.com/edgelesssys/constellation"},{label:"Newsletter",href:"https://www.edgeless.systems/#footer"}]},{title:"Social",items:[{label:"Blog",href:"https://www.edgeless.systems/blog/"},{label:"Twitter",href:"https://twitter.com/EdgelessSystems"},{label:"LinkedIn",href:"https://www.linkedin.com/company/edgeless-systems/"},{label:"Youtube",href:"https://www.youtube.com/channel/UCOOInN0sCv6icUesisYIDeA"}]},{title:"Company",items:[{label:"Imprint",href:"https://www.edgeless.systems/imprint/"},{label:"Privacy Policy",href:"https://www.edgeless.systems/privacy/"},{html:'<a href="javascript: Cookiebot.renew()" class="footer__link-item">Cookie Settings</a>'},{label:"Contact Us",href:"https://www.edgeless.systems/contact-us/"}]}],copyright:"Copyright \xa9 2025 Edgeless Systems"},prism:{theme:{plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},darkTheme:{plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},additionalLanguages:["shell-session"],magicComments:[{className:"theme-code-block-highlighted-line",line:"highlight-next-line",block:{start:"highlight-start",end:"highlight-end"}}]},mermaid:{theme:{light:"base",dark:"base"},options:{themeVariables:{fontFamily:'"Open Sans", sans-serif',primaryColor:"#90FF99",primaryTextColor:"#000000",secondaryColor:"#A5A5A5",secondaryTextColor:"#000000",tertiaryColor:"#E7E6E6",tertiaryTextColor:"#000000",clusterBorder:"#A5A5A5",clusterBkg:"#ffffff",edgeLabelBackground:"#ffffff",activationBorderColor:"#000000",actorBorder:"#A5A5A5",actorFontFamily:'"Open Sans", sans-serif',noteBkgColor:"#8B04DD",noteTextColor:"#ffffff"},startOnLoad:!0}},docs:{versionPersistence:"localStorage",sidebar:{hideable:!1,autoCollapseCategories:!1}},blog:{sidebar:{groupByYear:!0}},metadata:[],tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3}},plugins:[["/home/runner/work/constellation/constellation/docs/node_modules/@cmfcmf/docusaurus-search-local/lib/server/index.js",{indexDocs:!0,indexDocSidebarParentCategories:0,indexBlog:!1,indexPages:!1,language:"en",maxSearchResults:8,lunr:{tokenizerSeparator:{},b:.75,k1:1.2,titleBoost:5,contentBoost:1,tagsBoost:3,parentCategoriesBoost:2}}]],baseUrlIssueBanner:!0,future:{v4:{removeLegacyPostBuildHeadAttribute:!1,useCssCascadeLayers:!1},experimental_faster:{swcJsLoader:!1,swcJsMinimizer:!1,swcHtmlMinimizer:!1,lightningCssMinimizer:!1,mdxCrossCompilerCache:!1,rspackBundler:!1,rspackPersistentCache:!1,ssgWorkerThreads:!1},experimental_storage:{type:"localStorage",namespace:!1},experimental_router:"browser"},onDuplicateRoutes:"warn",staticDirectories:["static"],customFields:{},headTags:[],stylesheets:[],clientModules:[],titleDelimiter:"|",noIndex:!1}},4799:(e,t,n)=>{"use strict";n.d(t,{Be:()=>c,ZC:()=>s,_q:()=>a,dV:()=>l,fM:()=>u});var r=n(96540),o=n(36494),i=n(74848);function a(e){const t=(0,r.useRef)(e);return(0,o.A)(()=>{t.current=e},[e]),(0,r.useCallback)((...e)=>t.current(...e),[])}function s(e){const t=(0,r.useRef)();return(0,o.A)(()=>{t.current=e}),t.current}class l extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?<name>\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function c(e){const t=Object.entries(e);return t.sort((e,t)=>e[0].localeCompare(t[0])),(0,r.useMemo)(()=>e,t.flat())}function u(e){return({children:t})=>(0,i.jsx)(i.Fragment,{children:e.reduceRight((e,t)=>(0,i.jsx)(t,{children:e}),t)})}},5338:(e,t,n)=>{"use strict";var r=n(40961);t.createRoot=r.createRoot,t.hydrateRoot=r.hydrateRoot},5556:(e,t,n)=>{e.exports=n(2694)()},5947:function(e,t,n){var r,o;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};function o(e,t,n){return e<t?t:e>n?n:e}function i(e){return 100*(-1+e)}function a(e,t,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+i(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+i(e)+"%,0)"}:{"margin-left":i(e)+"%"}).transition="all "+t+"ms "+n,o}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=o(e,r.minimum,1),n.status=1===e?null:e;var i=n.render(!t),c=i.querySelector(r.barSelector),u=r.speed,p=r.easing;return i.offsetWidth,s(function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),l(c,a(e,u,p)),1===e?(l(i,{transition:"none",opacity:1}),i.offsetWidth,setTimeout(function(){l(i,{transition:"all "+u+"ms linear",opacity:0}),setTimeout(function(){n.remove(),t()},u)},u)):setTimeout(t,u)}),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout(function(){n.status&&(n.trickle(),e())},r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*o(Math.random()*t,.1,.95)),t=o(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always(function(){0===--t?(e=0,n.done()):n.set((e-t)/e)}),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var o,a=t.querySelector(r.barSelector),s=e?"-100":i(n.status||0),c=document.querySelector(r.parent);return l(a,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),r.showSpinner||(o=t.querySelector(r.spinnerSelector))&&f(o),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){p(document.documentElement,"nprogress-busy"),p(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var s=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),l=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(e,t){return t.toUpperCase()})}function r(t){var n=document.body.style;if(t in n)return t;for(var r,o=e.length,i=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((r=e[o]+i)in n)return r;return t}function o(e){return e=n(e),t[e]||(t[e]=r(e))}function i(e,t,n){t=o(t),e.style[t]=n}return function(e,t){var n,r,o=arguments;if(2==o.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&i(e,n,r);else i(e,o[1],o[2])}}();function c(e,t){return("string"==typeof e?e:d(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=d(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function p(e,t){var n,r=d(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function d(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(o="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=o)},6925:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},7463:(e,t)=>{"use strict";function n(e,t){var n=e.length;e.push(t);e:for(;0<n;){var r=n-1>>>1,o=e[r];if(!(0<i(o,t)))break e;e[r]=t,e[n]=o,n=r}}function r(e){return 0===e.length?null:e[0]}function o(e){if(0===e.length)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,o=e.length,a=o>>>1;r<a;){var s=2*(r+1)-1,l=e[s],c=s+1,u=e[c];if(0>i(l,n))c<o&&0>i(u,l)?(e[r]=u,e[c]=n,r=c):(e[r]=l,e[s]=n,r=s);else{if(!(c<o&&0>i(u,n)))break e;e[r]=u,e[c]=n,r=c}}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}if("object"==typeof performance&&"function"==typeof performance.now){var a=performance;t.unstable_now=function(){return a.now()}}else{var s=Date,l=s.now();t.unstable_now=function(){return s.now()-l}}var c=[],u=[],p=1,d=null,f=3,m=!1,h=!1,v=!1,g="function"==typeof setTimeout?setTimeout:null,b="function"==typeof clearTimeout?clearTimeout:null,y="undefined"!=typeof setImmediate?setImmediate:null;function w(e){for(var t=r(u);null!==t;){if(null===t.callback)o(u);else{if(!(t.startTime<=e))break;o(u),t.sortIndex=t.expirationTime,n(c,t)}t=r(u)}}function x(e){if(v=!1,w(e),!h)if(null!==r(c))h=!0,N(k);else{var t=r(u);null!==t&&L(x,t.startTime-e)}}function k(e,n){h=!1,v&&(v=!1,b(O),O=-1),m=!0;var i=f;try{for(w(n),d=r(c);null!==d&&(!(d.expirationTime>n)||e&&!C());){var a=d.callback;if("function"==typeof a){d.callback=null,f=d.priorityLevel;var s=a(d.expirationTime<=n);n=t.unstable_now(),"function"==typeof s?d.callback=s:d===r(c)&&o(c),w(n)}else o(c);d=r(c)}if(null!==d)var l=!0;else{var p=r(u);null!==p&&L(x,p.startTime-n),l=!1}return l}finally{d=null,f=i,m=!1}}"undefined"!=typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var _,S=!1,E=null,O=-1,j=5,P=-1;function C(){return!(t.unstable_now()-P<j)}function A(){if(null!==E){var e=t.unstable_now();P=e;var n=!0;try{n=E(!0,e)}finally{n?_():(S=!1,E=null)}}else S=!1}if("function"==typeof y)_=function(){y(A)};else if("undefined"!=typeof MessageChannel){var T=new MessageChannel,I=T.port2;T.port1.onmessage=A,_=function(){I.postMessage(null)}}else _=function(){g(A,0)};function N(e){E=e,S||(S=!0,_())}function L(e,n){O=g(function(){e(t.unstable_now())},n)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){h||m||(h=!0,N(k))},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):j=0<e?Math.floor(1e3/e):5},t.unstable_getCurrentPriorityLevel=function(){return f},t.unstable_getFirstCallbackNode=function(){return r(c)},t.unstable_next=function(e){switch(f){case 1:case 2:case 3:var t=3;break;default:t=f}var n=f;f=t;try{return e()}finally{f=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=function(){},t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=f;f=e;try{return t()}finally{f=n}},t.unstable_scheduleCallback=function(e,o,i){var a=t.unstable_now();switch("object"==typeof i&&null!==i?i="number"==typeof(i=i.delay)&&0<i?a+i:a:i=a,e){case 1:var s=-1;break;case 2:s=250;break;case 5:s=1073741823;break;case 4:s=1e4;break;default:s=5e3}return e={id:p++,callback:o,priorityLevel:e,startTime:i,expirationTime:s=i+s,sortIndex:-1},i>a?(e.sortIndex=i,n(u,e),null===r(c)&&e===r(u)&&(v?(b(O),O=-1):v=!0,L(x,i-a))):(e.sortIndex=s,n(c,e),h||m||(h=!0,N(k))),e},t.unstable_shouldYield=C,t.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}},7710:(e,t,n)=>{"use strict";n.d(t,{G:()=>x,a:()=>w});var r=n(96540),o=n(11062),i=n(4799),a=n(69900),s=n(86957),l=n(74848);function c(){return window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}function u(e){return function(e,t){const n=window.matchMedia(e);return n.addEventListener("change",t),()=>n.removeEventListener("change",t)}("(prefers-color-scheme: dark)",()=>e(c()))}const p=r.createContext(void 0),d=(0,a.Wf)("theme"),f="system",m=e=>"dark"===e?"dark":"light",h=e=>null===e||e===f?null:m(e),v={get:()=>m(document.documentElement.getAttribute("data-theme")),set:e=>{document.documentElement.setAttribute("data-theme",m(e))}},g={get:()=>h(document.documentElement.getAttribute("data-theme-choice")),set:e=>{document.documentElement.setAttribute("data-theme-choice",h(e)??f)}},b=e=>{null===e?d.del():d.set(m(e))};function y(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,s.p)(),{colorMode:i,setColorModeState:a,colorModeChoice:l,setColorModeChoiceState:p}=function(){const{colorMode:{defaultMode:e}}=(0,s.p)(),t=(0,o.A)(),[n,i]=(0,r.useState)(t?v.get():e),[a,l]=(0,r.useState)(t?g.get():null);return(0,r.useEffect)(()=>{i(v.get()),l(g.get())},[]),{colorMode:n,setColorModeState:i,colorModeChoice:a,setColorModeChoiceState:l}}();(0,r.useEffect)(()=>{t&&d.del()},[t]);const f=(0,r.useCallback)((t,r={})=>{const{persist:o=!0}=r;if(null===t){const t=n?c():e;v.set(t),a(t),g.set(null),p(null)}else v.set(t),g.set(t),a(t),p(t);o&&b(t)},[a,p,n,e]);return(0,r.useEffect)(()=>d.listen(e=>{f(h(e.newValue))}),[f]),(0,r.useEffect)(()=>{if(null===l&&n)return u(e=>{a(e),v.set(e)})},[n,l,a]),(0,r.useMemo)(()=>({colorMode:i,colorModeChoice:l,setColorMode:f,get isDarkTheme(){return"dark"===i},setLightTheme(){f("light")},setDarkTheme(){f("dark")}}),[i,l,f])}function w({children:e}){const t=y();return(0,l.jsx)(p.Provider,{value:t,children:e})}function x(){const e=(0,r.useContext)(p);if(null==e)throw new i.dV("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},11062:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});var r=n(96540),o=n(48848);function i(){return(0,r.useContext)(o.o)}},11561:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});var r=!0,o="Invariant failed";function i(e,t){if(!e){if(r)throw new Error(o);var n="function"==typeof t?t():t,i=n?"".concat(o,": ").concat(n):o;throw new Error(i)}}},14783:(e,t,n)=>{"use strict";n.d(t,{A:()=>f});var r=n(96540),o=n(54625),i=n(64609),a=n(97639),s=n(40877),l=n(31712),c=n(37344),u=n(98180),p=n(74848);function d({isNavLink:e,to:t,href:n,activeClassName:d,isActive:f,"data-noBrokenLinkCheck":m,autoAddBaseUrl:h=!0,...v},g){const{siteConfig:b}=(0,a.A)(),{trailingSlash:y,baseUrl:w}=b,x=b.future.experimental_router,{withBaseUrl:k}=(0,u.hH)(),_=(0,c.A)(),S=(0,r.useRef)(null);(0,r.useImperativeHandle)(g,()=>S.current);const E=t||n;const O=(0,s.A)(E),j=E?.replace("pathname://","");let P=void 0!==j?(C=j,h&&(e=>e.startsWith("/"))(C)?k(C):C):void 0;var C;"hash"===x&&P?.startsWith("./")&&(P=P?.slice(1)),P&&O&&(P=(0,i.Ks)(P,{trailingSlash:y,baseUrl:w}));const A=(0,r.useRef)(!1),T=e?o.k2:o.N_,I=l.A.canUseIntersectionObserver,N=(0,r.useRef)(),L=()=>{A.current||null==P||(window.docusaurus.preload(P),A.current=!0)};(0,r.useEffect)(()=>(!I&&O&&l.A.canUseDOM&&null!=P&&window.docusaurus.prefetch(P),()=>{I&&N.current&&N.current.disconnect()}),[N,P,I,O]);const R=P?.startsWith("#")??!1,D=!v.target||"_self"===v.target,F=!P||!O||!D||R&&"hash"!==x;m||!R&&F||_.collectLink(P),v.id&&_.collectAnchor(v.id);const M={};return F?(0,p.jsx)("a",{ref:S,href:P,...E&&!O&&{target:"_blank",rel:"noopener noreferrer"},...v,...M}):(0,p.jsx)(T,{...v,onMouseEnter:L,onTouchStart:L,innerRef:e=>{S.current=e,I&&e&&O&&(N.current=new window.IntersectionObserver(t=>{t.forEach(t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(N.current.unobserve(e),N.current.disconnect(),null!=P&&window.docusaurus.prefetch(P))})}),N.current.observe(e))},to:P,...e&&{isActive:f,activeClassName:d},...M})}const f=r.forwardRef(d)},15287:(e,t)=>{"use strict";var n=Symbol.for("react.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),i=Symbol.for("react.strict_mode"),a=Symbol.for("react.profiler"),s=Symbol.for("react.provider"),l=Symbol.for("react.context"),c=Symbol.for("react.forward_ref"),u=Symbol.for("react.suspense"),p=Symbol.for("react.memo"),d=Symbol.for("react.lazy"),f=Symbol.iterator;var m={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},h=Object.assign,v={};function g(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||m}function b(){}function y(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||m}g.prototype.isReactComponent={},g.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},g.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},b.prototype=g.prototype;var w=y.prototype=new b;w.constructor=y,h(w,g.prototype),w.isPureReactComponent=!0;var x=Array.isArray,k=Object.prototype.hasOwnProperty,_={current:null},S={key:!0,ref:!0,__self:!0,__source:!0};function E(e,t,r){var o,i={},a=null,s=null;if(null!=t)for(o in void 0!==t.ref&&(s=t.ref),void 0!==t.key&&(a=""+t.key),t)k.call(t,o)&&!S.hasOwnProperty(o)&&(i[o]=t[o]);var l=arguments.length-2;if(1===l)i.children=r;else if(1<l){for(var c=Array(l),u=0;u<l;u++)c[u]=arguments[u+2];i.children=c}if(e&&e.defaultProps)for(o in l=e.defaultProps)void 0===i[o]&&(i[o]=l[o]);return{$$typeof:n,type:e,key:a,ref:s,props:i,_owner:_.current}}function O(e){return"object"==typeof e&&null!==e&&e.$$typeof===n}var j=/\/+/g;function P(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,function(e){return t[e]})}(""+e.key):t.toString(36)}function C(e,t,o,i,a){var s=typeof e;"undefined"!==s&&"boolean"!==s||(e=null);var l=!1;if(null===e)l=!0;else switch(s){case"string":case"number":l=!0;break;case"object":switch(e.$$typeof){case n:case r:l=!0}}if(l)return a=a(l=e),e=""===i?"."+P(l,0):i,x(a)?(o="",null!=e&&(o=e.replace(j,"$&/")+"/"),C(a,t,o,"",function(e){return e})):null!=a&&(O(a)&&(a=function(e,t){return{$$typeof:n,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(a,o+(!a.key||l&&l.key===a.key?"":(""+a.key).replace(j,"$&/")+"/")+e)),t.push(a)),1;if(l=0,i=""===i?".":i+":",x(e))for(var c=0;c<e.length;c++){var u=i+P(s=e[c],c);l+=C(s,t,o,u,a)}else if(u=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=f&&e[f]||e["@@iterator"])?e:null}(e),"function"==typeof u)for(e=u.call(e),c=0;!(s=e.next()).done;)l+=C(s=s.value,t,o,u=i+P(s,c++),a);else if("object"===s)throw t=String(e),Error("Objects are not valid as a React child (found: "+("[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t)+"). If you meant to render a collection of children, use an array instead.");return l}function A(e,t,n){if(null==e)return e;var r=[],o=0;return C(e,r,"","",function(e){return t.call(n,e,o++)}),r}function T(e){if(-1===e._status){var t=e._result;(t=t()).then(function(t){0!==e._status&&-1!==e._status||(e._status=1,e._result=t)},function(t){0!==e._status&&-1!==e._status||(e._status=2,e._result=t)}),-1===e._status&&(e._status=0,e._result=t)}if(1===e._status)return e._result.default;throw e._result}var I={current:null},N={transition:null},L={ReactCurrentDispatcher:I,ReactCurrentBatchConfig:N,ReactCurrentOwner:_};function R(){throw Error("act(...) is not supported in production builds of React.")}t.Children={map:A,forEach:function(e,t,n){A(e,function(){t.apply(this,arguments)},n)},count:function(e){var t=0;return A(e,function(){t++}),t},toArray:function(e){return A(e,function(e){return e})||[]},only:function(e){if(!O(e))throw Error("React.Children.only expected to receive a single React element child.");return e}},t.Component=g,t.Fragment=o,t.Profiler=a,t.PureComponent=y,t.StrictMode=i,t.Suspense=u,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=L,t.act=R,t.cloneElement=function(e,t,r){if(null==e)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+e+".");var o=h({},e.props),i=e.key,a=e.ref,s=e._owner;if(null!=t){if(void 0!==t.ref&&(a=t.ref,s=_.current),void 0!==t.key&&(i=""+t.key),e.type&&e.type.defaultProps)var l=e.type.defaultProps;for(c in t)k.call(t,c)&&!S.hasOwnProperty(c)&&(o[c]=void 0===t[c]&&void 0!==l?l[c]:t[c])}var c=arguments.length-2;if(1===c)o.children=r;else if(1<c){l=Array(c);for(var u=0;u<c;u++)l[u]=arguments[u+2];o.children=l}return{$$typeof:n,type:e.type,key:i,ref:a,props:o,_owner:s}},t.createContext=function(e){return(e={$$typeof:l,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null}).Provider={$$typeof:s,_context:e},e.Consumer=e},t.createElement=E,t.createFactory=function(e){var t=E.bind(null,e);return t.type=e,t},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:c,render:e}},t.isValidElement=O,t.lazy=function(e){return{$$typeof:d,_payload:{_status:-1,_result:e},_init:T}},t.memo=function(e,t){return{$$typeof:p,type:e,compare:void 0===t?null:t}},t.startTransition=function(e){var t=N.transition;N.transition={};try{e()}finally{N.transition=t}},t.unstable_act=R,t.useCallback=function(e,t){return I.current.useCallback(e,t)},t.useContext=function(e){return I.current.useContext(e)},t.useDebugValue=function(){},t.useDeferredValue=function(e){return I.current.useDeferredValue(e)},t.useEffect=function(e,t){return I.current.useEffect(e,t)},t.useId=function(){return I.current.useId()},t.useImperativeHandle=function(e,t,n){return I.current.useImperativeHandle(e,t,n)},t.useInsertionEffect=function(e,t){return I.current.useInsertionEffect(e,t)},t.useLayoutEffect=function(e,t){return I.current.useLayoutEffect(e,t)},t.useMemo=function(e,t){return I.current.useMemo(e,t)},t.useReducer=function(e,t,n){return I.current.useReducer(e,t,n)},t.useRef=function(e){return I.current.useRef(e)},t.useState=function(e){return I.current.useState(e)},t.useSyncExternalStore=function(e,t,n){return I.current.useSyncExternalStore(e,t,n)},t.useTransition=function(){return I.current.useTransition()},t.version="18.3.1"},17153:(e,t,n)=>{"use strict";n.d(t,{Jx:()=>g,be:()=>m,e3:()=>v});var r=n(96540),o=n(34164),i=n(21141),a=n(93512),s=n(98180),l=n(84030),c=n(74848);function u({title:e}){const t=(0,l.s$)().format(e);return(0,c.jsxs)(i.A,{children:[(0,c.jsx)("title",{children:t}),(0,c.jsx)("meta",{property:"og:title",content:t})]})}function p({description:e}){return(0,c.jsxs)(i.A,{children:[(0,c.jsx)("meta",{name:"description",content:e}),(0,c.jsx)("meta",{property:"og:description",content:e})]})}function d({image:e}){const{withBaseUrl:t}=(0,s.hH)(),n=t(e,{absolute:!0});return(0,c.jsxs)(i.A,{children:[(0,c.jsx)("meta",{property:"og:image",content:n}),(0,c.jsx)("meta",{name:"twitter:image",content:n})]})}function f({keywords:e}){return(0,c.jsx)(i.A,{children:(0,c.jsx)("meta",{name:"keywords",content:Array.isArray(e)?e.join(","):e})})}function m({title:e,description:t,keywords:n,image:r,children:o}){return(0,c.jsxs)(c.Fragment,{children:[e&&(0,c.jsx)(u,{title:e}),t&&(0,c.jsx)(p,{description:t}),n&&(0,c.jsx)(f,{keywords:n}),r&&(0,c.jsx)(d,{image:r}),o&&(0,c.jsx)(i.A,{children:o})]})}const h=r.createContext(void 0);function v({className:e,children:t}){const n=r.useContext(h),a=(0,o.A)(n,e);return(0,c.jsxs)(h.Provider,{value:a,children:[(0,c.jsx)(i.A,{children:(0,c.jsx)("html",{className:a})}),t]})}function g({children:e}){const t=(0,a.A)(),n=`plugin-${t.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const r=`plugin-id-${t.plugin.id}`;return(0,c.jsx)(v,{className:(0,o.A)(n,r),children:e})}},18630:(e,t,n)=>{"use strict";n.d(t,{G:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",blogAuthorsListPage:"blog-authors-list-page",blogAuthorsPostsPage:"blog-authors-posts-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",draftBanner:"theme-draft-banner",admonitionType:e=>`theme-admonition-${e}`},announcementBar:{container:"theme-announcement-bar"},tabs:{container:"theme-tabs-container"},layout:{navbar:{container:"theme-layout-navbar",containerLeft:"theme-layout-navbar-left",containerRight:"theme-layout-navbar-right",mobileSidebar:{container:"theme-layout-navbar-sidebar",panel:"theme-layout-navbar-sidebar-panel"}},main:{container:"theme-layout-main"},footer:{container:"theme-layout-footer",column:"theme-layout-footer-column"}},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{blogFooterTagsRow:"theme-blog-footer-tags-row",blogFooterEditMetaRow:"theme-blog-footer-edit-meta-row"},pages:{pageFooterEditMetaRow:"theme-pages-footer-edit-meta-row"}}},19503:(e,t,n)=>{"use strict";n.d(t,{w:()=>o,J:()=>i});var r=n(96540);const o="navigation-with-keyboard";function i(){(0,r.useEffect)(()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(o),"mousedown"===e.type&&document.body.classList.remove(o)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(o),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}},[])}},19700:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,o,i){if(n.language===r){var a=n.tokenStack=[];n.code=n.code.replace(o,function(e){if("function"==typeof i&&!i(e))return e;for(var o,s=a.length;-1!==n.code.indexOf(o=t(r,s));)++s;return a[s]=e,o}),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var o=0,i=Object.keys(n.tokenStack);!function a(s){for(var l=0;l<s.length&&!(o>=i.length);l++){var c=s[l];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=i[o],p=n.tokenStack[u],d="string"==typeof c?c:c.content,f=t(r,u),m=d.indexOf(f);if(m>-1){++o;var h=d.substring(0,m),v=new e.Token(r,e.tokenize(p,n.grammar),"language-"+r,p),g=d.substring(m+f.length),b=[];h&&b.push.apply(b,a([h])),b.push(v),g&&b.push.apply(b,a([g])),"string"==typeof c?s.splice.apply(s,[l,1].concat(b)):c.content=b}}else c.content&&a(c.content)}return s}(n.tokens)}}}})}(Prism)},19802:(e,t,n)=>{"use strict";n.d(t,{d1:()=>l.d1,zK:()=>b,vT:()=>m,gk:()=>h,Gy:()=>d,$S:()=>l.$S,HW:()=>y,vF:()=>u.v,ht:()=>f,g1:()=>c.g1,r7:()=>g,jh:()=>v});var r=n(56347),o=n(26503);const i=e=>e.versions.find(e=>e.isLast);function a(e,t){return[...e.versions].sort((e,t)=>e.path===t.path?0:e.path.includes(t.path)?-1:t.path.includes(e.path)?1:0).find(e=>!!(0,r.B6)(t,{path:e.path,exact:!1,strict:!1}))}function s(e,t){const n=a(e,t),o=n?.docs.find(e=>!!(0,r.B6)(t,{path:e.path,exact:!0,strict:!1}));return{activeVersion:n,activeDoc:o,alternateDocVersions:o?function(t){const n={};return e.versions.forEach(e=>{e.docs.forEach(r=>{r.id===t&&(n[e.name]=r)})}),n}(o.id):{}}}var l=n(45357),c=n(86457),u=n(73718);const p={},d=()=>(0,o.kh)("docusaurus-plugin-content-docs")??p,f=e=>{try{return(0,o.P_)("docusaurus-plugin-content-docs",e,{failfast:!0})}catch(t){throw new Error("You are using a feature of the Docusaurus docs plugin, but this plugin does not seem to be enabled"+("Default"===e?"":` (pluginId=${e}`),{cause:t})}};function m(e={}){const t=d(),{pathname:n}=(0,r.zy)();return function(e,t,n={}){const o=Object.entries(e).sort((e,t)=>t[1].path.localeCompare(e[1].path)).find(([,e])=>!!(0,r.B6)(t,{path:e.path,exact:!1,strict:!1})),i=o?{pluginId:o[0],pluginData:o[1]}:void 0;if(!i&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map(e=>e.path).join(", ")}`);return i}(t,n,e)}function h(e={}){const t=m(e),{pathname:n}=(0,r.zy)();if(!t)return;return{activePlugin:t,activeVersion:a(t.pluginData,n)}}function v(e){return f(e).versions}function g(e){const t=f(e);return i(t)}function b(e){const t=f(e),{pathname:n}=(0,r.zy)();return s(t,n)}function y(e){const t=f(e),{pathname:n}=(0,r.zy)();return function(e,t){const n=i(e);return{latestDocSuggestion:s(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},19819:(e,t,n)=>{"use strict";n.d(t,{v:()=>i});var r=n(86957);const o={anchorTargetStickyNavbar:"anchorTargetStickyNavbar_Vzrq",anchorTargetHideOnScrollNavbar:"anchorTargetHideOnScrollNavbar_vjPI"};function i(e){const{navbar:{hideOnScroll:t}}=(0,r.p)();if(void 0!==e)return t?o.anchorTargetHideOnScrollNavbar:o.anchorTargetStickyNavbar}},20020:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});n(96540);var r=n(14783),o=n(98180),i=n(97639),a=n(86957),s=n(40975),l=n(74848);function c({logo:e,alt:t,imageClassName:n}){const r={light:(0,o.Ay)(e.src),dark:(0,o.Ay)(e.srcDark||e.src)},i=(0,l.jsx)(s.A,{className:e.className,sources:r,height:e.height,width:e.width,alt:t,style:e.style});return n?(0,l.jsx)("div",{className:n,children:i}):i}function u(e){const{siteConfig:{title:t}}=(0,i.A)(),{navbar:{title:n,logo:s}}=(0,a.p)(),{imageClassName:u,titleClassName:p,...d}=e,f=(0,o.Ay)(s?.href||"/"),m=n?"":t,h=s?.alt??m;return(0,l.jsxs)(r.A,{to:f,...d,...s?.target&&{target:s.target},children:[s&&(0,l.jsx)(c,{logo:s,alt:h,imageClassName:u}),null!=n&&(0,l.jsx)("b",{className:p,children:n})]})}},20040:(e,t,n)=>{"use strict";n.d(t,{V:()=>l,t:()=>c});var r=n(96540),o=n(4799),i=n(74848);const a=Symbol("EmptyContext"),s=r.createContext(a);function l({children:e,name:t,items:n}){const o=(0,r.useMemo)(()=>t&&n?{name:t,items:n}:null,[t,n]);return(0,i.jsx)(s.Provider,{value:o,children:e})}function c(){const e=(0,r.useContext)(s);if(e===a)throw new o.dV("DocsSidebarProvider");return e}},20311:e=>{"use strict";e.exports=function(e,t,n,r,o,i,a,s){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,o,i,a,s],u=0;(l=new Error(t.replace(/%s/g,function(){return c[u++]}))).name="Invariant Violation"}throw l.framesToPop=1,l}}},21020:(e,t,n)=>{"use strict";var r=n(96540),o=Symbol.for("react.element"),i=Symbol.for("react.fragment"),a=Object.prototype.hasOwnProperty,s=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,n){var r,i={},c=null,u=null;for(r in void 0!==n&&(c=""+n),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)a.call(t,r)&&!l.hasOwnProperty(r)&&(i[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps)void 0===i[r]&&(i[r]=t[r]);return{$$typeof:o,type:e,key:c,ref:u,props:i,_owner:s.current}}t.Fragment=i,t.jsx=c,t.jsxs=c},21141:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});n(96540);var r=n(80545),o=n(74848);function i(e){return(0,o.jsx)(r.mg,{...e})}},22551:(e,t,n)=>{"use strict";var r=n(96540),o=n(69982);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var a=new Set,s={};function l(e,t){c(e,t),c(e+"Capture",t)}function c(e,t){for(s[e]=t,e=0;e<t.length;e++)a.add(t[e])}var u=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),p=Object.prototype.hasOwnProperty,d=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,f={},m={};function h(e,t,n,r,o,i,a){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=r,this.attributeNamespace=o,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=i,this.removeEmptyString=a}var v={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){v[e]=new h(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];v[t]=new h(t,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){v[e]=new h(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){v[e]=new h(e,2,!1,e,null,!1,!1)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){v[e]=new h(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){v[e]=new h(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){v[e]=new h(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){v[e]=new h(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){v[e]=new h(e,5,!1,e.toLowerCase(),null,!1,!1)});var g=/[\-:]([a-z])/g;function b(e){return e[1].toUpperCase()}function y(e,t,n,r){var o=v.hasOwnProperty(t)?v[t]:null;(null!==o?0!==o.type:r||!(2<t.length)||"o"!==t[0]&&"O"!==t[0]||"n"!==t[1]&&"N"!==t[1])&&(function(e,t,n,r){if(null==t||function(e,t,n,r){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,r))return!0;if(r)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,o,r)&&(n=null),r||null===o?function(e){return!!p.call(m,e)||!p.call(f,e)&&(d.test(e)?m[e]=!0:(f[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):o.mustUseProperty?e[o.propertyName]=null===n?3!==o.type&&"":n:(t=o.attributeName,r=o.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(o=o.type)||4===o&&!0===n?"":""+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var t=e.replace(g,b);v[t]=new h(t,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(g,b);v[t]=new h(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(g,b);v[t]=new h(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){v[e]=new h(e,1,!1,e.toLowerCase(),null,!1,!1)}),v.xlinkHref=new h("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){v[e]=new h(e,1,!1,e.toLowerCase(),null,!0,!0)});var w=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,x=Symbol.for("react.element"),k=Symbol.for("react.portal"),_=Symbol.for("react.fragment"),S=Symbol.for("react.strict_mode"),E=Symbol.for("react.profiler"),O=Symbol.for("react.provider"),j=Symbol.for("react.context"),P=Symbol.for("react.forward_ref"),C=Symbol.for("react.suspense"),A=Symbol.for("react.suspense_list"),T=Symbol.for("react.memo"),I=Symbol.for("react.lazy");Symbol.for("react.scope"),Symbol.for("react.debug_trace_mode");var N=Symbol.for("react.offscreen");Symbol.for("react.legacy_hidden"),Symbol.for("react.cache"),Symbol.for("react.tracing_marker");var L=Symbol.iterator;function R(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=L&&e[L]||e["@@iterator"])?e:null}var D,F=Object.assign;function M(e){if(void 0===D)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);D=t&&t[1]||""}return"\n"+D+e}var B=!1;function z(e,t){if(!e||B)return"";B=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(t,[])}catch(c){var r=c}Reflect.construct(e,[],t)}else{try{t.call()}catch(c){r=c}e.call(t.prototype)}else{try{throw Error()}catch(c){r=c}e()}}catch(c){if(c&&r&&"string"==typeof c.stack){for(var o=c.stack.split("\n"),i=r.stack.split("\n"),a=o.length-1,s=i.length-1;1<=a&&0<=s&&o[a]!==i[s];)s--;for(;1<=a&&0<=s;a--,s--)if(o[a]!==i[s]){if(1!==a||1!==s)do{if(a--,0>--s||o[a]!==i[s]){var l="\n"+o[a].replace(" at new "," at ");return e.displayName&&l.includes("<anonymous>")&&(l=l.replace("<anonymous>",e.displayName)),l}}while(1<=a&&0<=s);break}}}finally{B=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?M(e):""}function $(e){switch(e.tag){case 5:return M(e.type);case 16:return M("Lazy");case 13:return M("Suspense");case 19:return M("SuspenseList");case 0:case 2:case 15:return e=z(e.type,!1);case 11:return e=z(e.type.render,!1);case 1:return e=z(e.type,!0);default:return""}}function U(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case _:return"Fragment";case k:return"Portal";case E:return"Profiler";case S:return"StrictMode";case C:return"Suspense";case A:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case j:return(e.displayName||"Context")+".Consumer";case O:return(e._context.displayName||"Context")+".Provider";case P:var t=e.render;return(e=e.displayName)||(e=""!==(e=t.displayName||t.name||"")?"ForwardRef("+e+")":"ForwardRef"),e;case T:return null!==(t=e.displayName||null)?t:U(e.type)||"Memo";case I:t=e._payload,e=e._init;try{return U(e(t))}catch(n){}}return null}function V(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=(e=t.render).displayName||e.name||"",t.displayName||(""!==e?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return U(t);case 8:return t===S?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if("function"==typeof t)return t.displayName||t.name||null;if("string"==typeof t)return t}return null}function Q(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":case"object":return e;default:return""}}function H(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function W(e){e._valueTracker||(e._valueTracker=function(e){var t=H(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var o=n.get,i=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(e){r=""+e,i.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function q(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=H(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}function G(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function K(e,t){var n=t.checked;return F({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function Y(e,t){var n=null==t.defaultValue?"":t.defaultValue,r=null!=t.checked?t.checked:t.defaultChecked;n=Q(null!=t.value?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function Z(e,t){null!=(t=t.checked)&&y(e,"checked",t,!1)}function J(e,t){Z(e,t);var n=Q(t.value),r=t.type;if(null!=n)"number"===r?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===r||"reset"===r)return void e.removeAttribute("value");t.hasOwnProperty("value")?ee(e,t.type,n):t.hasOwnProperty("defaultValue")&&ee(e,t.type,Q(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function X(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!("submit"!==r&&"reset"!==r||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function ee(e,t,n){"number"===t&&G(e.ownerDocument)===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var te=Array.isArray;function ne(e,t,n,r){if(e=e.options,t){t={};for(var o=0;o<n.length;o++)t["$"+n[o]]=!0;for(n=0;n<e.length;n++)o=t.hasOwnProperty("$"+e[n].value),e[n].selected!==o&&(e[n].selected=o),o&&r&&(e[n].defaultSelected=!0)}else{for(n=""+Q(n),t=null,o=0;o<e.length;o++){if(e[o].value===n)return e[o].selected=!0,void(r&&(e[o].defaultSelected=!0));null!==t||e[o].disabled||(t=e[o])}null!==t&&(t.selected=!0)}}function re(e,t){if(null!=t.dangerouslySetInnerHTML)throw Error(i(91));return F({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function oe(e,t){var n=t.value;if(null==n){if(n=t.children,t=t.defaultValue,null!=n){if(null!=t)throw Error(i(92));if(te(n)){if(1<n.length)throw Error(i(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:Q(n)}}function ie(e,t){var n=Q(t.value),r=Q(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=r&&(e.defaultValue=""+r)}function ae(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}function se(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function le(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?se(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var ce,ue,pe=(ue=function(e,t){if("http://www.w3.org/2000/svg"!==e.namespaceURI||"innerHTML"in e)e.innerHTML=t;else{for((ce=ce||document.createElement("div")).innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=ce.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,r){MSApp.execUnsafeLocalFunction(function(){return ue(e,t)})}:ue);function de(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var fe={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},me=["Webkit","ms","Moz","O"];function he(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||fe.hasOwnProperty(e)&&fe[e]?(""+t).trim():t+"px"}function ve(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=0===n.indexOf("--"),o=he(n,t[n],r);"float"===n&&(n="cssFloat"),r?e.setProperty(n,o):e[n]=o}}Object.keys(fe).forEach(function(e){me.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),fe[t]=fe[e]})});var ge=F({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function be(e,t){if(t){if(ge[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML))throw Error(i(137,e));if(null!=t.dangerouslySetInnerHTML){if(null!=t.children)throw Error(i(60));if("object"!=typeof t.dangerouslySetInnerHTML||!("__html"in t.dangerouslySetInnerHTML))throw Error(i(61))}if(null!=t.style&&"object"!=typeof t.style)throw Error(i(62))}}function ye(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var we=null;function xe(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var ke=null,_e=null,Se=null;function Ee(e){if(e=wo(e)){if("function"!=typeof ke)throw Error(i(280));var t=e.stateNode;t&&(t=ko(t),ke(e.stateNode,e.type,t))}}function Oe(e){_e?Se?Se.push(e):Se=[e]:_e=e}function je(){if(_e){var e=_e,t=Se;if(Se=_e=null,Ee(e),t)for(e=0;e<t.length;e++)Ee(t[e])}}function Pe(e,t){return e(t)}function Ce(){}var Ae=!1;function Te(e,t,n){if(Ae)return e(t,n);Ae=!0;try{return Pe(e,t,n)}finally{Ae=!1,(null!==_e||null!==Se)&&(Ce(),je())}}function Ie(e,t){var n=e.stateNode;if(null===n)return null;var r=ko(n);if(null===r)return null;n=r[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(r=!r.disabled)||(r=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!r;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(i(231,t,typeof n));return n}var Ne=!1;if(u)try{var Le={};Object.defineProperty(Le,"passive",{get:function(){Ne=!0}}),window.addEventListener("test",Le,Le),window.removeEventListener("test",Le,Le)}catch(ue){Ne=!1}function Re(e,t,n,r,o,i,a,s,l){var c=Array.prototype.slice.call(arguments,3);try{t.apply(n,c)}catch(u){this.onError(u)}}var De=!1,Fe=null,Me=!1,Be=null,ze={onError:function(e){De=!0,Fe=e}};function $e(e,t,n,r,o,i,a,s,l){De=!1,Fe=null,Re.apply(ze,arguments)}function Ue(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{!!(4098&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function Ve(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function Qe(e){if(Ue(e)!==e)throw Error(i(188))}function He(e){return null!==(e=function(e){var t=e.alternate;if(!t){if(null===(t=Ue(e)))throw Error(i(188));return t!==e?null:e}for(var n=e,r=t;;){var o=n.return;if(null===o)break;var a=o.alternate;if(null===a){if(null!==(r=o.return)){n=r;continue}break}if(o.child===a.child){for(a=o.child;a;){if(a===n)return Qe(o),e;if(a===r)return Qe(o),t;a=a.sibling}throw Error(i(188))}if(n.return!==r.return)n=o,r=a;else{for(var s=!1,l=o.child;l;){if(l===n){s=!0,n=o,r=a;break}if(l===r){s=!0,r=o,n=a;break}l=l.sibling}if(!s){for(l=a.child;l;){if(l===n){s=!0,n=a,r=o;break}if(l===r){s=!0,r=a,n=o;break}l=l.sibling}if(!s)throw Error(i(189))}}if(n.alternate!==r)throw Error(i(190))}if(3!==n.tag)throw Error(i(188));return n.stateNode.current===n?e:t}(e))?We(e):null}function We(e){if(5===e.tag||6===e.tag)return e;for(e=e.child;null!==e;){var t=We(e);if(null!==t)return t;e=e.sibling}return null}var qe=o.unstable_scheduleCallback,Ge=o.unstable_cancelCallback,Ke=o.unstable_shouldYield,Ye=o.unstable_requestPaint,Ze=o.unstable_now,Je=o.unstable_getCurrentPriorityLevel,Xe=o.unstable_ImmediatePriority,et=o.unstable_UserBlockingPriority,tt=o.unstable_NormalPriority,nt=o.unstable_LowPriority,rt=o.unstable_IdlePriority,ot=null,it=null;var at=Math.clz32?Math.clz32:function(e){return e>>>=0,0===e?32:31-(st(e)/lt|0)|0},st=Math.log,lt=Math.LN2;var ct=64,ut=4194304;function pt(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return 4194240&e;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return 130023424&e;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function dt(e,t){var n=e.pendingLanes;if(0===n)return 0;var r=0,o=e.suspendedLanes,i=e.pingedLanes,a=268435455&n;if(0!==a){var s=a&~o;0!==s?r=pt(s):0!==(i&=a)&&(r=pt(i))}else 0!==(a=n&~o)?r=pt(a):0!==i&&(r=pt(i));if(0===r)return 0;if(0!==t&&t!==r&&0===(t&o)&&((o=r&-r)>=(i=t&-t)||16===o&&4194240&i))return t;if(4&r&&(r|=16&n),0!==(t=e.entangledLanes))for(e=e.entanglements,t&=r;0<t;)o=1<<(n=31-at(t)),r|=e[n],t&=~o;return r}function ft(e,t){switch(e){case 1:case 2:case 4:return t+250;case 8:case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;default:return-1}}function mt(e){return 0!==(e=-1073741825&e.pendingLanes)?e:1073741824&e?1073741824:0}function ht(){var e=ct;return!(4194240&(ct<<=1))&&(ct=64),e}function vt(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function gt(e,t,n){e.pendingLanes|=t,536870912!==t&&(e.suspendedLanes=0,e.pingedLanes=0),(e=e.eventTimes)[t=31-at(t)]=n}function bt(e,t){var n=e.entangledLanes|=t;for(e=e.entanglements;n;){var r=31-at(n),o=1<<r;o&t|e[r]&t&&(e[r]|=t),n&=~o}}var yt=0;function wt(e){return 1<(e&=-e)?4<e?268435455&e?16:536870912:4:1}var xt,kt,_t,St,Et,Ot=!1,jt=[],Pt=null,Ct=null,At=null,Tt=new Map,It=new Map,Nt=[],Lt="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function Rt(e,t){switch(e){case"focusin":case"focusout":Pt=null;break;case"dragenter":case"dragleave":Ct=null;break;case"mouseover":case"mouseout":At=null;break;case"pointerover":case"pointerout":Tt.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":It.delete(t.pointerId)}}function Dt(e,t,n,r,o,i){return null===e||e.nativeEvent!==i?(e={blockedOn:t,domEventName:n,eventSystemFlags:r,nativeEvent:i,targetContainers:[o]},null!==t&&(null!==(t=wo(t))&&kt(t)),e):(e.eventSystemFlags|=r,t=e.targetContainers,null!==o&&-1===t.indexOf(o)&&t.push(o),e)}function Ft(e){var t=yo(e.target);if(null!==t){var n=Ue(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=Ve(n)))return e.blockedOn=t,void Et(e.priority,function(){_t(n)})}else if(3===t&&n.stateNode.current.memoizedState.isDehydrated)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function Mt(e){if(null!==e.blockedOn)return!1;for(var t=e.targetContainers;0<t.length;){var n=Kt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n)return null!==(t=wo(n))&&kt(t),e.blockedOn=n,!1;var r=new(n=e.nativeEvent).constructor(n.type,n);we=r,n.target.dispatchEvent(r),we=null,t.shift()}return!0}function Bt(e,t,n){Mt(e)&&n.delete(t)}function zt(){Ot=!1,null!==Pt&&Mt(Pt)&&(Pt=null),null!==Ct&&Mt(Ct)&&(Ct=null),null!==At&&Mt(At)&&(At=null),Tt.forEach(Bt),It.forEach(Bt)}function $t(e,t){e.blockedOn===t&&(e.blockedOn=null,Ot||(Ot=!0,o.unstable_scheduleCallback(o.unstable_NormalPriority,zt)))}function Ut(e){function t(t){return $t(t,e)}if(0<jt.length){$t(jt[0],e);for(var n=1;n<jt.length;n++){var r=jt[n];r.blockedOn===e&&(r.blockedOn=null)}}for(null!==Pt&&$t(Pt,e),null!==Ct&&$t(Ct,e),null!==At&&$t(At,e),Tt.forEach(t),It.forEach(t),n=0;n<Nt.length;n++)(r=Nt[n]).blockedOn===e&&(r.blockedOn=null);for(;0<Nt.length&&null===(n=Nt[0]).blockedOn;)Ft(n),null===n.blockedOn&&Nt.shift()}var Vt=w.ReactCurrentBatchConfig,Qt=!0;function Ht(e,t,n,r){var o=yt,i=Vt.transition;Vt.transition=null;try{yt=1,qt(e,t,n,r)}finally{yt=o,Vt.transition=i}}function Wt(e,t,n,r){var o=yt,i=Vt.transition;Vt.transition=null;try{yt=4,qt(e,t,n,r)}finally{yt=o,Vt.transition=i}}function qt(e,t,n,r){if(Qt){var o=Kt(e,t,n,r);if(null===o)Qr(e,t,r,Gt,n),Rt(e,r);else if(function(e,t,n,r,o){switch(t){case"focusin":return Pt=Dt(Pt,e,t,n,r,o),!0;case"dragenter":return Ct=Dt(Ct,e,t,n,r,o),!0;case"mouseover":return At=Dt(At,e,t,n,r,o),!0;case"pointerover":var i=o.pointerId;return Tt.set(i,Dt(Tt.get(i)||null,e,t,n,r,o)),!0;case"gotpointercapture":return i=o.pointerId,It.set(i,Dt(It.get(i)||null,e,t,n,r,o)),!0}return!1}(o,e,t,n,r))r.stopPropagation();else if(Rt(e,r),4&t&&-1<Lt.indexOf(e)){for(;null!==o;){var i=wo(o);if(null!==i&&xt(i),null===(i=Kt(e,t,n,r))&&Qr(e,t,r,Gt,n),i===o)break;o=i}null!==o&&r.stopPropagation()}else Qr(e,t,r,null,n)}}var Gt=null;function Kt(e,t,n,r){if(Gt=null,null!==(e=yo(e=xe(r))))if(null===(t=Ue(e)))e=null;else if(13===(n=t.tag)){if(null!==(e=Ve(t)))return e;e=null}else if(3===n){if(t.stateNode.current.memoizedState.isDehydrated)return 3===t.tag?t.stateNode.containerInfo:null;e=null}else t!==e&&(e=null);return Gt=e,null}function Yt(e){switch(e){case"cancel":case"click":case"close":case"contextmenu":case"copy":case"cut":case"auxclick":case"dblclick":case"dragend":case"dragstart":case"drop":case"focusin":case"focusout":case"input":case"invalid":case"keydown":case"keypress":case"keyup":case"mousedown":case"mouseup":case"paste":case"pause":case"play":case"pointercancel":case"pointerdown":case"pointerup":case"ratechange":case"reset":case"resize":case"seeked":case"submit":case"touchcancel":case"touchend":case"touchstart":case"volumechange":case"change":case"selectionchange":case"textInput":case"compositionstart":case"compositionend":case"compositionupdate":case"beforeblur":case"afterblur":case"beforeinput":case"blur":case"fullscreenchange":case"focus":case"hashchange":case"popstate":case"select":case"selectstart":return 1;case"drag":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"mousemove":case"mouseout":case"mouseover":case"pointermove":case"pointerout":case"pointerover":case"scroll":case"toggle":case"touchmove":case"wheel":case"mouseenter":case"mouseleave":case"pointerenter":case"pointerleave":return 4;case"message":switch(Je()){case Xe:return 1;case et:return 4;case tt:case nt:return 16;case rt:return 536870912;default:return 16}default:return 16}}var Zt=null,Jt=null,Xt=null;function en(){if(Xt)return Xt;var e,t,n=Jt,r=n.length,o="value"in Zt?Zt.value:Zt.textContent,i=o.length;for(e=0;e<r&&n[e]===o[e];e++);var a=r-e;for(t=1;t<=a&&n[r-t]===o[i-t];t++);return Xt=o.slice(e,1<t?1-t:void 0)}function tn(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}function nn(){return!0}function rn(){return!1}function on(e){function t(t,n,r,o,i){for(var a in this._reactName=t,this._targetInst=r,this.type=n,this.nativeEvent=o,this.target=i,this.currentTarget=null,e)e.hasOwnProperty(a)&&(t=e[a],this[a]=t?t(o):o[a]);return this.isDefaultPrevented=(null!=o.defaultPrevented?o.defaultPrevented:!1===o.returnValue)?nn:rn,this.isPropagationStopped=rn,this}return F(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=nn)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=nn)},persist:function(){},isPersistent:nn}),t}var an,sn,ln,cn={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},un=on(cn),pn=F({},cn,{view:0,detail:0}),dn=on(pn),fn=F({},pn,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:En,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==ln&&(ln&&"mousemove"===e.type?(an=e.screenX-ln.screenX,sn=e.screenY-ln.screenY):sn=an=0,ln=e),an)},movementY:function(e){return"movementY"in e?e.movementY:sn}}),mn=on(fn),hn=on(F({},fn,{dataTransfer:0})),vn=on(F({},pn,{relatedTarget:0})),gn=on(F({},cn,{animationName:0,elapsedTime:0,pseudoElement:0})),bn=F({},cn,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),yn=on(bn),wn=on(F({},cn,{data:0})),xn={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},kn={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},_n={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Sn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=_n[e])&&!!t[e]}function En(){return Sn}var On=F({},pn,{key:function(e){if(e.key){var t=xn[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=tn(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?kn[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:En,charCode:function(e){return"keypress"===e.type?tn(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?tn(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),jn=on(On),Pn=on(F({},fn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),Cn=on(F({},pn,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:En})),An=on(F({},cn,{propertyName:0,elapsedTime:0,pseudoElement:0})),Tn=F({},fn,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),In=on(Tn),Nn=[9,13,27,32],Ln=u&&"CompositionEvent"in window,Rn=null;u&&"documentMode"in document&&(Rn=document.documentMode);var Dn=u&&"TextEvent"in window&&!Rn,Fn=u&&(!Ln||Rn&&8<Rn&&11>=Rn),Mn=String.fromCharCode(32),Bn=!1;function zn(e,t){switch(e){case"keyup":return-1!==Nn.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function $n(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var Un=!1;var Vn={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Qn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!Vn[e.type]:"textarea"===t}function Hn(e,t,n,r){Oe(r),0<(t=Wr(t,"onChange")).length&&(n=new un("onChange","change",null,n,r),e.push({event:n,listeners:t}))}var Wn=null,qn=null;function Gn(e){Mr(e,0)}function Kn(e){if(q(xo(e)))return e}function Yn(e,t){if("change"===e)return t}var Zn=!1;if(u){var Jn;if(u){var Xn="oninput"in document;if(!Xn){var er=document.createElement("div");er.setAttribute("oninput","return;"),Xn="function"==typeof er.oninput}Jn=Xn}else Jn=!1;Zn=Jn&&(!document.documentMode||9<document.documentMode)}function tr(){Wn&&(Wn.detachEvent("onpropertychange",nr),qn=Wn=null)}function nr(e){if("value"===e.propertyName&&Kn(qn)){var t=[];Hn(t,qn,e,xe(e)),Te(Gn,t)}}function rr(e,t,n){"focusin"===e?(tr(),qn=n,(Wn=t).attachEvent("onpropertychange",nr)):"focusout"===e&&tr()}function or(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Kn(qn)}function ir(e,t){if("click"===e)return Kn(t)}function ar(e,t){if("input"===e||"change"===e)return Kn(t)}var sr="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t};function lr(e,t){if(sr(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++){var o=n[r];if(!p.call(t,o)||!sr(e[o],t[o]))return!1}return!0}function cr(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function ur(e,t){var n,r=cr(e);for(e=0;r;){if(3===r.nodeType){if(n=e+r.textContent.length,e<=t&&n>=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=cr(r)}}function pr(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?pr(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function dr(){for(var e=window,t=G();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(r){n=!1}if(!n)break;t=G((e=t.contentWindow).document)}return t}function fr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}function mr(e){var t=dr(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&pr(n.ownerDocument.documentElement,n)){if(null!==r&&fr(n))if(t=r.start,void 0===(e=r.end)&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if((e=(t=n.ownerDocument||document)&&t.defaultView||window).getSelection){e=e.getSelection();var o=n.textContent.length,i=Math.min(r.start,o);r=void 0===r.end?i:Math.min(r.end,o),!e.extend&&i>r&&(o=r,r=i,i=o),o=ur(n,i);var a=ur(n,r);o&&a&&(1!==e.rangeCount||e.anchorNode!==o.node||e.anchorOffset!==o.offset||e.focusNode!==a.node||e.focusOffset!==a.offset)&&((t=t.createRange()).setStart(o.node,o.offset),e.removeAllRanges(),i>r?(e.addRange(t),e.extend(a.node,a.offset)):(t.setEnd(a.node,a.offset),e.addRange(t)))}for(t=[],e=n;e=e.parentNode;)1===e.nodeType&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for("function"==typeof n.focus&&n.focus(),n=0;n<t.length;n++)(e=t[n]).element.scrollLeft=e.left,e.element.scrollTop=e.top}}var hr=u&&"documentMode"in document&&11>=document.documentMode,vr=null,gr=null,br=null,yr=!1;function wr(e,t,n){var r=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;yr||null==vr||vr!==G(r)||("selectionStart"in(r=vr)&&fr(r)?r={start:r.selectionStart,end:r.selectionEnd}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},br&&lr(br,r)||(br=r,0<(r=Wr(gr,"onSelect")).length&&(t=new un("onSelect","select",null,t,n),e.push({event:t,listeners:r}),t.target=vr)))}function xr(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var kr={animationend:xr("Animation","AnimationEnd"),animationiteration:xr("Animation","AnimationIteration"),animationstart:xr("Animation","AnimationStart"),transitionend:xr("Transition","TransitionEnd")},_r={},Sr={};function Er(e){if(_r[e])return _r[e];if(!kr[e])return e;var t,n=kr[e];for(t in n)if(n.hasOwnProperty(t)&&t in Sr)return _r[e]=n[t];return e}u&&(Sr=document.createElement("div").style,"AnimationEvent"in window||(delete kr.animationend.animation,delete kr.animationiteration.animation,delete kr.animationstart.animation),"TransitionEvent"in window||delete kr.transitionend.transition);var Or=Er("animationend"),jr=Er("animationiteration"),Pr=Er("animationstart"),Cr=Er("transitionend"),Ar=new Map,Tr="abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");function Ir(e,t){Ar.set(e,t),l(t,[e])}for(var Nr=0;Nr<Tr.length;Nr++){var Lr=Tr[Nr];Ir(Lr.toLowerCase(),"on"+(Lr[0].toUpperCase()+Lr.slice(1)))}Ir(Or,"onAnimationEnd"),Ir(jr,"onAnimationIteration"),Ir(Pr,"onAnimationStart"),Ir("dblclick","onDoubleClick"),Ir("focusin","onFocus"),Ir("focusout","onBlur"),Ir(Cr,"onTransitionEnd"),c("onMouseEnter",["mouseout","mouseover"]),c("onMouseLeave",["mouseout","mouseover"]),c("onPointerEnter",["pointerout","pointerover"]),c("onPointerLeave",["pointerout","pointerover"]),l("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),l("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),l("onBeforeInput",["compositionend","keypress","textInput","paste"]),l("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),l("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),l("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var Rr="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Dr=new Set("cancel close invalid load scroll toggle".split(" ").concat(Rr));function Fr(e,t,n){var r=e.type||"unknown-event";e.currentTarget=n,function(e,t,n,r,o,a,s,l,c){if($e.apply(this,arguments),De){if(!De)throw Error(i(198));var u=Fe;De=!1,Fe=null,Me||(Me=!0,Be=u)}}(r,t,void 0,e),e.currentTarget=null}function Mr(e,t){t=!!(4&t);for(var n=0;n<e.length;n++){var r=e[n],o=r.event;r=r.listeners;e:{var i=void 0;if(t)for(var a=r.length-1;0<=a;a--){var s=r[a],l=s.instance,c=s.currentTarget;if(s=s.listener,l!==i&&o.isPropagationStopped())break e;Fr(o,s,c),i=l}else for(a=0;a<r.length;a++){if(l=(s=r[a]).instance,c=s.currentTarget,s=s.listener,l!==i&&o.isPropagationStopped())break e;Fr(o,s,c),i=l}}}if(Me)throw e=Be,Me=!1,Be=null,e}function Br(e,t){var n=t[vo];void 0===n&&(n=t[vo]=new Set);var r=e+"__bubble";n.has(r)||(Vr(t,e,2,!1),n.add(r))}function zr(e,t,n){var r=0;t&&(r|=4),Vr(n,e,r,t)}var $r="_reactListening"+Math.random().toString(36).slice(2);function Ur(e){if(!e[$r]){e[$r]=!0,a.forEach(function(t){"selectionchange"!==t&&(Dr.has(t)||zr(t,!1,e),zr(t,!0,e))});var t=9===e.nodeType?e:e.ownerDocument;null===t||t[$r]||(t[$r]=!0,zr("selectionchange",!1,t))}}function Vr(e,t,n,r){switch(Yt(t)){case 1:var o=Ht;break;case 4:o=Wt;break;default:o=qt}n=o.bind(null,t,n,e),o=void 0,!Ne||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(o=!0),r?void 0!==o?e.addEventListener(t,n,{capture:!0,passive:o}):e.addEventListener(t,n,!0):void 0!==o?e.addEventListener(t,n,{passive:o}):e.addEventListener(t,n,!1)}function Qr(e,t,n,r,o){var i=r;if(!(1&t||2&t||null===r))e:for(;;){if(null===r)return;var a=r.tag;if(3===a||4===a){var s=r.stateNode.containerInfo;if(s===o||8===s.nodeType&&s.parentNode===o)break;if(4===a)for(a=r.return;null!==a;){var l=a.tag;if((3===l||4===l)&&((l=a.stateNode.containerInfo)===o||8===l.nodeType&&l.parentNode===o))return;a=a.return}for(;null!==s;){if(null===(a=yo(s)))return;if(5===(l=a.tag)||6===l){r=i=a;continue e}s=s.parentNode}}r=r.return}Te(function(){var r=i,o=xe(n),a=[];e:{var s=Ar.get(e);if(void 0!==s){var l=un,c=e;switch(e){case"keypress":if(0===tn(n))break e;case"keydown":case"keyup":l=jn;break;case"focusin":c="focus",l=vn;break;case"focusout":c="blur",l=vn;break;case"beforeblur":case"afterblur":l=vn;break;case"click":if(2===n.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":l=mn;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":l=hn;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":l=Cn;break;case Or:case jr:case Pr:l=gn;break;case Cr:l=An;break;case"scroll":l=dn;break;case"wheel":l=In;break;case"copy":case"cut":case"paste":l=yn;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":l=Pn}var u=!!(4&t),p=!u&&"scroll"===e,d=u?null!==s?s+"Capture":null:s;u=[];for(var f,m=r;null!==m;){var h=(f=m).stateNode;if(5===f.tag&&null!==h&&(f=h,null!==d&&(null!=(h=Ie(m,d))&&u.push(Hr(m,h,f)))),p)break;m=m.return}0<u.length&&(s=new l(s,c,null,n,o),a.push({event:s,listeners:u}))}}if(!(7&t)){if(l="mouseout"===e||"pointerout"===e,(!(s="mouseover"===e||"pointerover"===e)||n===we||!(c=n.relatedTarget||n.fromElement)||!yo(c)&&!c[ho])&&(l||s)&&(s=o.window===o?o:(s=o.ownerDocument)?s.defaultView||s.parentWindow:window,l?(l=r,null!==(c=(c=n.relatedTarget||n.toElement)?yo(c):null)&&(c!==(p=Ue(c))||5!==c.tag&&6!==c.tag)&&(c=null)):(l=null,c=r),l!==c)){if(u=mn,h="onMouseLeave",d="onMouseEnter",m="mouse","pointerout"!==e&&"pointerover"!==e||(u=Pn,h="onPointerLeave",d="onPointerEnter",m="pointer"),p=null==l?s:xo(l),f=null==c?s:xo(c),(s=new u(h,m+"leave",l,n,o)).target=p,s.relatedTarget=f,h=null,yo(o)===r&&((u=new u(d,m+"enter",c,n,o)).target=f,u.relatedTarget=p,h=u),p=h,l&&c)e:{for(d=c,m=0,f=u=l;f;f=qr(f))m++;for(f=0,h=d;h;h=qr(h))f++;for(;0<m-f;)u=qr(u),m--;for(;0<f-m;)d=qr(d),f--;for(;m--;){if(u===d||null!==d&&u===d.alternate)break e;u=qr(u),d=qr(d)}u=null}else u=null;null!==l&&Gr(a,s,l,u,!1),null!==c&&null!==p&&Gr(a,p,c,u,!0)}if("select"===(l=(s=r?xo(r):window).nodeName&&s.nodeName.toLowerCase())||"input"===l&&"file"===s.type)var v=Yn;else if(Qn(s))if(Zn)v=ar;else{v=or;var g=rr}else(l=s.nodeName)&&"input"===l.toLowerCase()&&("checkbox"===s.type||"radio"===s.type)&&(v=ir);switch(v&&(v=v(e,r))?Hn(a,v,n,o):(g&&g(e,s,r),"focusout"===e&&(g=s._wrapperState)&&g.controlled&&"number"===s.type&&ee(s,"number",s.value)),g=r?xo(r):window,e){case"focusin":(Qn(g)||"true"===g.contentEditable)&&(vr=g,gr=r,br=null);break;case"focusout":br=gr=vr=null;break;case"mousedown":yr=!0;break;case"contextmenu":case"mouseup":case"dragend":yr=!1,wr(a,n,o);break;case"selectionchange":if(hr)break;case"keydown":case"keyup":wr(a,n,o)}var b;if(Ln)e:{switch(e){case"compositionstart":var y="onCompositionStart";break e;case"compositionend":y="onCompositionEnd";break e;case"compositionupdate":y="onCompositionUpdate";break e}y=void 0}else Un?zn(e,n)&&(y="onCompositionEnd"):"keydown"===e&&229===n.keyCode&&(y="onCompositionStart");y&&(Fn&&"ko"!==n.locale&&(Un||"onCompositionStart"!==y?"onCompositionEnd"===y&&Un&&(b=en()):(Jt="value"in(Zt=o)?Zt.value:Zt.textContent,Un=!0)),0<(g=Wr(r,y)).length&&(y=new wn(y,e,null,n,o),a.push({event:y,listeners:g}),b?y.data=b:null!==(b=$n(n))&&(y.data=b))),(b=Dn?function(e,t){switch(e){case"compositionend":return $n(t);case"keypress":return 32!==t.which?null:(Bn=!0,Mn);case"textInput":return(e=t.data)===Mn&&Bn?null:e;default:return null}}(e,n):function(e,t){if(Un)return"compositionend"===e||!Ln&&zn(e,t)?(e=en(),Xt=Jt=Zt=null,Un=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return Fn&&"ko"!==t.locale?null:t.data}}(e,n))&&(0<(r=Wr(r,"onBeforeInput")).length&&(o=new wn("onBeforeInput","beforeinput",null,n,o),a.push({event:o,listeners:r}),o.data=b))}Mr(a,t)})}function Hr(e,t,n){return{instance:e,listener:t,currentTarget:n}}function Wr(e,t){for(var n=t+"Capture",r=[];null!==e;){var o=e,i=o.stateNode;5===o.tag&&null!==i&&(o=i,null!=(i=Ie(e,n))&&r.unshift(Hr(e,i,o)),null!=(i=Ie(e,t))&&r.push(Hr(e,i,o))),e=e.return}return r}function qr(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag);return e||null}function Gr(e,t,n,r,o){for(var i=t._reactName,a=[];null!==n&&n!==r;){var s=n,l=s.alternate,c=s.stateNode;if(null!==l&&l===r)break;5===s.tag&&null!==c&&(s=c,o?null!=(l=Ie(n,i))&&a.unshift(Hr(n,l,s)):o||null!=(l=Ie(n,i))&&a.push(Hr(n,l,s))),n=n.return}0!==a.length&&e.push({event:t,listeners:a})}var Kr=/\r\n?/g,Yr=/\u0000|\uFFFD/g;function Zr(e){return("string"==typeof e?e:""+e).replace(Kr,"\n").replace(Yr,"")}function Jr(e,t,n){if(t=Zr(t),Zr(e)!==t&&n)throw Error(i(425))}function Xr(){}var eo=null,to=null;function no(e,t){return"textarea"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var ro="function"==typeof setTimeout?setTimeout:void 0,oo="function"==typeof clearTimeout?clearTimeout:void 0,io="function"==typeof Promise?Promise:void 0,ao="function"==typeof queueMicrotask?queueMicrotask:void 0!==io?function(e){return io.resolve(null).then(e).catch(so)}:ro;function so(e){setTimeout(function(){throw e})}function lo(e,t){var n=t,r=0;do{var o=n.nextSibling;if(e.removeChild(n),o&&8===o.nodeType)if("/$"===(n=o.data)){if(0===r)return e.removeChild(o),void Ut(t);r--}else"$"!==n&&"$?"!==n&&"$!"!==n||r++;n=o}while(n);Ut(t)}function co(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break;if(8===t){if("$"===(t=e.data)||"$!"===t||"$?"===t)break;if("/$"===t)return null}}return e}function uo(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||"$!"===n||"$?"===n){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}var po=Math.random().toString(36).slice(2),fo="__reactFiber$"+po,mo="__reactProps$"+po,ho="__reactContainer$"+po,vo="__reactEvents$"+po,go="__reactListeners$"+po,bo="__reactHandles$"+po;function yo(e){var t=e[fo];if(t)return t;for(var n=e.parentNode;n;){if(t=n[ho]||n[fo]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=uo(e);null!==e;){if(n=e[fo])return n;e=uo(e)}return t}n=(e=n).parentNode}return null}function wo(e){return!(e=e[fo]||e[ho])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function xo(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(i(33))}function ko(e){return e[mo]||null}var _o=[],So=-1;function Eo(e){return{current:e}}function Oo(e){0>So||(e.current=_o[So],_o[So]=null,So--)}function jo(e,t){So++,_o[So]=e.current,e.current=t}var Po={},Co=Eo(Po),Ao=Eo(!1),To=Po;function Io(e,t){var n=e.type.contextTypes;if(!n)return Po;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var o,i={};for(o in n)i[o]=t[o];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=i),i}function No(e){return null!=(e=e.childContextTypes)}function Lo(){Oo(Ao),Oo(Co)}function Ro(e,t,n){if(Co.current!==Po)throw Error(i(168));jo(Co,t),jo(Ao,n)}function Do(e,t,n){var r=e.stateNode;if(t=t.childContextTypes,"function"!=typeof r.getChildContext)return n;for(var o in r=r.getChildContext())if(!(o in t))throw Error(i(108,V(e)||"Unknown",o));return F({},n,r)}function Fo(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Po,To=Co.current,jo(Co,e),jo(Ao,Ao.current),!0}function Mo(e,t,n){var r=e.stateNode;if(!r)throw Error(i(169));n?(e=Do(e,t,To),r.__reactInternalMemoizedMergedChildContext=e,Oo(Ao),Oo(Co),jo(Co,e)):Oo(Ao),jo(Ao,n)}var Bo=null,zo=!1,$o=!1;function Uo(e){null===Bo?Bo=[e]:Bo.push(e)}function Vo(){if(!$o&&null!==Bo){$o=!0;var e=0,t=yt;try{var n=Bo;for(yt=1;e<n.length;e++){var r=n[e];do{r=r(!0)}while(null!==r)}Bo=null,zo=!1}catch(o){throw null!==Bo&&(Bo=Bo.slice(e+1)),qe(Xe,Vo),o}finally{yt=t,$o=!1}}return null}var Qo=[],Ho=0,Wo=null,qo=0,Go=[],Ko=0,Yo=null,Zo=1,Jo="";function Xo(e,t){Qo[Ho++]=qo,Qo[Ho++]=Wo,Wo=e,qo=t}function ei(e,t,n){Go[Ko++]=Zo,Go[Ko++]=Jo,Go[Ko++]=Yo,Yo=e;var r=Zo;e=Jo;var o=32-at(r)-1;r&=~(1<<o),n+=1;var i=32-at(t)+o;if(30<i){var a=o-o%5;i=(r&(1<<a)-1).toString(32),r>>=a,o-=a,Zo=1<<32-at(t)+o|n<<o|r,Jo=i+e}else Zo=1<<i|n<<o|r,Jo=e}function ti(e){null!==e.return&&(Xo(e,1),ei(e,1,0))}function ni(e){for(;e===Wo;)Wo=Qo[--Ho],Qo[Ho]=null,qo=Qo[--Ho],Qo[Ho]=null;for(;e===Yo;)Yo=Go[--Ko],Go[Ko]=null,Jo=Go[--Ko],Go[Ko]=null,Zo=Go[--Ko],Go[Ko]=null}var ri=null,oi=null,ii=!1,ai=null;function si(e,t){var n=Tc(5,null,null,0);n.elementType="DELETED",n.stateNode=t,n.return=e,null===(t=e.deletions)?(e.deletions=[n],e.flags|=16):t.push(n)}function li(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,ri=e,oi=co(t.firstChild),!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,ri=e,oi=null,!0);case 13:return null!==(t=8!==t.nodeType?null:t)&&(n=null!==Yo?{id:Zo,overflow:Jo}:null,e.memoizedState={dehydrated:t,treeContext:n,retryLane:1073741824},(n=Tc(18,null,null,0)).stateNode=t,n.return=e,e.child=n,ri=e,oi=null,!0);default:return!1}}function ci(e){return!(!(1&e.mode)||128&e.flags)}function ui(e){if(ii){var t=oi;if(t){var n=t;if(!li(e,t)){if(ci(e))throw Error(i(418));t=co(n.nextSibling);var r=ri;t&&li(e,t)?si(r,n):(e.flags=-4097&e.flags|2,ii=!1,ri=e)}}else{if(ci(e))throw Error(i(418));e.flags=-4097&e.flags|2,ii=!1,ri=e}}}function pi(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;ri=e}function di(e){if(e!==ri)return!1;if(!ii)return pi(e),ii=!0,!1;var t;if((t=3!==e.tag)&&!(t=5!==e.tag)&&(t="head"!==(t=e.type)&&"body"!==t&&!no(e.type,e.memoizedProps)),t&&(t=oi)){if(ci(e))throw fi(),Error(i(418));for(;t;)si(e,t),t=co(t.nextSibling)}if(pi(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(i(317));e:{for(e=e.nextSibling,t=0;e;){if(8===e.nodeType){var n=e.data;if("/$"===n){if(0===t){oi=co(e.nextSibling);break e}t--}else"$"!==n&&"$!"!==n&&"$?"!==n||t++}e=e.nextSibling}oi=null}}else oi=ri?co(e.stateNode.nextSibling):null;return!0}function fi(){for(var e=oi;e;)e=co(e.nextSibling)}function mi(){oi=ri=null,ii=!1}function hi(e){null===ai?ai=[e]:ai.push(e)}var vi=w.ReactCurrentBatchConfig;function gi(e,t,n){if(null!==(e=n.ref)&&"function"!=typeof e&&"object"!=typeof e){if(n._owner){if(n=n._owner){if(1!==n.tag)throw Error(i(309));var r=n.stateNode}if(!r)throw Error(i(147,e));var o=r,a=""+e;return null!==t&&null!==t.ref&&"function"==typeof t.ref&&t.ref._stringRef===a?t.ref:(t=function(e){var t=o.refs;null===e?delete t[a]:t[a]=e},t._stringRef=a,t)}if("string"!=typeof e)throw Error(i(284));if(!n._owner)throw Error(i(290,e))}return e}function bi(e,t){throw e=Object.prototype.toString.call(t),Error(i(31,"[object Object]"===e?"object with keys {"+Object.keys(t).join(", ")+"}":e))}function yi(e){return(0,e._init)(e._payload)}function wi(e){function t(t,n){if(e){var r=t.deletions;null===r?(t.deletions=[n],t.flags|=16):r.push(n)}}function n(n,r){if(!e)return null;for(;null!==r;)t(n,r),r=r.sibling;return null}function r(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function o(e,t){return(e=Nc(e,t)).index=0,e.sibling=null,e}function a(t,n,r){return t.index=r,e?null!==(r=t.alternate)?(r=r.index)<n?(t.flags|=2,n):r:(t.flags|=2,n):(t.flags|=1048576,n)}function s(t){return e&&null===t.alternate&&(t.flags|=2),t}function l(e,t,n,r){return null===t||6!==t.tag?((t=Fc(n,e.mode,r)).return=e,t):((t=o(t,n)).return=e,t)}function c(e,t,n,r){var i=n.type;return i===_?p(e,t,n.props.children,r,n.key):null!==t&&(t.elementType===i||"object"==typeof i&&null!==i&&i.$$typeof===I&&yi(i)===t.type)?((r=o(t,n.props)).ref=gi(e,t,n),r.return=e,r):((r=Lc(n.type,n.key,n.props,null,e.mode,r)).ref=gi(e,t,n),r.return=e,r)}function u(e,t,n,r){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=Mc(n,e.mode,r)).return=e,t):((t=o(t,n.children||[])).return=e,t)}function p(e,t,n,r,i){return null===t||7!==t.tag?((t=Rc(n,e.mode,r,i)).return=e,t):((t=o(t,n)).return=e,t)}function d(e,t,n){if("string"==typeof t&&""!==t||"number"==typeof t)return(t=Fc(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case x:return(n=Lc(t.type,t.key,t.props,null,e.mode,n)).ref=gi(e,null,t),n.return=e,n;case k:return(t=Mc(t,e.mode,n)).return=e,t;case I:return d(e,(0,t._init)(t._payload),n)}if(te(t)||R(t))return(t=Rc(t,e.mode,n,null)).return=e,t;bi(e,t)}return null}function f(e,t,n,r){var o=null!==t?t.key:null;if("string"==typeof n&&""!==n||"number"==typeof n)return null!==o?null:l(e,t,""+n,r);if("object"==typeof n&&null!==n){switch(n.$$typeof){case x:return n.key===o?c(e,t,n,r):null;case k:return n.key===o?u(e,t,n,r):null;case I:return f(e,t,(o=n._init)(n._payload),r)}if(te(n)||R(n))return null!==o?null:p(e,t,n,r,null);bi(e,n)}return null}function m(e,t,n,r,o){if("string"==typeof r&&""!==r||"number"==typeof r)return l(t,e=e.get(n)||null,""+r,o);if("object"==typeof r&&null!==r){switch(r.$$typeof){case x:return c(t,e=e.get(null===r.key?n:r.key)||null,r,o);case k:return u(t,e=e.get(null===r.key?n:r.key)||null,r,o);case I:return m(e,t,n,(0,r._init)(r._payload),o)}if(te(r)||R(r))return p(t,e=e.get(n)||null,r,o,null);bi(t,r)}return null}function h(o,i,s,l){for(var c=null,u=null,p=i,h=i=0,v=null;null!==p&&h<s.length;h++){p.index>h?(v=p,p=null):v=p.sibling;var g=f(o,p,s[h],l);if(null===g){null===p&&(p=v);break}e&&p&&null===g.alternate&&t(o,p),i=a(g,i,h),null===u?c=g:u.sibling=g,u=g,p=v}if(h===s.length)return n(o,p),ii&&Xo(o,h),c;if(null===p){for(;h<s.length;h++)null!==(p=d(o,s[h],l))&&(i=a(p,i,h),null===u?c=p:u.sibling=p,u=p);return ii&&Xo(o,h),c}for(p=r(o,p);h<s.length;h++)null!==(v=m(p,o,h,s[h],l))&&(e&&null!==v.alternate&&p.delete(null===v.key?h:v.key),i=a(v,i,h),null===u?c=v:u.sibling=v,u=v);return e&&p.forEach(function(e){return t(o,e)}),ii&&Xo(o,h),c}function v(o,s,l,c){var u=R(l);if("function"!=typeof u)throw Error(i(150));if(null==(l=u.call(l)))throw Error(i(151));for(var p=u=null,h=s,v=s=0,g=null,b=l.next();null!==h&&!b.done;v++,b=l.next()){h.index>v?(g=h,h=null):g=h.sibling;var y=f(o,h,b.value,c);if(null===y){null===h&&(h=g);break}e&&h&&null===y.alternate&&t(o,h),s=a(y,s,v),null===p?u=y:p.sibling=y,p=y,h=g}if(b.done)return n(o,h),ii&&Xo(o,v),u;if(null===h){for(;!b.done;v++,b=l.next())null!==(b=d(o,b.value,c))&&(s=a(b,s,v),null===p?u=b:p.sibling=b,p=b);return ii&&Xo(o,v),u}for(h=r(o,h);!b.done;v++,b=l.next())null!==(b=m(h,o,v,b.value,c))&&(e&&null!==b.alternate&&h.delete(null===b.key?v:b.key),s=a(b,s,v),null===p?u=b:p.sibling=b,p=b);return e&&h.forEach(function(e){return t(o,e)}),ii&&Xo(o,v),u}return function e(r,i,a,l){if("object"==typeof a&&null!==a&&a.type===_&&null===a.key&&(a=a.props.children),"object"==typeof a&&null!==a){switch(a.$$typeof){case x:e:{for(var c=a.key,u=i;null!==u;){if(u.key===c){if((c=a.type)===_){if(7===u.tag){n(r,u.sibling),(i=o(u,a.props.children)).return=r,r=i;break e}}else if(u.elementType===c||"object"==typeof c&&null!==c&&c.$$typeof===I&&yi(c)===u.type){n(r,u.sibling),(i=o(u,a.props)).ref=gi(r,u,a),i.return=r,r=i;break e}n(r,u);break}t(r,u),u=u.sibling}a.type===_?((i=Rc(a.props.children,r.mode,l,a.key)).return=r,r=i):((l=Lc(a.type,a.key,a.props,null,r.mode,l)).ref=gi(r,i,a),l.return=r,r=l)}return s(r);case k:e:{for(u=a.key;null!==i;){if(i.key===u){if(4===i.tag&&i.stateNode.containerInfo===a.containerInfo&&i.stateNode.implementation===a.implementation){n(r,i.sibling),(i=o(i,a.children||[])).return=r,r=i;break e}n(r,i);break}t(r,i),i=i.sibling}(i=Mc(a,r.mode,l)).return=r,r=i}return s(r);case I:return e(r,i,(u=a._init)(a._payload),l)}if(te(a))return h(r,i,a,l);if(R(a))return v(r,i,a,l);bi(r,a)}return"string"==typeof a&&""!==a||"number"==typeof a?(a=""+a,null!==i&&6===i.tag?(n(r,i.sibling),(i=o(i,a)).return=r,r=i):(n(r,i),(i=Fc(a,r.mode,l)).return=r,r=i),s(r)):n(r,i)}}var xi=wi(!0),ki=wi(!1),_i=Eo(null),Si=null,Ei=null,Oi=null;function ji(){Oi=Ei=Si=null}function Pi(e){var t=_i.current;Oo(_i),e._currentValue=t}function Ci(e,t,n){for(;null!==e;){var r=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,null!==r&&(r.childLanes|=t)):null!==r&&(r.childLanes&t)!==t&&(r.childLanes|=t),e===n)break;e=e.return}}function Ai(e,t){Si=e,Oi=Ei=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(0!==(e.lanes&t)&&(ys=!0),e.firstContext=null)}function Ti(e){var t=e._currentValue;if(Oi!==e)if(e={context:e,memoizedValue:t,next:null},null===Ei){if(null===Si)throw Error(i(308));Ei=e,Si.dependencies={lanes:0,firstContext:e}}else Ei=Ei.next=e;return t}var Ii=null;function Ni(e){null===Ii?Ii=[e]:Ii.push(e)}function Li(e,t,n,r){var o=t.interleaved;return null===o?(n.next=n,Ni(t)):(n.next=o.next,o.next=n),t.interleaved=n,Ri(e,r)}function Ri(e,t){e.lanes|=t;var n=e.alternate;for(null!==n&&(n.lanes|=t),n=e,e=e.return;null!==e;)e.childLanes|=t,null!==(n=e.alternate)&&(n.childLanes|=t),n=e,e=e.return;return 3===n.tag?n.stateNode:null}var Di=!1;function Fi(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Mi(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Bi(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function zi(e,t,n){var r=e.updateQueue;if(null===r)return null;if(r=r.shared,2&Pl){var o=r.pending;return null===o?t.next=t:(t.next=o.next,o.next=t),r.pending=t,Ri(e,n)}return null===(o=r.interleaved)?(t.next=t,Ni(r)):(t.next=o.next,o.next=t),r.interleaved=t,Ri(e,n)}function $i(e,t,n){if(null!==(t=t.updateQueue)&&(t=t.shared,4194240&n)){var r=t.lanes;n|=r&=e.pendingLanes,t.lanes=n,bt(e,n)}}function Ui(e,t){var n=e.updateQueue,r=e.alternate;if(null!==r&&n===(r=r.updateQueue)){var o=null,i=null;if(null!==(n=n.firstBaseUpdate)){do{var a={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};null===i?o=i=a:i=i.next=a,n=n.next}while(null!==n);null===i?o=i=t:i=i.next=t}else o=i=t;return n={baseState:r.baseState,firstBaseUpdate:o,lastBaseUpdate:i,shared:r.shared,effects:r.effects},void(e.updateQueue=n)}null===(e=n.lastBaseUpdate)?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function Vi(e,t,n,r){var o=e.updateQueue;Di=!1;var i=o.firstBaseUpdate,a=o.lastBaseUpdate,s=o.shared.pending;if(null!==s){o.shared.pending=null;var l=s,c=l.next;l.next=null,null===a?i=c:a.next=c,a=l;var u=e.alternate;null!==u&&((s=(u=u.updateQueue).lastBaseUpdate)!==a&&(null===s?u.firstBaseUpdate=c:s.next=c,u.lastBaseUpdate=l))}if(null!==i){var p=o.baseState;for(a=0,u=c=l=null,s=i;;){var d=s.lane,f=s.eventTime;if((r&d)===d){null!==u&&(u=u.next={eventTime:f,lane:0,tag:s.tag,payload:s.payload,callback:s.callback,next:null});e:{var m=e,h=s;switch(d=t,f=n,h.tag){case 1:if("function"==typeof(m=h.payload)){p=m.call(f,p,d);break e}p=m;break e;case 3:m.flags=-65537&m.flags|128;case 0:if(null==(d="function"==typeof(m=h.payload)?m.call(f,p,d):m))break e;p=F({},p,d);break e;case 2:Di=!0}}null!==s.callback&&0!==s.lane&&(e.flags|=64,null===(d=o.effects)?o.effects=[s]:d.push(s))}else f={eventTime:f,lane:d,tag:s.tag,payload:s.payload,callback:s.callback,next:null},null===u?(c=u=f,l=p):u=u.next=f,a|=d;if(null===(s=s.next)){if(null===(s=o.shared.pending))break;s=(d=s).next,d.next=null,o.lastBaseUpdate=d,o.shared.pending=null}}if(null===u&&(l=p),o.baseState=l,o.firstBaseUpdate=c,o.lastBaseUpdate=u,null!==(t=o.shared.interleaved)){o=t;do{a|=o.lane,o=o.next}while(o!==t)}else null===i&&(o.shared.lanes=0);Dl|=a,e.lanes=a,e.memoizedState=p}}function Qi(e,t,n){if(e=t.effects,t.effects=null,null!==e)for(t=0;t<e.length;t++){var r=e[t],o=r.callback;if(null!==o){if(r.callback=null,r=n,"function"!=typeof o)throw Error(i(191,o));o.call(r)}}}var Hi={},Wi=Eo(Hi),qi=Eo(Hi),Gi=Eo(Hi);function Ki(e){if(e===Hi)throw Error(i(174));return e}function Yi(e,t){switch(jo(Gi,t),jo(qi,e),jo(Wi,Hi),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:le(null,"");break;default:t=le(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}Oo(Wi),jo(Wi,t)}function Zi(){Oo(Wi),Oo(qi),Oo(Gi)}function Ji(e){Ki(Gi.current);var t=Ki(Wi.current),n=le(t,e.type);t!==n&&(jo(qi,e),jo(Wi,n))}function Xi(e){qi.current===e&&(Oo(Wi),Oo(qi))}var ea=Eo(0);function ta(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(128&t.flags)return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var na=[];function ra(){for(var e=0;e<na.length;e++)na[e]._workInProgressVersionPrimary=null;na.length=0}var oa=w.ReactCurrentDispatcher,ia=w.ReactCurrentBatchConfig,aa=0,sa=null,la=null,ca=null,ua=!1,pa=!1,da=0,fa=0;function ma(){throw Error(i(321))}function ha(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!sr(e[n],t[n]))return!1;return!0}function va(e,t,n,r,o,a){if(aa=a,sa=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,oa.current=null===e||null===e.memoizedState?Xa:es,e=n(r,o),pa){a=0;do{if(pa=!1,da=0,25<=a)throw Error(i(301));a+=1,ca=la=null,t.updateQueue=null,oa.current=ts,e=n(r,o)}while(pa)}if(oa.current=Ja,t=null!==la&&null!==la.next,aa=0,ca=la=sa=null,ua=!1,t)throw Error(i(300));return e}function ga(){var e=0!==da;return da=0,e}function ba(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===ca?sa.memoizedState=ca=e:ca=ca.next=e,ca}function ya(){if(null===la){var e=sa.alternate;e=null!==e?e.memoizedState:null}else e=la.next;var t=null===ca?sa.memoizedState:ca.next;if(null!==t)ca=t,la=e;else{if(null===e)throw Error(i(310));e={memoizedState:(la=e).memoizedState,baseState:la.baseState,baseQueue:la.baseQueue,queue:la.queue,next:null},null===ca?sa.memoizedState=ca=e:ca=ca.next=e}return ca}function wa(e,t){return"function"==typeof t?t(e):t}function xa(e){var t=ya(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var r=la,o=r.baseQueue,a=n.pending;if(null!==a){if(null!==o){var s=o.next;o.next=a.next,a.next=s}r.baseQueue=o=a,n.pending=null}if(null!==o){a=o.next,r=r.baseState;var l=s=null,c=null,u=a;do{var p=u.lane;if((aa&p)===p)null!==c&&(c=c.next={lane:0,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null}),r=u.hasEagerState?u.eagerState:e(r,u.action);else{var d={lane:p,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null};null===c?(l=c=d,s=r):c=c.next=d,sa.lanes|=p,Dl|=p}u=u.next}while(null!==u&&u!==a);null===c?s=r:c.next=l,sr(r,t.memoizedState)||(ys=!0),t.memoizedState=r,t.baseState=s,t.baseQueue=c,n.lastRenderedState=r}if(null!==(e=n.interleaved)){o=e;do{a=o.lane,sa.lanes|=a,Dl|=a,o=o.next}while(o!==e)}else null===o&&(n.lanes=0);return[t.memoizedState,n.dispatch]}function ka(e){var t=ya(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var r=n.dispatch,o=n.pending,a=t.memoizedState;if(null!==o){n.pending=null;var s=o=o.next;do{a=e(a,s.action),s=s.next}while(s!==o);sr(a,t.memoizedState)||(ys=!0),t.memoizedState=a,null===t.baseQueue&&(t.baseState=a),n.lastRenderedState=a}return[a,r]}function _a(){}function Sa(e,t){var n=sa,r=ya(),o=t(),a=!sr(r.memoizedState,o);if(a&&(r.memoizedState=o,ys=!0),r=r.queue,Da(ja.bind(null,n,r,e),[e]),r.getSnapshot!==t||a||null!==ca&&1&ca.memoizedState.tag){if(n.flags|=2048,Ta(9,Oa.bind(null,n,r,o,t),void 0,null),null===Cl)throw Error(i(349));30&aa||Ea(n,t,o)}return o}function Ea(e,t,n){e.flags|=16384,e={getSnapshot:t,value:n},null===(t=sa.updateQueue)?(t={lastEffect:null,stores:null},sa.updateQueue=t,t.stores=[e]):null===(n=t.stores)?t.stores=[e]:n.push(e)}function Oa(e,t,n,r){t.value=n,t.getSnapshot=r,Pa(t)&&Ca(e)}function ja(e,t,n){return n(function(){Pa(t)&&Ca(e)})}function Pa(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!sr(e,n)}catch(r){return!0}}function Ca(e){var t=Ri(e,1);null!==t&&nc(t,e,1,-1)}function Aa(e){var t=ba();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:wa,lastRenderedState:e},t.queue=e,e=e.dispatch=Ga.bind(null,sa,e),[t.memoizedState,e]}function Ta(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},null===(t=sa.updateQueue)?(t={lastEffect:null,stores:null},sa.updateQueue=t,t.lastEffect=e.next=e):null===(n=t.lastEffect)?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e),e}function Ia(){return ya().memoizedState}function Na(e,t,n,r){var o=ba();sa.flags|=e,o.memoizedState=Ta(1|t,n,void 0,void 0===r?null:r)}function La(e,t,n,r){var o=ya();r=void 0===r?null:r;var i=void 0;if(null!==la){var a=la.memoizedState;if(i=a.destroy,null!==r&&ha(r,a.deps))return void(o.memoizedState=Ta(t,n,i,r))}sa.flags|=e,o.memoizedState=Ta(1|t,n,i,r)}function Ra(e,t){return Na(8390656,8,e,t)}function Da(e,t){return La(2048,8,e,t)}function Fa(e,t){return La(4,2,e,t)}function Ma(e,t){return La(4,4,e,t)}function Ba(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function za(e,t,n){return n=null!=n?n.concat([e]):null,La(4,4,Ba.bind(null,t,e),n)}function $a(){}function Ua(e,t){var n=ya();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&ha(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function Va(e,t){var n=ya();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&ha(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)}function Qa(e,t,n){return 21&aa?(sr(n,t)||(n=ht(),sa.lanes|=n,Dl|=n,e.baseState=!0),t):(e.baseState&&(e.baseState=!1,ys=!0),e.memoizedState=n)}function Ha(e,t){var n=yt;yt=0!==n&&4>n?n:4,e(!0);var r=ia.transition;ia.transition={};try{e(!1),t()}finally{yt=n,ia.transition=r}}function Wa(){return ya().memoizedState}function qa(e,t,n){var r=tc(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},Ka(e))Ya(t,n);else if(null!==(n=Li(e,t,n,r))){nc(n,e,r,ec()),Za(n,t,r)}}function Ga(e,t,n){var r=tc(e),o={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(Ka(e))Ya(t,o);else{var i=e.alternate;if(0===e.lanes&&(null===i||0===i.lanes)&&null!==(i=t.lastRenderedReducer))try{var a=t.lastRenderedState,s=i(a,n);if(o.hasEagerState=!0,o.eagerState=s,sr(s,a)){var l=t.interleaved;return null===l?(o.next=o,Ni(t)):(o.next=l.next,l.next=o),void(t.interleaved=o)}}catch(c){}null!==(n=Li(e,t,o,r))&&(nc(n,e,r,o=ec()),Za(n,t,r))}}function Ka(e){var t=e.alternate;return e===sa||null!==t&&t===sa}function Ya(e,t){pa=ua=!0;var n=e.pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Za(e,t,n){if(4194240&n){var r=t.lanes;n|=r&=e.pendingLanes,t.lanes=n,bt(e,n)}}var Ja={readContext:Ti,useCallback:ma,useContext:ma,useEffect:ma,useImperativeHandle:ma,useInsertionEffect:ma,useLayoutEffect:ma,useMemo:ma,useReducer:ma,useRef:ma,useState:ma,useDebugValue:ma,useDeferredValue:ma,useTransition:ma,useMutableSource:ma,useSyncExternalStore:ma,useId:ma,unstable_isNewReconciler:!1},Xa={readContext:Ti,useCallback:function(e,t){return ba().memoizedState=[e,void 0===t?null:t],e},useContext:Ti,useEffect:Ra,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,Na(4194308,4,Ba.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Na(4194308,4,e,t)},useInsertionEffect:function(e,t){return Na(4,2,e,t)},useMemo:function(e,t){var n=ba();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=ba();return t=void 0!==n?n(t):t,r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=qa.bind(null,sa,e),[r.memoizedState,e]},useRef:function(e){return e={current:e},ba().memoizedState=e},useState:Aa,useDebugValue:$a,useDeferredValue:function(e){return ba().memoizedState=e},useTransition:function(){var e=Aa(!1),t=e[0];return e=Ha.bind(null,e[1]),ba().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var r=sa,o=ba();if(ii){if(void 0===n)throw Error(i(407));n=n()}else{if(n=t(),null===Cl)throw Error(i(349));30&aa||Ea(r,t,n)}o.memoizedState=n;var a={value:n,getSnapshot:t};return o.queue=a,Ra(ja.bind(null,r,a,e),[e]),r.flags|=2048,Ta(9,Oa.bind(null,r,a,n,t),void 0,null),n},useId:function(){var e=ba(),t=Cl.identifierPrefix;if(ii){var n=Jo;t=":"+t+"R"+(n=(Zo&~(1<<32-at(Zo)-1)).toString(32)+n),0<(n=da++)&&(t+="H"+n.toString(32)),t+=":"}else t=":"+t+"r"+(n=fa++).toString(32)+":";return e.memoizedState=t},unstable_isNewReconciler:!1},es={readContext:Ti,useCallback:Ua,useContext:Ti,useEffect:Da,useImperativeHandle:za,useInsertionEffect:Fa,useLayoutEffect:Ma,useMemo:Va,useReducer:xa,useRef:Ia,useState:function(){return xa(wa)},useDebugValue:$a,useDeferredValue:function(e){return Qa(ya(),la.memoizedState,e)},useTransition:function(){return[xa(wa)[0],ya().memoizedState]},useMutableSource:_a,useSyncExternalStore:Sa,useId:Wa,unstable_isNewReconciler:!1},ts={readContext:Ti,useCallback:Ua,useContext:Ti,useEffect:Da,useImperativeHandle:za,useInsertionEffect:Fa,useLayoutEffect:Ma,useMemo:Va,useReducer:ka,useRef:Ia,useState:function(){return ka(wa)},useDebugValue:$a,useDeferredValue:function(e){var t=ya();return null===la?t.memoizedState=e:Qa(t,la.memoizedState,e)},useTransition:function(){return[ka(wa)[0],ya().memoizedState]},useMutableSource:_a,useSyncExternalStore:Sa,useId:Wa,unstable_isNewReconciler:!1};function ns(e,t){if(e&&e.defaultProps){for(var n in t=F({},t),e=e.defaultProps)void 0===t[n]&&(t[n]=e[n]);return t}return t}function rs(e,t,n,r){n=null==(n=n(r,t=e.memoizedState))?t:F({},t,n),e.memoizedState=n,0===e.lanes&&(e.updateQueue.baseState=n)}var os={isMounted:function(e){return!!(e=e._reactInternals)&&Ue(e)===e},enqueueSetState:function(e,t,n){e=e._reactInternals;var r=ec(),o=tc(e),i=Bi(r,o);i.payload=t,null!=n&&(i.callback=n),null!==(t=zi(e,i,o))&&(nc(t,e,o,r),$i(t,e,o))},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var r=ec(),o=tc(e),i=Bi(r,o);i.tag=1,i.payload=t,null!=n&&(i.callback=n),null!==(t=zi(e,i,o))&&(nc(t,e,o,r),$i(t,e,o))},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=ec(),r=tc(e),o=Bi(n,r);o.tag=2,null!=t&&(o.callback=t),null!==(t=zi(e,o,r))&&(nc(t,e,r,n),$i(t,e,r))}};function is(e,t,n,r,o,i,a){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(r,i,a):!t.prototype||!t.prototype.isPureReactComponent||(!lr(n,r)||!lr(o,i))}function as(e,t,n){var r=!1,o=Po,i=t.contextType;return"object"==typeof i&&null!==i?i=Ti(i):(o=No(t)?To:Co.current,i=(r=null!=(r=t.contextTypes))?Io(e,o):Po),t=new t(n,i),e.memoizedState=null!==t.state&&void 0!==t.state?t.state:null,t.updater=os,e.stateNode=t,t._reactInternals=e,r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=o,e.__reactInternalMemoizedMaskedChildContext=i),t}function ss(e,t,n,r){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,r),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&os.enqueueReplaceState(t,t.state,null)}function ls(e,t,n,r){var o=e.stateNode;o.props=n,o.state=e.memoizedState,o.refs={},Fi(e);var i=t.contextType;"object"==typeof i&&null!==i?o.context=Ti(i):(i=No(t)?To:Co.current,o.context=Io(e,i)),o.state=e.memoizedState,"function"==typeof(i=t.getDerivedStateFromProps)&&(rs(e,t,i,n),o.state=e.memoizedState),"function"==typeof t.getDerivedStateFromProps||"function"==typeof o.getSnapshotBeforeUpdate||"function"!=typeof o.UNSAFE_componentWillMount&&"function"!=typeof o.componentWillMount||(t=o.state,"function"==typeof o.componentWillMount&&o.componentWillMount(),"function"==typeof o.UNSAFE_componentWillMount&&o.UNSAFE_componentWillMount(),t!==o.state&&os.enqueueReplaceState(o,o.state,null),Vi(e,n,o,r),o.state=e.memoizedState),"function"==typeof o.componentDidMount&&(e.flags|=4194308)}function cs(e,t){try{var n="",r=t;do{n+=$(r),r=r.return}while(r);var o=n}catch(i){o="\nError generating stack: "+i.message+"\n"+i.stack}return{value:e,source:t,stack:o,digest:null}}function us(e,t,n){return{value:e,source:null,stack:null!=n?n:null,digest:null!=t?t:null}}function ps(e,t){try{console.error(t.value)}catch(n){setTimeout(function(){throw n})}}var ds="function"==typeof WeakMap?WeakMap:Map;function fs(e,t,n){(n=Bi(-1,n)).tag=3,n.payload={element:null};var r=t.value;return n.callback=function(){Ql||(Ql=!0,Hl=r),ps(0,t)},n}function ms(e,t,n){(n=Bi(-1,n)).tag=3;var r=e.type.getDerivedStateFromError;if("function"==typeof r){var o=t.value;n.payload=function(){return r(o)},n.callback=function(){ps(0,t)}}var i=e.stateNode;return null!==i&&"function"==typeof i.componentDidCatch&&(n.callback=function(){ps(0,t),"function"!=typeof r&&(null===Wl?Wl=new Set([this]):Wl.add(this));var e=t.stack;this.componentDidCatch(t.value,{componentStack:null!==e?e:""})}),n}function hs(e,t,n){var r=e.pingCache;if(null===r){r=e.pingCache=new ds;var o=new Set;r.set(t,o)}else void 0===(o=r.get(t))&&(o=new Set,r.set(t,o));o.has(n)||(o.add(n),e=Ec.bind(null,e,t,n),t.then(e,e))}function vs(e){do{var t;if((t=13===e.tag)&&(t=null===(t=e.memoizedState)||null!==t.dehydrated),t)return e;e=e.return}while(null!==e);return null}function gs(e,t,n,r,o){return 1&e.mode?(e.flags|=65536,e.lanes=o,e):(e===t?e.flags|=65536:(e.flags|=128,n.flags|=131072,n.flags&=-52805,1===n.tag&&(null===n.alternate?n.tag=17:((t=Bi(-1,1)).tag=2,zi(n,t,1))),n.lanes|=1),e)}var bs=w.ReactCurrentOwner,ys=!1;function ws(e,t,n,r){t.child=null===e?ki(t,null,n,r):xi(t,e.child,n,r)}function xs(e,t,n,r,o){n=n.render;var i=t.ref;return Ai(t,o),r=va(e,t,n,r,i,o),n=ga(),null===e||ys?(ii&&n&&ti(t),t.flags|=1,ws(e,t,r,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,Qs(e,t,o))}function ks(e,t,n,r,o){if(null===e){var i=n.type;return"function"!=typeof i||Ic(i)||void 0!==i.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=Lc(n.type,null,r,t,t.mode,o)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=i,_s(e,t,i,r,o))}if(i=e.child,0===(e.lanes&o)){var a=i.memoizedProps;if((n=null!==(n=n.compare)?n:lr)(a,r)&&e.ref===t.ref)return Qs(e,t,o)}return t.flags|=1,(e=Nc(i,r)).ref=t.ref,e.return=t,t.child=e}function _s(e,t,n,r,o){if(null!==e){var i=e.memoizedProps;if(lr(i,r)&&e.ref===t.ref){if(ys=!1,t.pendingProps=r=i,0===(e.lanes&o))return t.lanes=e.lanes,Qs(e,t,o);131072&e.flags&&(ys=!0)}}return Os(e,t,n,r,o)}function Ss(e,t,n){var r=t.pendingProps,o=r.children,i=null!==e?e.memoizedState:null;if("hidden"===r.mode)if(1&t.mode){if(!(1073741824&n))return e=null!==i?i.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e,cachePool:null,transitions:null},t.updateQueue=null,jo(Nl,Il),Il|=e,null;t.memoizedState={baseLanes:0,cachePool:null,transitions:null},r=null!==i?i.baseLanes:n,jo(Nl,Il),Il|=r}else t.memoizedState={baseLanes:0,cachePool:null,transitions:null},jo(Nl,Il),Il|=n;else null!==i?(r=i.baseLanes|n,t.memoizedState=null):r=n,jo(Nl,Il),Il|=r;return ws(e,t,o,n),t.child}function Es(e,t){var n=t.ref;(null===e&&null!==n||null!==e&&e.ref!==n)&&(t.flags|=512,t.flags|=2097152)}function Os(e,t,n,r,o){var i=No(n)?To:Co.current;return i=Io(t,i),Ai(t,o),n=va(e,t,n,r,i,o),r=ga(),null===e||ys?(ii&&r&&ti(t),t.flags|=1,ws(e,t,n,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,Qs(e,t,o))}function js(e,t,n,r,o){if(No(n)){var i=!0;Fo(t)}else i=!1;if(Ai(t,o),null===t.stateNode)Vs(e,t),as(t,n,r),ls(t,n,r,o),r=!0;else if(null===e){var a=t.stateNode,s=t.memoizedProps;a.props=s;var l=a.context,c=n.contextType;"object"==typeof c&&null!==c?c=Ti(c):c=Io(t,c=No(n)?To:Co.current);var u=n.getDerivedStateFromProps,p="function"==typeof u||"function"==typeof a.getSnapshotBeforeUpdate;p||"function"!=typeof a.UNSAFE_componentWillReceiveProps&&"function"!=typeof a.componentWillReceiveProps||(s!==r||l!==c)&&ss(t,a,r,c),Di=!1;var d=t.memoizedState;a.state=d,Vi(t,r,a,o),l=t.memoizedState,s!==r||d!==l||Ao.current||Di?("function"==typeof u&&(rs(t,n,u,r),l=t.memoizedState),(s=Di||is(t,n,s,r,d,l,c))?(p||"function"!=typeof a.UNSAFE_componentWillMount&&"function"!=typeof a.componentWillMount||("function"==typeof a.componentWillMount&&a.componentWillMount(),"function"==typeof a.UNSAFE_componentWillMount&&a.UNSAFE_componentWillMount()),"function"==typeof a.componentDidMount&&(t.flags|=4194308)):("function"==typeof a.componentDidMount&&(t.flags|=4194308),t.memoizedProps=r,t.memoizedState=l),a.props=r,a.state=l,a.context=c,r=s):("function"==typeof a.componentDidMount&&(t.flags|=4194308),r=!1)}else{a=t.stateNode,Mi(e,t),s=t.memoizedProps,c=t.type===t.elementType?s:ns(t.type,s),a.props=c,p=t.pendingProps,d=a.context,"object"==typeof(l=n.contextType)&&null!==l?l=Ti(l):l=Io(t,l=No(n)?To:Co.current);var f=n.getDerivedStateFromProps;(u="function"==typeof f||"function"==typeof a.getSnapshotBeforeUpdate)||"function"!=typeof a.UNSAFE_componentWillReceiveProps&&"function"!=typeof a.componentWillReceiveProps||(s!==p||d!==l)&&ss(t,a,r,l),Di=!1,d=t.memoizedState,a.state=d,Vi(t,r,a,o);var m=t.memoizedState;s!==p||d!==m||Ao.current||Di?("function"==typeof f&&(rs(t,n,f,r),m=t.memoizedState),(c=Di||is(t,n,c,r,d,m,l)||!1)?(u||"function"!=typeof a.UNSAFE_componentWillUpdate&&"function"!=typeof a.componentWillUpdate||("function"==typeof a.componentWillUpdate&&a.componentWillUpdate(r,m,l),"function"==typeof a.UNSAFE_componentWillUpdate&&a.UNSAFE_componentWillUpdate(r,m,l)),"function"==typeof a.componentDidUpdate&&(t.flags|=4),"function"==typeof a.getSnapshotBeforeUpdate&&(t.flags|=1024)):("function"!=typeof a.componentDidUpdate||s===e.memoizedProps&&d===e.memoizedState||(t.flags|=4),"function"!=typeof a.getSnapshotBeforeUpdate||s===e.memoizedProps&&d===e.memoizedState||(t.flags|=1024),t.memoizedProps=r,t.memoizedState=m),a.props=r,a.state=m,a.context=l,r=c):("function"!=typeof a.componentDidUpdate||s===e.memoizedProps&&d===e.memoizedState||(t.flags|=4),"function"!=typeof a.getSnapshotBeforeUpdate||s===e.memoizedProps&&d===e.memoizedState||(t.flags|=1024),r=!1)}return Ps(e,t,n,r,i,o)}function Ps(e,t,n,r,o,i){Es(e,t);var a=!!(128&t.flags);if(!r&&!a)return o&&Mo(t,n,!1),Qs(e,t,i);r=t.stateNode,bs.current=t;var s=a&&"function"!=typeof n.getDerivedStateFromError?null:r.render();return t.flags|=1,null!==e&&a?(t.child=xi(t,e.child,null,i),t.child=xi(t,null,s,i)):ws(e,t,s,i),t.memoizedState=r.state,o&&Mo(t,n,!0),t.child}function Cs(e){var t=e.stateNode;t.pendingContext?Ro(0,t.pendingContext,t.pendingContext!==t.context):t.context&&Ro(0,t.context,!1),Yi(e,t.containerInfo)}function As(e,t,n,r,o){return mi(),hi(o),t.flags|=256,ws(e,t,n,r),t.child}var Ts,Is,Ns,Ls,Rs={dehydrated:null,treeContext:null,retryLane:0};function Ds(e){return{baseLanes:e,cachePool:null,transitions:null}}function Fs(e,t,n){var r,o=t.pendingProps,a=ea.current,s=!1,l=!!(128&t.flags);if((r=l)||(r=(null===e||null!==e.memoizedState)&&!!(2&a)),r?(s=!0,t.flags&=-129):null!==e&&null===e.memoizedState||(a|=1),jo(ea,1&a),null===e)return ui(t),null!==(e=t.memoizedState)&&null!==(e=e.dehydrated)?(1&t.mode?"$!"===e.data?t.lanes=8:t.lanes=1073741824:t.lanes=1,null):(l=o.children,e=o.fallback,s?(o=t.mode,s=t.child,l={mode:"hidden",children:l},1&o||null===s?s=Dc(l,o,0,null):(s.childLanes=0,s.pendingProps=l),e=Rc(e,o,n,null),s.return=t,e.return=t,s.sibling=e,t.child=s,t.child.memoizedState=Ds(n),t.memoizedState=Rs,e):Ms(t,l));if(null!==(a=e.memoizedState)&&null!==(r=a.dehydrated))return function(e,t,n,r,o,a,s){if(n)return 256&t.flags?(t.flags&=-257,Bs(e,t,s,r=us(Error(i(422))))):null!==t.memoizedState?(t.child=e.child,t.flags|=128,null):(a=r.fallback,o=t.mode,r=Dc({mode:"visible",children:r.children},o,0,null),(a=Rc(a,o,s,null)).flags|=2,r.return=t,a.return=t,r.sibling=a,t.child=r,1&t.mode&&xi(t,e.child,null,s),t.child.memoizedState=Ds(s),t.memoizedState=Rs,a);if(!(1&t.mode))return Bs(e,t,s,null);if("$!"===o.data){if(r=o.nextSibling&&o.nextSibling.dataset)var l=r.dgst;return r=l,Bs(e,t,s,r=us(a=Error(i(419)),r,void 0))}if(l=0!==(s&e.childLanes),ys||l){if(null!==(r=Cl)){switch(s&-s){case 4:o=2;break;case 16:o=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:o=32;break;case 536870912:o=268435456;break;default:o=0}0!==(o=0!==(o&(r.suspendedLanes|s))?0:o)&&o!==a.retryLane&&(a.retryLane=o,Ri(e,o),nc(r,e,o,-1))}return hc(),Bs(e,t,s,r=us(Error(i(421))))}return"$?"===o.data?(t.flags|=128,t.child=e.child,t=jc.bind(null,e),o._reactRetry=t,null):(e=a.treeContext,oi=co(o.nextSibling),ri=t,ii=!0,ai=null,null!==e&&(Go[Ko++]=Zo,Go[Ko++]=Jo,Go[Ko++]=Yo,Zo=e.id,Jo=e.overflow,Yo=t),t=Ms(t,r.children),t.flags|=4096,t)}(e,t,l,o,r,a,n);if(s){s=o.fallback,l=t.mode,r=(a=e.child).sibling;var c={mode:"hidden",children:o.children};return 1&l||t.child===a?(o=Nc(a,c)).subtreeFlags=14680064&a.subtreeFlags:((o=t.child).childLanes=0,o.pendingProps=c,t.deletions=null),null!==r?s=Nc(r,s):(s=Rc(s,l,n,null)).flags|=2,s.return=t,o.return=t,o.sibling=s,t.child=o,o=s,s=t.child,l=null===(l=e.child.memoizedState)?Ds(n):{baseLanes:l.baseLanes|n,cachePool:null,transitions:l.transitions},s.memoizedState=l,s.childLanes=e.childLanes&~n,t.memoizedState=Rs,o}return e=(s=e.child).sibling,o=Nc(s,{mode:"visible",children:o.children}),!(1&t.mode)&&(o.lanes=n),o.return=t,o.sibling=null,null!==e&&(null===(n=t.deletions)?(t.deletions=[e],t.flags|=16):n.push(e)),t.child=o,t.memoizedState=null,o}function Ms(e,t){return(t=Dc({mode:"visible",children:t},e.mode,0,null)).return=e,e.child=t}function Bs(e,t,n,r){return null!==r&&hi(r),xi(t,e.child,null,n),(e=Ms(t,t.pendingProps.children)).flags|=2,t.memoizedState=null,e}function zs(e,t,n){e.lanes|=t;var r=e.alternate;null!==r&&(r.lanes|=t),Ci(e.return,t,n)}function $s(e,t,n,r,o){var i=e.memoizedState;null===i?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:o}:(i.isBackwards=t,i.rendering=null,i.renderingStartTime=0,i.last=r,i.tail=n,i.tailMode=o)}function Us(e,t,n){var r=t.pendingProps,o=r.revealOrder,i=r.tail;if(ws(e,t,r.children,n),2&(r=ea.current))r=1&r|2,t.flags|=128;else{if(null!==e&&128&e.flags)e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&zs(e,n,t);else if(19===e.tag)zs(e,n,t);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(jo(ea,r),1&t.mode)switch(o){case"forwards":for(n=t.child,o=null;null!==n;)null!==(e=n.alternate)&&null===ta(e)&&(o=n),n=n.sibling;null===(n=o)?(o=t.child,t.child=null):(o=n.sibling,n.sibling=null),$s(t,!1,o,n,i);break;case"backwards":for(n=null,o=t.child,t.child=null;null!==o;){if(null!==(e=o.alternate)&&null===ta(e)){t.child=o;break}e=o.sibling,o.sibling=n,n=o,o=e}$s(t,!0,n,null,i);break;case"together":$s(t,!1,null,null,void 0);break;default:t.memoizedState=null}else t.memoizedState=null;return t.child}function Vs(e,t){!(1&t.mode)&&null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2)}function Qs(e,t,n){if(null!==e&&(t.dependencies=e.dependencies),Dl|=t.lanes,0===(n&t.childLanes))return null;if(null!==e&&t.child!==e.child)throw Error(i(153));if(null!==t.child){for(n=Nc(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Nc(e,e.pendingProps)).return=t;n.sibling=null}return t.child}function Hs(e,t){if(!ii)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var r=null;null!==n;)null!==n.alternate&&(r=n),n=n.sibling;null===r?t||null===e.tail?e.tail=null:e.tail.sibling=null:r.sibling=null}}function Ws(e){var t=null!==e.alternate&&e.alternate.child===e.child,n=0,r=0;if(t)for(var o=e.child;null!==o;)n|=o.lanes|o.childLanes,r|=14680064&o.subtreeFlags,r|=14680064&o.flags,o.return=e,o=o.sibling;else for(o=e.child;null!==o;)n|=o.lanes|o.childLanes,r|=o.subtreeFlags,r|=o.flags,o.return=e,o=o.sibling;return e.subtreeFlags|=r,e.childLanes=n,t}function qs(e,t,n){var r=t.pendingProps;switch(ni(t),t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Ws(t),null;case 1:case 17:return No(t.type)&&Lo(),Ws(t),null;case 3:return r=t.stateNode,Zi(),Oo(Ao),Oo(Co),ra(),r.pendingContext&&(r.context=r.pendingContext,r.pendingContext=null),null!==e&&null!==e.child||(di(t)?t.flags|=4:null===e||e.memoizedState.isDehydrated&&!(256&t.flags)||(t.flags|=1024,null!==ai&&(ac(ai),ai=null))),Is(e,t),Ws(t),null;case 5:Xi(t);var o=Ki(Gi.current);if(n=t.type,null!==e&&null!=t.stateNode)Ns(e,t,n,r,o),e.ref!==t.ref&&(t.flags|=512,t.flags|=2097152);else{if(!r){if(null===t.stateNode)throw Error(i(166));return Ws(t),null}if(e=Ki(Wi.current),di(t)){r=t.stateNode,n=t.type;var a=t.memoizedProps;switch(r[fo]=t,r[mo]=a,e=!!(1&t.mode),n){case"dialog":Br("cancel",r),Br("close",r);break;case"iframe":case"object":case"embed":Br("load",r);break;case"video":case"audio":for(o=0;o<Rr.length;o++)Br(Rr[o],r);break;case"source":Br("error",r);break;case"img":case"image":case"link":Br("error",r),Br("load",r);break;case"details":Br("toggle",r);break;case"input":Y(r,a),Br("invalid",r);break;case"select":r._wrapperState={wasMultiple:!!a.multiple},Br("invalid",r);break;case"textarea":oe(r,a),Br("invalid",r)}for(var l in be(n,a),o=null,a)if(a.hasOwnProperty(l)){var c=a[l];"children"===l?"string"==typeof c?r.textContent!==c&&(!0!==a.suppressHydrationWarning&&Jr(r.textContent,c,e),o=["children",c]):"number"==typeof c&&r.textContent!==""+c&&(!0!==a.suppressHydrationWarning&&Jr(r.textContent,c,e),o=["children",""+c]):s.hasOwnProperty(l)&&null!=c&&"onScroll"===l&&Br("scroll",r)}switch(n){case"input":W(r),X(r,a,!0);break;case"textarea":W(r),ae(r);break;case"select":case"option":break;default:"function"==typeof a.onClick&&(r.onclick=Xr)}r=o,t.updateQueue=r,null!==r&&(t.flags|=4)}else{l=9===o.nodeType?o:o.ownerDocument,"http://www.w3.org/1999/xhtml"===e&&(e=se(n)),"http://www.w3.org/1999/xhtml"===e?"script"===n?((e=l.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):"string"==typeof r.is?e=l.createElement(n,{is:r.is}):(e=l.createElement(n),"select"===n&&(l=e,r.multiple?l.multiple=!0:r.size&&(l.size=r.size))):e=l.createElementNS(e,n),e[fo]=t,e[mo]=r,Ts(e,t,!1,!1),t.stateNode=e;e:{switch(l=ye(n,r),n){case"dialog":Br("cancel",e),Br("close",e),o=r;break;case"iframe":case"object":case"embed":Br("load",e),o=r;break;case"video":case"audio":for(o=0;o<Rr.length;o++)Br(Rr[o],e);o=r;break;case"source":Br("error",e),o=r;break;case"img":case"image":case"link":Br("error",e),Br("load",e),o=r;break;case"details":Br("toggle",e),o=r;break;case"input":Y(e,r),o=K(e,r),Br("invalid",e);break;case"option":default:o=r;break;case"select":e._wrapperState={wasMultiple:!!r.multiple},o=F({},r,{value:void 0}),Br("invalid",e);break;case"textarea":oe(e,r),o=re(e,r),Br("invalid",e)}for(a in be(n,o),c=o)if(c.hasOwnProperty(a)){var u=c[a];"style"===a?ve(e,u):"dangerouslySetInnerHTML"===a?null!=(u=u?u.__html:void 0)&&pe(e,u):"children"===a?"string"==typeof u?("textarea"!==n||""!==u)&&de(e,u):"number"==typeof u&&de(e,""+u):"suppressContentEditableWarning"!==a&&"suppressHydrationWarning"!==a&&"autoFocus"!==a&&(s.hasOwnProperty(a)?null!=u&&"onScroll"===a&&Br("scroll",e):null!=u&&y(e,a,u,l))}switch(n){case"input":W(e),X(e,r,!1);break;case"textarea":W(e),ae(e);break;case"option":null!=r.value&&e.setAttribute("value",""+Q(r.value));break;case"select":e.multiple=!!r.multiple,null!=(a=r.value)?ne(e,!!r.multiple,a,!1):null!=r.defaultValue&&ne(e,!!r.multiple,r.defaultValue,!0);break;default:"function"==typeof o.onClick&&(e.onclick=Xr)}switch(n){case"button":case"input":case"select":case"textarea":r=!!r.autoFocus;break e;case"img":r=!0;break e;default:r=!1}}r&&(t.flags|=4)}null!==t.ref&&(t.flags|=512,t.flags|=2097152)}return Ws(t),null;case 6:if(e&&null!=t.stateNode)Ls(e,t,e.memoizedProps,r);else{if("string"!=typeof r&&null===t.stateNode)throw Error(i(166));if(n=Ki(Gi.current),Ki(Wi.current),di(t)){if(r=t.stateNode,n=t.memoizedProps,r[fo]=t,(a=r.nodeValue!==n)&&null!==(e=ri))switch(e.tag){case 3:Jr(r.nodeValue,n,!!(1&e.mode));break;case 5:!0!==e.memoizedProps.suppressHydrationWarning&&Jr(r.nodeValue,n,!!(1&e.mode))}a&&(t.flags|=4)}else(r=(9===n.nodeType?n:n.ownerDocument).createTextNode(r))[fo]=t,t.stateNode=r}return Ws(t),null;case 13:if(Oo(ea),r=t.memoizedState,null===e||null!==e.memoizedState&&null!==e.memoizedState.dehydrated){if(ii&&null!==oi&&1&t.mode&&!(128&t.flags))fi(),mi(),t.flags|=98560,a=!1;else if(a=di(t),null!==r&&null!==r.dehydrated){if(null===e){if(!a)throw Error(i(318));if(!(a=null!==(a=t.memoizedState)?a.dehydrated:null))throw Error(i(317));a[fo]=t}else mi(),!(128&t.flags)&&(t.memoizedState=null),t.flags|=4;Ws(t),a=!1}else null!==ai&&(ac(ai),ai=null),a=!0;if(!a)return 65536&t.flags?t:null}return 128&t.flags?(t.lanes=n,t):((r=null!==r)!==(null!==e&&null!==e.memoizedState)&&r&&(t.child.flags|=8192,1&t.mode&&(null===e||1&ea.current?0===Ll&&(Ll=3):hc())),null!==t.updateQueue&&(t.flags|=4),Ws(t),null);case 4:return Zi(),Is(e,t),null===e&&Ur(t.stateNode.containerInfo),Ws(t),null;case 10:return Pi(t.type._context),Ws(t),null;case 19:if(Oo(ea),null===(a=t.memoizedState))return Ws(t),null;if(r=!!(128&t.flags),null===(l=a.rendering))if(r)Hs(a,!1);else{if(0!==Ll||null!==e&&128&e.flags)for(e=t.child;null!==e;){if(null!==(l=ta(e))){for(t.flags|=128,Hs(a,!1),null!==(r=l.updateQueue)&&(t.updateQueue=r,t.flags|=4),t.subtreeFlags=0,r=n,n=t.child;null!==n;)e=r,(a=n).flags&=14680066,null===(l=a.alternate)?(a.childLanes=0,a.lanes=e,a.child=null,a.subtreeFlags=0,a.memoizedProps=null,a.memoizedState=null,a.updateQueue=null,a.dependencies=null,a.stateNode=null):(a.childLanes=l.childLanes,a.lanes=l.lanes,a.child=l.child,a.subtreeFlags=0,a.deletions=null,a.memoizedProps=l.memoizedProps,a.memoizedState=l.memoizedState,a.updateQueue=l.updateQueue,a.type=l.type,e=l.dependencies,a.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return jo(ea,1&ea.current|2),t.child}e=e.sibling}null!==a.tail&&Ze()>Ul&&(t.flags|=128,r=!0,Hs(a,!1),t.lanes=4194304)}else{if(!r)if(null!==(e=ta(l))){if(t.flags|=128,r=!0,null!==(n=e.updateQueue)&&(t.updateQueue=n,t.flags|=4),Hs(a,!0),null===a.tail&&"hidden"===a.tailMode&&!l.alternate&&!ii)return Ws(t),null}else 2*Ze()-a.renderingStartTime>Ul&&1073741824!==n&&(t.flags|=128,r=!0,Hs(a,!1),t.lanes=4194304);a.isBackwards?(l.sibling=t.child,t.child=l):(null!==(n=a.last)?n.sibling=l:t.child=l,a.last=l)}return null!==a.tail?(t=a.tail,a.rendering=t,a.tail=t.sibling,a.renderingStartTime=Ze(),t.sibling=null,n=ea.current,jo(ea,r?1&n|2:1&n),t):(Ws(t),null);case 22:case 23:return pc(),r=null!==t.memoizedState,null!==e&&null!==e.memoizedState!==r&&(t.flags|=8192),r&&1&t.mode?!!(1073741824&Il)&&(Ws(t),6&t.subtreeFlags&&(t.flags|=8192)):Ws(t),null;case 24:case 25:return null}throw Error(i(156,t.tag))}function Gs(e,t){switch(ni(t),t.tag){case 1:return No(t.type)&&Lo(),65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 3:return Zi(),Oo(Ao),Oo(Co),ra(),65536&(e=t.flags)&&!(128&e)?(t.flags=-65537&e|128,t):null;case 5:return Xi(t),null;case 13:if(Oo(ea),null!==(e=t.memoizedState)&&null!==e.dehydrated){if(null===t.alternate)throw Error(i(340));mi()}return 65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 19:return Oo(ea),null;case 4:return Zi(),null;case 10:return Pi(t.type._context),null;case 22:case 23:return pc(),null;default:return null}}Ts=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Is=function(){},Ns=function(e,t,n,r){var o=e.memoizedProps;if(o!==r){e=t.stateNode,Ki(Wi.current);var i,a=null;switch(n){case"input":o=K(e,o),r=K(e,r),a=[];break;case"select":o=F({},o,{value:void 0}),r=F({},r,{value:void 0}),a=[];break;case"textarea":o=re(e,o),r=re(e,r),a=[];break;default:"function"!=typeof o.onClick&&"function"==typeof r.onClick&&(e.onclick=Xr)}for(u in be(n,r),n=null,o)if(!r.hasOwnProperty(u)&&o.hasOwnProperty(u)&&null!=o[u])if("style"===u){var l=o[u];for(i in l)l.hasOwnProperty(i)&&(n||(n={}),n[i]="")}else"dangerouslySetInnerHTML"!==u&&"children"!==u&&"suppressContentEditableWarning"!==u&&"suppressHydrationWarning"!==u&&"autoFocus"!==u&&(s.hasOwnProperty(u)?a||(a=[]):(a=a||[]).push(u,null));for(u in r){var c=r[u];if(l=null!=o?o[u]:void 0,r.hasOwnProperty(u)&&c!==l&&(null!=c||null!=l))if("style"===u)if(l){for(i in l)!l.hasOwnProperty(i)||c&&c.hasOwnProperty(i)||(n||(n={}),n[i]="");for(i in c)c.hasOwnProperty(i)&&l[i]!==c[i]&&(n||(n={}),n[i]=c[i])}else n||(a||(a=[]),a.push(u,n)),n=c;else"dangerouslySetInnerHTML"===u?(c=c?c.__html:void 0,l=l?l.__html:void 0,null!=c&&l!==c&&(a=a||[]).push(u,c)):"children"===u?"string"!=typeof c&&"number"!=typeof c||(a=a||[]).push(u,""+c):"suppressContentEditableWarning"!==u&&"suppressHydrationWarning"!==u&&(s.hasOwnProperty(u)?(null!=c&&"onScroll"===u&&Br("scroll",e),a||l===c||(a=[])):(a=a||[]).push(u,c))}n&&(a=a||[]).push("style",n);var u=a;(t.updateQueue=u)&&(t.flags|=4)}},Ls=function(e,t,n,r){n!==r&&(t.flags|=4)};var Ks=!1,Ys=!1,Zs="function"==typeof WeakSet?WeakSet:Set,Js=null;function Xs(e,t){var n=e.ref;if(null!==n)if("function"==typeof n)try{n(null)}catch(r){Sc(e,t,r)}else n.current=null}function el(e,t,n){try{n()}catch(r){Sc(e,t,r)}}var tl=!1;function nl(e,t,n){var r=t.updateQueue;if(null!==(r=null!==r?r.lastEffect:null)){var o=r=r.next;do{if((o.tag&e)===e){var i=o.destroy;o.destroy=void 0,void 0!==i&&el(t,n,i)}o=o.next}while(o!==r)}}function rl(e,t){if(null!==(t=null!==(t=t.updateQueue)?t.lastEffect:null)){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function ol(e){var t=e.ref;if(null!==t){var n=e.stateNode;e.tag,e=n,"function"==typeof t?t(e):t.current=e}}function il(e){var t=e.alternate;null!==t&&(e.alternate=null,il(t)),e.child=null,e.deletions=null,e.sibling=null,5===e.tag&&(null!==(t=e.stateNode)&&(delete t[fo],delete t[mo],delete t[vo],delete t[go],delete t[bo])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function al(e){return 5===e.tag||3===e.tag||4===e.tag}function sl(e){e:for(;;){for(;null===e.sibling;){if(null===e.return||al(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;5!==e.tag&&6!==e.tag&&18!==e.tag;){if(2&e.flags)continue e;if(null===e.child||4===e.tag)continue e;e.child.return=e,e=e.child}if(!(2&e.flags))return e.stateNode}}function ll(e,t,n){var r=e.tag;if(5===r||6===r)e=e.stateNode,t?8===n.nodeType?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(8===n.nodeType?(t=n.parentNode).insertBefore(e,n):(t=n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=Xr));else if(4!==r&&null!==(e=e.child))for(ll(e,t,n),e=e.sibling;null!==e;)ll(e,t,n),e=e.sibling}function cl(e,t,n){var r=e.tag;if(5===r||6===r)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==r&&null!==(e=e.child))for(cl(e,t,n),e=e.sibling;null!==e;)cl(e,t,n),e=e.sibling}var ul=null,pl=!1;function dl(e,t,n){for(n=n.child;null!==n;)fl(e,t,n),n=n.sibling}function fl(e,t,n){if(it&&"function"==typeof it.onCommitFiberUnmount)try{it.onCommitFiberUnmount(ot,n)}catch(s){}switch(n.tag){case 5:Ys||Xs(n,t);case 6:var r=ul,o=pl;ul=null,dl(e,t,n),pl=o,null!==(ul=r)&&(pl?(e=ul,n=n.stateNode,8===e.nodeType?e.parentNode.removeChild(n):e.removeChild(n)):ul.removeChild(n.stateNode));break;case 18:null!==ul&&(pl?(e=ul,n=n.stateNode,8===e.nodeType?lo(e.parentNode,n):1===e.nodeType&&lo(e,n),Ut(e)):lo(ul,n.stateNode));break;case 4:r=ul,o=pl,ul=n.stateNode.containerInfo,pl=!0,dl(e,t,n),ul=r,pl=o;break;case 0:case 11:case 14:case 15:if(!Ys&&(null!==(r=n.updateQueue)&&null!==(r=r.lastEffect))){o=r=r.next;do{var i=o,a=i.destroy;i=i.tag,void 0!==a&&(2&i||4&i)&&el(n,t,a),o=o.next}while(o!==r)}dl(e,t,n);break;case 1:if(!Ys&&(Xs(n,t),"function"==typeof(r=n.stateNode).componentWillUnmount))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(s){Sc(n,t,s)}dl(e,t,n);break;case 21:dl(e,t,n);break;case 22:1&n.mode?(Ys=(r=Ys)||null!==n.memoizedState,dl(e,t,n),Ys=r):dl(e,t,n);break;default:dl(e,t,n)}}function ml(e){var t=e.updateQueue;if(null!==t){e.updateQueue=null;var n=e.stateNode;null===n&&(n=e.stateNode=new Zs),t.forEach(function(t){var r=Pc.bind(null,e,t);n.has(t)||(n.add(t),t.then(r,r))})}}function hl(e,t){var n=t.deletions;if(null!==n)for(var r=0;r<n.length;r++){var o=n[r];try{var a=e,s=t,l=s;e:for(;null!==l;){switch(l.tag){case 5:ul=l.stateNode,pl=!1;break e;case 3:case 4:ul=l.stateNode.containerInfo,pl=!0;break e}l=l.return}if(null===ul)throw Error(i(160));fl(a,s,o),ul=null,pl=!1;var c=o.alternate;null!==c&&(c.return=null),o.return=null}catch(u){Sc(o,t,u)}}if(12854&t.subtreeFlags)for(t=t.child;null!==t;)vl(t,e),t=t.sibling}function vl(e,t){var n=e.alternate,r=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:if(hl(t,e),gl(e),4&r){try{nl(3,e,e.return),rl(3,e)}catch(v){Sc(e,e.return,v)}try{nl(5,e,e.return)}catch(v){Sc(e,e.return,v)}}break;case 1:hl(t,e),gl(e),512&r&&null!==n&&Xs(n,n.return);break;case 5:if(hl(t,e),gl(e),512&r&&null!==n&&Xs(n,n.return),32&e.flags){var o=e.stateNode;try{de(o,"")}catch(v){Sc(e,e.return,v)}}if(4&r&&null!=(o=e.stateNode)){var a=e.memoizedProps,s=null!==n?n.memoizedProps:a,l=e.type,c=e.updateQueue;if(e.updateQueue=null,null!==c)try{"input"===l&&"radio"===a.type&&null!=a.name&&Z(o,a),ye(l,s);var u=ye(l,a);for(s=0;s<c.length;s+=2){var p=c[s],d=c[s+1];"style"===p?ve(o,d):"dangerouslySetInnerHTML"===p?pe(o,d):"children"===p?de(o,d):y(o,p,d,u)}switch(l){case"input":J(o,a);break;case"textarea":ie(o,a);break;case"select":var f=o._wrapperState.wasMultiple;o._wrapperState.wasMultiple=!!a.multiple;var m=a.value;null!=m?ne(o,!!a.multiple,m,!1):f!==!!a.multiple&&(null!=a.defaultValue?ne(o,!!a.multiple,a.defaultValue,!0):ne(o,!!a.multiple,a.multiple?[]:"",!1))}o[mo]=a}catch(v){Sc(e,e.return,v)}}break;case 6:if(hl(t,e),gl(e),4&r){if(null===e.stateNode)throw Error(i(162));o=e.stateNode,a=e.memoizedProps;try{o.nodeValue=a}catch(v){Sc(e,e.return,v)}}break;case 3:if(hl(t,e),gl(e),4&r&&null!==n&&n.memoizedState.isDehydrated)try{Ut(t.containerInfo)}catch(v){Sc(e,e.return,v)}break;case 4:default:hl(t,e),gl(e);break;case 13:hl(t,e),gl(e),8192&(o=e.child).flags&&(a=null!==o.memoizedState,o.stateNode.isHidden=a,!a||null!==o.alternate&&null!==o.alternate.memoizedState||($l=Ze())),4&r&&ml(e);break;case 22:if(p=null!==n&&null!==n.memoizedState,1&e.mode?(Ys=(u=Ys)||p,hl(t,e),Ys=u):hl(t,e),gl(e),8192&r){if(u=null!==e.memoizedState,(e.stateNode.isHidden=u)&&!p&&1&e.mode)for(Js=e,p=e.child;null!==p;){for(d=Js=p;null!==Js;){switch(m=(f=Js).child,f.tag){case 0:case 11:case 14:case 15:nl(4,f,f.return);break;case 1:Xs(f,f.return);var h=f.stateNode;if("function"==typeof h.componentWillUnmount){r=f,n=f.return;try{t=r,h.props=t.memoizedProps,h.state=t.memoizedState,h.componentWillUnmount()}catch(v){Sc(r,n,v)}}break;case 5:Xs(f,f.return);break;case 22:if(null!==f.memoizedState){xl(d);continue}}null!==m?(m.return=f,Js=m):xl(d)}p=p.sibling}e:for(p=null,d=e;;){if(5===d.tag){if(null===p){p=d;try{o=d.stateNode,u?"function"==typeof(a=o.style).setProperty?a.setProperty("display","none","important"):a.display="none":(l=d.stateNode,s=null!=(c=d.memoizedProps.style)&&c.hasOwnProperty("display")?c.display:null,l.style.display=he("display",s))}catch(v){Sc(e,e.return,v)}}}else if(6===d.tag){if(null===p)try{d.stateNode.nodeValue=u?"":d.memoizedProps}catch(v){Sc(e,e.return,v)}}else if((22!==d.tag&&23!==d.tag||null===d.memoizedState||d===e)&&null!==d.child){d.child.return=d,d=d.child;continue}if(d===e)break e;for(;null===d.sibling;){if(null===d.return||d.return===e)break e;p===d&&(p=null),d=d.return}p===d&&(p=null),d.sibling.return=d.return,d=d.sibling}}break;case 19:hl(t,e),gl(e),4&r&&ml(e);case 21:}}function gl(e){var t=e.flags;if(2&t){try{e:{for(var n=e.return;null!==n;){if(al(n)){var r=n;break e}n=n.return}throw Error(i(160))}switch(r.tag){case 5:var o=r.stateNode;32&r.flags&&(de(o,""),r.flags&=-33),cl(e,sl(e),o);break;case 3:case 4:var a=r.stateNode.containerInfo;ll(e,sl(e),a);break;default:throw Error(i(161))}}catch(s){Sc(e,e.return,s)}e.flags&=-3}4096&t&&(e.flags&=-4097)}function bl(e,t,n){Js=e,yl(e,t,n)}function yl(e,t,n){for(var r=!!(1&e.mode);null!==Js;){var o=Js,i=o.child;if(22===o.tag&&r){var a=null!==o.memoizedState||Ks;if(!a){var s=o.alternate,l=null!==s&&null!==s.memoizedState||Ys;s=Ks;var c=Ys;if(Ks=a,(Ys=l)&&!c)for(Js=o;null!==Js;)l=(a=Js).child,22===a.tag&&null!==a.memoizedState?kl(o):null!==l?(l.return=a,Js=l):kl(o);for(;null!==i;)Js=i,yl(i,t,n),i=i.sibling;Js=o,Ks=s,Ys=c}wl(e)}else 8772&o.subtreeFlags&&null!==i?(i.return=o,Js=i):wl(e)}}function wl(e){for(;null!==Js;){var t=Js;if(8772&t.flags){var n=t.alternate;try{if(8772&t.flags)switch(t.tag){case 0:case 11:case 15:Ys||rl(5,t);break;case 1:var r=t.stateNode;if(4&t.flags&&!Ys)if(null===n)r.componentDidMount();else{var o=t.elementType===t.type?n.memoizedProps:ns(t.type,n.memoizedProps);r.componentDidUpdate(o,n.memoizedState,r.__reactInternalSnapshotBeforeUpdate)}var a=t.updateQueue;null!==a&&Qi(t,a,r);break;case 3:var s=t.updateQueue;if(null!==s){if(n=null,null!==t.child)switch(t.child.tag){case 5:case 1:n=t.child.stateNode}Qi(t,s,n)}break;case 5:var l=t.stateNode;if(null===n&&4&t.flags){n=l;var c=t.memoizedProps;switch(t.type){case"button":case"input":case"select":case"textarea":c.autoFocus&&n.focus();break;case"img":c.src&&(n.src=c.src)}}break;case 6:case 4:case 12:case 19:case 17:case 21:case 22:case 23:case 25:break;case 13:if(null===t.memoizedState){var u=t.alternate;if(null!==u){var p=u.memoizedState;if(null!==p){var d=p.dehydrated;null!==d&&Ut(d)}}}break;default:throw Error(i(163))}Ys||512&t.flags&&ol(t)}catch(f){Sc(t,t.return,f)}}if(t===e){Js=null;break}if(null!==(n=t.sibling)){n.return=t.return,Js=n;break}Js=t.return}}function xl(e){for(;null!==Js;){var t=Js;if(t===e){Js=null;break}var n=t.sibling;if(null!==n){n.return=t.return,Js=n;break}Js=t.return}}function kl(e){for(;null!==Js;){var t=Js;try{switch(t.tag){case 0:case 11:case 15:var n=t.return;try{rl(4,t)}catch(l){Sc(t,n,l)}break;case 1:var r=t.stateNode;if("function"==typeof r.componentDidMount){var o=t.return;try{r.componentDidMount()}catch(l){Sc(t,o,l)}}var i=t.return;try{ol(t)}catch(l){Sc(t,i,l)}break;case 5:var a=t.return;try{ol(t)}catch(l){Sc(t,a,l)}}}catch(l){Sc(t,t.return,l)}if(t===e){Js=null;break}var s=t.sibling;if(null!==s){s.return=t.return,Js=s;break}Js=t.return}}var _l,Sl=Math.ceil,El=w.ReactCurrentDispatcher,Ol=w.ReactCurrentOwner,jl=w.ReactCurrentBatchConfig,Pl=0,Cl=null,Al=null,Tl=0,Il=0,Nl=Eo(0),Ll=0,Rl=null,Dl=0,Fl=0,Ml=0,Bl=null,zl=null,$l=0,Ul=1/0,Vl=null,Ql=!1,Hl=null,Wl=null,ql=!1,Gl=null,Kl=0,Yl=0,Zl=null,Jl=-1,Xl=0;function ec(){return 6&Pl?Ze():-1!==Jl?Jl:Jl=Ze()}function tc(e){return 1&e.mode?2&Pl&&0!==Tl?Tl&-Tl:null!==vi.transition?(0===Xl&&(Xl=ht()),Xl):0!==(e=yt)?e:e=void 0===(e=window.event)?16:Yt(e.type):1}function nc(e,t,n,r){if(50<Yl)throw Yl=0,Zl=null,Error(i(185));gt(e,n,r),2&Pl&&e===Cl||(e===Cl&&(!(2&Pl)&&(Fl|=n),4===Ll&&sc(e,Tl)),rc(e,r),1===n&&0===Pl&&!(1&t.mode)&&(Ul=Ze()+500,zo&&Vo()))}function rc(e,t){var n=e.callbackNode;!function(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,o=e.expirationTimes,i=e.pendingLanes;0<i;){var a=31-at(i),s=1<<a,l=o[a];-1===l?0!==(s&n)&&0===(s&r)||(o[a]=ft(s,t)):l<=t&&(e.expiredLanes|=s),i&=~s}}(e,t);var r=dt(e,e===Cl?Tl:0);if(0===r)null!==n&&Ge(n),e.callbackNode=null,e.callbackPriority=0;else if(t=r&-r,e.callbackPriority!==t){if(null!=n&&Ge(n),1===t)0===e.tag?function(e){zo=!0,Uo(e)}(lc.bind(null,e)):Uo(lc.bind(null,e)),ao(function(){!(6&Pl)&&Vo()}),n=null;else{switch(wt(r)){case 1:n=Xe;break;case 4:n=et;break;case 16:default:n=tt;break;case 536870912:n=rt}n=Cc(n,oc.bind(null,e))}e.callbackPriority=t,e.callbackNode=n}}function oc(e,t){if(Jl=-1,Xl=0,6&Pl)throw Error(i(327));var n=e.callbackNode;if(kc()&&e.callbackNode!==n)return null;var r=dt(e,e===Cl?Tl:0);if(0===r)return null;if(30&r||0!==(r&e.expiredLanes)||t)t=vc(e,r);else{t=r;var o=Pl;Pl|=2;var a=mc();for(Cl===e&&Tl===t||(Vl=null,Ul=Ze()+500,dc(e,t));;)try{bc();break}catch(l){fc(e,l)}ji(),El.current=a,Pl=o,null!==Al?t=0:(Cl=null,Tl=0,t=Ll)}if(0!==t){if(2===t&&(0!==(o=mt(e))&&(r=o,t=ic(e,o))),1===t)throw n=Rl,dc(e,0),sc(e,r),rc(e,Ze()),n;if(6===t)sc(e,r);else{if(o=e.current.alternate,!(30&r||function(e){for(var t=e;;){if(16384&t.flags){var n=t.updateQueue;if(null!==n&&null!==(n=n.stores))for(var r=0;r<n.length;r++){var o=n[r],i=o.getSnapshot;o=o.value;try{if(!sr(i(),o))return!1}catch(s){return!1}}}if(n=t.child,16384&t.subtreeFlags&&null!==n)n.return=t,t=n;else{if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return!0;t=t.return}t.sibling.return=t.return,t=t.sibling}}return!0}(o)||(t=vc(e,r),2===t&&(a=mt(e),0!==a&&(r=a,t=ic(e,a))),1!==t)))throw n=Rl,dc(e,0),sc(e,r),rc(e,Ze()),n;switch(e.finishedWork=o,e.finishedLanes=r,t){case 0:case 1:throw Error(i(345));case 2:case 5:xc(e,zl,Vl);break;case 3:if(sc(e,r),(130023424&r)===r&&10<(t=$l+500-Ze())){if(0!==dt(e,0))break;if(((o=e.suspendedLanes)&r)!==r){ec(),e.pingedLanes|=e.suspendedLanes&o;break}e.timeoutHandle=ro(xc.bind(null,e,zl,Vl),t);break}xc(e,zl,Vl);break;case 4:if(sc(e,r),(4194240&r)===r)break;for(t=e.eventTimes,o=-1;0<r;){var s=31-at(r);a=1<<s,(s=t[s])>o&&(o=s),r&=~a}if(r=o,10<(r=(120>(r=Ze()-r)?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*Sl(r/1960))-r)){e.timeoutHandle=ro(xc.bind(null,e,zl,Vl),r);break}xc(e,zl,Vl);break;default:throw Error(i(329))}}}return rc(e,Ze()),e.callbackNode===n?oc.bind(null,e):null}function ic(e,t){var n=Bl;return e.current.memoizedState.isDehydrated&&(dc(e,t).flags|=256),2!==(e=vc(e,t))&&(t=zl,zl=n,null!==t&&ac(t)),e}function ac(e){null===zl?zl=e:zl.push.apply(zl,e)}function sc(e,t){for(t&=~Ml,t&=~Fl,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var n=31-at(t),r=1<<n;e[n]=-1,t&=~r}}function lc(e){if(6&Pl)throw Error(i(327));kc();var t=dt(e,0);if(!(1&t))return rc(e,Ze()),null;var n=vc(e,t);if(0!==e.tag&&2===n){var r=mt(e);0!==r&&(t=r,n=ic(e,r))}if(1===n)throw n=Rl,dc(e,0),sc(e,t),rc(e,Ze()),n;if(6===n)throw Error(i(345));return e.finishedWork=e.current.alternate,e.finishedLanes=t,xc(e,zl,Vl),rc(e,Ze()),null}function cc(e,t){var n=Pl;Pl|=1;try{return e(t)}finally{0===(Pl=n)&&(Ul=Ze()+500,zo&&Vo())}}function uc(e){null!==Gl&&0===Gl.tag&&!(6&Pl)&&kc();var t=Pl;Pl|=1;var n=jl.transition,r=yt;try{if(jl.transition=null,yt=1,e)return e()}finally{yt=r,jl.transition=n,!(6&(Pl=t))&&Vo()}}function pc(){Il=Nl.current,Oo(Nl)}function dc(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(-1!==n&&(e.timeoutHandle=-1,oo(n)),null!==Al)for(n=Al.return;null!==n;){var r=n;switch(ni(r),r.tag){case 1:null!=(r=r.type.childContextTypes)&&Lo();break;case 3:Zi(),Oo(Ao),Oo(Co),ra();break;case 5:Xi(r);break;case 4:Zi();break;case 13:case 19:Oo(ea);break;case 10:Pi(r.type._context);break;case 22:case 23:pc()}n=n.return}if(Cl=e,Al=e=Nc(e.current,null),Tl=Il=t,Ll=0,Rl=null,Ml=Fl=Dl=0,zl=Bl=null,null!==Ii){for(t=0;t<Ii.length;t++)if(null!==(r=(n=Ii[t]).interleaved)){n.interleaved=null;var o=r.next,i=n.pending;if(null!==i){var a=i.next;i.next=o,r.next=a}n.pending=r}Ii=null}return e}function fc(e,t){for(;;){var n=Al;try{if(ji(),oa.current=Ja,ua){for(var r=sa.memoizedState;null!==r;){var o=r.queue;null!==o&&(o.pending=null),r=r.next}ua=!1}if(aa=0,ca=la=sa=null,pa=!1,da=0,Ol.current=null,null===n||null===n.return){Ll=1,Rl=t,Al=null;break}e:{var a=e,s=n.return,l=n,c=t;if(t=Tl,l.flags|=32768,null!==c&&"object"==typeof c&&"function"==typeof c.then){var u=c,p=l,d=p.tag;if(!(1&p.mode||0!==d&&11!==d&&15!==d)){var f=p.alternate;f?(p.updateQueue=f.updateQueue,p.memoizedState=f.memoizedState,p.lanes=f.lanes):(p.updateQueue=null,p.memoizedState=null)}var m=vs(s);if(null!==m){m.flags&=-257,gs(m,s,l,0,t),1&m.mode&&hs(a,u,t),c=u;var h=(t=m).updateQueue;if(null===h){var v=new Set;v.add(c),t.updateQueue=v}else h.add(c);break e}if(!(1&t)){hs(a,u,t),hc();break e}c=Error(i(426))}else if(ii&&1&l.mode){var g=vs(s);if(null!==g){!(65536&g.flags)&&(g.flags|=256),gs(g,s,l,0,t),hi(cs(c,l));break e}}a=c=cs(c,l),4!==Ll&&(Ll=2),null===Bl?Bl=[a]:Bl.push(a),a=s;do{switch(a.tag){case 3:a.flags|=65536,t&=-t,a.lanes|=t,Ui(a,fs(0,c,t));break e;case 1:l=c;var b=a.type,y=a.stateNode;if(!(128&a.flags||"function"!=typeof b.getDerivedStateFromError&&(null===y||"function"!=typeof y.componentDidCatch||null!==Wl&&Wl.has(y)))){a.flags|=65536,t&=-t,a.lanes|=t,Ui(a,ms(a,l,t));break e}}a=a.return}while(null!==a)}wc(n)}catch(w){t=w,Al===n&&null!==n&&(Al=n=n.return);continue}break}}function mc(){var e=El.current;return El.current=Ja,null===e?Ja:e}function hc(){0!==Ll&&3!==Ll&&2!==Ll||(Ll=4),null===Cl||!(268435455&Dl)&&!(268435455&Fl)||sc(Cl,Tl)}function vc(e,t){var n=Pl;Pl|=2;var r=mc();for(Cl===e&&Tl===t||(Vl=null,dc(e,t));;)try{gc();break}catch(o){fc(e,o)}if(ji(),Pl=n,El.current=r,null!==Al)throw Error(i(261));return Cl=null,Tl=0,Ll}function gc(){for(;null!==Al;)yc(Al)}function bc(){for(;null!==Al&&!Ke();)yc(Al)}function yc(e){var t=_l(e.alternate,e,Il);e.memoizedProps=e.pendingProps,null===t?wc(e):Al=t,Ol.current=null}function wc(e){var t=e;do{var n=t.alternate;if(e=t.return,32768&t.flags){if(null!==(n=Gs(n,t)))return n.flags&=32767,void(Al=n);if(null===e)return Ll=6,void(Al=null);e.flags|=32768,e.subtreeFlags=0,e.deletions=null}else if(null!==(n=qs(n,t,Il)))return void(Al=n);if(null!==(t=t.sibling))return void(Al=t);Al=t=e}while(null!==t);0===Ll&&(Ll=5)}function xc(e,t,n){var r=yt,o=jl.transition;try{jl.transition=null,yt=1,function(e,t,n,r){do{kc()}while(null!==Gl);if(6&Pl)throw Error(i(327));n=e.finishedWork;var o=e.finishedLanes;if(null===n)return null;if(e.finishedWork=null,e.finishedLanes=0,n===e.current)throw Error(i(177));e.callbackNode=null,e.callbackPriority=0;var a=n.lanes|n.childLanes;if(function(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0<n;){var o=31-at(n),i=1<<o;t[o]=0,r[o]=-1,e[o]=-1,n&=~i}}(e,a),e===Cl&&(Al=Cl=null,Tl=0),!(2064&n.subtreeFlags)&&!(2064&n.flags)||ql||(ql=!0,Cc(tt,function(){return kc(),null})),a=!!(15990&n.flags),!!(15990&n.subtreeFlags)||a){a=jl.transition,jl.transition=null;var s=yt;yt=1;var l=Pl;Pl|=4,Ol.current=null,function(e,t){if(eo=Qt,fr(e=dr())){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{var r=(n=(n=e.ownerDocument)&&n.defaultView||window).getSelection&&n.getSelection();if(r&&0!==r.rangeCount){n=r.anchorNode;var o=r.anchorOffset,a=r.focusNode;r=r.focusOffset;try{n.nodeType,a.nodeType}catch(x){n=null;break e}var s=0,l=-1,c=-1,u=0,p=0,d=e,f=null;t:for(;;){for(var m;d!==n||0!==o&&3!==d.nodeType||(l=s+o),d!==a||0!==r&&3!==d.nodeType||(c=s+r),3===d.nodeType&&(s+=d.nodeValue.length),null!==(m=d.firstChild);)f=d,d=m;for(;;){if(d===e)break t;if(f===n&&++u===o&&(l=s),f===a&&++p===r&&(c=s),null!==(m=d.nextSibling))break;f=(d=f).parentNode}d=m}n=-1===l||-1===c?null:{start:l,end:c}}else n=null}n=n||{start:0,end:0}}else n=null;for(to={focusedElem:e,selectionRange:n},Qt=!1,Js=t;null!==Js;)if(e=(t=Js).child,1028&t.subtreeFlags&&null!==e)e.return=t,Js=e;else for(;null!==Js;){t=Js;try{var h=t.alternate;if(1024&t.flags)switch(t.tag){case 0:case 11:case 15:case 5:case 6:case 4:case 17:break;case 1:if(null!==h){var v=h.memoizedProps,g=h.memoizedState,b=t.stateNode,y=b.getSnapshotBeforeUpdate(t.elementType===t.type?v:ns(t.type,v),g);b.__reactInternalSnapshotBeforeUpdate=y}break;case 3:var w=t.stateNode.containerInfo;1===w.nodeType?w.textContent="":9===w.nodeType&&w.documentElement&&w.removeChild(w.documentElement);break;default:throw Error(i(163))}}catch(x){Sc(t,t.return,x)}if(null!==(e=t.sibling)){e.return=t.return,Js=e;break}Js=t.return}h=tl,tl=!1}(e,n),vl(n,e),mr(to),Qt=!!eo,to=eo=null,e.current=n,bl(n,e,o),Ye(),Pl=l,yt=s,jl.transition=a}else e.current=n;if(ql&&(ql=!1,Gl=e,Kl=o),a=e.pendingLanes,0===a&&(Wl=null),function(e){if(it&&"function"==typeof it.onCommitFiberRoot)try{it.onCommitFiberRoot(ot,e,void 0,!(128&~e.current.flags))}catch(t){}}(n.stateNode),rc(e,Ze()),null!==t)for(r=e.onRecoverableError,n=0;n<t.length;n++)o=t[n],r(o.value,{componentStack:o.stack,digest:o.digest});if(Ql)throw Ql=!1,e=Hl,Hl=null,e;!!(1&Kl)&&0!==e.tag&&kc(),a=e.pendingLanes,1&a?e===Zl?Yl++:(Yl=0,Zl=e):Yl=0,Vo()}(e,t,n,r)}finally{jl.transition=o,yt=r}return null}function kc(){if(null!==Gl){var e=wt(Kl),t=jl.transition,n=yt;try{if(jl.transition=null,yt=16>e?16:e,null===Gl)var r=!1;else{if(e=Gl,Gl=null,Kl=0,6&Pl)throw Error(i(331));var o=Pl;for(Pl|=4,Js=e.current;null!==Js;){var a=Js,s=a.child;if(16&Js.flags){var l=a.deletions;if(null!==l){for(var c=0;c<l.length;c++){var u=l[c];for(Js=u;null!==Js;){var p=Js;switch(p.tag){case 0:case 11:case 15:nl(8,p,a)}var d=p.child;if(null!==d)d.return=p,Js=d;else for(;null!==Js;){var f=(p=Js).sibling,m=p.return;if(il(p),p===u){Js=null;break}if(null!==f){f.return=m,Js=f;break}Js=m}}}var h=a.alternate;if(null!==h){var v=h.child;if(null!==v){h.child=null;do{var g=v.sibling;v.sibling=null,v=g}while(null!==v)}}Js=a}}if(2064&a.subtreeFlags&&null!==s)s.return=a,Js=s;else e:for(;null!==Js;){if(2048&(a=Js).flags)switch(a.tag){case 0:case 11:case 15:nl(9,a,a.return)}var b=a.sibling;if(null!==b){b.return=a.return,Js=b;break e}Js=a.return}}var y=e.current;for(Js=y;null!==Js;){var w=(s=Js).child;if(2064&s.subtreeFlags&&null!==w)w.return=s,Js=w;else e:for(s=y;null!==Js;){if(2048&(l=Js).flags)try{switch(l.tag){case 0:case 11:case 15:rl(9,l)}}catch(k){Sc(l,l.return,k)}if(l===s){Js=null;break e}var x=l.sibling;if(null!==x){x.return=l.return,Js=x;break e}Js=l.return}}if(Pl=o,Vo(),it&&"function"==typeof it.onPostCommitFiberRoot)try{it.onPostCommitFiberRoot(ot,e)}catch(k){}r=!0}return r}finally{yt=n,jl.transition=t}}return!1}function _c(e,t,n){e=zi(e,t=fs(0,t=cs(n,t),1),1),t=ec(),null!==e&&(gt(e,1,t),rc(e,t))}function Sc(e,t,n){if(3===e.tag)_c(e,e,n);else for(;null!==t;){if(3===t.tag){_c(t,e,n);break}if(1===t.tag){var r=t.stateNode;if("function"==typeof t.type.getDerivedStateFromError||"function"==typeof r.componentDidCatch&&(null===Wl||!Wl.has(r))){t=zi(t,e=ms(t,e=cs(n,e),1),1),e=ec(),null!==t&&(gt(t,1,e),rc(t,e));break}}t=t.return}}function Ec(e,t,n){var r=e.pingCache;null!==r&&r.delete(t),t=ec(),e.pingedLanes|=e.suspendedLanes&n,Cl===e&&(Tl&n)===n&&(4===Ll||3===Ll&&(130023424&Tl)===Tl&&500>Ze()-$l?dc(e,0):Ml|=n),rc(e,t)}function Oc(e,t){0===t&&(1&e.mode?(t=ut,!(130023424&(ut<<=1))&&(ut=4194304)):t=1);var n=ec();null!==(e=Ri(e,t))&&(gt(e,t,n),rc(e,n))}function jc(e){var t=e.memoizedState,n=0;null!==t&&(n=t.retryLane),Oc(e,n)}function Pc(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,o=e.memoizedState;null!==o&&(n=o.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(i(314))}null!==r&&r.delete(t),Oc(e,n)}function Cc(e,t){return qe(e,t)}function Ac(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Tc(e,t,n,r){return new Ac(e,t,n,r)}function Ic(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Nc(e,t){var n=e.alternate;return null===n?((n=Tc(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=14680064&e.flags,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Lc(e,t,n,r,o,a){var s=2;if(r=e,"function"==typeof e)Ic(e)&&(s=1);else if("string"==typeof e)s=5;else e:switch(e){case _:return Rc(n.children,o,a,t);case S:s=8,o|=8;break;case E:return(e=Tc(12,n,t,2|o)).elementType=E,e.lanes=a,e;case C:return(e=Tc(13,n,t,o)).elementType=C,e.lanes=a,e;case A:return(e=Tc(19,n,t,o)).elementType=A,e.lanes=a,e;case N:return Dc(n,o,a,t);default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case O:s=10;break e;case j:s=9;break e;case P:s=11;break e;case T:s=14;break e;case I:s=16,r=null;break e}throw Error(i(130,null==e?e:typeof e,""))}return(t=Tc(s,n,t,o)).elementType=e,t.type=r,t.lanes=a,t}function Rc(e,t,n,r){return(e=Tc(7,e,r,t)).lanes=n,e}function Dc(e,t,n,r){return(e=Tc(22,e,r,t)).elementType=N,e.lanes=n,e.stateNode={isHidden:!1},e}function Fc(e,t,n){return(e=Tc(6,e,null,t)).lanes=n,e}function Mc(e,t,n){return(t=Tc(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Bc(e,t,n,r,o){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=vt(0),this.expirationTimes=vt(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=vt(0),this.identifierPrefix=r,this.onRecoverableError=o,this.mutableSourceEagerHydrationData=null}function zc(e,t,n,r,o,i,a,s,l){return e=new Bc(e,t,n,s,l),1===t?(t=1,!0===i&&(t|=8)):t=0,i=Tc(3,null,null,t),e.current=i,i.stateNode=e,i.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},Fi(i),e}function $c(e){if(!e)return Po;e:{if(Ue(e=e._reactInternals)!==e||1!==e.tag)throw Error(i(170));var t=e;do{switch(t.tag){case 3:t=t.stateNode.context;break e;case 1:if(No(t.type)){t=t.stateNode.__reactInternalMemoizedMergedChildContext;break e}}t=t.return}while(null!==t);throw Error(i(171))}if(1===e.tag){var n=e.type;if(No(n))return Do(e,n,t)}return t}function Uc(e,t,n,r,o,i,a,s,l){return(e=zc(n,r,!0,e,0,i,0,s,l)).context=$c(null),n=e.current,(i=Bi(r=ec(),o=tc(n))).callback=null!=t?t:null,zi(n,i,o),e.current.lanes=o,gt(e,o,r),rc(e,r),e}function Vc(e,t,n,r){var o=t.current,i=ec(),a=tc(o);return n=$c(n),null===t.context?t.context=n:t.pendingContext=n,(t=Bi(i,a)).payload={element:e},null!==(r=void 0===r?null:r)&&(t.callback=r),null!==(e=zi(o,t,a))&&(nc(e,o,a,i),$i(e,o,a)),a}function Qc(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function Hc(e,t){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var n=e.retryLane;e.retryLane=0!==n&&n<t?n:t}}function Wc(e,t){Hc(e,t),(e=e.alternate)&&Hc(e,t)}_l=function(e,t,n){if(null!==e)if(e.memoizedProps!==t.pendingProps||Ao.current)ys=!0;else{if(0===(e.lanes&n)&&!(128&t.flags))return ys=!1,function(e,t,n){switch(t.tag){case 3:Cs(t),mi();break;case 5:Ji(t);break;case 1:No(t.type)&&Fo(t);break;case 4:Yi(t,t.stateNode.containerInfo);break;case 10:var r=t.type._context,o=t.memoizedProps.value;jo(_i,r._currentValue),r._currentValue=o;break;case 13:if(null!==(r=t.memoizedState))return null!==r.dehydrated?(jo(ea,1&ea.current),t.flags|=128,null):0!==(n&t.child.childLanes)?Fs(e,t,n):(jo(ea,1&ea.current),null!==(e=Qs(e,t,n))?e.sibling:null);jo(ea,1&ea.current);break;case 19:if(r=0!==(n&t.childLanes),128&e.flags){if(r)return Us(e,t,n);t.flags|=128}if(null!==(o=t.memoizedState)&&(o.rendering=null,o.tail=null,o.lastEffect=null),jo(ea,ea.current),r)break;return null;case 22:case 23:return t.lanes=0,Ss(e,t,n)}return Qs(e,t,n)}(e,t,n);ys=!!(131072&e.flags)}else ys=!1,ii&&1048576&t.flags&&ei(t,qo,t.index);switch(t.lanes=0,t.tag){case 2:var r=t.type;Vs(e,t),e=t.pendingProps;var o=Io(t,Co.current);Ai(t,n),o=va(null,t,r,e,o,n);var a=ga();return t.flags|=1,"object"==typeof o&&null!==o&&"function"==typeof o.render&&void 0===o.$$typeof?(t.tag=1,t.memoizedState=null,t.updateQueue=null,No(r)?(a=!0,Fo(t)):a=!1,t.memoizedState=null!==o.state&&void 0!==o.state?o.state:null,Fi(t),o.updater=os,t.stateNode=o,o._reactInternals=t,ls(t,r,e,n),t=Ps(null,t,r,!0,a,n)):(t.tag=0,ii&&a&&ti(t),ws(null,t,o,n),t=t.child),t;case 16:r=t.elementType;e:{switch(Vs(e,t),e=t.pendingProps,r=(o=r._init)(r._payload),t.type=r,o=t.tag=function(e){if("function"==typeof e)return Ic(e)?1:0;if(null!=e){if((e=e.$$typeof)===P)return 11;if(e===T)return 14}return 2}(r),e=ns(r,e),o){case 0:t=Os(null,t,r,e,n);break e;case 1:t=js(null,t,r,e,n);break e;case 11:t=xs(null,t,r,e,n);break e;case 14:t=ks(null,t,r,ns(r.type,e),n);break e}throw Error(i(306,r,""))}return t;case 0:return r=t.type,o=t.pendingProps,Os(e,t,r,o=t.elementType===r?o:ns(r,o),n);case 1:return r=t.type,o=t.pendingProps,js(e,t,r,o=t.elementType===r?o:ns(r,o),n);case 3:e:{if(Cs(t),null===e)throw Error(i(387));r=t.pendingProps,o=(a=t.memoizedState).element,Mi(e,t),Vi(t,r,null,n);var s=t.memoizedState;if(r=s.element,a.isDehydrated){if(a={element:r,isDehydrated:!1,cache:s.cache,pendingSuspenseBoundaries:s.pendingSuspenseBoundaries,transitions:s.transitions},t.updateQueue.baseState=a,t.memoizedState=a,256&t.flags){t=As(e,t,r,n,o=cs(Error(i(423)),t));break e}if(r!==o){t=As(e,t,r,n,o=cs(Error(i(424)),t));break e}for(oi=co(t.stateNode.containerInfo.firstChild),ri=t,ii=!0,ai=null,n=ki(t,null,r,n),t.child=n;n;)n.flags=-3&n.flags|4096,n=n.sibling}else{if(mi(),r===o){t=Qs(e,t,n);break e}ws(e,t,r,n)}t=t.child}return t;case 5:return Ji(t),null===e&&ui(t),r=t.type,o=t.pendingProps,a=null!==e?e.memoizedProps:null,s=o.children,no(r,o)?s=null:null!==a&&no(r,a)&&(t.flags|=32),Es(e,t),ws(e,t,s,n),t.child;case 6:return null===e&&ui(t),null;case 13:return Fs(e,t,n);case 4:return Yi(t,t.stateNode.containerInfo),r=t.pendingProps,null===e?t.child=xi(t,null,r,n):ws(e,t,r,n),t.child;case 11:return r=t.type,o=t.pendingProps,xs(e,t,r,o=t.elementType===r?o:ns(r,o),n);case 7:return ws(e,t,t.pendingProps,n),t.child;case 8:case 12:return ws(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,o=t.pendingProps,a=t.memoizedProps,s=o.value,jo(_i,r._currentValue),r._currentValue=s,null!==a)if(sr(a.value,s)){if(a.children===o.children&&!Ao.current){t=Qs(e,t,n);break e}}else for(null!==(a=t.child)&&(a.return=t);null!==a;){var l=a.dependencies;if(null!==l){s=a.child;for(var c=l.firstContext;null!==c;){if(c.context===r){if(1===a.tag){(c=Bi(-1,n&-n)).tag=2;var u=a.updateQueue;if(null!==u){var p=(u=u.shared).pending;null===p?c.next=c:(c.next=p.next,p.next=c),u.pending=c}}a.lanes|=n,null!==(c=a.alternate)&&(c.lanes|=n),Ci(a.return,n,t),l.lanes|=n;break}c=c.next}}else if(10===a.tag)s=a.type===t.type?null:a.child;else if(18===a.tag){if(null===(s=a.return))throw Error(i(341));s.lanes|=n,null!==(l=s.alternate)&&(l.lanes|=n),Ci(s,n,t),s=a.sibling}else s=a.child;if(null!==s)s.return=a;else for(s=a;null!==s;){if(s===t){s=null;break}if(null!==(a=s.sibling)){a.return=s.return,s=a;break}s=s.return}a=s}ws(e,t,o.children,n),t=t.child}return t;case 9:return o=t.type,r=t.pendingProps.children,Ai(t,n),r=r(o=Ti(o)),t.flags|=1,ws(e,t,r,n),t.child;case 14:return o=ns(r=t.type,t.pendingProps),ks(e,t,r,o=ns(r.type,o),n);case 15:return _s(e,t,t.type,t.pendingProps,n);case 17:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:ns(r,o),Vs(e,t),t.tag=1,No(r)?(e=!0,Fo(t)):e=!1,Ai(t,n),as(t,r,o),ls(t,r,o,n),Ps(null,t,r,!0,e,n);case 19:return Us(e,t,n);case 22:return Ss(e,t,n)}throw Error(i(156,t.tag))};var qc="function"==typeof reportError?reportError:function(e){console.error(e)};function Gc(e){this._internalRoot=e}function Kc(e){this._internalRoot=e}function Yc(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType)}function Zc(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function Jc(){}function Xc(e,t,n,r,o){var i=n._reactRootContainer;if(i){var a=i;if("function"==typeof o){var s=o;o=function(){var e=Qc(a);s.call(e)}}Vc(t,a,e,o)}else a=function(e,t,n,r,o){if(o){if("function"==typeof r){var i=r;r=function(){var e=Qc(a);i.call(e)}}var a=Uc(t,r,e,0,null,!1,0,"",Jc);return e._reactRootContainer=a,e[ho]=a.current,Ur(8===e.nodeType?e.parentNode:e),uc(),a}for(;o=e.lastChild;)e.removeChild(o);if("function"==typeof r){var s=r;r=function(){var e=Qc(l);s.call(e)}}var l=zc(e,0,!1,null,0,!1,0,"",Jc);return e._reactRootContainer=l,e[ho]=l.current,Ur(8===e.nodeType?e.parentNode:e),uc(function(){Vc(t,l,n,r)}),l}(n,t,e,o,r);return Qc(a)}Kc.prototype.render=Gc.prototype.render=function(e){var t=this._internalRoot;if(null===t)throw Error(i(409));Vc(e,t,null,null)},Kc.prototype.unmount=Gc.prototype.unmount=function(){var e=this._internalRoot;if(null!==e){this._internalRoot=null;var t=e.containerInfo;uc(function(){Vc(null,e,null,null)}),t[ho]=null}},Kc.prototype.unstable_scheduleHydration=function(e){if(e){var t=St();e={blockedOn:null,target:e,priority:t};for(var n=0;n<Nt.length&&0!==t&&t<Nt[n].priority;n++);Nt.splice(n,0,e),0===n&&Ft(e)}},xt=function(e){switch(e.tag){case 3:var t=e.stateNode;if(t.current.memoizedState.isDehydrated){var n=pt(t.pendingLanes);0!==n&&(bt(t,1|n),rc(t,Ze()),!(6&Pl)&&(Ul=Ze()+500,Vo()))}break;case 13:uc(function(){var t=Ri(e,1);if(null!==t){var n=ec();nc(t,e,1,n)}}),Wc(e,1)}},kt=function(e){if(13===e.tag){var t=Ri(e,134217728);if(null!==t)nc(t,e,134217728,ec());Wc(e,134217728)}},_t=function(e){if(13===e.tag){var t=tc(e),n=Ri(e,t);if(null!==n)nc(n,e,t,ec());Wc(e,t)}},St=function(){return yt},Et=function(e,t){var n=yt;try{return yt=e,t()}finally{yt=n}},ke=function(e,t,n){switch(t){case"input":if(J(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var r=n[t];if(r!==e&&r.form===e.form){var o=ko(r);if(!o)throw Error(i(90));q(r),J(r,o)}}}break;case"textarea":ie(e,n);break;case"select":null!=(t=n.value)&&ne(e,!!n.multiple,t,!1)}},Pe=cc,Ce=uc;var eu={usingClientEntryPoint:!1,Events:[wo,xo,ko,Oe,je,cc]},tu={findFiberByHostInstance:yo,bundleType:0,version:"18.3.1",rendererPackageName:"react-dom"},nu={bundleType:tu.bundleType,version:tu.version,rendererPackageName:tu.rendererPackageName,rendererConfig:tu.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:w.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=He(e))?null:e.stateNode},findFiberByHostInstance:tu.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.3.1-next-f1338f8080-20240426"};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var ru=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!ru.isDisabled&&ru.supportsFiber)try{ot=ru.inject(nu),it=ru}catch(ue){}}t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=eu,t.createPortal=function(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!Yc(t))throw Error(i(200));return function(e,t,n){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:k,key:null==r?null:""+r,children:e,containerInfo:t,implementation:n}}(e,t,null,n)},t.createRoot=function(e,t){if(!Yc(e))throw Error(i(299));var n=!1,r="",o=qc;return null!=t&&(!0===t.unstable_strictMode&&(n=!0),void 0!==t.identifierPrefix&&(r=t.identifierPrefix),void 0!==t.onRecoverableError&&(o=t.onRecoverableError)),t=zc(e,1,!1,null,0,n,0,r,o),e[ho]=t.current,Ur(8===e.nodeType?e.parentNode:e),new Gc(t)},t.findDOMNode=function(e){if(null==e)return null;if(1===e.nodeType)return e;var t=e._reactInternals;if(void 0===t){if("function"==typeof e.render)throw Error(i(188));throw e=Object.keys(e).join(","),Error(i(268,e))}return e=null===(e=He(t))?null:e.stateNode},t.flushSync=function(e){return uc(e)},t.hydrate=function(e,t,n){if(!Zc(t))throw Error(i(200));return Xc(null,e,t,!0,n)},t.hydrateRoot=function(e,t,n){if(!Yc(e))throw Error(i(405));var r=null!=n&&n.hydratedSources||null,o=!1,a="",s=qc;if(null!=n&&(!0===n.unstable_strictMode&&(o=!0),void 0!==n.identifierPrefix&&(a=n.identifierPrefix),void 0!==n.onRecoverableError&&(s=n.onRecoverableError)),t=Uc(t,null,e,1,null!=n?n:null,o,0,a,s),e[ho]=t.current,Ur(e),r)for(e=0;e<r.length;e++)o=(o=(n=r[e])._getVersion)(n._source),null==t.mutableSourceEagerHydrationData?t.mutableSourceEagerHydrationData=[n,o]:t.mutableSourceEagerHydrationData.push(n,o);return new Kc(t)},t.render=function(e,t,n){if(!Zc(t))throw Error(i(200));return Xc(null,e,t,!1,n)},t.unmountComponentAtNode=function(e){if(!Zc(e))throw Error(i(40));return!!e._reactRootContainer&&(uc(function(){Xc(null,null,e,!1,function(){e._reactRootContainer=null,e[ho]=null})}),!0)},t.unstable_batchedUpdates=cc,t.unstable_renderSubtreeIntoContainer=function(e,t,n,r){if(!Zc(n))throw Error(i(200));if(null==e||void 0===e._reactInternals)throw Error(i(38));return Xc(e,t,n,!1,r)},t.version="18.3.1-next-f1338f8080-20240426"},22654:e=>{"use strict";e.exports=JSON.parse('{"cmfcmf/d-s-l.searchBar.placeholder":"Search...","cmfcmf/d-s-l.searchBar.noResults":"No results found.","cmfcmf/d-s-l.searchBar.clearButtonTitle":"Clear","cmfcmf/d-s-l.searchBar.detachedCancelButtonText":"Cancel","cmfcmf/d-s-l.searchBar.submitButtonTitle":"Submit"}')},22799:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,o=n?Symbol.for("react.portal"):60106,i=n?Symbol.for("react.fragment"):60107,a=n?Symbol.for("react.strict_mode"):60108,s=n?Symbol.for("react.profiler"):60114,l=n?Symbol.for("react.provider"):60109,c=n?Symbol.for("react.context"):60110,u=n?Symbol.for("react.async_mode"):60111,p=n?Symbol.for("react.concurrent_mode"):60111,d=n?Symbol.for("react.forward_ref"):60112,f=n?Symbol.for("react.suspense"):60113,m=n?Symbol.for("react.suspense_list"):60120,h=n?Symbol.for("react.memo"):60115,v=n?Symbol.for("react.lazy"):60116,g=n?Symbol.for("react.block"):60121,b=n?Symbol.for("react.fundamental"):60117,y=n?Symbol.for("react.responder"):60118,w=n?Symbol.for("react.scope"):60119;function x(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case u:case p:case i:case s:case a:case f:return e;default:switch(e=e&&e.$$typeof){case c:case d:case v:case h:case l:return e;default:return t}}case o:return t}}}function k(e){return x(e)===p}t.AsyncMode=u,t.ConcurrentMode=p,t.ContextConsumer=c,t.ContextProvider=l,t.Element=r,t.ForwardRef=d,t.Fragment=i,t.Lazy=v,t.Memo=h,t.Portal=o,t.Profiler=s,t.StrictMode=a,t.Suspense=f,t.isAsyncMode=function(e){return k(e)||x(e)===u},t.isConcurrentMode=k,t.isContextConsumer=function(e){return x(e)===c},t.isContextProvider=function(e){return x(e)===l},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return x(e)===d},t.isFragment=function(e){return x(e)===i},t.isLazy=function(e){return x(e)===v},t.isMemo=function(e){return x(e)===h},t.isPortal=function(e){return x(e)===o},t.isProfiler=function(e){return x(e)===s},t.isStrictMode=function(e){return x(e)===a},t.isSuspense=function(e){return x(e)===f},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===i||e===p||e===s||e===a||e===f||e===m||"object"==typeof e&&null!==e&&(e.$$typeof===v||e.$$typeof===h||e.$$typeof===l||e.$$typeof===c||e.$$typeof===d||e.$$typeof===b||e.$$typeof===y||e.$$typeof===w||e.$$typeof===g)},t.typeOf=x},22831:(e,t,n)=>{"use strict";n.d(t,{u:()=>a,v:()=>s});var r=n(56347),o=n(58168),i=n(96540);function a(e,t,n){return void 0===n&&(n=[]),e.some(function(e){var o=e.path?(0,r.B6)(t,e):n.length?n[n.length-1].match:r.Ix.computeRootMatch(t);return o&&(n.push({route:e,match:o}),e.routes&&a(e.routes,t,n)),o}),n}function s(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?i.createElement(r.dO,n,e.map(function(e,n){return i.createElement(r.qh,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,o.A)({},n,{},t,{route:e})):i.createElement(e.component,(0,o.A)({},n,t,{route:e}))}})})):null}},23230:(e,t,n)=>{"use strict";n.d(t,{A:()=>c,T:()=>l});var r=n(96540),o=n(74848);function i(e,t){const n=e.split(/(\{\w+\})/).map((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e});return n.some(e=>(0,r.isValidElement)(e))?n.map((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e).filter(e=>""!==e):n.join("")}var a=n(22654);function s({id:e,message:t}){if(void 0===e&&void 0===t)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return a[e??t]??t??e}function l({message:e,id:t},n){return i(s({message:e,id:t}),n)}function c({children:e,id:t,values:n}){if(e&&"string"!=typeof e)throw console.warn("Illegal <Translate> children",e),new Error("The Docusaurus <Translate> component only accept simple string values");const r=s({message:e,id:t});return(0,o.jsx)(o.Fragment,{children:i(r,n)})}},23363:(e,t,n)=>{"use strict";n.d(t,{W:()=>a,o:()=>i});var r=n(96540),o=n(74848);const i=r.createContext(null);function a({children:e,value:t}){const n=r.useContext(i),a=(0,r.useMemo)(()=>function({parent:e,value:t}){if(!e){if(!t)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in t))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return t}const n={...e.data,...t?.data};return{plugin:e.plugin,data:n}}({parent:n,value:t}),[n,t]);return(0,o.jsx)(i.Provider,{value:a,children:e})}},23611:(e,t,n)=>{var r={"./prism-shell-session":60061};function o(e){var t=i(e);return n(t)}function i(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=i,e.exports=o,o.id=23611},24245:(e,t,n)=>{"use strict";n.d(t,{Mq:()=>f,Tv:()=>u,a_:()=>m,gk:()=>h});var r=n(96540),o=n(31712),i=n(11062),a=n(36494),s=n(4799),l=n(74848);const c=r.createContext(void 0);function u({children:e}){const t=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)(()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}}),[])}();return(0,l.jsx)(c.Provider,{value:t,children:e})}function p(){const e=(0,r.useContext)(c);if(null==e)throw new s.dV("ScrollControllerProvider");return e}const d=()=>o.A.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function f(e,t=[]){const{scrollEventsEnabledRef:n}=p(),o=(0,r.useRef)(d()),i=(0,s._q)(e);(0,r.useEffect)(()=>{const e=()=>{if(!n.current)return;const e=d();i(e,o.current),o.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)},[i,n,...t])}function m(){const e=p(),t=function(){const e=(0,r.useRef)({elem:null,top:0}),t=(0,r.useCallback)(t=>{e.current={elem:t,top:t.getBoundingClientRect().top}},[]),n=(0,r.useCallback)(()=>{const{current:{elem:t,top:n}}=e;if(!t)return{restored:!1};const r=t.getBoundingClientRect().top-n;return r&&window.scrollBy({left:0,top:r}),e.current={elem:null,top:0},{restored:0!==r}},[]);return(0,r.useMemo)(()=>({save:t,restore:n}),[n,t])}(),n=(0,r.useRef)(void 0),o=(0,r.useCallback)(r=>{t.save(r),e.disableScrollEvents(),n.current=()=>{const{restored:r}=t.restore();if(n.current=void 0,r){const t=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",t)};window.addEventListener("scroll",t)}else e.enableScrollEvents()}},[e,t]);return(0,a.A)(()=>{queueMicrotask(()=>n.current?.())}),{blockElementScrollPositionUntilNextRender:o}}function h(){const e=(0,r.useRef)(null),t=(0,i.A)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const o=document.documentElement.scrollTop;(n&&o>e||!n&&o<e)&&(t=requestAnimationFrame(r),window.scrollTo(0,Math.floor(.85*(o-e))+e))}(),()=>t&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},26503:(e,t,n)=>{"use strict";n.d(t,{P_:()=>a,kh:()=>i});var r=n(97639),o=n(44598);function i(e,t={}){const n=function(){const{globalData:e}=(0,r.A)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}function a(e,t=o.W,n={}){const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}},30115:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,r="function"==typeof Set,o="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function i(e,a){if(e===a)return!0;if(e&&a&&"object"==typeof e&&"object"==typeof a){if(e.constructor!==a.constructor)return!1;var s,l,c,u;if(Array.isArray(e)){if((s=e.length)!=a.length)return!1;for(l=s;0!==l--;)if(!i(e[l],a[l]))return!1;return!0}if(n&&e instanceof Map&&a instanceof Map){if(e.size!==a.size)return!1;for(u=e.entries();!(l=u.next()).done;)if(!a.has(l.value[0]))return!1;for(u=e.entries();!(l=u.next()).done;)if(!i(l.value[1],a.get(l.value[0])))return!1;return!0}if(r&&e instanceof Set&&a instanceof Set){if(e.size!==a.size)return!1;for(u=e.entries();!(l=u.next()).done;)if(!a.has(l.value[0]))return!1;return!0}if(o&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(a)){if((s=e.length)!=a.length)return!1;for(l=s;0!==l--;)if(e[l]!==a[l])return!1;return!0}if(e.constructor===RegExp)return e.source===a.source&&e.flags===a.flags;if(e.valueOf!==Object.prototype.valueOf&&"function"==typeof e.valueOf&&"function"==typeof a.valueOf)return e.valueOf()===a.valueOf();if(e.toString!==Object.prototype.toString&&"function"==typeof e.toString&&"function"==typeof a.toString)return e.toString()===a.toString();if((s=(c=Object.keys(e)).length)!==Object.keys(a).length)return!1;for(l=s;0!==l--;)if(!Object.prototype.hasOwnProperty.call(a,c[l]))return!1;if(t&&e instanceof Element)return!1;for(l=s;0!==l--;)if(("_owner"!==c[l]&&"__v"!==c[l]&&"__o"!==c[l]||!e.$$typeof)&&!i(e[c[l]],a[c[l]]))return!1;return!0}return e!=e&&a!=a}e.exports=function(e,t){try{return i(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},31513:(e,t,n)=>{"use strict";n.d(t,{zR:()=>w,TM:()=>O,yJ:()=>f,sC:()=>P,AO:()=>d});var r=n(58168);function o(e){return"/"===e.charAt(0)}function i(e,t){for(var n=t,r=n+1,o=e.length;r<o;n+=1,r+=1)e[n]=e[r];e.pop()}const a=function(e,t){void 0===t&&(t="");var n,r=e&&e.split("/")||[],a=t&&t.split("/")||[],s=e&&o(e),l=t&&o(t),c=s||l;if(e&&o(e)?a=r:r.length&&(a.pop(),a=a.concat(r)),!a.length)return"/";if(a.length){var u=a[a.length-1];n="."===u||".."===u||""===u}else n=!1;for(var p=0,d=a.length;d>=0;d--){var f=a[d];"."===f?i(a,d):".."===f?(i(a,d),p++):p&&(i(a,d),p--)}if(!c)for(;p--;p)a.unshift("..");!c||""===a[0]||a[0]&&o(a[0])||a.unshift("");var m=a.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var s=n(11561);function l(e){return"/"===e.charAt(0)?e:"/"+e}function c(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function p(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function d(e){var t=e.pathname,n=e.search,r=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(o+="#"===r.charAt(0)?r:"#"+r),o}function f(e,t,n,o){var i;"string"==typeof e?(i=function(e){var t=e||"/",n="",r="",o=t.indexOf("#");-1!==o&&(r=t.substr(o),t=t.substr(0,o));var i=t.indexOf("?");return-1!==i&&(n=t.substr(i),t=t.substr(0,i)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),i.state=t):(void 0===(i=(0,r.A)({},e)).pathname&&(i.pathname=""),i.search?"?"!==i.search.charAt(0)&&(i.search="?"+i.search):i.search="",i.hash?"#"!==i.hash.charAt(0)&&(i.hash="#"+i.hash):i.hash="",void 0!==t&&void 0===i.state&&(i.state=t));try{i.pathname=decodeURI(i.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+i.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(i.key=n),o?i.pathname?"/"!==i.pathname.charAt(0)&&(i.pathname=a(i.pathname,o.pathname)):i.pathname=o.pathname:i.pathname||(i.pathname="/"),i}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var i="function"==typeof e?e(t,n):e;"string"==typeof i?"function"==typeof r?r(i,o):o(!0):o(!1!==i)}else o(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter(function(e){return e!==r})}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];t.forEach(function(e){return e.apply(void 0,n)})}}}var h=!("undefined"==typeof window||!window.document||!window.document.createElement);function v(e,t){t(window.confirm(e))}var g="popstate",b="hashchange";function y(){try{return window.history.state||{}}catch(e){return{}}}function w(e){void 0===e&&(e={}),h||(0,s.A)(!1);var t,n=window.history,o=(-1===(t=window.navigator.userAgent).indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&window.history&&"pushState"in window.history,i=!(-1===window.navigator.userAgent.indexOf("Trident")),a=e,c=a.forceRefresh,w=void 0!==c&&c,x=a.getUserConfirmation,k=void 0===x?v:x,_=a.keyLength,S=void 0===_?6:_,E=e.basename?p(l(e.basename)):"";function O(e){var t=e||{},n=t.key,r=t.state,o=window.location,i=o.pathname+o.search+o.hash;return E&&(i=u(i,E)),f(i,r,n)}function j(){return Math.random().toString(36).substr(2,S)}var P=m();function C(e){(0,r.A)($,e),$.length=n.length,P.notifyListeners($.location,$.action)}function A(e){(function(e){return void 0===e.state&&-1===navigator.userAgent.indexOf("CriOS")})(e)||N(O(e.state))}function T(){N(O(y()))}var I=!1;function N(e){if(I)I=!1,C();else{P.confirmTransitionTo(e,"POP",k,function(t){t?C({action:"POP",location:e}):function(e){var t=$.location,n=R.indexOf(t.key);-1===n&&(n=0);var r=R.indexOf(e.key);-1===r&&(r=0);var o=n-r;o&&(I=!0,F(o))}(e)})}}var L=O(y()),R=[L.key];function D(e){return E+d(e)}function F(e){n.go(e)}var M=0;function B(e){1===(M+=e)&&1===e?(window.addEventListener(g,A),i&&window.addEventListener(b,T)):0===M&&(window.removeEventListener(g,A),i&&window.removeEventListener(b,T))}var z=!1;var $={length:n.length,action:"POP",location:L,createHref:D,push:function(e,t){var r="PUSH",i=f(e,t,j(),$.location);P.confirmTransitionTo(i,r,k,function(e){if(e){var t=D(i),a=i.key,s=i.state;if(o)if(n.pushState({key:a,state:s},null,t),w)window.location.href=t;else{var l=R.indexOf($.location.key),c=R.slice(0,l+1);c.push(i.key),R=c,C({action:r,location:i})}else window.location.href=t}})},replace:function(e,t){var r="REPLACE",i=f(e,t,j(),$.location);P.confirmTransitionTo(i,r,k,function(e){if(e){var t=D(i),a=i.key,s=i.state;if(o)if(n.replaceState({key:a,state:s},null,t),w)window.location.replace(t);else{var l=R.indexOf($.location.key);-1!==l&&(R[l]=i.key),C({action:r,location:i})}else window.location.replace(t)}})},go:F,goBack:function(){F(-1)},goForward:function(){F(1)},block:function(e){void 0===e&&(e=!1);var t=P.setPrompt(e);return z||(B(1),z=!0),function(){return z&&(z=!1,B(-1)),t()}},listen:function(e){var t=P.appendListener(e);return B(1),function(){B(-1),t()}}};return $}var x="hashchange",k={hashbang:{encodePath:function(e){return"!"===e.charAt(0)?e:"!/"+c(e)},decodePath:function(e){return"!"===e.charAt(0)?e.substr(1):e}},noslash:{encodePath:c,decodePath:l},slash:{encodePath:l,decodePath:l}};function _(e){var t=e.indexOf("#");return-1===t?e:e.slice(0,t)}function S(){var e=window.location.href,t=e.indexOf("#");return-1===t?"":e.substring(t+1)}function E(e){window.location.replace(_(window.location.href)+"#"+e)}function O(e){void 0===e&&(e={}),h||(0,s.A)(!1);var t=window.history,n=(window.navigator.userAgent.indexOf("Firefox"),e),o=n.getUserConfirmation,i=void 0===o?v:o,a=n.hashType,c=void 0===a?"slash":a,g=e.basename?p(l(e.basename)):"",b=k[c],y=b.encodePath,w=b.decodePath;function O(){var e=w(S());return g&&(e=u(e,g)),f(e)}var j=m();function P(e){(0,r.A)(z,e),z.length=t.length,j.notifyListeners(z.location,z.action)}var C=!1,A=null;function T(){var e,t,n=S(),r=y(n);if(n!==r)E(r);else{var o=O(),a=z.location;if(!C&&(t=o,(e=a).pathname===t.pathname&&e.search===t.search&&e.hash===t.hash))return;if(A===d(o))return;A=null,function(e){if(C)C=!1,P();else{var t="POP";j.confirmTransitionTo(e,t,i,function(n){n?P({action:t,location:e}):function(e){var t=z.location,n=R.lastIndexOf(d(t));-1===n&&(n=0);var r=R.lastIndexOf(d(e));-1===r&&(r=0);var o=n-r;o&&(C=!0,D(o))}(e)})}}(o)}}var I=S(),N=y(I);I!==N&&E(N);var L=O(),R=[d(L)];function D(e){t.go(e)}var F=0;function M(e){1===(F+=e)&&1===e?window.addEventListener(x,T):0===F&&window.removeEventListener(x,T)}var B=!1;var z={length:t.length,action:"POP",location:L,createHref:function(e){var t=document.querySelector("base"),n="";return t&&t.getAttribute("href")&&(n=_(window.location.href)),n+"#"+y(g+d(e))},push:function(e,t){var n="PUSH",r=f(e,void 0,void 0,z.location);j.confirmTransitionTo(r,n,i,function(e){if(e){var t=d(r),o=y(g+t);if(S()!==o){A=t,function(e){window.location.hash=e}(o);var i=R.lastIndexOf(d(z.location)),a=R.slice(0,i+1);a.push(t),R=a,P({action:n,location:r})}else P()}})},replace:function(e,t){var n="REPLACE",r=f(e,void 0,void 0,z.location);j.confirmTransitionTo(r,n,i,function(e){if(e){var t=d(r),o=y(g+t);S()!==o&&(A=t,E(o));var i=R.indexOf(d(z.location));-1!==i&&(R[i]=t),P({action:n,location:r})}})},go:D,goBack:function(){D(-1)},goForward:function(){D(1)},block:function(e){void 0===e&&(e=!1);var t=j.setPrompt(e);return B||(M(1),B=!0),function(){return B&&(B=!1,M(-1)),t()}},listen:function(e){var t=j.appendListener(e);return M(1),function(){M(-1),t()}}};return z}function j(e,t,n){return Math.min(Math.max(e,t),n)}function P(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,o=t.initialEntries,i=void 0===o?["/"]:o,a=t.initialIndex,s=void 0===a?0:a,l=t.keyLength,c=void 0===l?6:l,u=m();function p(e){(0,r.A)(w,e),w.length=w.entries.length,u.notifyListeners(w.location,w.action)}function h(){return Math.random().toString(36).substr(2,c)}var v=j(s,0,i.length-1),g=i.map(function(e){return f(e,void 0,"string"==typeof e?h():e.key||h())}),b=d;function y(e){var t=j(w.index+e,0,w.entries.length-1),r=w.entries[t];u.confirmTransitionTo(r,"POP",n,function(e){e?p({action:"POP",location:r,index:t}):p()})}var w={length:g.length,action:"POP",location:g[v],index:v,entries:g,createHref:b,push:function(e,t){var r="PUSH",o=f(e,t,h(),w.location);u.confirmTransitionTo(o,r,n,function(e){if(e){var t=w.index+1,n=w.entries.slice(0);n.length>t?n.splice(t,n.length-t,o):n.push(o),p({action:r,location:o,index:t,entries:n})}})},replace:function(e,t){var r="REPLACE",o=f(e,t,h(),w.location);u.confirmTransitionTo(o,r,n,function(e){e&&(w.entries[w.index]=o,p({action:r,location:o}))})},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t<w.entries.length},block:function(e){return void 0===e&&(e=!1),u.setPrompt(e)},listen:function(e){return u.appendListener(e)}};return w}},31635:(e,t,n)=>{"use strict";n.r(t),n.d(t,{__addDisposableResource:()=>R,__assign:()=>i,__asyncDelegator:()=>E,__asyncGenerator:()=>S,__asyncValues:()=>O,__await:()=>_,__awaiter:()=>m,__classPrivateFieldGet:()=>I,__classPrivateFieldIn:()=>L,__classPrivateFieldSet:()=>N,__createBinding:()=>v,__decorate:()=>s,__disposeResources:()=>F,__esDecorate:()=>c,__exportStar:()=>g,__extends:()=>o,__generator:()=>h,__importDefault:()=>T,__importStar:()=>A,__makeTemplateObject:()=>j,__metadata:()=>f,__param:()=>l,__propKey:()=>p,__read:()=>y,__rest:()=>a,__rewriteRelativeImportExtension:()=>M,__runInitializers:()=>u,__setFunctionName:()=>d,__spread:()=>w,__spreadArray:()=>k,__spreadArrays:()=>x,__values:()=>b,default:()=>B});var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},r(e,t)};function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var i=function(){return i=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},i.apply(this,arguments)};function a(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o<r.length;o++)t.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]])}return n}function s(e,t,n,r){var o,i=arguments.length,a=i<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}function l(e,t){return function(n,r){t(n,r,e)}}function c(e,t,n,r,o,i){function a(e){if(void 0!==e&&"function"!=typeof e)throw new TypeError("Function expected");return e}for(var s,l=r.kind,c="getter"===l?"get":"setter"===l?"set":"value",u=!t&&e?r.static?e:e.prototype:null,p=t||(u?Object.getOwnPropertyDescriptor(u,r.name):{}),d=!1,f=n.length-1;f>=0;f--){var m={};for(var h in r)m[h]="access"===h?{}:r[h];for(var h in r.access)m.access[h]=r.access[h];m.addInitializer=function(e){if(d)throw new TypeError("Cannot add initializers after decoration has completed");i.push(a(e||null))};var v=(0,n[f])("accessor"===l?{get:p.get,set:p.set}:p[c],m);if("accessor"===l){if(void 0===v)continue;if(null===v||"object"!=typeof v)throw new TypeError("Object expected");(s=a(v.get))&&(p.get=s),(s=a(v.set))&&(p.set=s),(s=a(v.init))&&o.unshift(s)}else(s=a(v))&&("field"===l?o.unshift(s):p[c]=s)}u&&Object.defineProperty(u,r.name,p),d=!0}function u(e,t,n){for(var r=arguments.length>2,o=0;o<t.length;o++)n=r?t[o].call(e,n):t[o].call(e);return r?n:void 0}function p(e){return"symbol"==typeof e?e:"".concat(e)}function d(e,t,n){return"symbol"==typeof t&&(t=t.description?"[".concat(t.description,"]"):""),Object.defineProperty(e,"name",{configurable:!0,value:n?"".concat(n," ",t):t})}function f(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function m(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{l(r.next(e))}catch(t){i(t)}}function s(e){try{l(r.throw(e))}catch(t){i(t)}}function l(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(a,s)}l((r=r.apply(e,t||[])).next())})}function h(e,t){var n,r,o,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},a=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return a.next=s(0),a.throw=s(1),a.return=s(2),"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(s){return function(l){return function(s){if(n)throw new TypeError("Generator is already executing.");for(;a&&(a=0,s[0]&&(i=0)),i;)try{if(n=1,r&&(o=2&s[0]?r.return:s[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,s[1])).done)return o;switch(r=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return i.label++,{value:s[1],done:!1};case 5:i.label++,r=s[1],s=[0];continue;case 7:s=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]<o[3])){i.label=s[1];break}if(6===s[0]&&i.label<o[1]){i.label=o[1],o=s;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(s);break}o[2]&&i.ops.pop(),i.trys.pop();continue}s=t.call(e,i)}catch(l){s=[6,l],r=0}finally{n=o=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}([s,l])}}}var v=Object.create?function(e,t,n,r){void 0===r&&(r=n);var o=Object.getOwnPropertyDescriptor(t,n);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,o)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]};function g(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||v(t,e,n)}function b(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 y(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,i=n.call(e),a=[];try{for(;(void 0===t||t-- >0)&&!(r=i.next()).done;)a.push(r.value)}catch(s){o={error:s}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return a}function w(){for(var e=[],t=0;t<arguments.length;t++)e=e.concat(y(arguments[t]));return e}function x(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),o=0;for(t=0;t<n;t++)for(var i=arguments[t],a=0,s=i.length;a<s;a++,o++)r[o]=i[a];return r}function k(e,t,n){if(n||2===arguments.length)for(var r,o=0,i=t.length;o<i;o++)!r&&o in t||(r||(r=Array.prototype.slice.call(t,0,o)),r[o]=t[o]);return e.concat(r||Array.prototype.slice.call(t))}function _(e){return this instanceof _?(this.v=e,this):new _(e)}function S(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var r,o=n.apply(e,t||[]),i=[];return r=Object.create(("function"==typeof AsyncIterator?AsyncIterator:Object).prototype),a("next"),a("throw"),a("return",function(e){return function(t){return Promise.resolve(t).then(e,c)}}),r[Symbol.asyncIterator]=function(){return this},r;function a(e,t){o[e]&&(r[e]=function(t){return new Promise(function(n,r){i.push([e,t,n,r])>1||s(e,t)})},t&&(r[e]=t(r[e])))}function s(e,t){try{(n=o[e](t)).value instanceof _?Promise.resolve(n.value.v).then(l,c):u(i[0][2],n)}catch(r){u(i[0][3],r)}var n}function l(e){s("next",e)}function c(e){s("throw",e)}function u(e,t){e(t),i.shift(),i.length&&s(i[0][0],i[0][1])}}function E(e){var t,n;return t={},r("next"),r("throw",function(e){throw e}),r("return"),t[Symbol.iterator]=function(){return this},t;function r(r,o){t[r]=e[r]?function(t){return(n=!n)?{value:_(e[r](t)),done:!1}:o?o(t):t}:o}}function O(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e=b(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)})}}}function j(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e}var P=Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t},C=function(e){return C=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},C(e)};function A(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n=C(e),r=0;r<n.length;r++)"default"!==n[r]&&v(t,e,n[r]);return P(t,e),t}function T(e){return e&&e.__esModule?e:{default:e}}function I(e,t,n,r){if("a"===n&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?r:"a"===n?r.call(e):r?r.value:t.get(e)}function N(e,t,n,r,o){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!o:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?o.call(e,n):o?o.value=n:t.set(e,n),n}function L(e,t){if(null===t||"object"!=typeof t&&"function"!=typeof t)throw new TypeError("Cannot use 'in' operator on non-object");return"function"==typeof e?t===e:e.has(t)}function R(e,t,n){if(null!=t){if("object"!=typeof t&&"function"!=typeof t)throw new TypeError("Object expected.");var r,o;if(n){if(!Symbol.asyncDispose)throw new TypeError("Symbol.asyncDispose is not defined.");r=t[Symbol.asyncDispose]}if(void 0===r){if(!Symbol.dispose)throw new TypeError("Symbol.dispose is not defined.");r=t[Symbol.dispose],n&&(o=r)}if("function"!=typeof r)throw new TypeError("Object not disposable.");o&&(r=function(){try{o.call(this)}catch(e){return Promise.reject(e)}}),e.stack.push({value:t,dispose:r,async:n})}else n&&e.stack.push({async:!0});return t}var D="function"==typeof SuppressedError?SuppressedError:function(e,t,n){var r=new Error(n);return r.name="SuppressedError",r.error=e,r.suppressed=t,r};function F(e){function t(t){e.error=e.hasError?new D(t,e.error,"An error was suppressed during disposal."):t,e.hasError=!0}var n,r=0;return function o(){for(;n=e.stack.pop();)try{if(!n.async&&1===r)return r=0,e.stack.push(n),Promise.resolve().then(o);if(n.dispose){var i=n.dispose.call(n.value);if(n.async)return r|=2,Promise.resolve(i).then(o,function(e){return t(e),o()})}else r|=1}catch(a){t(a)}if(1===r)return e.hasError?Promise.reject(e.error):Promise.resolve();if(e.hasError)throw e.error}()}function M(e,t){return"string"==typeof e&&/^\.\.?\//.test(e)?e.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i,function(e,n,r,o,i){return n?t?".jsx":".js":!r||o&&i?r+o+"."+i.toLowerCase()+"js":e}):e}const B={__extends:o,__assign:i,__rest:a,__decorate:s,__param:l,__esDecorate:c,__runInitializers:u,__propKey:p,__setFunctionName:d,__metadata:f,__awaiter:m,__generator:h,__createBinding:v,__exportStar:g,__values:b,__read:y,__spread:w,__spreadArrays:x,__spreadArray:k,__await:_,__asyncGenerator:S,__asyncDelegator:E,__asyncValues:O,__makeTemplateObject:j,__importStar:A,__importDefault:T,__classPrivateFieldGet:I,__classPrivateFieldSet:N,__classPrivateFieldIn:L,__addDisposableResource:R,__disposeResources:F,__rewriteRelativeImportExtension:M}},31712:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,o={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},33832:(e,t,n)=>{"use strict";n.d(t,{A:()=>h});var r=n(96540),o=n(31712),i=n(21141),a=n(64609),s=n(86185),l=n(23363),c=n(74848);function u({error:e,tryAgain:t}){return(0,c.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,c.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,c.jsx)("button",{type:"button",onClick:t,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,c.jsx)(p,{error:e})]})}function p({error:e}){const t=(0,a.rA)(e).map(e=>e.message).join("\n\nCause:\n");return(0,c.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:t})}function d({children:e}){return(0,c.jsx)(l.W,{value:{plugin:{name:"docusaurus-core-error-boundary",id:"default"}},children:e})}function f({error:e,tryAgain:t}){return(0,c.jsx)(d,{children:(0,c.jsxs)(h,{fallback:()=>(0,c.jsx)(u,{error:e,tryAgain:t}),children:[(0,c.jsx)(i.A,{children:(0,c.jsx)("title",{children:"Page Error"})}),(0,c.jsx)(s.A,{children:(0,c.jsx)(u,{error:e,tryAgain:t})})]})})}const m=e=>(0,c.jsx)(f,{...e});class h extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){o.A.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??m)(e)}return e??null}}},34164:(e,t,n)=>{"use strict";function r(e){var t,n,o="";if("string"==typeof e||"number"==typeof e)o+=e;else if("object"==typeof e)if(Array.isArray(e)){var i=e.length;for(t=0;t<i;t++)e[t]&&(n=r(e[t]))&&(o&&(o+=" "),o+=n)}else for(n in e)e[n]&&(o&&(o+=" "),o+=n);return o}n.d(t,{A:()=>o});const o=function(){for(var e,t,n=0,o="",i=arguments.length;n<i;n++)(e=arguments[n])&&(t=r(e))&&(o&&(o+=" "),o+=t);return o}},34176:(e,t,n)=>{"use strict";n.d(t,{bq:()=>u,MN:()=>c,a2:()=>l,k2:()=>p});var r=n(96540),o=n(23230),i=n(64609);const a={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};var s=n(74848);function l(e){return(0,s.jsx)("button",{type:"button",...e,children:(0,s.jsx)(o.A,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function c({error:e,tryAgain:t}){return(0,s.jsxs)("div",{className:a.errorBoundaryFallback,children:[(0,s.jsx)("p",{children:e.message}),(0,s.jsx)(l,{onClick:t})]})}function u({error:e}){const t=(0,i.rA)(e).map(e=>e.message).join("\n\nCause:\n");return(0,s.jsx)("p",{className:a.errorBoundaryError,children:t})}class p extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}},35302:(e,t,n)=>{var r=n(64634);e.exports=h,e.exports.parse=i,e.exports.compile=function(e,t){return c(i(e,t),t)},e.exports.tokensToFunction=c,e.exports.tokensToRegExp=m;var o=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function i(e,t){for(var n,r=[],i=0,s=0,l="",c=t&&t.delimiter||"/";null!=(n=o.exec(e));){var u=n[0],d=n[1],f=n.index;if(l+=e.slice(s,f),s=f+u.length,d)l+=d[1];else{var m=e[s],h=n[2],v=n[3],g=n[4],b=n[5],y=n[6],w=n[7];l&&(r.push(l),l="");var x=null!=h&&null!=m&&m!==h,k="+"===y||"*"===y,_="?"===y||"*"===y,S=h||c,E=g||b,O=h||("string"==typeof r[r.length-1]?r[r.length-1]:"");r.push({name:v||i++,prefix:h||"",delimiter:S,optional:_,repeat:k,partial:x,asterisk:!!w,pattern:E?p(E):w?".*":a(S,O)})}}return s<e.length&&(l+=e.substr(s)),l&&r.push(l),r}function a(e,t){return!t||t.indexOf(e)>-1?"[^"+u(e)+"]+?":u(t)+"|(?:(?!"+u(t)+")[^"+u(e)+"])+?"}function s(e){return encodeURI(e).replace(/[\/?#]/g,function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})}function l(e){return encodeURI(e).replace(/[?#]/g,function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})}function c(e,t){for(var n=new Array(e.length),o=0;o<e.length;o++)"object"==typeof e[o]&&(n[o]=new RegExp("^(?:"+e[o].pattern+")$",f(t)));return function(t,o){for(var i="",a=t||{},c=(o||{}).pretty?s:encodeURIComponent,u=0;u<e.length;u++){var p=e[u];if("string"!=typeof p){var d,f=a[p.name];if(null==f){if(p.optional){p.partial&&(i+=p.prefix);continue}throw new TypeError('Expected "'+p.name+'" to be defined')}if(r(f)){if(!p.repeat)throw new TypeError('Expected "'+p.name+'" to not repeat, but received `'+JSON.stringify(f)+"`");if(0===f.length){if(p.optional)continue;throw new TypeError('Expected "'+p.name+'" to not be empty')}for(var m=0;m<f.length;m++){if(d=c(f[m]),!n[u].test(d))throw new TypeError('Expected all "'+p.name+'" to match "'+p.pattern+'", but received `'+JSON.stringify(d)+"`");i+=(0===m?p.prefix:p.delimiter)+d}}else{if(d=p.asterisk?l(f):c(f),!n[u].test(d))throw new TypeError('Expected "'+p.name+'" to match "'+p.pattern+'", but received "'+d+'"');i+=p.prefix+d}}else i+=p}return i}}function u(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function p(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function d(e,t){return e.keys=t,e}function f(e){return e&&e.sensitive?"":"i"}function m(e,t,n){r(t)||(n=t||n,t=[]);for(var o=(n=n||{}).strict,i=!1!==n.end,a="",s=0;s<e.length;s++){var l=e[s];if("string"==typeof l)a+=u(l);else{var c=u(l.prefix),p="(?:"+l.pattern+")";t.push(l),l.repeat&&(p+="(?:"+c+p+")*"),a+=p=l.optional?l.partial?c+"("+p+")?":"(?:"+c+"("+p+"))?":c+"("+p+")"}}var m=u(n.delimiter||"/"),h=a.slice(-m.length)===m;return o||(a=(h?a.slice(0,-m.length):a)+"(?:"+m+"(?=$))?"),a+=i?"$":o&&h?"":"(?="+m+"|$)",d(new RegExp("^"+a,f(n)),t)}function h(e,t,n){return r(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var r=0;r<n.length;r++)t.push({name:r,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return d(e,t)}(e,t):r(e)?function(e,t,n){for(var r=[],o=0;o<e.length;o++)r.push(h(e[o],t,n).source);return d(new RegExp("(?:"+r.join("|")+")",f(n)),t)}(e,t,n):function(e,t,n){return m(i(e,n),t,n)}(e,t,n)}},36350:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{O:()=>r})},36494:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(96540);const o=n(31712).A.canUseDOM?r.useLayoutEffect:r.useEffect},37344:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=n(96540);n(74848);const o=r.createContext({collectAnchor:()=>{},collectLink:()=>{}}),i=()=>(0,r.useContext)(o);function a(){return i()}},40002:(e,t,n)=>{"use strict";n.d(t,{M:()=>h,o:()=>m});var r=n(96540),o=n(11062),i=n(69900),a=n(4799),s=n(86957),l=n(74848);const c=(0,i.Wf)("docusaurus.announcement.dismiss"),u=(0,i.Wf)("docusaurus.announcement.id"),p=()=>"true"===c.get(),d=e=>c.set(String(e)),f=r.createContext(null);function m({children:e}){const t=function(){const{announcementBar:e}=(0,s.p)(),t=(0,o.A)(),[n,i]=(0,r.useState)(()=>!!t&&p());(0,r.useEffect)(()=>{i(p())},[]);const a=(0,r.useCallback)(()=>{d(!0),i(!0)},[]);return(0,r.useEffect)(()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&d(!1),!r&&p()||i(!1)},[e]),(0,r.useMemo)(()=>({isActive:!!e&&!n,close:a}),[e,n,a])}();return(0,l.jsx)(f.Provider,{value:t,children:e})}function h(){const e=(0,r.useContext)(f);if(!e)throw new a.dV("AnnouncementBarProvider");return e}},40877:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!r(e)}n.d(t,{A:()=>o,z:()=>r})},40961:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(22551)},40975:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});var r=n(96540),o=n(34164),i=n(11062),a=n(7710);const s={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var l=n(74848);function c({className:e,children:t}){const n=(0,i.A)(),{colorMode:c}=(0,a.G)();return(0,l.jsx)(l.Fragment,{children:(n?"dark"===c?["dark"]:["light"]:["light","dark"]).map(n=>{const i=t({theme:n,className:(0,o.A)(e,s.themedComponent,s[`themedComponent--${n}`])});return(0,l.jsx)(r.Fragment,{children:i},n)})})}function u(e){const{sources:t,className:n,alt:r,...o}=e;return(0,l.jsx)(c,{className:n,children:({theme:e,className:n})=>(0,l.jsx)("img",{src:t[e],alt:r,className:n,...o})})}},42892:(e,t,n)=>{"use strict";function r(e,t){return r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},r(e,t)}function o(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{A:()=>o})},44356:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addTrailingSlash=o,t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),s="/"===a||a===r?a:(l=a,c=n,c?o(l):i(l));var l,c;return e.replace(a,s)},t.addLeadingSlash=function(e){return(0,r.addPrefix)(e,"/")},t.removeTrailingSlash=i;const r=n(50835);function o(e){return e.endsWith("/")?e:`${e}/`}function i(e){return(0,r.removeSuffix)(e,"/")}},44363:(e,t,n)=>{"use strict";e.exports=n(22799)},44598:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});const r="default"},45167:(e,t,n)=>{"use strict";function r(e,t=(e,t)=>e===t){return e.filter((n,r)=>e.findIndex(e=>t(e,n))!==r)}function o(e){return Array.from(new Set(e))}n.d(t,{XI:()=>r,sb:()=>o})},45357:(e,t,n)=>{"use strict";n.d(t,{$S:()=>m,B5:()=>O,Nr:()=>f,OF:()=>k,QB:()=>E,Vd:()=>_,Y:()=>w,a4:()=>h,cC:()=>d,d1:()=>j,fW:()=>S,w8:()=>b});var r=n(96540),o=n(56347),i=n(22831),a=n(19802),s=n(80260),l=n(45167),c=n(86457),u=n(91704),p=n(20040);function d(e){const t=(0,u.r)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function f(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=f(t);if(e)return e}}(e):void 0:e.href}function m(){const{pathname:e}=(0,o.zy)(),t=(0,p.t)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=x({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}function h(){const{pathname:e}=(0,o.zy)(),t=(0,p.t)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=x({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];return n?.items??t.items}const v=(e,t)=>void 0!==e&&(0,s.ys)(e,t),g=(e,t)=>e.some(e=>b(e,t));function b(e,t){return"link"===e.type?v(e.href,t):"category"===e.type&&(v(e.href,t)||g(e.items,t))}function y(e,t){switch(e.type){case"category":return b(e,t)||void 0!==e.href&&!e.linkUnlisted||e.items.some(e=>y(e,t));case"link":return!e.unlisted||b(e,t);default:return!0}}function w(e,t){return(0,r.useMemo)(()=>e.filter(e=>y(e,t)),[e,t])}function x({sidebarItems:e,pathname:t,onlyCategories:n=!1}){const r=[];return function e(o){for(const i of o)if("category"===i.type&&((0,s.ys)(i.href,t)||e(i.items))||"link"===i.type&&(0,s.ys)(i.href,t)){return n&&"category"!==i.type||r.unshift(i),!0}return!1}(e),r}function k(){const e=(0,p.t)(),{pathname:t}=(0,o.zy)(),n=(0,a.vT)()?.pluginData.breadcrumbs;return!1!==n&&e?x({sidebarItems:e.items,pathname:t}):null}function _(e){const{activeVersion:t}=(0,a.zK)(e),{preferredVersion:n}=(0,c.g1)(e),o=(0,a.r7)(e);return(0,r.useMemo)(()=>(0,l.sb)([t,n,o].filter(Boolean)),[t,n,o])}function S(e,t){const n=_(t);return(0,r.useMemo)(()=>{const t=n.flatMap(e=>e.sidebars?Object.entries(e.sidebars):[]),r=t.find(t=>t[0]===e);if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map(e=>e.name).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map(e=>e[0]).join("\n- ")}`);return r[1]},[e,n])}function E(e,t){const n=_(t);return(0,r.useMemo)(()=>{const t=n.flatMap(e=>e.docs),r=t.find(t=>t.id===e);if(!r){if(n.flatMap(e=>e.draftIds).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map(e=>e.name).join(", ")}".\nAvailable doc ids are:\n- ${(0,l.sb)(t.map(e=>e.id)).join("\n- ")}`)}return r},[e,n])}function O({route:e}){const t=(0,o.zy)(),n=(0,u.r)(),r=e.routes,a=r.find(e=>(0,o.B6)(t.pathname,e));if(!a)return null;const s=a.sidebar,l=s?n.docsSidebars[s]:void 0;return{docElement:(0,i.v)(r),sidebarName:s,sidebarItems:l}}function j(e){return e.filter(e=>!("category"===e.type||"link"===e.type)||!!f(e))}},48848:(e,t,n)=>{"use strict";n.d(t,{o:()=>i,x:()=>a});var r=n(96540),o=n(74848);const i=r.createContext(!1);function a({children:e}){const[t,n]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{n(!0)},[]),(0,o.jsx)(i.Provider,{value:t,children:e})}},50835:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addPrefix=function(e,t){return e.startsWith(t)?e:`${t}${e}`},t.removeSuffix=function(e,t){if(""===t)return e;return e.endsWith(t)?e.slice(0,-t.length):e},t.addSuffix=function(e,t){return e.endsWith(t)?e:`${e}${t}`},t.removePrefix=function(e,t){return e.startsWith(t)?e.slice(t.length):e}},51210:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});n(96540);var r=n(21141),o=n(74848);function i({locale:e,version:t,tag:n}){const i=e;return(0,o.jsxs)(r.A,{children:[e&&(0,o.jsx)("meta",{name:"docusaurus_locale",content:e}),t&&(0,o.jsx)("meta",{name:"docusaurus_version",content:t}),n&&(0,o.jsx)("meta",{name:"docusaurus_tag",content:n}),i&&(0,o.jsx)("meta",{name:"docsearch:language",content:i}),t&&(0,o.jsx)("meta",{name:"docsearch:version",content:t}),n&&(0,o.jsx)("meta",{name:"docsearch:docusaurus_tag",content:n})]})}},53259:(e,t,n)=>{"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function o(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(){return a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}var s=n(96540),l=[],c=[];var u=s.createContext(null);function p(e){var t=e(),n={loading:!0,loaded:null,error:null};return n.promise=t.then(function(e){return n.loading=!1,n.loaded=e,e}).catch(function(e){throw n.loading=!1,n.error=e,e}),n}function d(e){var t={loading:!1,loaded:{},error:null},n=[];try{Object.keys(e).forEach(function(r){var o=p(e[r]);o.loading?t.loading=!0:(t.loaded[r]=o.loaded,t.error=o.error),n.push(o.promise),o.promise.then(function(e){t.loaded[r]=e}).catch(function(e){t.error=e})})}catch(r){t.error=r}return t.promise=Promise.all(n).then(function(e){return t.loading=!1,e}).catch(function(e){throw t.loading=!1,e}),t}function f(e,t){return s.createElement((n=e)&&n.__esModule?n.default:n,t);var n}function m(e,t){var p,d;if(!t.loading)throw new Error("react-loadable requires a `loading` component");var m=a({loader:null,loading:null,delay:200,timeout:null,render:f,webpack:null,modules:null},t),h=null;function v(){return h||(h=e(m.loader)),h.promise}return l.push(v),"function"==typeof m.webpack&&c.push(function(){if((0,m.webpack)().every(function(e){return void 0!==e&&void 0!==n.m[e]}))return v()}),d=p=function(t){function n(n){var r;return i(o(o(r=t.call(this,n)||this)),"retry",function(){r.setState({error:null,loading:!0,timedOut:!1}),h=e(m.loader),r._loadModule()}),v(),r.state={error:h.error,pastDelay:!1,timedOut:!1,loading:h.loading,loaded:h.loaded},r}r(n,t),n.preload=function(){return v()};var a=n.prototype;return a.UNSAFE_componentWillMount=function(){this._loadModule()},a.componentDidMount=function(){this._mounted=!0},a._loadModule=function(){var e=this;if(this.context&&Array.isArray(m.modules)&&m.modules.forEach(function(t){e.context.report(t)}),h.loading){var t=function(t){e._mounted&&e.setState(t)};"number"==typeof m.delay&&(0===m.delay?this.setState({pastDelay:!0}):this._delay=setTimeout(function(){t({pastDelay:!0})},m.delay)),"number"==typeof m.timeout&&(this._timeout=setTimeout(function(){t({timedOut:!0})},m.timeout));var n=function(){t({error:h.error,loaded:h.loaded,loading:h.loading}),e._clearTimeouts()};h.promise.then(function(){return n(),null}).catch(function(e){return n(),null})}},a.componentWillUnmount=function(){this._mounted=!1,this._clearTimeouts()},a._clearTimeouts=function(){clearTimeout(this._delay),clearTimeout(this._timeout)},a.render=function(){return this.state.loading||this.state.error?s.createElement(m.loading,{isLoading:this.state.loading,pastDelay:this.state.pastDelay,timedOut:this.state.timedOut,error:this.state.error,retry:this.retry}):this.state.loaded?m.render(this.state.loaded,this.props):null},n}(s.Component),i(p,"contextType",u),d}function h(e){return m(p,e)}h.Map=function(e){if("function"!=typeof e.render)throw new Error("LoadableMap requires a `render(loaded, props)` function");return m(d,e)};var v=function(e){function t(){return e.apply(this,arguments)||this}return r(t,e),t.prototype.render=function(){return s.createElement(u.Provider,{value:{report:this.props.report}},s.Children.only(this.props.children))},t}(s.Component);function g(e){for(var t=[];e.length;){var n=e.pop();t.push(n())}return Promise.all(t).then(function(){if(e.length)return g(e)})}h.Capture=v,h.preloadAll=function(){return new Promise(function(e,t){g(l).then(e,t)})},h.preloadReady=function(){return new Promise(function(e,t){g(c).then(e,e)})},e.exports=h},53366:(e,t,n)=>{"use strict";n.d(t,{o:()=>p,l:()=>d});var r=n(96540),o=n(4784);const i=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/constellation/pr-preview/pr-4027/","versions":[{"name":"current","label":"Next","isLast":false,"path":"/constellation/pr-preview/pr-4027/next","mainDocId":"intro","docs":[{"id":"architecture/attestation","path":"/constellation/pr-preview/pr-4027/next/architecture/attestation","sidebar":"docs"},{"id":"architecture/encrypted-storage","path":"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage","sidebar":"docs"},{"id":"architecture/images","path":"/constellation/pr-preview/pr-4027/next/architecture/images","sidebar":"docs"},{"id":"architecture/keys","path":"/constellation/pr-preview/pr-4027/next/architecture/keys","sidebar":"docs"},{"id":"architecture/microservices","path":"/constellation/pr-preview/pr-4027/next/architecture/microservices","sidebar":"docs"},{"id":"architecture/networking","path":"/constellation/pr-preview/pr-4027/next/architecture/networking","sidebar":"docs"},{"id":"architecture/observability","path":"/constellation/pr-preview/pr-4027/next/architecture/observability","sidebar":"docs"},{"id":"architecture/orchestration","path":"/constellation/pr-preview/pr-4027/next/architecture/orchestration","sidebar":"docs"},{"id":"architecture/overview","path":"/constellation/pr-preview/pr-4027/next/architecture/overview","sidebar":"docs"},{"id":"architecture/versions","path":"/constellation/pr-preview/pr-4027/next/architecture/versions","sidebar":"docs"},{"id":"getting-started/examples","path":"/constellation/pr-preview/pr-4027/next/getting-started/examples","sidebar":"docs"},{"id":"getting-started/examples/emojivoto","path":"/constellation/pr-preview/pr-4027/next/getting-started/examples/emojivoto","sidebar":"docs"},{"id":"getting-started/examples/filestash-s3proxy","path":"/constellation/pr-preview/pr-4027/next/getting-started/examples/filestash-s3proxy","sidebar":"docs"},{"id":"getting-started/examples/horizontal-scaling","path":"/constellation/pr-preview/pr-4027/next/getting-started/examples/horizontal-scaling","sidebar":"docs"},{"id":"getting-started/examples/online-boutique","path":"/constellation/pr-preview/pr-4027/next/getting-started/examples/online-boutique","sidebar":"docs"},{"id":"getting-started/first-steps","path":"/constellation/pr-preview/pr-4027/next/getting-started/first-steps","sidebar":"docs"},{"id":"getting-started/first-steps-local","path":"/constellation/pr-preview/pr-4027/next/getting-started/first-steps-local","sidebar":"docs"},{"id":"getting-started/install","path":"/constellation/pr-preview/pr-4027/next/getting-started/install","sidebar":"docs"},{"id":"getting-started/marketplaces","path":"/constellation/pr-preview/pr-4027/next/getting-started/marketplaces","sidebar":"docs"},{"id":"intro","path":"/constellation/pr-preview/pr-4027/next/","sidebar":"docs"},{"id":"overview/clouds","path":"/constellation/pr-preview/pr-4027/next/overview/clouds","sidebar":"docs"},{"id":"overview/confidential-kubernetes","path":"/constellation/pr-preview/pr-4027/next/overview/confidential-kubernetes","sidebar":"docs"},{"id":"overview/license","path":"/constellation/pr-preview/pr-4027/next/overview/license","sidebar":"docs"},{"id":"overview/performance/application","path":"/constellation/pr-preview/pr-4027/next/overview/performance/application","sidebar":"docs"},{"id":"overview/performance/compute","path":"/constellation/pr-preview/pr-4027/next/overview/performance/compute","sidebar":"docs"},{"id":"overview/performance/io","path":"/constellation/pr-preview/pr-4027/next/overview/performance/io","sidebar":"docs"},{"id":"overview/performance/performance","path":"/constellation/pr-preview/pr-4027/next/overview/performance/","sidebar":"docs"},{"id":"overview/product","path":"/constellation/pr-preview/pr-4027/next/overview/product","sidebar":"docs"},{"id":"overview/security-benefits","path":"/constellation/pr-preview/pr-4027/next/overview/security-benefits","sidebar":"docs"},{"id":"reference/cli","path":"/constellation/pr-preview/pr-4027/next/reference/cli","sidebar":"docs"},{"id":"reference/migration","path":"/constellation/pr-preview/pr-4027/next/reference/migration","sidebar":"docs"},{"id":"reference/slsa","path":"/constellation/pr-preview/pr-4027/next/reference/slsa","sidebar":"docs"},{"id":"reference/terraform","path":"/constellation/pr-preview/pr-4027/next/reference/terraform","sidebar":"docs"},{"id":"workflows/cert-manager","path":"/constellation/pr-preview/pr-4027/next/workflows/cert-manager","sidebar":"docs"},{"id":"workflows/config","path":"/constellation/pr-preview/pr-4027/next/workflows/config","sidebar":"docs"},{"id":"workflows/create","path":"/constellation/pr-preview/pr-4027/next/workflows/create","sidebar":"docs"},{"id":"workflows/lb","path":"/constellation/pr-preview/pr-4027/next/workflows/lb","sidebar":"docs"},{"id":"workflows/recovery","path":"/constellation/pr-preview/pr-4027/next/workflows/recovery","sidebar":"docs"},{"id":"workflows/reproducible-builds","path":"/constellation/pr-preview/pr-4027/next/workflows/reproducible-builds","sidebar":"docs"},{"id":"workflows/s3proxy","path":"/constellation/pr-preview/pr-4027/next/workflows/s3proxy","sidebar":"docs"},{"id":"workflows/sbom","path":"/constellation/pr-preview/pr-4027/next/workflows/sbom","sidebar":"docs"},{"id":"workflows/scale","path":"/constellation/pr-preview/pr-4027/next/workflows/scale","sidebar":"docs"},{"id":"workflows/storage","path":"/constellation/pr-preview/pr-4027/next/workflows/storage","sidebar":"docs"},{"id":"workflows/terminate","path":"/constellation/pr-preview/pr-4027/next/workflows/terminate","sidebar":"docs"},{"id":"workflows/terraform-provider","path":"/constellation/pr-preview/pr-4027/next/workflows/terraform-provider","sidebar":"docs"},{"id":"workflows/troubleshooting","path":"/constellation/pr-preview/pr-4027/next/workflows/troubleshooting","sidebar":"docs"},{"id":"workflows/trusted-launch","path":"/constellation/pr-preview/pr-4027/next/workflows/trusted-launch"},{"id":"workflows/upgrade","path":"/constellation/pr-preview/pr-4027/next/workflows/upgrade","sidebar":"docs"},{"id":"workflows/verify-cli","path":"/constellation/pr-preview/pr-4027/next/workflows/verify-cli","sidebar":"docs"},{"id":"workflows/verify-cluster","path":"/constellation/pr-preview/pr-4027/next/workflows/verify-cluster","sidebar":"docs"},{"id":"/category/basics","path":"/constellation/pr-preview/pr-4027/next/category/basics","sidebar":"docs"},{"id":"/category/getting-started","path":"/constellation/pr-preview/pr-4027/next/category/getting-started","sidebar":"docs"},{"id":"/category/workflows","path":"/constellation/pr-preview/pr-4027/next/category/workflows","sidebar":"docs"},{"id":"/category/architecture","path":"/constellation/pr-preview/pr-4027/next/category/architecture","sidebar":"docs"},{"id":"/category/reference","path":"/constellation/pr-preview/pr-4027/next/category/reference","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/constellation/pr-preview/pr-4027/next/","label":"Introduction"}}}},{"name":"2.24","label":"2.24","isLast":true,"path":"/constellation/pr-preview/pr-4027/","mainDocId":"intro","docs":[{"id":"architecture/attestation","path":"/constellation/pr-preview/pr-4027/architecture/attestation","sidebar":"docs"},{"id":"architecture/encrypted-storage","path":"/constellation/pr-preview/pr-4027/architecture/encrypted-storage","sidebar":"docs"},{"id":"architecture/images","path":"/constellation/pr-preview/pr-4027/architecture/images","sidebar":"docs"},{"id":"architecture/keys","path":"/constellation/pr-preview/pr-4027/architecture/keys","sidebar":"docs"},{"id":"architecture/microservices","path":"/constellation/pr-preview/pr-4027/architecture/microservices","sidebar":"docs"},{"id":"architecture/networking","path":"/constellation/pr-preview/pr-4027/architecture/networking","sidebar":"docs"},{"id":"architecture/observability","path":"/constellation/pr-preview/pr-4027/architecture/observability","sidebar":"docs"},{"id":"architecture/orchestration","path":"/constellation/pr-preview/pr-4027/architecture/orchestration","sidebar":"docs"},{"id":"architecture/overview","path":"/constellation/pr-preview/pr-4027/architecture/overview","sidebar":"docs"},{"id":"architecture/versions","path":"/constellation/pr-preview/pr-4027/architecture/versions","sidebar":"docs"},{"id":"getting-started/examples","path":"/constellation/pr-preview/pr-4027/getting-started/examples","sidebar":"docs"},{"id":"getting-started/examples/emojivoto","path":"/constellation/pr-preview/pr-4027/getting-started/examples/emojivoto","sidebar":"docs"},{"id":"getting-started/examples/filestash-s3proxy","path":"/constellation/pr-preview/pr-4027/getting-started/examples/filestash-s3proxy","sidebar":"docs"},{"id":"getting-started/examples/horizontal-scaling","path":"/constellation/pr-preview/pr-4027/getting-started/examples/horizontal-scaling","sidebar":"docs"},{"id":"getting-started/examples/online-boutique","path":"/constellation/pr-preview/pr-4027/getting-started/examples/online-boutique","sidebar":"docs"},{"id":"getting-started/first-steps","path":"/constellation/pr-preview/pr-4027/getting-started/first-steps","sidebar":"docs"},{"id":"getting-started/first-steps-local","path":"/constellation/pr-preview/pr-4027/getting-started/first-steps-local","sidebar":"docs"},{"id":"getting-started/install","path":"/constellation/pr-preview/pr-4027/getting-started/install","sidebar":"docs"},{"id":"getting-started/marketplaces","path":"/constellation/pr-preview/pr-4027/getting-started/marketplaces","sidebar":"docs"},{"id":"intro","path":"/constellation/pr-preview/pr-4027/","sidebar":"docs"},{"id":"overview/clouds","path":"/constellation/pr-preview/pr-4027/overview/clouds","sidebar":"docs"},{"id":"overview/confidential-kubernetes","path":"/constellation/pr-preview/pr-4027/overview/confidential-kubernetes","sidebar":"docs"},{"id":"overview/license","path":"/constellation/pr-preview/pr-4027/overview/license","sidebar":"docs"},{"id":"overview/performance/application","path":"/constellation/pr-preview/pr-4027/overview/performance/application","sidebar":"docs"},{"id":"overview/performance/compute","path":"/constellation/pr-preview/pr-4027/overview/performance/compute","sidebar":"docs"},{"id":"overview/performance/io","path":"/constellation/pr-preview/pr-4027/overview/performance/io","sidebar":"docs"},{"id":"overview/performance/performance","path":"/constellation/pr-preview/pr-4027/overview/performance/","sidebar":"docs"},{"id":"overview/product","path":"/constellation/pr-preview/pr-4027/overview/product","sidebar":"docs"},{"id":"overview/security-benefits","path":"/constellation/pr-preview/pr-4027/overview/security-benefits","sidebar":"docs"},{"id":"reference/cli","path":"/constellation/pr-preview/pr-4027/reference/cli","sidebar":"docs"},{"id":"reference/migration","path":"/constellation/pr-preview/pr-4027/reference/migration","sidebar":"docs"},{"id":"reference/slsa","path":"/constellation/pr-preview/pr-4027/reference/slsa","sidebar":"docs"},{"id":"reference/terraform","path":"/constellation/pr-preview/pr-4027/reference/terraform","sidebar":"docs"},{"id":"workflows/cert-manager","path":"/constellation/pr-preview/pr-4027/workflows/cert-manager","sidebar":"docs"},{"id":"workflows/config","path":"/constellation/pr-preview/pr-4027/workflows/config","sidebar":"docs"},{"id":"workflows/create","path":"/constellation/pr-preview/pr-4027/workflows/create","sidebar":"docs"},{"id":"workflows/lb","path":"/constellation/pr-preview/pr-4027/workflows/lb","sidebar":"docs"},{"id":"workflows/recovery","path":"/constellation/pr-preview/pr-4027/workflows/recovery","sidebar":"docs"},{"id":"workflows/reproducible-builds","path":"/constellation/pr-preview/pr-4027/workflows/reproducible-builds","sidebar":"docs"},{"id":"workflows/s3proxy","path":"/constellation/pr-preview/pr-4027/workflows/s3proxy","sidebar":"docs"},{"id":"workflows/sbom","path":"/constellation/pr-preview/pr-4027/workflows/sbom","sidebar":"docs"},{"id":"workflows/scale","path":"/constellation/pr-preview/pr-4027/workflows/scale","sidebar":"docs"},{"id":"workflows/storage","path":"/constellation/pr-preview/pr-4027/workflows/storage","sidebar":"docs"},{"id":"workflows/terminate","path":"/constellation/pr-preview/pr-4027/workflows/terminate","sidebar":"docs"},{"id":"workflows/terraform-provider","path":"/constellation/pr-preview/pr-4027/workflows/terraform-provider","sidebar":"docs"},{"id":"workflows/troubleshooting","path":"/constellation/pr-preview/pr-4027/workflows/troubleshooting","sidebar":"docs"},{"id":"workflows/trusted-launch","path":"/constellation/pr-preview/pr-4027/workflows/trusted-launch"},{"id":"workflows/upgrade","path":"/constellation/pr-preview/pr-4027/workflows/upgrade","sidebar":"docs"},{"id":"workflows/verify-cli","path":"/constellation/pr-preview/pr-4027/workflows/verify-cli","sidebar":"docs"},{"id":"workflows/verify-cluster","path":"/constellation/pr-preview/pr-4027/workflows/verify-cluster","sidebar":"docs"},{"id":"/category/basics","path":"/constellation/pr-preview/pr-4027/category/basics","sidebar":"docs"},{"id":"/category/getting-started","path":"/constellation/pr-preview/pr-4027/category/getting-started","sidebar":"docs"},{"id":"/category/workflows","path":"/constellation/pr-preview/pr-4027/category/workflows","sidebar":"docs"},{"id":"/category/architecture","path":"/constellation/pr-preview/pr-4027/category/architecture","sidebar":"docs"},{"id":"/category/reference","path":"/constellation/pr-preview/pr-4027/category/reference","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/constellation/pr-preview/pr-4027/","label":"Introduction"}}}},{"name":"2.23","label":"2.23","isLast":false,"path":"/constellation/pr-preview/pr-4027/2.23","mainDocId":"intro","docs":[{"id":"architecture/attestation","path":"/constellation/pr-preview/pr-4027/2.23/architecture/attestation","sidebar":"docs"},{"id":"architecture/encrypted-storage","path":"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage","sidebar":"docs"},{"id":"architecture/images","path":"/constellation/pr-preview/pr-4027/2.23/architecture/images","sidebar":"docs"},{"id":"architecture/keys","path":"/constellation/pr-preview/pr-4027/2.23/architecture/keys","sidebar":"docs"},{"id":"architecture/microservices","path":"/constellation/pr-preview/pr-4027/2.23/architecture/microservices","sidebar":"docs"},{"id":"architecture/networking","path":"/constellation/pr-preview/pr-4027/2.23/architecture/networking","sidebar":"docs"},{"id":"architecture/observability","path":"/constellation/pr-preview/pr-4027/2.23/architecture/observability","sidebar":"docs"},{"id":"architecture/orchestration","path":"/constellation/pr-preview/pr-4027/2.23/architecture/orchestration","sidebar":"docs"},{"id":"architecture/overview","path":"/constellation/pr-preview/pr-4027/2.23/architecture/overview","sidebar":"docs"},{"id":"architecture/versions","path":"/constellation/pr-preview/pr-4027/2.23/architecture/versions","sidebar":"docs"},{"id":"getting-started/examples","path":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples","sidebar":"docs"},{"id":"getting-started/examples/emojivoto","path":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/emojivoto","sidebar":"docs"},{"id":"getting-started/examples/filestash-s3proxy","path":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/filestash-s3proxy","sidebar":"docs"},{"id":"getting-started/examples/horizontal-scaling","path":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/horizontal-scaling","sidebar":"docs"},{"id":"getting-started/examples/online-boutique","path":"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/online-boutique","sidebar":"docs"},{"id":"getting-started/first-steps","path":"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps","sidebar":"docs"},{"id":"getting-started/first-steps-local","path":"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps-local","sidebar":"docs"},{"id":"getting-started/install","path":"/constellation/pr-preview/pr-4027/2.23/getting-started/install","sidebar":"docs"},{"id":"getting-started/marketplaces","path":"/constellation/pr-preview/pr-4027/2.23/getting-started/marketplaces","sidebar":"docs"},{"id":"intro","path":"/constellation/pr-preview/pr-4027/2.23/","sidebar":"docs"},{"id":"overview/clouds","path":"/constellation/pr-preview/pr-4027/2.23/overview/clouds","sidebar":"docs"},{"id":"overview/confidential-kubernetes","path":"/constellation/pr-preview/pr-4027/2.23/overview/confidential-kubernetes","sidebar":"docs"},{"id":"overview/license","path":"/constellation/pr-preview/pr-4027/2.23/overview/license","sidebar":"docs"},{"id":"overview/performance/application","path":"/constellation/pr-preview/pr-4027/2.23/overview/performance/application","sidebar":"docs"},{"id":"overview/performance/compute","path":"/constellation/pr-preview/pr-4027/2.23/overview/performance/compute","sidebar":"docs"},{"id":"overview/performance/io","path":"/constellation/pr-preview/pr-4027/2.23/overview/performance/io","sidebar":"docs"},{"id":"overview/performance/performance","path":"/constellation/pr-preview/pr-4027/2.23/overview/performance/","sidebar":"docs"},{"id":"overview/product","path":"/constellation/pr-preview/pr-4027/2.23/overview/product","sidebar":"docs"},{"id":"overview/security-benefits","path":"/constellation/pr-preview/pr-4027/2.23/overview/security-benefits","sidebar":"docs"},{"id":"reference/cli","path":"/constellation/pr-preview/pr-4027/2.23/reference/cli","sidebar":"docs"},{"id":"reference/migration","path":"/constellation/pr-preview/pr-4027/2.23/reference/migration","sidebar":"docs"},{"id":"reference/slsa","path":"/constellation/pr-preview/pr-4027/2.23/reference/slsa","sidebar":"docs"},{"id":"reference/terraform","path":"/constellation/pr-preview/pr-4027/2.23/reference/terraform","sidebar":"docs"},{"id":"workflows/cert-manager","path":"/constellation/pr-preview/pr-4027/2.23/workflows/cert-manager","sidebar":"docs"},{"id":"workflows/config","path":"/constellation/pr-preview/pr-4027/2.23/workflows/config","sidebar":"docs"},{"id":"workflows/create","path":"/constellation/pr-preview/pr-4027/2.23/workflows/create","sidebar":"docs"},{"id":"workflows/lb","path":"/constellation/pr-preview/pr-4027/2.23/workflows/lb","sidebar":"docs"},{"id":"workflows/recovery","path":"/constellation/pr-preview/pr-4027/2.23/workflows/recovery","sidebar":"docs"},{"id":"workflows/reproducible-builds","path":"/constellation/pr-preview/pr-4027/2.23/workflows/reproducible-builds","sidebar":"docs"},{"id":"workflows/s3proxy","path":"/constellation/pr-preview/pr-4027/2.23/workflows/s3proxy","sidebar":"docs"},{"id":"workflows/sbom","path":"/constellation/pr-preview/pr-4027/2.23/workflows/sbom","sidebar":"docs"},{"id":"workflows/scale","path":"/constellation/pr-preview/pr-4027/2.23/workflows/scale","sidebar":"docs"},{"id":"workflows/storage","path":"/constellation/pr-preview/pr-4027/2.23/workflows/storage","sidebar":"docs"},{"id":"workflows/terminate","path":"/constellation/pr-preview/pr-4027/2.23/workflows/terminate","sidebar":"docs"},{"id":"workflows/terraform-provider","path":"/constellation/pr-preview/pr-4027/2.23/workflows/terraform-provider","sidebar":"docs"},{"id":"workflows/troubleshooting","path":"/constellation/pr-preview/pr-4027/2.23/workflows/troubleshooting","sidebar":"docs"},{"id":"workflows/trusted-launch","path":"/constellation/pr-preview/pr-4027/2.23/workflows/trusted-launch"},{"id":"workflows/upgrade","path":"/constellation/pr-preview/pr-4027/2.23/workflows/upgrade","sidebar":"docs"},{"id":"workflows/verify-cli","path":"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cli","sidebar":"docs"},{"id":"workflows/verify-cluster","path":"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cluster","sidebar":"docs"},{"id":"/category/basics","path":"/constellation/pr-preview/pr-4027/2.23/category/basics","sidebar":"docs"},{"id":"/category/getting-started","path":"/constellation/pr-preview/pr-4027/2.23/category/getting-started","sidebar":"docs"},{"id":"/category/workflows","path":"/constellation/pr-preview/pr-4027/2.23/category/workflows","sidebar":"docs"},{"id":"/category/architecture","path":"/constellation/pr-preview/pr-4027/2.23/category/architecture","sidebar":"docs"},{"id":"/category/reference","path":"/constellation/pr-preview/pr-4027/2.23/category/reference","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/constellation/pr-preview/pr-4027/2.23/","label":"Introduction"}}}},{"name":"2.22","label":"2.22","isLast":false,"path":"/constellation/pr-preview/pr-4027/2.22","mainDocId":"intro","docs":[{"id":"architecture/attestation","path":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation","sidebar":"docs"},{"id":"architecture/encrypted-storage","path":"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage","sidebar":"docs"},{"id":"architecture/images","path":"/constellation/pr-preview/pr-4027/2.22/architecture/images","sidebar":"docs"},{"id":"architecture/keys","path":"/constellation/pr-preview/pr-4027/2.22/architecture/keys","sidebar":"docs"},{"id":"architecture/microservices","path":"/constellation/pr-preview/pr-4027/2.22/architecture/microservices","sidebar":"docs"},{"id":"architecture/networking","path":"/constellation/pr-preview/pr-4027/2.22/architecture/networking","sidebar":"docs"},{"id":"architecture/observability","path":"/constellation/pr-preview/pr-4027/2.22/architecture/observability","sidebar":"docs"},{"id":"architecture/orchestration","path":"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration","sidebar":"docs"},{"id":"architecture/overview","path":"/constellation/pr-preview/pr-4027/2.22/architecture/overview","sidebar":"docs"},{"id":"architecture/versions","path":"/constellation/pr-preview/pr-4027/2.22/architecture/versions","sidebar":"docs"},{"id":"getting-started/examples","path":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples","sidebar":"docs"},{"id":"getting-started/examples/emojivoto","path":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/emojivoto","sidebar":"docs"},{"id":"getting-started/examples/filestash-s3proxy","path":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/filestash-s3proxy","sidebar":"docs"},{"id":"getting-started/examples/horizontal-scaling","path":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scaling","sidebar":"docs"},{"id":"getting-started/examples/online-boutique","path":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/online-boutique","sidebar":"docs"},{"id":"getting-started/first-steps","path":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps","sidebar":"docs"},{"id":"getting-started/first-steps-local","path":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local","sidebar":"docs"},{"id":"getting-started/install","path":"/constellation/pr-preview/pr-4027/2.22/getting-started/install","sidebar":"docs"},{"id":"getting-started/marketplaces","path":"/constellation/pr-preview/pr-4027/2.22/getting-started/marketplaces","sidebar":"docs"},{"id":"intro","path":"/constellation/pr-preview/pr-4027/2.22/","sidebar":"docs"},{"id":"overview/clouds","path":"/constellation/pr-preview/pr-4027/2.22/overview/clouds","sidebar":"docs"},{"id":"overview/confidential-kubernetes","path":"/constellation/pr-preview/pr-4027/2.22/overview/confidential-kubernetes","sidebar":"docs"},{"id":"overview/license","path":"/constellation/pr-preview/pr-4027/2.22/overview/license","sidebar":"docs"},{"id":"overview/performance/application","path":"/constellation/pr-preview/pr-4027/2.22/overview/performance/application","sidebar":"docs"},{"id":"overview/performance/compute","path":"/constellation/pr-preview/pr-4027/2.22/overview/performance/compute","sidebar":"docs"},{"id":"overview/performance/io","path":"/constellation/pr-preview/pr-4027/2.22/overview/performance/io","sidebar":"docs"},{"id":"overview/performance/performance","path":"/constellation/pr-preview/pr-4027/2.22/overview/performance/","sidebar":"docs"},{"id":"overview/product","path":"/constellation/pr-preview/pr-4027/2.22/overview/product","sidebar":"docs"},{"id":"overview/security-benefits","path":"/constellation/pr-preview/pr-4027/2.22/overview/security-benefits","sidebar":"docs"},{"id":"reference/cli","path":"/constellation/pr-preview/pr-4027/2.22/reference/cli","sidebar":"docs"},{"id":"reference/migration","path":"/constellation/pr-preview/pr-4027/2.22/reference/migration","sidebar":"docs"},{"id":"reference/slsa","path":"/constellation/pr-preview/pr-4027/2.22/reference/slsa","sidebar":"docs"},{"id":"reference/terraform","path":"/constellation/pr-preview/pr-4027/2.22/reference/terraform","sidebar":"docs"},{"id":"workflows/cert-manager","path":"/constellation/pr-preview/pr-4027/2.22/workflows/cert-manager","sidebar":"docs"},{"id":"workflows/config","path":"/constellation/pr-preview/pr-4027/2.22/workflows/config","sidebar":"docs"},{"id":"workflows/create","path":"/constellation/pr-preview/pr-4027/2.22/workflows/create","sidebar":"docs"},{"id":"workflows/lb","path":"/constellation/pr-preview/pr-4027/2.22/workflows/lb","sidebar":"docs"},{"id":"workflows/recovery","path":"/constellation/pr-preview/pr-4027/2.22/workflows/recovery","sidebar":"docs"},{"id":"workflows/reproducible-builds","path":"/constellation/pr-preview/pr-4027/2.22/workflows/reproducible-builds","sidebar":"docs"},{"id":"workflows/s3proxy","path":"/constellation/pr-preview/pr-4027/2.22/workflows/s3proxy","sidebar":"docs"},{"id":"workflows/sbom","path":"/constellation/pr-preview/pr-4027/2.22/workflows/sbom","sidebar":"docs"},{"id":"workflows/scale","path":"/constellation/pr-preview/pr-4027/2.22/workflows/scale","sidebar":"docs"},{"id":"workflows/storage","path":"/constellation/pr-preview/pr-4027/2.22/workflows/storage","sidebar":"docs"},{"id":"workflows/terminate","path":"/constellation/pr-preview/pr-4027/2.22/workflows/terminate","sidebar":"docs"},{"id":"workflows/terraform-provider","path":"/constellation/pr-preview/pr-4027/2.22/workflows/terraform-provider","sidebar":"docs"},{"id":"workflows/troubleshooting","path":"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting","sidebar":"docs"},{"id":"workflows/trusted-launch","path":"/constellation/pr-preview/pr-4027/2.22/workflows/trusted-launch"},{"id":"workflows/upgrade","path":"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade","sidebar":"docs"},{"id":"workflows/verify-cli","path":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli","sidebar":"docs"},{"id":"workflows/verify-cluster","path":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cluster","sidebar":"docs"},{"id":"/category/basics","path":"/constellation/pr-preview/pr-4027/2.22/category/basics","sidebar":"docs"},{"id":"/category/getting-started","path":"/constellation/pr-preview/pr-4027/2.22/category/getting-started","sidebar":"docs"},{"id":"/category/workflows","path":"/constellation/pr-preview/pr-4027/2.22/category/workflows","sidebar":"docs"},{"id":"/category/architecture","path":"/constellation/pr-preview/pr-4027/2.22/category/architecture","sidebar":"docs"},{"id":"/category/reference","path":"/constellation/pr-preview/pr-4027/2.22/category/reference","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/constellation/pr-preview/pr-4027/2.22/","label":"Introduction"}}}}],"breadcrumbs":true}},"@cmfcmf/docusaurus-search-local":{"default":{"titleBoost":5,"contentBoost":1,"tagsBoost":3,"parentCategoriesBoost":2,"indexDocSidebarParentCategories":0,"maxSearchResults":8}}}'),a=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en","translate":false,"url":"https://docs.edgeless.systems","baseUrl":"/constellation/pr-preview/pr-4027/"}}}');var s=n(22654);const l=JSON.parse('{"docusaurusVersion":"3.9.2","siteVersion":"2.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.9.2"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.9.2"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.9.2"},"docusaurus-plugin-svgr":{"type":"package","name":"@docusaurus/plugin-svgr","version":"3.9.2"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.9.2"},"@cmfcmf/docusaurus-search-local":{"type":"package","name":"@cmfcmf/docusaurus-search-local","version":"2.0.1"},"docusaurus-theme-mermaid":{"type":"package","name":"@docusaurus/theme-mermaid","version":"3.9.2"}}}');var c=n(74848);const u={siteConfig:o.A,siteMetadata:l,globalData:i,i18n:a,codeTranslations:s},p=r.createContext(u);function d({children:e}){return(0,c.jsx)(p.Provider,{value:u,children:e})}},54067:(e,t,n)=>{"use strict";n.d(t,{$:()=>a});var r=n(96540),o=n(56347),i=n(4799);function a(e){const t=(0,o.zy)(),n=(0,i.ZC)(t),a=(0,i._q)(e);(0,r.useEffect)(()=>{n&&t!==n&&a({location:t,previousLocation:n})},[a,t,n])}},54625:(e,t,n)=>{"use strict";n.d(t,{I9:()=>p,Kd:()=>u,N_:()=>g,k2:()=>w});var r=n(56347),o=n(42892),i=n(96540),a=n(31513),s=n(58168),l=n(98587),c=n(11561),u=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,a.zR)(t.props),t}return(0,o.A)(t,e),t.prototype.render=function(){return i.createElement(r.Ix,{history:this.history,children:this.props.children})},t}(i.Component);var p=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,a.TM)(t.props),t}return(0,o.A)(t,e),t.prototype.render=function(){return i.createElement(r.Ix,{history:this.history,children:this.props.children})},t}(i.Component);var d=function(e,t){return"function"==typeof e?e(t):e},f=function(e,t){return"string"==typeof e?(0,a.yJ)(e,null,null,t):e},m=function(e){return e},h=i.forwardRef;void 0===h&&(h=m);var v=h(function(e,t){var n=e.innerRef,r=e.navigate,o=e.onClick,a=(0,l.A)(e,["innerRef","navigate","onClick"]),c=a.target,u=(0,s.A)({},a,{onClick:function(e){try{o&&o(e)}catch(t){throw e.preventDefault(),t}e.defaultPrevented||0!==e.button||c&&"_self"!==c||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e)||(e.preventDefault(),r())}});return u.ref=m!==h&&t||n,i.createElement("a",u)});var g=h(function(e,t){var n=e.component,o=void 0===n?v:n,u=e.replace,p=e.to,g=e.innerRef,b=(0,l.A)(e,["component","replace","to","innerRef"]);return i.createElement(r.XZ.Consumer,null,function(e){e||(0,c.A)(!1);var n=e.history,r=f(d(p,e.location),e.location),l=r?n.createHref(r):"",v=(0,s.A)({},b,{href:l,navigate:function(){var t=d(p,e.location),r=(0,a.AO)(e.location)===(0,a.AO)(f(t));(u||r?n.replace:n.push)(t)}});return m!==h?v.ref=t||g:v.innerRef=g,i.createElement(o,v)})}),b=function(e){return e},y=i.forwardRef;void 0===y&&(y=b);var w=y(function(e,t){var n=e["aria-current"],o=void 0===n?"page":n,a=e.activeClassName,u=void 0===a?"active":a,p=e.activeStyle,m=e.className,h=e.exact,v=e.isActive,w=e.location,x=e.sensitive,k=e.strict,_=e.style,S=e.to,E=e.innerRef,O=(0,l.A)(e,["aria-current","activeClassName","activeStyle","className","exact","isActive","location","sensitive","strict","style","to","innerRef"]);return i.createElement(r.XZ.Consumer,null,function(e){e||(0,c.A)(!1);var n=w||e.location,a=f(d(S,n),n),l=a.pathname,j=l&&l.replace(/([.+*?=^!:${}()[\]|/\\])/g,"\\$1"),P=j?(0,r.B6)(n.pathname,{path:j,exact:h,sensitive:x,strict:k}):null,C=!!(v?v(P,n):P),A="function"==typeof m?m(C):m,T="function"==typeof _?_(C):_;C&&(A=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.filter(function(e){return e}).join(" ")}(A,u),T=(0,s.A)({},T,p));var I=(0,s.A)({"aria-current":C&&o||null,className:A,style:T,to:a},O);return b!==y?I.ref=t||E:I.innerRef=E,i.createElement(g,I)})})},56347:(e,t,n)=>{"use strict";n.d(t,{B6:()=>_,Ix:()=>y,W6:()=>I,XZ:()=>b,dO:()=>A,qh:()=>S,zy:()=>N});var r=n(42892),o=n(96540),i=n(5556),a=n.n(i),s=n(31513),l=n(11561),c=n(58168),u=n(35302),p=n.n(u),d=(n(44363),n(98587)),f=(n(4146),1073741823),m="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};var h=o.createContext||function(e,t){var n,i,s="__create-react-context-"+function(){var e="__global_unique_id__";return m[e]=(m[e]||0)+1}()+"__",l=function(e){function n(){for(var t,n,r,o=arguments.length,i=new Array(o),a=0;a<o;a++)i[a]=arguments[a];return(t=e.call.apply(e,[this].concat(i))||this).emitter=(n=t.props.value,r=[],{on:function(e){r.push(e)},off:function(e){r=r.filter(function(t){return t!==e})},get:function(){return n},set:function(e,t){n=e,r.forEach(function(e){return e(n,t)})}}),t}(0,r.A)(n,e);var o=n.prototype;return o.getChildContext=function(){var e;return(e={})[s]=this.emitter,e},o.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,r=this.props.value,o=e.value;((i=r)===(a=o)?0!==i||1/i==1/a:i!=i&&a!=a)?n=0:(n="function"==typeof t?t(r,o):f,0!==(n|=0)&&this.emitter.set(e.value,n))}var i,a},o.render=function(){return this.props.children},n}(o.Component);l.childContextTypes=((n={})[s]=a().object.isRequired,n);var c=function(t){function n(){for(var e,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(e=t.call.apply(t,[this].concat(r))||this).observedBits=void 0,e.state={value:e.getValue()},e.onUpdate=function(t,n){0!==((0|e.observedBits)&n)&&e.setState({value:e.getValue()})},e}(0,r.A)(n,t);var o=n.prototype;return o.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?f:t},o.componentDidMount=function(){this.context[s]&&this.context[s].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?f:e},o.componentWillUnmount=function(){this.context[s]&&this.context[s].off(this.onUpdate)},o.getValue=function(){return this.context[s]?this.context[s].get():e},o.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(o.Component);return c.contextTypes=((i={})[s]=a().object,i),{Provider:l,Consumer:c}},v=function(e){var t=h();return t.displayName=e,t},g=v("Router-History"),b=v("Router"),y=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen(function(e){n._pendingLocation=e})),n}(0,r.A)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){var e=this;this._isMounted=!0,this.unlisten&&this.unlisten(),this.props.staticContext||(this.unlisten=this.props.history.listen(function(t){e._isMounted&&e.setState({location:t})})),this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return o.createElement(b.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},o.createElement(g.Provider,{children:this.props.children||null,value:this.props.history}))},t}(o.Component);o.Component;o.Component;var w={},x=1e4,k=0;function _(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,r=n.path,o=n.exact,i=void 0!==o&&o,a=n.strict,s=void 0!==a&&a,l=n.sensitive,c=void 0!==l&&l;return[].concat(r).reduce(function(t,n){if(!n&&""!==n)return null;if(t)return t;var r=function(e,t){var n=""+t.end+t.strict+t.sensitive,r=w[n]||(w[n]={});if(r[e])return r[e];var o=[],i={regexp:p()(e,o,t),keys:o};return k<x&&(r[e]=i,k++),i}(n,{end:i,strict:s,sensitive:c}),o=r.regexp,a=r.keys,l=o.exec(e);if(!l)return null;var u=l[0],d=l.slice(1),f=e===u;return i&&!f?null:{path:n,url:"/"===n&&""===u?"/":u,isExact:f,params:a.reduce(function(e,t,n){return e[t.name]=d[n],e},{})}},null)}var S=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.A)(t,e),t.prototype.render=function(){var e=this;return o.createElement(b.Consumer,null,function(t){t||(0,l.A)(!1);var n=e.props.location||t.location,r=e.props.computedMatch?e.props.computedMatch:e.props.path?_(n.pathname,e.props):t.match,i=(0,c.A)({},t,{location:n,match:r}),a=e.props,s=a.children,u=a.component,p=a.render;return Array.isArray(s)&&function(e){return 0===o.Children.count(e)}(s)&&(s=null),o.createElement(b.Provider,{value:i},i.match?s?"function"==typeof s?s(i):s:u?o.createElement(u,i):p?p(i):null:"function"==typeof s?s(i):null)})},t}(o.Component);function E(e){return"/"===e.charAt(0)?e:"/"+e}function O(e,t){if(!e)return t;var n=E(e);return 0!==t.pathname.indexOf(n)?t:(0,c.A)({},t,{pathname:t.pathname.substr(n.length)})}function j(e){return"string"==typeof e?e:(0,s.AO)(e)}function P(e){return function(){(0,l.A)(!1)}}function C(){}o.Component;var A=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.A)(t,e),t.prototype.render=function(){var e=this;return o.createElement(b.Consumer,null,function(t){t||(0,l.A)(!1);var n,r,i=e.props.location||t.location;return o.Children.forEach(e.props.children,function(e){if(null==r&&o.isValidElement(e)){n=e;var a=e.props.path||e.props.from;r=a?_(i.pathname,(0,c.A)({},e.props,{path:a})):t.match}}),r?o.cloneElement(n,{location:i,computedMatch:r}):null})},t}(o.Component);var T=o.useContext;function I(){return T(g)}function N(){return T(b).location}},58168:(e,t,n)=>{"use strict";function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(null,arguments)}n.d(t,{A:()=>r})},58252:(e,t,n)=>{"use strict";n.r(t)},60061:()=>{!function(e){var t=[/"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/.source,/'[^']*'/.source,/\$'(?:[^'\\]|\\[\s\S])*'/.source,/<<-?\s*(["']?)(\w+)\1\s[\s\S]*?[\r\n]\2/.source].join("|");e.languages["shell-session"]={command:{pattern:RegExp(/^/.source+"(?:"+/[^\s@:$#%*!/\\]+@[^\r\n@:$#%*!/\\]+(?::[^\0-\x1F$#%*?"<>:;|]+)?/.source+"|"+/[/~.][^\0-\x1F$#%*?"<>@:;|]*/.source+")?"+/[$#%](?=\s)/.source+/(?:[^\\\r\n \t'"<$]|[ \t](?:(?!#)|#.*$)|\\(?:[^\r]|\r\n?)|\$(?!')|<(?!<)|<<str>>)+/.source.replace(/<<str>>/g,function(){return t}),"m"),greedy:!0,inside:{info:{pattern:/^[^#$%]+/,alias:"punctuation",inside:{user:/^[^\s@:$#%*!/\\]+@[^\r\n@:$#%*!/\\]+/,punctuation:/:/,path:/[\s\S]+/}},bash:{pattern:/(^[$#%]\s*)\S[\s\S]*/,lookbehind:!0,alias:"language-bash",inside:e.languages.bash},"shell-symbol":{pattern:/^[$#%]/,alias:"important"}}},output:/.(?:.*(?:[\r\n]|.$))*/},e.languages["sh-session"]=e.languages.shellsession=e.languages["shell-session"]}(Prism)},60774:(e,t,n)=>{var r,o;!function(){var i,a,s,l,c,u,p,d,f,m,h,v,g,b,y,w,x,k,_,S,E,O,j,P,C,A,T,I,N,L,R=function(e){var t=new R.Builder;return t.pipeline.add(R.trimmer,R.stopWordFilter,R.stemmer),t.searchPipeline.add(R.stemmer),e.call(t,t),t.build()};R.version="2.3.9",R.utils={},R.utils.warn=(i=this,function(e){i.console&&console.warn&&console.warn(e)}),R.utils.asString=function(e){return null==e?"":e.toString()},R.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),n=Object.keys(e),r=0;r<n.length;r++){var o=n[r],i=e[o];if(Array.isArray(i))t[o]=i.slice();else{if("string"!=typeof i&&"number"!=typeof i&&"boolean"!=typeof i)throw new TypeError("clone is not deep and does not support nested objects");t[o]=i}}return t},R.FieldRef=function(e,t,n){this.docRef=e,this.fieldName=t,this._stringValue=n},R.FieldRef.joiner="/",R.FieldRef.fromString=function(e){var t=e.indexOf(R.FieldRef.joiner);if(-1===t)throw"malformed field ref string";var n=e.slice(0,t),r=e.slice(t+1);return new R.FieldRef(r,n,e)},R.FieldRef.prototype.toString=function(){return null==this._stringValue&&(this._stringValue=this.fieldName+R.FieldRef.joiner+this.docRef),this._stringValue},R.Set=function(e){if(this.elements=Object.create(null),e){this.length=e.length;for(var t=0;t<this.length;t++)this.elements[e[t]]=!0}else this.length=0},R.Set.complete={intersect:function(e){return e},union:function(){return this},contains:function(){return!0}},R.Set.empty={intersect:function(){return this},union:function(e){return e},contains:function(){return!1}},R.Set.prototype.contains=function(e){return!!this.elements[e]},R.Set.prototype.intersect=function(e){var t,n,r,o=[];if(e===R.Set.complete)return this;if(e===R.Set.empty)return e;this.length<e.length?(t=this,n=e):(t=e,n=this),r=Object.keys(t.elements);for(var i=0;i<r.length;i++){var a=r[i];a in n.elements&&o.push(a)}return new R.Set(o)},R.Set.prototype.union=function(e){return e===R.Set.complete?R.Set.complete:e===R.Set.empty?this:new R.Set(Object.keys(this.elements).concat(Object.keys(e.elements)))},R.idf=function(e,t){var n=0;for(var r in e)"_index"!=r&&(n+=Object.keys(e[r]).length);var o=(t-n+.5)/(n+.5);return Math.log(1+Math.abs(o))},R.Token=function(e,t){this.str=e||"",this.metadata=t||{}},R.Token.prototype.toString=function(){return this.str},R.Token.prototype.update=function(e){return this.str=e(this.str,this.metadata),this},R.Token.prototype.clone=function(e){return e=e||function(e){return e},new R.Token(e(this.str,this.metadata),this.metadata)},R.tokenizer=function(e,t){if(null==e||null==e)return[];if(Array.isArray(e))return e.map(function(e){return new R.Token(R.utils.asString(e).toLowerCase(),R.utils.clone(t))});for(var n=e.toString().toLowerCase(),r=n.length,o=[],i=0,a=0;i<=r;i++){var s=i-a;if(n.charAt(i).match(R.tokenizer.separator)||i==r){if(s>0){var l=R.utils.clone(t)||{};l.position=[a,s],l.index=o.length,o.push(new R.Token(n.slice(a,i),l))}a=i+1}}return o},R.tokenizer.separator=/[\s\-]+/,R.Pipeline=function(){this._stack=[]},R.Pipeline.registeredFunctions=Object.create(null),R.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&R.utils.warn("Overwriting existing registered function: "+t),e.label=t,R.Pipeline.registeredFunctions[e.label]=e},R.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||R.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},R.Pipeline.load=function(e){var t=new R.Pipeline;return e.forEach(function(e){var n=R.Pipeline.registeredFunctions[e];if(!n)throw new Error("Cannot load unregistered function: "+e);t.add(n)}),t},R.Pipeline.prototype.add=function(){Array.prototype.slice.call(arguments).forEach(function(e){R.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},R.Pipeline.prototype.after=function(e,t){R.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");n+=1,this._stack.splice(n,0,t)},R.Pipeline.prototype.before=function(e,t){R.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");this._stack.splice(n,0,t)},R.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},R.Pipeline.prototype.run=function(e){for(var t=this._stack.length,n=0;n<t;n++){for(var r=this._stack[n],o=[],i=0;i<e.length;i++){var a=r(e[i],i,e);if(null!=a&&""!==a)if(Array.isArray(a))for(var s=0;s<a.length;s++)o.push(a[s]);else o.push(a)}e=o}return e},R.Pipeline.prototype.runString=function(e,t){var n=new R.Token(e,t);return this.run([n]).map(function(e){return e.toString()})},R.Pipeline.prototype.reset=function(){this._stack=[]},R.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return R.Pipeline.warnIfFunctionNotRegistered(e),e.label})},R.Vector=function(e){this._magnitude=0,this.elements=e||[]},R.Vector.prototype.positionForIndex=function(e){if(0==this.elements.length)return 0;for(var t=0,n=this.elements.length/2,r=n-t,o=Math.floor(r/2),i=this.elements[2*o];r>1&&(i<e&&(t=o),i>e&&(n=o),i!=e);)r=n-t,o=t+Math.floor(r/2),i=this.elements[2*o];return i==e||i>e?2*o:i<e?2*(o+1):void 0},R.Vector.prototype.insert=function(e,t){this.upsert(e,t,function(){throw"duplicate index"})},R.Vector.prototype.upsert=function(e,t,n){this._magnitude=0;var r=this.positionForIndex(e);this.elements[r]==e?this.elements[r+1]=n(this.elements[r+1],t):this.elements.splice(r,0,e,t)},R.Vector.prototype.magnitude=function(){if(this._magnitude)return this._magnitude;for(var e=0,t=this.elements.length,n=1;n<t;n+=2){var r=this.elements[n];e+=r*r}return this._magnitude=Math.sqrt(e)},R.Vector.prototype.dot=function(e){for(var t=0,n=this.elements,r=e.elements,o=n.length,i=r.length,a=0,s=0,l=0,c=0;l<o&&c<i;)(a=n[l])<(s=r[c])?l+=2:a>s?c+=2:a==s&&(t+=n[l+1]*r[c+1],l+=2,c+=2);return t},R.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},R.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,n=0;t<this.elements.length;t+=2,n++)e[n]=this.elements[t];return e},R.Vector.prototype.toJSON=function(){return this.elements},R.stemmer=(a={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},s={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},p="^("+(c="[^aeiou][^aeiouy]*")+")?"+(u=(l="[aeiouy]")+"[aeiou]*")+c+"("+u+")?$",d="^("+c+")?"+u+c+u+c,f="^("+c+")?"+l,m=new RegExp("^("+c+")?"+u+c),h=new RegExp(d),v=new RegExp(p),g=new RegExp(f),b=/^(.+?)(ss|i)es$/,y=/^(.+?)([^s])s$/,w=/^(.+?)eed$/,x=/^(.+?)(ed|ing)$/,k=/.$/,_=/(at|bl|iz)$/,S=new RegExp("([^aeiouylsz])\\1$"),E=new RegExp("^"+c+l+"[^aeiouwxy]$"),O=/^(.+?[^aeiou])y$/,j=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,P=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,C=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,A=/^(.+?)(s|t)(ion)$/,T=/^(.+?)e$/,I=/ll$/,N=new RegExp("^"+c+l+"[^aeiouwxy]$"),L=function(e){var t,n,r,o,i,l,c;if(e.length<3)return e;if("y"==(r=e.substr(0,1))&&(e=r.toUpperCase()+e.substr(1)),i=y,(o=b).test(e)?e=e.replace(o,"$1$2"):i.test(e)&&(e=e.replace(i,"$1$2")),i=x,(o=w).test(e)){var u=o.exec(e);(o=m).test(u[1])&&(o=k,e=e.replace(o,""))}else i.test(e)&&(t=(u=i.exec(e))[1],(i=g).test(t)&&(l=S,c=E,(i=_).test(e=t)?e+="e":l.test(e)?(o=k,e=e.replace(o,"")):c.test(e)&&(e+="e")));return(o=O).test(e)&&(e=(t=(u=o.exec(e))[1])+"i"),(o=j).test(e)&&(t=(u=o.exec(e))[1],n=u[2],(o=m).test(t)&&(e=t+a[n])),(o=P).test(e)&&(t=(u=o.exec(e))[1],n=u[2],(o=m).test(t)&&(e=t+s[n])),i=A,(o=C).test(e)?(t=(u=o.exec(e))[1],(o=h).test(t)&&(e=t)):i.test(e)&&(t=(u=i.exec(e))[1]+u[2],(i=h).test(t)&&(e=t)),(o=T).test(e)&&(t=(u=o.exec(e))[1],i=v,l=N,((o=h).test(t)||i.test(t)&&!l.test(t))&&(e=t)),i=h,(o=I).test(e)&&i.test(e)&&(o=k,e=e.replace(o,"")),"y"==r&&(e=r.toLowerCase()+e.substr(1)),e},function(e){return e.update(L)}),R.Pipeline.registerFunction(R.stemmer,"stemmer"),R.generateStopWordFilter=function(e){var t=e.reduce(function(e,t){return e[t]=t,e},{});return function(e){if(e&&t[e.toString()]!==e.toString())return e}},R.stopWordFilter=R.generateStopWordFilter(["a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"]),R.Pipeline.registerFunction(R.stopWordFilter,"stopWordFilter"),R.trimmer=function(e){return e.update(function(e){return e.replace(/^\W+/,"").replace(/\W+$/,"")})},R.Pipeline.registerFunction(R.trimmer,"trimmer"),R.TokenSet=function(){this.final=!1,this.edges={},this.id=R.TokenSet._nextId,R.TokenSet._nextId+=1},R.TokenSet._nextId=1,R.TokenSet.fromArray=function(e){for(var t=new R.TokenSet.Builder,n=0,r=e.length;n<r;n++)t.insert(e[n]);return t.finish(),t.root},R.TokenSet.fromClause=function(e){return"editDistance"in e?R.TokenSet.fromFuzzyString(e.term,e.editDistance):R.TokenSet.fromString(e.term)},R.TokenSet.fromFuzzyString=function(e,t){for(var n=new R.TokenSet,r=[{node:n,editsRemaining:t,str:e}];r.length;){var o=r.pop();if(o.str.length>0){var i,a=o.str.charAt(0);a in o.node.edges?i=o.node.edges[a]:(i=new R.TokenSet,o.node.edges[a]=i),1==o.str.length&&(i.final=!0),r.push({node:i,editsRemaining:o.editsRemaining,str:o.str.slice(1)})}if(0!=o.editsRemaining){if("*"in o.node.edges)var s=o.node.edges["*"];else{s=new R.TokenSet;o.node.edges["*"]=s}if(0==o.str.length&&(s.final=!0),r.push({node:s,editsRemaining:o.editsRemaining-1,str:o.str}),o.str.length>1&&r.push({node:o.node,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)}),1==o.str.length&&(o.node.final=!0),o.str.length>=1){if("*"in o.node.edges)var l=o.node.edges["*"];else{l=new R.TokenSet;o.node.edges["*"]=l}1==o.str.length&&(l.final=!0),r.push({node:l,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)})}if(o.str.length>1){var c,u=o.str.charAt(0),p=o.str.charAt(1);p in o.node.edges?c=o.node.edges[p]:(c=new R.TokenSet,o.node.edges[p]=c),1==o.str.length&&(c.final=!0),r.push({node:c,editsRemaining:o.editsRemaining-1,str:u+o.str.slice(2)})}}}return n},R.TokenSet.fromString=function(e){for(var t=new R.TokenSet,n=t,r=0,o=e.length;r<o;r++){var i=e[r],a=r==o-1;if("*"==i)t.edges[i]=t,t.final=a;else{var s=new R.TokenSet;s.final=a,t.edges[i]=s,t=s}}return n},R.TokenSet.prototype.toArray=function(){for(var e=[],t=[{prefix:"",node:this}];t.length;){var n=t.pop(),r=Object.keys(n.node.edges),o=r.length;n.node.final&&(n.prefix.charAt(0),e.push(n.prefix));for(var i=0;i<o;i++){var a=r[i];t.push({prefix:n.prefix.concat(a),node:n.node.edges[a]})}}return e},R.TokenSet.prototype.toString=function(){if(this._str)return this._str;for(var e=this.final?"1":"0",t=Object.keys(this.edges).sort(),n=t.length,r=0;r<n;r++){var o=t[r];e=e+o+this.edges[o].id}return e},R.TokenSet.prototype.intersect=function(e){for(var t=new R.TokenSet,n=void 0,r=[{qNode:e,output:t,node:this}];r.length;){n=r.pop();for(var o=Object.keys(n.qNode.edges),i=o.length,a=Object.keys(n.node.edges),s=a.length,l=0;l<i;l++)for(var c=o[l],u=0;u<s;u++){var p=a[u];if(p==c||"*"==c){var d=n.node.edges[p],f=n.qNode.edges[c],m=d.final&&f.final,h=void 0;p in n.output.edges?(h=n.output.edges[p]).final=h.final||m:((h=new R.TokenSet).final=m,n.output.edges[p]=h),r.push({qNode:f,output:h,node:d})}}}return t},R.TokenSet.Builder=function(){this.previousWord="",this.root=new R.TokenSet,this.uncheckedNodes=[],this.minimizedNodes={}},R.TokenSet.Builder.prototype.insert=function(e){var t,n=0;if(e<this.previousWord)throw new Error("Out of order word insertion");for(var r=0;r<e.length&&r<this.previousWord.length&&e[r]==this.previousWord[r];r++)n++;this.minimize(n),t=0==this.uncheckedNodes.length?this.root:this.uncheckedNodes[this.uncheckedNodes.length-1].child;for(r=n;r<e.length;r++){var o=new R.TokenSet,i=e[r];t.edges[i]=o,this.uncheckedNodes.push({parent:t,char:i,child:o}),t=o}t.final=!0,this.previousWord=e},R.TokenSet.Builder.prototype.finish=function(){this.minimize(0)},R.TokenSet.Builder.prototype.minimize=function(e){for(var t=this.uncheckedNodes.length-1;t>=e;t--){var n=this.uncheckedNodes[t],r=n.child.toString();r in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[r]:(n.child._str=r,this.minimizedNodes[r]=n.child),this.uncheckedNodes.pop()}},R.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},R.Index.prototype.search=function(e){return this.query(function(t){new R.QueryParser(e,t).parse()})},R.Index.prototype.query=function(e){for(var t=new R.Query(this.fields),n=Object.create(null),r=Object.create(null),o=Object.create(null),i=Object.create(null),a=Object.create(null),s=0;s<this.fields.length;s++)r[this.fields[s]]=new R.Vector;e.call(t,t);for(s=0;s<t.clauses.length;s++){var l=t.clauses[s],c=null,u=R.Set.empty;c=l.usePipeline?this.pipeline.runString(l.term,{fields:l.fields}):[l.term];for(var p=0;p<c.length;p++){var d=c[p];l.term=d;var f=R.TokenSet.fromClause(l),m=this.tokenSet.intersect(f).toArray();if(0===m.length&&l.presence===R.Query.presence.REQUIRED){for(var h=0;h<l.fields.length;h++){i[T=l.fields[h]]=R.Set.empty}break}for(var v=0;v<m.length;v++){var g=m[v],b=this.invertedIndex[g],y=b._index;for(h=0;h<l.fields.length;h++){var w=b[T=l.fields[h]],x=Object.keys(w),k=g+"/"+T,_=new R.Set(x);if(l.presence==R.Query.presence.REQUIRED&&(u=u.union(_),void 0===i[T]&&(i[T]=R.Set.complete)),l.presence!=R.Query.presence.PROHIBITED){if(r[T].upsert(y,l.boost,function(e,t){return e+t}),!o[k]){for(var S=0;S<x.length;S++){var E,O=x[S],j=new R.FieldRef(O,T),P=w[O];void 0===(E=n[j])?n[j]=new R.MatchData(g,T,P):E.add(g,T,P)}o[k]=!0}}else void 0===a[T]&&(a[T]=R.Set.empty),a[T]=a[T].union(_)}}}if(l.presence===R.Query.presence.REQUIRED)for(h=0;h<l.fields.length;h++){i[T=l.fields[h]]=i[T].intersect(u)}}var C=R.Set.complete,A=R.Set.empty;for(s=0;s<this.fields.length;s++){var T;i[T=this.fields[s]]&&(C=C.intersect(i[T])),a[T]&&(A=A.union(a[T]))}var I=Object.keys(n),N=[],L=Object.create(null);if(t.isNegated()){I=Object.keys(this.fieldVectors);for(s=0;s<I.length;s++){j=I[s];var D=R.FieldRef.fromString(j);n[j]=new R.MatchData}}for(s=0;s<I.length;s++){var F=(D=R.FieldRef.fromString(I[s])).docRef;if(C.contains(F)&&!A.contains(F)){var M,B=this.fieldVectors[D],z=r[D.fieldName].similarity(B);if(void 0!==(M=L[F]))M.score+=z,M.matchData.combine(n[D]);else{var $={ref:F,score:z,matchData:n[D]};L[F]=$,N.push($)}}}return N.sort(function(e,t){return t.score-e.score})},R.Index.prototype.toJSON=function(){var e=Object.keys(this.invertedIndex).sort().map(function(e){return[e,this.invertedIndex[e]]},this),t=Object.keys(this.fieldVectors).map(function(e){return[e,this.fieldVectors[e].toJSON()]},this);return{version:R.version,fields:this.fields,fieldVectors:t,invertedIndex:e,pipeline:this.pipeline.toJSON()}},R.Index.load=function(e){var t={},n={},r=e.fieldVectors,o=Object.create(null),i=e.invertedIndex,a=new R.TokenSet.Builder,s=R.Pipeline.load(e.pipeline);e.version!=R.version&&R.utils.warn("Version mismatch when loading serialised index. Current version of lunr '"+R.version+"' does not match serialized index '"+e.version+"'");for(var l=0;l<r.length;l++){var c=(p=r[l])[0],u=p[1];n[c]=new R.Vector(u)}for(l=0;l<i.length;l++){var p,d=(p=i[l])[0],f=p[1];a.insert(d),o[d]=f}return a.finish(),t.fields=e.fields,t.fieldVectors=n,t.invertedIndex=o,t.tokenSet=a.root,t.pipeline=s,new R.Index(t)},R.Builder=function(){this._ref="id",this._fields=Object.create(null),this._documents=Object.create(null),this.invertedIndex=Object.create(null),this.fieldTermFrequencies={},this.fieldLengths={},this.tokenizer=R.tokenizer,this.pipeline=new R.Pipeline,this.searchPipeline=new R.Pipeline,this.documentCount=0,this._b=.75,this._k1=1.2,this.termIndex=0,this.metadataWhitelist=[]},R.Builder.prototype.ref=function(e){this._ref=e},R.Builder.prototype.field=function(e,t){if(/\//.test(e))throw new RangeError("Field '"+e+"' contains illegal character '/'");this._fields[e]=t||{}},R.Builder.prototype.b=function(e){this._b=e<0?0:e>1?1:e},R.Builder.prototype.k1=function(e){this._k1=e},R.Builder.prototype.add=function(e,t){var n=e[this._ref],r=Object.keys(this._fields);this._documents[n]=t||{},this.documentCount+=1;for(var o=0;o<r.length;o++){var i=r[o],a=this._fields[i].extractor,s=this._fields[i].isLiteral??!1,l=a?a(e):e[i],c=s?[l]:this.tokenizer(l,{fields:[i]}),u=s?c:this.pipeline.run(c),p=new R.FieldRef(n,i),d=Object.create(null);this.fieldTermFrequencies[p]=d,this.fieldLengths[p]=0,this.fieldLengths[p]+=u.length;for(var f=0;f<u.length;f++){var m=u[f];if(null==d[m]&&(d[m]=0),d[m]+=1,null==this.invertedIndex[m]){var h=Object.create(null);h._index=this.termIndex,this.termIndex+=1;for(var v=0;v<r.length;v++)h[r[v]]=Object.create(null);this.invertedIndex[m]=h}null==this.invertedIndex[m][i][n]&&(this.invertedIndex[m][i][n]=Object.create(null));for(var g=0;g<this.metadataWhitelist.length;g++){var b=this.metadataWhitelist[g],y=m.metadata[b];null==this.invertedIndex[m][i][n][b]&&(this.invertedIndex[m][i][n][b]=[]),this.invertedIndex[m][i][n][b].push(y)}}}},R.Builder.prototype.calculateAverageFieldLengths=function(){for(var e=Object.keys(this.fieldLengths),t=e.length,n={},r={},o=0;o<t;o++){var i=R.FieldRef.fromString(e[o]),a=i.fieldName;r[a]||(r[a]=0),r[a]+=1,n[a]||(n[a]=0),n[a]+=this.fieldLengths[i]}var s=Object.keys(this._fields);for(o=0;o<s.length;o++){var l=s[o];n[l]=n[l]/r[l]}this.averageFieldLength=n},R.Builder.prototype.createFieldVectors=function(){for(var e={},t=Object.keys(this.fieldTermFrequencies),n=t.length,r=Object.create(null),o=0;o<n;o++){for(var i=R.FieldRef.fromString(t[o]),a=i.fieldName,s=this.fieldLengths[i],l=new R.Vector,c=this.fieldTermFrequencies[i],u=Object.keys(c),p=u.length,d=this._fields[a].boost||1,f=this._documents[i.docRef].boost||1,m=0;m<p;m++){var h,v,g,b=u[m],y=c[b],w=this.invertedIndex[b]._index;void 0===r[b]?(h=R.idf(this.invertedIndex[b],this.documentCount),r[b]=h):h=r[b],v=h*((this._k1+1)*y)/(this._k1*(1-this._b+this._b*(s/this.averageFieldLength[a]))+y),v*=d,v*=f,g=Math.round(1e3*v)/1e3,l.insert(w,g)}e[i]=l}this.fieldVectors=e},R.Builder.prototype.createTokenSet=function(){this.tokenSet=R.TokenSet.fromArray(Object.keys(this.invertedIndex).sort())},R.Builder.prototype.build=function(){return this.calculateAverageFieldLengths(),this.createFieldVectors(),this.createTokenSet(),new R.Index({invertedIndex:this.invertedIndex,fieldVectors:this.fieldVectors,tokenSet:this.tokenSet,fields:Object.keys(this._fields),pipeline:this.searchPipeline})},R.Builder.prototype.use=function(e){var t=Array.prototype.slice.call(arguments,1);t.unshift(this),e.apply(this,t)},R.MatchData=function(e,t,n){for(var r=Object.create(null),o=Object.keys(n||{}),i=0;i<o.length;i++){var a=o[i];r[a]=n[a].slice()}this.metadata=Object.create(null),void 0!==e&&(this.metadata[e]=Object.create(null),this.metadata[e][t]=r)},R.MatchData.prototype.combine=function(e){for(var t=Object.keys(e.metadata),n=0;n<t.length;n++){var r=t[n],o=Object.keys(e.metadata[r]);null==this.metadata[r]&&(this.metadata[r]=Object.create(null));for(var i=0;i<o.length;i++){var a=o[i],s=Object.keys(e.metadata[r][a]);null==this.metadata[r][a]&&(this.metadata[r][a]=Object.create(null));for(var l=0;l<s.length;l++){var c=s[l];null==this.metadata[r][a][c]?this.metadata[r][a][c]=e.metadata[r][a][c]:this.metadata[r][a][c]=this.metadata[r][a][c].concat(e.metadata[r][a][c])}}}},R.MatchData.prototype.add=function(e,t,n){if(!(e in this.metadata))return this.metadata[e]=Object.create(null),void(this.metadata[e][t]=n);if(t in this.metadata[e])for(var r=Object.keys(n),o=0;o<r.length;o++){var i=r[o];i in this.metadata[e][t]?this.metadata[e][t][i]=this.metadata[e][t][i].concat(n[i]):this.metadata[e][t][i]=n[i]}else this.metadata[e][t]=n},R.Query=function(e){this.clauses=[],this.allFields=e},R.Query.wildcard=new String("*"),R.Query.wildcard.NONE=0,R.Query.wildcard.LEADING=1,R.Query.wildcard.TRAILING=2,R.Query.presence={OPTIONAL:1,REQUIRED:2,PROHIBITED:3},R.Query.prototype.clause=function(e){return"fields"in e||(e.fields=this.allFields),"boost"in e||(e.boost=1),"usePipeline"in e||(e.usePipeline=!0),"wildcard"in e||(e.wildcard=R.Query.wildcard.NONE),e.wildcard&R.Query.wildcard.LEADING&&e.term.charAt(0)!=R.Query.wildcard&&(e.term="*"+e.term),e.wildcard&R.Query.wildcard.TRAILING&&e.term.slice(-1)!=R.Query.wildcard&&(e.term=e.term+"*"),"presence"in e||(e.presence=R.Query.presence.OPTIONAL),this.clauses.push(e),this},R.Query.prototype.isNegated=function(){for(var e=0;e<this.clauses.length;e++)if(this.clauses[e].presence!=R.Query.presence.PROHIBITED)return!1;return!0},R.Query.prototype.term=function(e,t){if(Array.isArray(e))return e.forEach(function(e){this.term(e,R.utils.clone(t))},this),this;var n=t||{};return n.term=e.toString(),this.clause(n),this},R.QueryParseError=function(e,t,n){this.name="QueryParseError",this.message=e,this.start=t,this.end=n},R.QueryParseError.prototype=new Error,R.QueryLexer=function(e){this.lexemes=[],this.str=e,this.length=e.length,this.pos=0,this.start=0,this.escapeCharPositions=[]},R.QueryLexer.prototype.run=function(){for(var e=R.QueryLexer.lexText;e;)e=e(this)},R.QueryLexer.prototype.sliceString=function(){for(var e=[],t=this.start,n=this.pos,r=0;r<this.escapeCharPositions.length;r++)n=this.escapeCharPositions[r],e.push(this.str.slice(t,n)),t=n+1;return e.push(this.str.slice(t,this.pos)),this.escapeCharPositions.length=0,e.join("")},R.QueryLexer.prototype.emit=function(e){this.lexemes.push({type:e,str:this.sliceString(),start:this.start,end:this.pos}),this.start=this.pos},R.QueryLexer.prototype.escapeCharacter=function(){this.escapeCharPositions.push(this.pos-1),this.pos+=1},R.QueryLexer.prototype.next=function(){if(this.pos>=this.length)return R.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},R.QueryLexer.prototype.width=function(){return this.pos-this.start},R.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},R.QueryLexer.prototype.backup=function(){this.pos-=1},R.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{t=(e=this.next()).charCodeAt(0)}while(t>47&&t<58);e!=R.QueryLexer.EOS&&this.backup()},R.QueryLexer.prototype.more=function(){return this.pos<this.length},R.QueryLexer.EOS="EOS",R.QueryLexer.FIELD="FIELD",R.QueryLexer.TERM="TERM",R.QueryLexer.EDIT_DISTANCE="EDIT_DISTANCE",R.QueryLexer.BOOST="BOOST",R.QueryLexer.PRESENCE="PRESENCE",R.QueryLexer.lexField=function(e){return e.backup(),e.emit(R.QueryLexer.FIELD),e.ignore(),R.QueryLexer.lexText},R.QueryLexer.lexTerm=function(e){if(e.width()>1&&(e.backup(),e.emit(R.QueryLexer.TERM)),e.ignore(),e.more())return R.QueryLexer.lexText},R.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(R.QueryLexer.EDIT_DISTANCE),R.QueryLexer.lexText},R.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(R.QueryLexer.BOOST),R.QueryLexer.lexText},R.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(R.QueryLexer.TERM)},R.QueryLexer.termSeparator=R.tokenizer.separator,R.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==R.QueryLexer.EOS)return R.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return R.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(R.QueryLexer.TERM),R.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(R.QueryLexer.TERM),R.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(R.QueryLexer.PRESENCE),R.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(R.QueryLexer.PRESENCE),R.QueryLexer.lexText;if(t.match(R.QueryLexer.termSeparator))return R.QueryLexer.lexTerm}else e.escapeCharacter()}},R.QueryParser=function(e,t){this.lexer=new R.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},R.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=R.QueryParser.parseClause;e;)e=e(this);return this.query},R.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},R.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},R.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},R.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(null!=t)switch(t.type){case R.QueryLexer.PRESENCE:return R.QueryParser.parsePresence;case R.QueryLexer.FIELD:return R.QueryParser.parseField;case R.QueryLexer.TERM:return R.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(n+=" with value '"+t.str+"'"),new R.QueryParseError(n,t.start,t.end)}},R.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(null!=t){switch(t.str){case"-":e.currentClause.presence=R.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=R.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+t.str+"'";throw new R.QueryParseError(n,t.start,t.end)}var r=e.peekLexeme();if(null==r){n="expecting term or field, found nothing";throw new R.QueryParseError(n,t.start,t.end)}switch(r.type){case R.QueryLexer.FIELD:return R.QueryParser.parseField;case R.QueryLexer.TERM:return R.QueryParser.parseTerm;default:n="expecting term or field, found '"+r.type+"'";throw new R.QueryParseError(n,r.start,r.end)}}},R.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(null!=t){if(-1==e.query.allFields.indexOf(t.str)){var n=e.query.allFields.map(function(e){return"'"+e+"'"}).join(", "),r="unrecognised field '"+t.str+"', possible fields: "+n;throw new R.QueryParseError(r,t.start,t.end)}e.currentClause.fields=[t.str];var o=e.peekLexeme();if(null==o){r="expecting term, found nothing";throw new R.QueryParseError(r,t.start,t.end)}if(o.type===R.QueryLexer.TERM)return R.QueryParser.parseTerm;r="expecting term, found '"+o.type+"'";throw new R.QueryParseError(r,o.start,o.end)}},R.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(null!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(null!=n)switch(n.type){case R.QueryLexer.TERM:return e.nextClause(),R.QueryParser.parseTerm;case R.QueryLexer.FIELD:return e.nextClause(),R.QueryParser.parseField;case R.QueryLexer.EDIT_DISTANCE:return R.QueryParser.parseEditDistance;case R.QueryLexer.BOOST:return R.QueryParser.parseBoost;case R.QueryLexer.PRESENCE:return e.nextClause(),R.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+n.type+"'";throw new R.QueryParseError(r,n.start,n.end)}else e.nextClause()}},R.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="edit distance must be numeric";throw new R.QueryParseError(r,t.start,t.end)}e.currentClause.editDistance=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case R.QueryLexer.TERM:return e.nextClause(),R.QueryParser.parseTerm;case R.QueryLexer.FIELD:return e.nextClause(),R.QueryParser.parseField;case R.QueryLexer.EDIT_DISTANCE:return R.QueryParser.parseEditDistance;case R.QueryLexer.BOOST:return R.QueryParser.parseBoost;case R.QueryLexer.PRESENCE:return e.nextClause(),R.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+o.type+"'";throw new R.QueryParseError(r,o.start,o.end)}else e.nextClause()}},R.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="boost must be numeric";throw new R.QueryParseError(r,t.start,t.end)}e.currentClause.boost=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case R.QueryLexer.TERM:return e.nextClause(),R.QueryParser.parseTerm;case R.QueryLexer.FIELD:return e.nextClause(),R.QueryParser.parseField;case R.QueryLexer.EDIT_DISTANCE:return R.QueryParser.parseEditDistance;case R.QueryLexer.BOOST:return R.QueryParser.parseBoost;case R.QueryLexer.PRESENCE:return e.nextClause(),R.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+o.type+"'";throw new R.QueryParseError(r,o.start,o.end)}else e.nextClause()}},void 0===(o="function"==typeof(r=function(){return R})?r.call(t,n,t,e):r)||(e.exports=o)}()},61482:(e,t,n)=>{"use strict";n.d(t,{C:()=>r});const r="default"},61938:(e,t,n)=>{"use strict";n.d(t,{M:()=>m,e:()=>f});var r=n(96540),o=n(70763),i=n(82216),a=n(62814),s=n(86957),l=n(4799),c=n(74848);const u=r.createContext(void 0);function p(){const e=function(){const e=(0,o.YL)(),{items:t}=(0,s.p)().navbar;return 0===t.length&&!e.component}(),t=(0,i.l)(),n=!e&&"mobile"===t,[a,l]=(0,r.useState)(!1),c=(0,r.useCallback)(()=>{l(e=>!e)},[]);return(0,r.useEffect)(()=>{"desktop"===t&&l(!1)},[t]),(0,r.useMemo)(()=>({disabled:e,shouldRender:n,toggle:c,shown:a}),[e,n,c,a])}function d({handler:e}){return(0,a.$Z)(e),null}function f({children:e}){const t=p();return(0,c.jsxs)(c.Fragment,{children:[t.shown&&(0,c.jsx)(d,{handler:()=>(t.toggle(),!1)}),(0,c.jsx)(u.Provider,{value:t,children:e})]})}function m(){const e=r.useContext(u);if(void 0===e)throw new l.dV("NavbarMobileSidebarProvider");return e}},62814:(e,t,n)=>{"use strict";n.d(t,{$Z:()=>a,Hl:()=>s,aZ:()=>l,jy:()=>c});var r=n(96540),o=n(56347),i=n(4799);function a(e){!function(e){const t=(0,o.W6)(),n=(0,i._q)(e);(0,r.useEffect)(()=>t.block((e,t)=>n(e,t)),[t,n])}((t,n)=>{if("POP"===n)return e(t,n)})}function s(e){const t=(0,o.W6)();return(0,r.useSyncExternalStore)(t.listen,()=>e(t),()=>e({...t,location:{...t.location,search:"",hash:"",state:void 0}}))}function l(e){return s(t=>null===e?null:new URLSearchParams(t.location.search).get(e))}function c(e,t){const n=function(e,t){const n=new URLSearchParams;for(const r of e)for(const[e,o]of r.entries())"append"===t?n.append(e,o):n.set(e,o);return n}(e.map(e=>new URLSearchParams(e??"")),t),r=n.toString();return r?`?${r}`:r}},64609:(e,t,n)=>{"use strict";t.rA=t.Ks=void 0;const r=n(31635);var o=n(44356);Object.defineProperty(t,"Ks",{enumerable:!0,get:function(){return r.__importDefault(o).default}});var i=n(50835);var a=n(68274);Object.defineProperty(t,"rA",{enumerable:!0,get:function(){return a.getErrorCausalChain}})},64634:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},68274:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=function e(t){if(t.cause)return[t,...e(t.cause)];return[t]}},69900:(e,t,n)=>{"use strict";n.d(t,{Wf:()=>u,Dv:()=>p});var r=n(96540);const o=JSON.parse('{"N":"localStorage","M":""}'),i=o.N;function a({key:e,oldValue:t,newValue:n,storage:r}){if(t===n)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,e,t,n,window.location.href,r),window.dispatchEvent(o)}function s(e=i){if("undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,l||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),l=!0),null}var t}let l=!1;const c={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function u(e,t){const n=`${e}${o.M}`;if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(n);const r=s(t?.persistence);return null===r?c:{get:()=>{try{return r.getItem(n)}catch(e){return console.error(`Docusaurus storage error, can't get key=${n}`,e),null}},set:e=>{try{const t=r.getItem(n);r.setItem(n,e),a({key:n,oldValue:t,newValue:e,storage:r})}catch(t){console.error(`Docusaurus storage error, can't set ${n}=${e}`,t)}},del:()=>{try{const e=r.getItem(n);r.removeItem(n),a({key:n,oldValue:e,newValue:null,storage:r})}catch(e){console.error(`Docusaurus storage error, can't delete key=${n}`,e)}},listen:e=>{try{const t=t=>{t.storageArea===r&&t.key===n&&e(t)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)}catch(t){return console.error(`Docusaurus storage error, can't listen for changes of key=${n}`,t),()=>{}}}}}function p(e,t){const[n]=(0,r.useState)(()=>null===e?c:u(e,t)),o=(0,r.useCallback)(e=>"undefined"==typeof window?()=>{}:n.listen(e),[n]);return[(0,r.useSyncExternalStore)(o,()=>n.get(),()=>null),n]}},69982:(e,t,n)=>{"use strict";e.exports=n(7463)},70763:(e,t,n)=>{"use strict";n.d(t,{GX:()=>c,YL:()=>l,y_:()=>s});var r=n(96540),o=n(4799),i=n(74848);const a=r.createContext(null);function s({children:e}){const t=(0,r.useState)({component:null,props:null});return(0,i.jsx)(a.Provider,{value:t,children:e})}function l(){const e=(0,r.useContext)(a);if(!e)throw new o.dV("NavbarSecondaryMenuContentProvider");return e[0]}function c({component:e,props:t}){const n=(0,r.useContext)(a);if(!n)throw new o.dV("NavbarSecondaryMenuContentProvider");const[,i]=n,s=(0,o.Be)(t);return(0,r.useEffect)(()=>{i({component:e,props:s})},[i,e,s]),(0,r.useEffect)(()=>()=>i({component:null,props:null}),[i]),null}},71765:(e,t,n)=>{"use strict";n.d(t,{My:()=>j,f4:()=>ne});var r,o,i,a,s,l,c,u=n(96540),p=n(34164),d=Object.create,f=Object.defineProperty,m=Object.defineProperties,h=Object.getOwnPropertyDescriptor,v=Object.getOwnPropertyDescriptors,g=Object.getOwnPropertyNames,b=Object.getOwnPropertySymbols,y=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty,x=Object.prototype.propertyIsEnumerable,k=(e,t,n)=>t in e?f(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,_=(e,t)=>{for(var n in t||(t={}))w.call(t,n)&&k(e,n,t[n]);if(b)for(var n of b(t))x.call(t,n)&&k(e,n,t[n]);return e},S=(e,t)=>m(e,v(t)),E=(e,t)=>{var n={};for(var r in e)w.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&b)for(var r of b(e))t.indexOf(r)<0&&x.call(e,r)&&(n[r]=e[r]);return n},O=(r={"../../node_modules/.pnpm/prismjs@1.29.0_patch_hash=vrxx3pzkik6jpmgpayxfjunetu/node_modules/prismjs/prism.js"(e,t){var n=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof o?new o(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(t,n){var o,i;switch(n=n||{},r.util.type(t)){case"Object":if(i=r.util.objId(t),n[i])return n[i];for(var a in o={},n[i]=o,t)t.hasOwnProperty(a)&&(o[a]=e(t[a],n));return o;case"Array":return i=r.util.objId(t),n[i]?n[i]:(o=[],n[i]=o,t.forEach(function(t,r){o[r]=e(t,n)}),o);default:return t}},getLanguage:function(t){for(;t;){var n=e.exec(t.className);if(n)return n[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,n){t.className=t.className.replace(RegExp(e,"gi"),""),t.classList.add("language-"+n)},isActive:function(e,t,n){for(var r="no-"+t;e;){var o=e.classList;if(o.contains(t))return!0;if(o.contains(r))return!1;e=e.parentElement}return!!n}},languages:{plain:n,plaintext:n,text:n,txt:n,extend:function(e,t){var n=r.util.clone(r.languages[e]);for(var o in t)n[o]=t[o];return n},insertBefore:function(e,t,n,o){var i=(o=o||r.languages)[e],a={};for(var s in i)if(i.hasOwnProperty(s)){if(s==t)for(var l in n)n.hasOwnProperty(l)&&(a[l]=n[l]);n.hasOwnProperty(s)||(a[s]=i[s])}var c=o[e];return o[e]=a,r.languages.DFS(r.languages,function(t,n){n===c&&t!=e&&(this[t]=a)}),a},DFS:function e(t,n,o,i){i=i||{};var a=r.util.objId;for(var s in t)if(t.hasOwnProperty(s)){n.call(t,s,t[s],o||s);var l=t[s],c=r.util.type(l);"Object"!==c||i[a(l)]?"Array"!==c||i[a(l)]||(i[a(l)]=!0,e(l,n,s,i)):(i[a(l)]=!0,e(l,n,null,i))}}},plugins:{},highlight:function(e,t,n){var i={code:e,grammar:t,language:n};if(r.hooks.run("before-tokenize",i),!i.grammar)throw new Error('The language "'+i.language+'" has no grammar.');return i.tokens=r.tokenize(i.code,i.grammar),r.hooks.run("after-tokenize",i),o.stringify(r.util.encode(i.tokens),i.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}var o=new s;return l(o,o.head,e),a(e,o,t,o.head,0),function(e){for(var t=[],n=e.head.next;n!==e.tail;)t.push(n.value),n=n.next;return t}(o)},hooks:{all:{},add:function(e,t){var n=r.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=r.hooks.all[e];if(n&&n.length)for(var o,i=0;o=n[i++];)o(t)}},Token:o};function o(e,t,n,r){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length}function i(e,t,n,r){e.lastIndex=t;var o=e.exec(n);if(o&&r&&o[1]){var i=o[1].length;o.index+=i,o[0]=o[0].slice(i)}return o}function a(e,t,n,s,u,p){for(var d in n)if(n.hasOwnProperty(d)&&n[d]){var f=n[d];f=Array.isArray(f)?f:[f];for(var m=0;m<f.length;++m){if(p&&p.cause==d+","+m)return;var h=f[m],v=h.inside,g=!!h.lookbehind,b=!!h.greedy,y=h.alias;if(b&&!h.pattern.global){var w=h.pattern.toString().match(/[imsuy]*$/)[0];h.pattern=RegExp(h.pattern.source,w+"g")}for(var x=h.pattern||h,k=s.next,_=u;k!==t.tail&&!(p&&_>=p.reach);_+=k.value.length,k=k.next){var S=k.value;if(t.length>e.length)return;if(!(S instanceof o)){var E,O=1;if(b){if(!(E=i(x,_,e,g))||E.index>=e.length)break;var j=E.index,P=E.index+E[0].length,C=_;for(C+=k.value.length;j>=C;)C+=(k=k.next).value.length;if(_=C-=k.value.length,k.value instanceof o)continue;for(var A=k;A!==t.tail&&(C<P||"string"==typeof A.value);A=A.next)O++,C+=A.value.length;O--,S=e.slice(_,C),E.index-=_}else if(!(E=i(x,0,S,g)))continue;j=E.index;var T=E[0],I=S.slice(0,j),N=S.slice(j+T.length),L=_+S.length;p&&L>p.reach&&(p.reach=L);var R=k.prev;if(I&&(R=l(t,R,I),_+=I.length),c(t,R,O),k=l(t,R,new o(d,v?r.tokenize(T,v):T,y,T)),N&&l(t,k,N),O>1){var D={cause:d+","+m,reach:L};a(e,t,n,k.prev,_,D),p&&D.reach>p.reach&&(p.reach=D.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function l(e,t,n){var r=t.next,o={value:n,prev:t,next:r};return t.next=o,r.prev=o,e.length++,o}function c(e,t,n){for(var r=t.next,o=0;o<n&&r!==e.tail;o++)r=r.next;t.next=r,r.prev=t,e.length-=o}return o.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var o="";return t.forEach(function(t){o+=e(t,n)}),o}var i={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},a=t.alias;a&&(Array.isArray(a)?Array.prototype.push.apply(i.classes,a):i.classes.push(a)),r.hooks.run("wrap",i);var s="";for(var l in i.attributes)s+=" "+l+'="'+(i.attributes[l]||"").replace(/"/g,""")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'"'+s+">"+i.content+"</"+i.tag+">"},r}();t.exports=n,n.default=n}},function(){return o||(0,r[g(r)[0]])((o={exports:{}}).exports,o),o.exports}),j=((e,t,n)=>(n=null!=e?d(y(e)):{},((e,t,n,r)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let o of g(t))w.call(e,o)||o===n||f(e,o,{get:()=>t[o],enumerable:!(r=h(t,o))||r.enumerable});return e})(!t&&e&&e.__esModule?n:f(n,"default",{value:e,enumerable:!0}),e)))(O());j.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},j.languages.markup.tag.inside["attr-value"].inside.entity=j.languages.markup.entity,j.languages.markup.doctype.inside["internal-subset"].inside=j.languages.markup,j.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),Object.defineProperty(j.languages.markup.tag,"addInlined",{value:function(e,t){var n;(t=((n=((n={})["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:j.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i,{"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}}))["language-"+t]={pattern:/[\s\S]+/,inside:j.languages[t]},{}))[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,function(){return e}),"i"),lookbehind:!0,greedy:!0,inside:n},j.languages.insertBefore("markup","cdata",t)}}),Object.defineProperty(j.languages.markup.tag,"addAttribute",{value:function(e,t){j.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:j.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),j.languages.html=j.languages.markup,j.languages.mathml=j.languages.markup,j.languages.svg=j.languages.markup,j.languages.xml=j.languages.extend("markup",{}),j.languages.ssml=j.languages.xml,j.languages.atom=j.languages.xml,j.languages.rss=j.languages.xml,i=j,a={pattern:/\\[\\(){}[\]^$+*?|.]/,alias:"escape"},l="(?:[^\\\\-]|"+(s=/\\(?:x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]+\}|0[0-7]{0,2}|[123][0-7]{2}|c[a-zA-Z]|.)/).source+")",l=RegExp(l+"-"+l),c={pattern:/(<|')[^<>']+(?=[>']$)/,lookbehind:!0,alias:"variable"},i.languages.regex={"char-class":{pattern:/((?:^|[^\\])(?:\\\\)*)\[(?:[^\\\]]|\\[\s\S])*\]/,lookbehind:!0,inside:{"char-class-negation":{pattern:/(^\[)\^/,lookbehind:!0,alias:"operator"},"char-class-punctuation":{pattern:/^\[|\]$/,alias:"punctuation"},range:{pattern:l,inside:{escape:s,"range-punctuation":{pattern:/-/,alias:"operator"}}},"special-escape":a,"char-set":{pattern:/\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},escape:s}},"special-escape":a,"char-set":{pattern:/\.|\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},backreference:[{pattern:/\\(?![123][0-7]{2})[1-9]/,alias:"keyword"},{pattern:/\\k<[^<>']+>/,alias:"keyword",inside:{"group-name":c}}],anchor:{pattern:/[$^]|\\[ABbGZz]/,alias:"function"},escape:s,group:[{pattern:/\((?:\?(?:<[^<>']+>|'[^<>']+'|[>:]|<?[=!]|[idmnsuxU]+(?:-[idmnsuxU]+)?:?))?/,alias:"punctuation",inside:{"group-name":c}},{pattern:/\)/,alias:"punctuation"}],quantifier:{pattern:/(?:[+*?]|\{\d+(?:,\d*)?\})[?+]?/,alias:"number"},alternation:{pattern:/\|/,alias:"keyword"}},j.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},j.languages.javascript=j.languages.extend("clike",{"class-name":[j.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),j.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,j.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:j.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:j.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:j.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:j.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:j.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),j.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:j.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),j.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),j.languages.markup&&(j.languages.markup.tag.addInlined("script","javascript"),j.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),j.languages.js=j.languages.javascript,j.languages.actionscript=j.languages.extend("javascript",{keyword:/\b(?:as|break|case|catch|class|const|default|delete|do|dynamic|each|else|extends|final|finally|for|function|get|if|implements|import|in|include|instanceof|interface|internal|is|namespace|native|new|null|override|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|use|var|void|while|with)\b/,operator:/\+\+|--|(?:[+\-*\/%^]|&&?|\|\|?|<<?|>>?>?|[!=]=?)=?|[~?@]/}),j.languages.actionscript["class-name"].alias="function",delete j.languages.actionscript.parameter,delete j.languages.actionscript["literal-property"],j.languages.markup&&j.languages.insertBefore("actionscript","string",{xml:{pattern:/(^|[^.])<\/?\w+(?:\s+[^\s>\/=]+=("|')(?:\\[\s\S]|(?!\2)[^\\])*\2)*\s*\/?>/,lookbehind:!0,inside:j.languages.markup}}),function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(j),function(e){var t=e.languages.javadoclike={parameter:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*@(?:arg|arguments|param)\s+)\w+/m,lookbehind:!0},keyword:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*|\{)@[a-z][a-zA-Z-]+\b/m,lookbehind:!0},punctuation:/[{}]/};Object.defineProperty(t,"addSupport",{value:function(t,n){(t="string"==typeof t?[t]:t).forEach(function(t){var r=function(e){e.inside||(e.inside={}),e.inside.rest=n},o="doc-comment";if(i=e.languages[t]){var i,a=i[o];if((a=a||(i=e.languages.insertBefore(t,"comment",{"doc-comment":{pattern:/(^|[^\\])\/\*\*[^/][\s\S]*?(?:\*\/|$)/,lookbehind:!0,alias:"comment"}}))[o])instanceof RegExp&&(a=i[o]={pattern:a}),Array.isArray(a))for(var s=0,l=a.length;s<l;s++)a[s]instanceof RegExp&&(a[s]={pattern:a[s]}),r(a[s]);else r(a)}})}}),t.addSupport(["java","javascript","php"],t)}(j),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;(t=(e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+t.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css,e.languages.markup))&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(j),function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,n=(t=(e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+t.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[t,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}}),{pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0}),{pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0});e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|RebeccaPurple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,number:n})}(j),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",o=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source}),i=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function a(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<<prop>>/g,function(){return r}).replace(/<<value>>/g,function(){return e});return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,function(){return r})),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,function(){return r}).replace(/<<key>>/g,function(){return"(?:"+o+"|"+i+")"})),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:a(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:a(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:a(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:a(i),lookbehind:!0,greedy:!0},number:{pattern:a(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(j),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(/<inner>/g,function(){return t}),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,o=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,function(){return r}),i=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source,a=(e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+o+i+"(?:"+o+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+o+i+")(?:"+o+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+o+")"+i+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+o+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~)<inner>)+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach(function(t){["url","bold","italic","strike","code-snippet"].forEach(function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])})}),e.hooks.add("after-tokenize",function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n<r;n++){var o,i=t[n];"code"!==i.type?e(i.content):(o=i.content[1],i=i.content[3],o&&i&&"code-language"===o.type&&"code-block"===i.type&&"string"==typeof o.content&&(o=o.content.replace(/\b#/g,"sharp").replace(/\b\+\+/g,"pp"),o="language-"+(o=(/[a-z][\w-]*/i.exec(o)||[""])[0].toLowerCase()),i.alias?"string"==typeof i.alias?i.alias=[i.alias,o]:i.alias.push(o):i.alias=[o]))}}(e.tokens)}),e.hooks.add("wrap",function(t){if("code-block"===t.type){for(var n="",r=0,o=t.classes.length;r<o;r++){var i=t.classes[r];if(i=/language-(.+)/.exec(i)){n=i[1];break}}var c,u=e.languages[n];u?t.content=e.highlight(t.content.replace(a,"").replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,function(e,t){var n;return"#"===(t=t.toLowerCase())[0]?(n="x"===t[1]?parseInt(t.slice(2),16):Number(t.slice(1)),l(n)):s[t]||e}),u,n):n&&"none"!==n&&e.plugins.autoloader&&(c="md-"+(new Date).valueOf()+"-"+Math.floor(1e16*Math.random()),t.attributes.id=c,e.plugins.autoloader.loadLanguages(n,function(){var t=document.getElementById(c);t&&(t.innerHTML=e.highlight(t.textContent,e.languages[n],n))}))}}),RegExp(e.languages.markup.tag.pattern.source,"gi")),s={amp:"&",lt:"<",gt:">",quot:'"'},l=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(j),j.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:j.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},j.hooks.add("after-tokenize",function(e){if("graphql"===e.language)for(var t=e.tokens.filter(function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type}),n=0;n<t.length;){var r=t[n++];if("keyword"===r.type&&"mutation"===r.content){var o=[];if(p(["definition-mutation","punctuation"])&&"("===u(1).content){n+=2;var i=d(/^\($/,/^\)$/);if(-1===i)continue;for(;n<i;n++){var a=u(0);"variable"===a.type&&(f(a,"variable-input"),o.push(a.content))}n=i+1}if(p(["punctuation","property-query"])&&"{"===u(0).content&&(n++,f(u(0),"property-mutation"),0<o.length)){var s=d(/^\{$/,/^\}$/);if(-1!==s)for(var l=n;l<s;l++){var c=t[l];"variable"===c.type&&0<=o.indexOf(c.content)&&f(c,"variable-input")}}}}function u(e){return t[n+e]}function p(e,t){t=t||0;for(var n=0;n<e.length;n++){var r=u(n+t);if(!r||r.type!==e[n])return}return 1}function d(e,r){for(var o=1,i=n;i<t.length;i++){var a=t[i],s=a.content;if("punctuation"===a.type&&"string"==typeof s)if(e.test(s))o++;else if(r.test(s)&&0===--o)return i}return-1}function f(e,t){var n=e.alias;n?Array.isArray(n)||(e.alias=n=[n]):e.alias=n=[],n.push(t)}}),j.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,o=r.inside["interpolation-punctuation"],i=r.pattern.source;function a(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function s(t,n,r){return t={code:t,grammar:n,language:r},e.hooks.run("before-tokenize",t),t.tokens=e.tokenize(t.code,t.grammar),e.hooks.run("after-tokenize",t),t.tokens}function l(t,n,a){var l=e.tokenize(t,{interpolation:{pattern:RegExp(i),lookbehind:!0}}),c=0,u={},p=(l=s(l.map(function(e){if("string"==typeof e)return e;var n,r;for(e=e.content;-1!==t.indexOf((r=c++,n="___"+a.toUpperCase()+"_"+r+"___")););return u[n]=e,n}).join(""),n,a),Object.keys(u));return c=0,function t(n){for(var i=0;i<n.length;i++){if(c>=p.length)return;var a,l,d,f,m,h,v,g=n[i];"string"==typeof g||"string"==typeof g.content?(a=p[c],-1!==(v=(h="string"==typeof g?g:g.content).indexOf(a))&&(++c,l=h.substring(0,v),m=u[a],d=void 0,(f={})["interpolation-punctuation"]=o,3===(f=e.tokenize(m,f)).length&&((d=[1,1]).push.apply(d,s(f[1],e.languages.javascript,"javascript")),f.splice.apply(f,d)),d=new e.Token("interpolation",f,r.alias,m),f=h.substring(v+a.length),m=[],l&&m.push(l),m.push(d),f&&(t(h=[f]),m.push.apply(m,h)),"string"==typeof g?(n.splice.apply(n,[i,1].concat(m)),i+=m.length-1):g.content=m)):(v=g.content,Array.isArray(v)?t(v):t([v]))}}(l),new e.Token(a,l,"language-"+a,t)}e.languages.javascript["template-string"]=[a("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),a("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),a("svg",/\bsvg/.source),a("markdown",/\b(?:markdown|md)/.source),a("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),a("sql",/\bsql/.source),t].filter(Boolean);var c={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function u(e){return"string"==typeof e?e:Array.isArray(e)?e.map(u).join(""):u(e.content)}e.hooks.add("after-tokenize",function(t){t.language in c&&function t(n){for(var r=0,o=n.length;r<o;r++){var i,a,s,c=n[r];"string"!=typeof c&&(i=c.content,Array.isArray(i)?"template-string"===c.type?(c=i[1],3===i.length&&"string"!=typeof c&&"embedded-code"===c.type&&(a=u(c),c=c.alias,c=Array.isArray(c)?c[0]:c,s=e.languages[c])&&(i[1]=l(a,s,c))):t(i):"string"!=typeof i&&t([i]))}}(t.tokens)})}(j),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(j),function(e){var t=e.languages.javascript,n=/\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})+\}/.source,r="(@(?:arg|argument|param|property)\\s+(?:"+n+"\\s+)?)";e.languages.jsdoc=e.languages.extend("javadoclike",{parameter:{pattern:RegExp(r+/(?:(?!\s)[$\w\xA0-\uFFFF.])+(?=\s|$)/.source),lookbehind:!0,inside:{punctuation:/\./}}}),e.languages.insertBefore("jsdoc","keyword",{"optional-parameter":{pattern:RegExp(r+/\[(?:(?!\s)[$\w\xA0-\uFFFF.])+(?:=[^[\]]+)?\](?=\s|$)/.source),lookbehind:!0,inside:{parameter:{pattern:/(^\[)[$\w\xA0-\uFFFF\.]+/,lookbehind:!0,inside:{punctuation:/\./}},code:{pattern:/(=)[\s\S]*(?=\]$)/,lookbehind:!0,inside:t,alias:"language-javascript"},punctuation:/[=[\]]/}},"class-name":[{pattern:RegExp(/(@(?:augments|class|extends|interface|memberof!?|template|this|typedef)\s+(?:<TYPE>\s+)?)[A-Z]\w*(?:\.[A-Z]\w*)*/.source.replace(/<TYPE>/g,function(){return n})),lookbehind:!0,inside:{punctuation:/\./}},{pattern:RegExp("(@[a-z]+\\s+)"+n),lookbehind:!0,inside:{string:t.string,number:t.number,boolean:t.boolean,keyword:e.languages.typescript.keyword,operator:/=>|\.\.\.|[&|?:*]/,punctuation:/[.,;=<>{}()[\]]/}}],example:{pattern:/(@example\s+(?!\s))(?:[^@\s]|\s+(?!\s))+?(?=\s*(?:\*\s*)?(?:@\w|\*\/))/,lookbehind:!0,inside:{code:{pattern:/^([\t ]*(?:\*\s*)?)\S.*$/m,lookbehind:!0,inside:t,alias:"language-javascript"}}}}),e.languages.javadoclike.addSupport("javascript",e.languages.jsdoc)}(j),function(e){e.languages.flow=e.languages.extend("javascript",{}),e.languages.insertBefore("flow","keyword",{type:[{pattern:/\b(?:[Bb]oolean|Function|[Nn]umber|[Ss]tring|[Ss]ymbol|any|mixed|null|void)\b/,alias:"class-name"}]}),e.languages.flow["function-variable"].pattern=/(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=\s*(?:function\b|(?:\([^()]*\)(?:\s*:\s*\w+)?|(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/i,delete e.languages.flow.parameter,e.languages.insertBefore("flow","operator",{"flow-punctuation":{pattern:/\{\||\|\}/,alias:"punctuation"}}),Array.isArray(e.languages.flow.keyword)||(e.languages.flow.keyword=[e.languages.flow.keyword]),e.languages.flow.keyword.unshift({pattern:/(^|[^$]\b)(?:Class|declare|opaque|type)\b(?!\$)/,lookbehind:!0},{pattern:/(^|[^$]\B)\$(?:Diff|Enum|Exact|Keys|ObjMap|PropertyType|Record|Shape|Subtype|Supertype|await)\b(?!\$)/,lookbehind:!0})}(j),j.languages.n4js=j.languages.extend("javascript",{keyword:/\b(?:Array|any|boolean|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|module|new|null|number|package|private|protected|public|return|set|static|string|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/}),j.languages.insertBefore("n4js","constant",{annotation:{pattern:/@+\w+/,alias:"operator"}}),j.languages.n4jsd=j.languages.n4js,function(e){function t(e,t){return RegExp(e.replace(/<ID>/g,function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source}),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:<ID>(?:\s*,\s*(?:\*\s*as\s+<ID>|\{[^{}]*\}))?|\*\s*as\s+<ID>|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+<ID>)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?<ID>/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r<n.length;r++){var o=n[r],i=e.languages.javascript[o];o=(i="RegExp"===e.util.type(i)?e.languages.javascript[o]={pattern:i}:i).inside||{};(i.inside=o)["maybe-class-name"]=/^[A-Z][\s\S]*/}}(j),function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,r=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,o=/(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;function i(e,t){return e=e.replace(/<S>/g,function(){return n}).replace(/<BRACES>/g,function(){return r}).replace(/<SPREAD>/g,function(){return o}),RegExp(e,t)}function a(t){for(var n=[],r=0;r<t.length;r++){var o=t[r],i=!1;"string"!=typeof o&&("tag"===o.type&&o.content[0]&&"tag"===o.content[0].type?"</"===o.content[0].content[0].content?0<n.length&&n[n.length-1].tagName===s(o.content[0].content[1])&&n.pop():"/>"!==o.content[o.content.length-1].content&&n.push({tagName:s(o.content[0].content[1]),openedBraces:0}):0<n.length&&"punctuation"===o.type&&"{"===o.content?n[n.length-1].openedBraces++:0<n.length&&0<n[n.length-1].openedBraces&&"punctuation"===o.type&&"}"===o.content?n[n.length-1].openedBraces--:i=!0),(i||"string"==typeof o)&&0<n.length&&0===n[n.length-1].openedBraces&&(i=s(o),r<t.length-1&&("string"==typeof t[r+1]||"plain-text"===t[r+1].type)&&(i+=s(t[r+1]),t.splice(r+1,1)),0<r&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(i=s(t[r-1])+i,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",i,null,i)),o.content&&"string"!=typeof o.content&&a(o.content)}}o=i(o).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=i(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:i(/<SPREAD>/.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:i(/=<BRACES>/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var s=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(s).join(""):""};e.hooks.add("after-tokenize",function(e){"jsx"!==e.language&&"tsx"!==e.language||a(e.tokens)})}(j),function(e){var t=e.util.clone(e.languages.typescript);(t=(e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"],e.languages.tsx.tag)).pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+t.pattern.source+")",t.pattern.flags),t.lookbehind=!0}(j),j.languages.swift={comment:{pattern:/(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/,lookbehind:!0,greedy:!0},"string-literal":[{pattern:RegExp(/(^|[^"#])/.source+"(?:"+/"(?:\\(?:\((?:[^()]|\([^()]*\))*\)|\r\n|[^(])|[^\\\r\n"])*"/.source+"|"+/"""(?:\\(?:\((?:[^()]|\([^()]*\))*\)|[^(])|[^\\"]|"(?!""))*"""/.source+")"+/(?!["#])/.source),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\\($/,alias:"punctuation"},punctuation:/\\(?=[\r\n])/,string:/[\s\S]+/}},{pattern:RegExp(/(^|[^"#])(#+)/.source+"(?:"+/"(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|\r\n|[^#])|[^\\\r\n])*?"/.source+"|"+/"""(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|[^#])|[^\\])*?"""/.source+")\\2"),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\#+\($/,alias:"punctuation"},string:/[\s\S]+/}}],directive:{pattern:RegExp(/#/.source+"(?:"+/(?:elseif|if)\b/.source+"(?:[ \t]*"+/(?:![ \t]*)?(?:\b\w+\b(?:[ \t]*\((?:[^()]|\([^()]*\))*\))?|\((?:[^()]|\([^()]*\))*\))(?:[ \t]*(?:&&|\|\|))?/.source+")+|"+/(?:else|endif)\b/.source+")"),alias:"property",inside:{"directive-name":/^#\w+/,boolean:/\b(?:false|true)\b/,number:/\b\d+(?:\.\d+)*\b/,operator:/!|&&|\|\||[<>]=?/,punctuation:/[(),]/}},literal:{pattern:/#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/,alias:"constant"},"other-directive":{pattern:/#\w+\b/,alias:"property"},attribute:{pattern:/@\w+/,alias:"atrule"},"function-definition":{pattern:/(\bfunc\s+)\w+/,lookbehind:!0,alias:"function"},label:{pattern:/\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/,lookbehind:!0,alias:"important"},keyword:/\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|isolated|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/,boolean:/\b(?:false|true)\b/,nil:{pattern:/\bnil\b/,alias:"constant"},"short-argument":/\$\d+\b/,omit:{pattern:/\b_\b/,alias:"keyword"},number:/\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,"class-name":/\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/,function:/\b[a-z_]\w*(?=\s*\()/i,constant:/\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,operator:/[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/,punctuation:/[{}[\]();,.:\\]/},j.languages.swift["string-literal"].forEach(function(e){e.inside.interpolation.inside=j.languages.swift}),function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"];var t={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:e.languages.kotlin}};e.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:t},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:t},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete e.languages.kotlin.string,e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(j),j.languages.c=j.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),j.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),j.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},j.languages.c.string],char:j.languages.c.char,comment:j.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:j.languages.c}}}}),j.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete j.languages.c.boolean,j.languages.objectivec=j.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete j.languages.objectivec["class-name"],j.languages.objc=j.languages.objectivec,j.languages.reason=j.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),j.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete j.languages.reason.function,function(e){for(var t=/\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|<self>)*\*\//.source,n=0;n<2;n++)t=t.replace(/<self>/g,function(){return t});t=t.replace(/<self>/g,function(){return/[^\s\S]/.source}),e.languages.rust={comment:[{pattern:RegExp(/(^|[^\\])/.source+t),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(j),j.languages.go=j.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),j.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete j.languages.go["class-name"],function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g,function(){return t.source});e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source.replace(/<keyword>/g,function(){return t.source})),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g,function(){return n})+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(j),j.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},j.languages.python["string-interpolation"].inside.interpolation.inside.rest=j.languages.python,j.languages.py=j.languages.python,j.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},j.languages.webmanifest=j.languages.json;((e,t)=>{for(var n in t)f(e,n,{get:t[n],enumerable:!0})})({},{dracula:()=>P,duotoneDark:()=>C,duotoneLight:()=>A,github:()=>T,gruvboxMaterialDark:()=>G,gruvboxMaterialLight:()=>K,jettwaveDark:()=>Q,jettwaveLight:()=>H,nightOwl:()=>I,nightOwlLight:()=>N,oceanicNext:()=>D,okaidia:()=>F,oneDark:()=>W,oneLight:()=>q,palenight:()=>M,shadesOfPurple:()=>B,synthwave84:()=>z,ultramin:()=>$,vsDark:()=>U,vsLight:()=>V});var P={plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},C={plain:{backgroundColor:"#2a2734",color:"#9a86fd"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#6c6783"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#e09142"}},{types:["property","function"],style:{color:"#9a86fd"}},{types:["tag-id","selector","atrule-id"],style:{color:"#eeebff"}},{types:["attr-name"],style:{color:"#c4b9fe"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule","placeholder","variable"],style:{color:"#ffcc99"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#c4b9fe"}}]},A={plain:{backgroundColor:"#faf8f5",color:"#728fcb"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#b6ad9a"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#063289"}},{types:["property","function"],style:{color:"#b29762"}},{types:["tag-id","selector","atrule-id"],style:{color:"#2d2006"}},{types:["attr-name"],style:{color:"#896724"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule"],style:{color:"#728fcb"}},{types:["placeholder","variable"],style:{color:"#93abdc"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#896724"}}]},T={plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},I={plain:{color:"#d6deeb",backgroundColor:"#011627"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(99, 119, 119)",fontStyle:"italic"}},{types:["string","url"],style:{color:"rgb(173, 219, 103)"}},{types:["variable"],style:{color:"rgb(214, 222, 235)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation"],style:{color:"rgb(199, 146, 234)"}},{types:["selector","doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(255, 203, 139)"}},{types:["tag","operator","keyword"],style:{color:"rgb(127, 219, 202)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["property"],style:{color:"rgb(128, 203, 196)"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}}]},N={plain:{color:"#403f53",backgroundColor:"#FBFBFB"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(72, 118, 214)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(152, 159, 177)",fontStyle:"italic"}},{types:["string","builtin","char","constant","url"],style:{color:"rgb(72, 118, 214)"}},{types:["variable"],style:{color:"rgb(201, 103, 101)"}},{types:["number"],style:{color:"rgb(170, 9, 130)"}},{types:["punctuation"],style:{color:"rgb(153, 76, 195)"}},{types:["function","selector","doctype"],style:{color:"rgb(153, 76, 195)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(17, 17, 17)"}},{types:["tag"],style:{color:"rgb(153, 76, 195)"}},{types:["operator","property","keyword","namespace"],style:{color:"rgb(12, 150, 155)"}},{types:["boolean"],style:{color:"rgb(188, 84, 84)"}}]},L="#c5a5c5",R="#8dc891",D={plain:{backgroundColor:"#282c34",color:"#ffffff"},styles:[{types:["attr-name"],style:{color:L}},{types:["attr-value"],style:{color:R}},{types:["comment","block-comment","prolog","doctype","cdata","shebang"],style:{color:"#999999"}},{types:["property","number","function-name","constant","symbol","deleted"],style:{color:"#5a9bcf"}},{types:["boolean"],style:{color:"#ff8b50"}},{types:["tag"],style:{color:"#fc929e"}},{types:["string"],style:{color:R}},{types:["punctuation"],style:{color:R}},{types:["selector","char","builtin","inserted"],style:{color:"#D8DEE9"}},{types:["function"],style:{color:"#79b6f2"}},{types:["operator","entity","url","variable"],style:{color:"#d7deea"}},{types:["keyword"],style:{color:L}},{types:["atrule","class-name"],style:{color:"#FAC863"}},{types:["important"],style:{fontWeight:"400"}},{types:["bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}}]},F={plain:{color:"#f8f8f2",backgroundColor:"#272822"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"#f92672",fontStyle:"italic"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"#8292a2",fontStyle:"italic"}},{types:["string","url"],style:{color:"#a6e22e"}},{types:["variable"],style:{color:"#f8f8f2"}},{types:["number"],style:{color:"#ae81ff"}},{types:["builtin","char","constant","function","class-name"],style:{color:"#e6db74"}},{types:["punctuation"],style:{color:"#f8f8f2"}},{types:["selector","doctype"],style:{color:"#a6e22e",fontStyle:"italic"}},{types:["tag","operator","keyword"],style:{color:"#66d9ef"}},{types:["boolean"],style:{color:"#ae81ff"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)",opacity:.7}},{types:["tag","property"],style:{color:"#f92672"}},{types:["attr-name"],style:{color:"#a6e22e !important"}},{types:["doctype"],style:{color:"#8292a2"}},{types:["rule"],style:{color:"#e6db74"}}]},M={plain:{color:"#bfc7d5",backgroundColor:"#292d3e"},styles:[{types:["comment"],style:{color:"rgb(105, 112, 152)",fontStyle:"italic"}},{types:["string","inserted"],style:{color:"rgb(195, 232, 141)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation","selector"],style:{color:"rgb(199, 146, 234)"}},{types:["variable"],style:{color:"rgb(191, 199, 213)"}},{types:["class-name","attr-name"],style:{color:"rgb(255, 203, 107)"}},{types:["tag","deleted"],style:{color:"rgb(255, 85, 114)"}},{types:["operator"],style:{color:"rgb(137, 221, 255)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["keyword"],style:{fontStyle:"italic"}},{types:["doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}},{types:["url"],style:{color:"rgb(221, 221, 221)"}}]},B={plain:{color:"#9EFEFF",backgroundColor:"#2D2A55"},styles:[{types:["changed"],style:{color:"rgb(255, 238, 128)"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)"}},{types:["comment"],style:{color:"rgb(179, 98, 255)",fontStyle:"italic"}},{types:["punctuation"],style:{color:"rgb(255, 255, 255)"}},{types:["constant"],style:{color:"rgb(255, 98, 140)"}},{types:["string","url"],style:{color:"rgb(165, 255, 144)"}},{types:["variable"],style:{color:"rgb(255, 238, 128)"}},{types:["number","boolean"],style:{color:"rgb(255, 98, 140)"}},{types:["attr-name"],style:{color:"rgb(255, 180, 84)"}},{types:["keyword","operator","property","namespace","tag","selector","doctype"],style:{color:"rgb(255, 157, 0)"}},{types:["builtin","char","constant","function","class-name"],style:{color:"rgb(250, 208, 0)"}}]},z={plain:{backgroundColor:"linear-gradient(to bottom, #2a2139 75%, #34294f)",backgroundImage:"#34294f",color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"},styles:[{types:["comment","block-comment","prolog","doctype","cdata"],style:{color:"#495495",fontStyle:"italic"}},{types:["punctuation"],style:{color:"#ccc"}},{types:["tag","attr-name","namespace","number","unit","hexcode","deleted"],style:{color:"#e2777a"}},{types:["property","selector"],style:{color:"#72f1b8",textShadow:"0 0 2px #100c0f, 0 0 10px #257c5575, 0 0 35px #21272475"}},{types:["function-name"],style:{color:"#6196cc"}},{types:["boolean","selector-id","function"],style:{color:"#fdfdfd",textShadow:"0 0 2px #001716, 0 0 3px #03edf975, 0 0 5px #03edf975, 0 0 8px #03edf975"}},{types:["class-name","maybe-class-name","builtin"],style:{color:"#fff5f6",textShadow:"0 0 2px #000, 0 0 10px #fc1f2c75, 0 0 5px #fc1f2c75, 0 0 25px #fc1f2c75"}},{types:["constant","symbol"],style:{color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"}},{types:["important","atrule","keyword","selector-class"],style:{color:"#f4eee4",textShadow:"0 0 2px #393a33, 0 0 8px #f39f0575, 0 0 2px #f39f0575"}},{types:["string","char","attr-value","regex","variable"],style:{color:"#f87c32"}},{types:["parameter"],style:{fontStyle:"italic"}},{types:["entity","url"],style:{color:"#67cdcc"}},{types:["operator"],style:{color:"ffffffee"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["entity"],style:{cursor:"help"}},{types:["inserted"],style:{color:"green"}}]},$={plain:{color:"#282a2e",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(197, 200, 198)"}},{types:["string","number","builtin","variable"],style:{color:"rgb(150, 152, 150)"}},{types:["class-name","function","tag","attr-name"],style:{color:"rgb(40, 42, 46)"}}]},U={plain:{color:"#9CDCFE",backgroundColor:"#1E1E1E"},styles:[{types:["prolog"],style:{color:"rgb(0, 0, 128)"}},{types:["comment"],style:{color:"rgb(106, 153, 85)"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"rgb(86, 156, 214)"}},{types:["number","inserted"],style:{color:"rgb(181, 206, 168)"}},{types:["constant"],style:{color:"rgb(100, 102, 149)"}},{types:["attr-name","variable"],style:{color:"rgb(156, 220, 254)"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"rgb(206, 145, 120)"}},{types:["selector"],style:{color:"rgb(215, 186, 125)"}},{types:["tag"],style:{color:"rgb(78, 201, 176)"}},{types:["tag"],languages:["markup"],style:{color:"rgb(86, 156, 214)"}},{types:["punctuation","operator"],style:{color:"rgb(212, 212, 212)"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"rgb(220, 220, 170)"}},{types:["class-name"],style:{color:"rgb(78, 201, 176)"}},{types:["char"],style:{color:"rgb(209, 105, 105)"}}]},V={plain:{color:"#000000",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(0, 128, 0)"}},{types:["builtin"],style:{color:"rgb(0, 112, 193)"}},{types:["number","variable","inserted"],style:{color:"rgb(9, 134, 88)"}},{types:["operator"],style:{color:"rgb(0, 0, 0)"}},{types:["constant","char"],style:{color:"rgb(129, 31, 63)"}},{types:["tag"],style:{color:"rgb(128, 0, 0)"}},{types:["attr-name"],style:{color:"rgb(255, 0, 0)"}},{types:["deleted","string"],style:{color:"rgb(163, 21, 21)"}},{types:["changed","punctuation"],style:{color:"rgb(4, 81, 165)"}},{types:["function","keyword"],style:{color:"rgb(0, 0, 255)"}},{types:["class-name"],style:{color:"rgb(38, 127, 153)"}}]},Q={plain:{color:"#f8fafc",backgroundColor:"#011627"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#569CD6"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#f8fafc"}},{types:["attr-name","variable"],style:{color:"#9CDCFE"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#cbd5e1"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#D4D4D4"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#7dd3fc"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},H={plain:{color:"#0f172a",backgroundColor:"#f1f5f9"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#0c4a6e"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#0f172a"}},{types:["attr-name","variable"],style:{color:"#0c4a6e"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#64748b"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#475569"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#0e7490"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},W={plain:{backgroundColor:"hsl(220, 13%, 18%)",color:"hsl(220, 14%, 71%)",textShadow:"0 1px rgba(0, 0, 0, 0.3)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(220, 10%, 40%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(220, 14%, 71%)"}},{types:["attr-name","class-name","maybe-class-name","boolean","constant","number","atrule"],style:{color:"hsl(29, 54%, 61%)"}},{types:["keyword"],style:{color:"hsl(286, 60%, 67%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(355, 65%, 65%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value"],style:{color:"hsl(95, 38%, 62%)"}},{types:["variable","operator","function"],style:{color:"hsl(207, 82%, 66%)"}},{types:["url"],style:{color:"hsl(187, 47%, 55%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(220, 14%, 71%)"}}]},q={plain:{backgroundColor:"hsl(230, 1%, 98%)",color:"hsl(230, 8%, 24%)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(230, 4%, 64%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(230, 8%, 24%)"}},{types:["attr-name","class-name","boolean","constant","number","atrule"],style:{color:"hsl(35, 99%, 36%)"}},{types:["keyword"],style:{color:"hsl(301, 63%, 40%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(5, 74%, 59%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value","punctuation"],style:{color:"hsl(119, 34%, 47%)"}},{types:["variable","operator","function"],style:{color:"hsl(221, 87%, 60%)"}},{types:["url"],style:{color:"hsl(198, 99%, 37%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(230, 8%, 24%)"}}]},G={plain:{color:"#ebdbb2",backgroundColor:"#292828"},styles:[{types:["imports","class-name","maybe-class-name","constant","doctype","builtin","function"],style:{color:"#d8a657"}},{types:["property-access"],style:{color:"#7daea3"}},{types:["tag"],style:{color:"#e78a4e"}},{types:["attr-name","char","url","regex"],style:{color:"#a9b665"}},{types:["attr-value","string"],style:{color:"#89b482"}},{types:["comment","prolog","cdata","operator","inserted"],style:{color:"#a89984"}},{types:["delimiter","boolean","keyword","selector","important","atrule","property","variable","deleted"],style:{color:"#ea6962"}},{types:["entity","number","symbol"],style:{color:"#d3869b"}}]},K={plain:{color:"#654735",backgroundColor:"#f9f5d7"},styles:[{types:["delimiter","boolean","keyword","selector","important","atrule","property","variable","deleted"],style:{color:"#af2528"}},{types:["imports","class-name","maybe-class-name","constant","doctype","builtin"],style:{color:"#b4730e"}},{types:["string","attr-value"],style:{color:"#477a5b"}},{types:["property-access"],style:{color:"#266b79"}},{types:["function","attr-name","char","url"],style:{color:"#72761e"}},{types:["tag"],style:{color:"#b94c07"}},{types:["comment","prolog","cdata","operator","inserted"],style:{color:"#a89984"}},{types:["entity","number","symbol"],style:{color:"#924f79"}}]},Y=/\r\n|\r|\n/,Z=e=>{0===e.length?e.push({types:["plain"],content:"\n",empty:!0}):1===e.length&&""===e[0].content&&(e[0].content="\n",e[0].empty=!0)},J=(e,t)=>{const n=e.length;return n>0&&e[n-1]===t?e:e.concat(t)},X=e=>{const t=[[]],n=[e],r=[0],o=[e.length];let i=0,a=0,s=[];const l=[s];for(;a>-1;){for(;(i=r[a]++)<o[a];){let e,c=t[a];const u=n[a][i];if("string"==typeof u?(c=a>0?c:["plain"],e=u):(c=J(c,u.type),u.alias&&(c=J(c,u.alias)),e=u.content),"string"!=typeof e){a++,t.push(c),n.push(e),r.push(0),o.push(e.length);continue}const p=e.split(Y),d=p.length;s.push({types:c,content:p[0]});for(let t=1;t<d;t++)Z(s),l.push(s=[]),s.push({types:c,content:p[t]})}a--,t.pop(),n.pop(),r.pop(),o.pop()}return Z(s),l},ee=(e,t)=>{const{plain:n}=e,r=e.styles.reduce((e,n)=>{const{languages:r,style:o}=n;return r&&!r.includes(t)||n.types.forEach(t=>{const n=_(_({},e[t]),o);e[t]=n}),e},{});return r.root=n,r.plain=S(_({},n),{backgroundColor:void 0}),r},te=({children:e,language:t,code:n,theme:r,prism:o})=>{const i=t.toLowerCase(),a=ee(r,i),s=(e=>(0,u.useCallback)(t=>{var n=t,{className:r,style:o,line:i}=n,a=E(n,["className","style","line"]);const s=S(_({},a),{className:(0,p.A)("token-line",r)});return"object"==typeof e&&"plain"in e&&(s.style=e.plain),"object"==typeof o&&(s.style=_(_({},s.style||{}),o)),s},[e]))(a),l=(e=>{const t=(0,u.useCallback)(({types:t,empty:n})=>{if(null!=e)return 1===t.length&&"plain"===t[0]?null!=n?{display:"inline-block"}:void 0:1===t.length&&null!=n?e[t[0]]:Object.assign(null!=n?{display:"inline-block"}:{},...t.map(t=>e[t]))},[e]);return(0,u.useCallback)(e=>{var n=e,{token:r,className:o,style:i}=n,a=E(n,["token","className","style"]);const s=S(_({},a),{className:(0,p.A)("token",...r.types,o),children:r.content,style:t(r)});return null!=i&&(s.style=_(_({},s.style||{}),i)),s},[t])})(a),c=(({prism:e,code:t,grammar:n,language:r})=>(0,u.useMemo)(()=>{if(null==n)return X([t]);const o={code:t,grammar:n,language:r,tokens:[]};return e.hooks.run("before-tokenize",o),o.tokens=e.tokenize(t,n),e.hooks.run("after-tokenize",o),X(o.tokens)},[t,n,r,e]))({prism:o,language:i,code:n,grammar:o.languages[i]});return e({tokens:c,className:`prism-code language-${i}`,style:null!=a?a.root:{},getLineProps:s,getTokenProps:l})},ne=e=>(0,u.createElement)(te,S(_({},e),{prism:e.prism||j,theme:e.theme||U,code:e.code,language:e.language}))},73718:(e,t,n)=>{"use strict";n.d(t,{k:()=>i,v:()=>a});var r=n(19802),o=n(86457);function i(e,t){return`docs-${e}-${t}`}function a(){const e=(0,r.Gy)(),t=(0,r.gk)(),n=(0,o.XK)();return[...Object.keys(e).map(function(r){const o=t?.activePlugin.pluginId===r?t.activeVersion:void 0,a=n[r],s=e[r].versions.find(e=>e.isLast);return i(r,(o??a??s).name)})]}},74753:(e,t,n)=>{"use strict";var r=n(71765),o=n(4784);!function(e){const{themeConfig:{prism:t}}=o.A,{additionalLanguages:r}=t,i=globalThis.Prism;globalThis.Prism=e,r.forEach(e=>{"php"===e&&n(19700),n(23611)(`./prism-${e}`)}),delete globalThis.Prism,void 0!==i&&(globalThis.Prism=e)}(r.My)},74848:(e,t,n)=>{"use strict";e.exports=n(21020)},75729:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r=n(5947),o=n.n(r);o().configure({showSpinner:!1});const i={onRouteUpdate({location:e,previousLocation:t}){if(t&&e.pathname!==t.pathname){const e=window.setTimeout(()=>{o().start()},200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){o().done()}}},80260:(e,t,n)=>{"use strict";n.d(t,{Dt:()=>s,ys:()=>a});var r=n(96540),o=n(92413),i=n(97639);function a(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function s(){const{baseUrl:e}=(0,i.A)().siteConfig;return(0,r.useMemo)(()=>function({baseUrl:e,routes:t}){function n(t){return t.path===e&&!0===t.exact}function r(t){return t.path===e&&!t.exact}return function e(t){if(0===t.length)return;return t.find(n)||e(t.filter(r).flatMap(e=>e.routes??[]))}(t)}({routes:o.A,baseUrl:e}),[e])}},80545:(e,t,n)=>{"use strict";n.d(t,{mg:()=>X,vd:()=>H});var r=n(96540),o=n(5556),i=n.n(o),a=n(30115),s=n.n(a),l=n(20311),c=n.n(l),u=n(2833),p=n.n(u);function d(){return d=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},d.apply(this,arguments)}function f(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,m(e,t)}function m(e,t){return m=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},m(e,t)}function h(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)t.indexOf(n=i[r])>=0||(o[n]=e[n]);return o}var v={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},g={rel:["amphtml","canonical","alternate"]},b={type:["application/ld+json"]},y={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},w=Object.keys(v).map(function(e){return v[e]}),x={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},k=Object.keys(x).reduce(function(e,t){return e[x[t]]=t,e},{}),_=function(e,t){for(var n=e.length-1;n>=0;n-=1){var r=e[n];if(Object.prototype.hasOwnProperty.call(r,t))return r[t]}return null},S=function(e){var t=_(e,v.TITLE),n=_(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,function(){return t});var r=_(e,"defaultTitle");return t||r||void 0},E=function(e){return _(e,"onChangeClientState")||function(){}},O=function(e,t){return t.filter(function(t){return void 0!==t[e]}).map(function(t){return t[e]}).reduce(function(e,t){return d({},e,t)},{})},j=function(e,t){return t.filter(function(e){return void 0!==e[v.BASE]}).map(function(e){return e[v.BASE]}).reverse().reduce(function(t,n){if(!t.length)for(var r=Object.keys(n),o=0;o<r.length;o+=1){var i=r[o].toLowerCase();if(-1!==e.indexOf(i)&&n[i])return t.concat(n)}return t},[])},P=function(e,t,n){var r={};return n.filter(function(t){return!!Array.isArray(t[e])||(void 0!==t[e]&&console&&"function"==typeof console.warn&&console.warn("Helmet: "+e+' should be of type "Array". Instead found type "'+typeof t[e]+'"'),!1)}).map(function(t){return t[e]}).reverse().reduce(function(e,n){var o={};n.filter(function(e){for(var n,i=Object.keys(e),a=0;a<i.length;a+=1){var s=i[a],l=s.toLowerCase();-1===t.indexOf(l)||"rel"===n&&"canonical"===e[n].toLowerCase()||"rel"===l&&"stylesheet"===e[l].toLowerCase()||(n=l),-1===t.indexOf(s)||"innerHTML"!==s&&"cssText"!==s&&"itemprop"!==s||(n=s)}if(!n||!e[n])return!1;var c=e[n].toLowerCase();return r[n]||(r[n]={}),o[n]||(o[n]={}),!r[n][c]&&(o[n][c]=!0,!0)}).reverse().forEach(function(t){return e.push(t)});for(var i=Object.keys(o),a=0;a<i.length;a+=1){var s=i[a],l=d({},r[s],o[s]);r[s]=l}return e},[]).reverse()},C=function(e,t){if(Array.isArray(e)&&e.length)for(var n=0;n<e.length;n+=1)if(e[n][t])return!0;return!1},A=function(e){return Array.isArray(e)?e.join(""):e},T=function(e,t){return Array.isArray(e)?e.reduce(function(e,n){return function(e,t){for(var n=Object.keys(e),r=0;r<n.length;r+=1)if(t[n[r]]&&t[n[r]].includes(e[n[r]]))return!0;return!1}(n,t)?e.priority.push(n):e.default.push(n),e},{priority:[],default:[]}):{default:e}},I=function(e,t){var n;return d({},e,((n={})[t]=void 0,n))},N=[v.NOSCRIPT,v.SCRIPT,v.STYLE],L=function(e,t){return void 0===t&&(t=!0),!1===t?String(e):String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},R=function(e){return Object.keys(e).reduce(function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r},"")},D=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce(function(t,n){return t[x[n]||n]=e[n],t},t)},F=function(e,t){return t.map(function(t,n){var o,i=((o={key:n})["data-rh"]=!0,o);return Object.keys(t).forEach(function(e){var n=x[e]||e;"innerHTML"===n||"cssText"===n?i.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:i[n]=t[e]}),r.createElement(e,i)})},M=function(e,t,n){switch(e){case v.TITLE:return{toComponent:function(){return n=t.titleAttributes,(o={key:e=t.title})["data-rh"]=!0,i=D(n,o),[r.createElement(v.TITLE,i,e)];var e,n,o,i},toString:function(){return function(e,t,n,r){var o=R(n),i=A(t);return o?"<"+e+' data-rh="true" '+o+">"+L(i,r)+"</"+e+">":"<"+e+' data-rh="true">'+L(i,r)+"</"+e+">"}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return D(t)},toString:function(){return R(t)}};default:return{toComponent:function(){return F(e,t)},toString:function(){return function(e,t,n){return t.reduce(function(t,r){var o=Object.keys(r).filter(function(e){return!("innerHTML"===e||"cssText"===e)}).reduce(function(e,t){var o=void 0===r[t]?t:t+'="'+L(r[t],n)+'"';return e?e+" "+o:o},""),i=r.innerHTML||r.cssText||"",a=-1===N.indexOf(e);return t+"<"+e+' data-rh="true" '+o+(a?"/>":">"+i+"</"+e+">")},"")}(e,t,n)}}}},B=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,o=e.htmlAttributes,i=e.noscriptTags,a=e.styleTags,s=e.title,l=void 0===s?"":s,c=e.titleAttributes,u=e.linkTags,p=e.metaTags,d=e.scriptTags,f={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var m=function(e){var t=e.linkTags,n=e.scriptTags,r=e.encode,o=T(e.metaTags,y),i=T(t,g),a=T(n,b);return{priorityMethods:{toComponent:function(){return[].concat(F(v.META,o.priority),F(v.LINK,i.priority),F(v.SCRIPT,a.priority))},toString:function(){return M(v.META,o.priority,r)+" "+M(v.LINK,i.priority,r)+" "+M(v.SCRIPT,a.priority,r)}},metaTags:o.default,linkTags:i.default,scriptTags:a.default}}(e);f=m.priorityMethods,u=m.linkTags,p=m.metaTags,d=m.scriptTags}return{priority:f,base:M(v.BASE,t,r),bodyAttributes:M("bodyAttributes",n,r),htmlAttributes:M("htmlAttributes",o,r),link:M(v.LINK,u,r),meta:M(v.META,p,r),noscript:M(v.NOSCRIPT,i,r),script:M(v.SCRIPT,d,r),style:M(v.STYLE,a,r),title:M(v.TITLE,{title:l,titleAttributes:c},r)}},z=[],$=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?z:n.instances},add:function(e){(n.canUseDOM?z:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?z:n.instances).indexOf(e);(n.canUseDOM?z:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=B({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},U=r.createContext({}),V=i().shape({setHelmet:i().func,helmetInstances:i().shape({get:i().func,add:i().func,remove:i().func})}),Q="undefined"!=typeof document,H=function(e){function t(n){var r;return(r=e.call(this,n)||this).helmetData=new $(r.props.context,t.canUseDOM),r}return f(t,e),t.prototype.render=function(){return r.createElement(U.Provider,{value:this.helmetData.value},this.props.children)},t}(r.Component);H.canUseDOM=Q,H.propTypes={context:i().shape({helmet:i().shape()}),children:i().node.isRequired},H.defaultProps={context:{}},H.displayName="HelmetProvider";var W=function(e,t){var n,r=document.head||document.querySelector(v.HEAD),o=r.querySelectorAll(e+"[data-rh]"),i=[].slice.call(o),a=[];return t&&t.length&&t.forEach(function(t){var r=document.createElement(e);for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&("innerHTML"===o?r.innerHTML=t.innerHTML:"cssText"===o?r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText)):r.setAttribute(o,void 0===t[o]?"":t[o]));r.setAttribute("data-rh","true"),i.some(function(e,t){return n=t,r.isEqualNode(e)})?i.splice(n,1):a.push(r)}),i.forEach(function(e){return e.parentNode.removeChild(e)}),a.forEach(function(e){return r.appendChild(e)}),{oldTags:i,newTags:a}},q=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute("data-rh"),o=r?r.split(","):[],i=[].concat(o),a=Object.keys(t),s=0;s<a.length;s+=1){var l=a[s],c=t[l]||"";n.getAttribute(l)!==c&&n.setAttribute(l,c),-1===o.indexOf(l)&&o.push(l);var u=i.indexOf(l);-1!==u&&i.splice(u,1)}for(var p=i.length-1;p>=0;p-=1)n.removeAttribute(i[p]);o.length===i.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==a.join(",")&&n.setAttribute("data-rh",a.join(","))}},G=function(e,t){var n=e.baseTag,r=e.htmlAttributes,o=e.linkTags,i=e.metaTags,a=e.noscriptTags,s=e.onChangeClientState,l=e.scriptTags,c=e.styleTags,u=e.title,p=e.titleAttributes;q(v.BODY,e.bodyAttributes),q(v.HTML,r),function(e,t){void 0!==e&&document.title!==e&&(document.title=A(e)),q(v.TITLE,t)}(u,p);var d={baseTag:W(v.BASE,n),linkTags:W(v.LINK,o),metaTags:W(v.META,i),noscriptTags:W(v.NOSCRIPT,a),scriptTags:W(v.SCRIPT,l),styleTags:W(v.STYLE,c)},f={},m={};Object.keys(d).forEach(function(e){var t=d[e],n=t.newTags,r=t.oldTags;n.length&&(f[e]=n),r.length&&(m[e]=d[e].oldTags)}),t&&t(),s(e,f,m)},K=null,Y=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).rendered=!1,t}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!p()(e,this.props)},n.componentDidUpdate=function(){this.emitChange()},n.componentWillUnmount=function(){this.props.context.helmetInstances.remove(this),this.emitChange()},n.emitChange=function(){var e,t,n=this.props.context,r=n.setHelmet,o=null,i=(e=n.helmetInstances.get().map(function(e){var t=d({},e.props);return delete t.context,t}),{baseTag:j(["href"],e),bodyAttributes:O("bodyAttributes",e),defer:_(e,"defer"),encode:_(e,"encodeSpecialCharacters"),htmlAttributes:O("htmlAttributes",e),linkTags:P(v.LINK,["rel","href"],e),metaTags:P(v.META,["name","charset","http-equiv","property","itemprop"],e),noscriptTags:P(v.NOSCRIPT,["innerHTML"],e),onChangeClientState:E(e),scriptTags:P(v.SCRIPT,["src","innerHTML"],e),styleTags:P(v.STYLE,["cssText"],e),title:S(e),titleAttributes:O("titleAttributes",e),prioritizeSeoTags:C(e,"prioritizeSeoTags")});H.canUseDOM?(t=i,K&&cancelAnimationFrame(K),t.defer?K=requestAnimationFrame(function(){G(t,function(){K=null})}):(G(t),K=null)):B&&(o=B(i)),r(o)},n.init=function(){this.rendered||(this.rendered=!0,this.props.context.helmetInstances.add(this),this.emitChange())},n.render=function(){return this.init(),null},t}(r.Component);Y.propTypes={context:V.isRequired},Y.displayName="HelmetDispatcher";var Z=["children"],J=["children"],X=function(e){function t(){return e.apply(this,arguments)||this}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!s()(I(this.props,"helmetData"),I(e,"helmetData"))},n.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case v.SCRIPT:case v.NOSCRIPT:return{innerHTML:t};case v.STYLE:return{cssText:t};default:throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren;return d({},r,((t={})[n.type]=[].concat(r[n.type]||[],[d({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,r=e.child,o=e.newProps,i=e.newChildProps,a=e.nestedChildren;switch(r.type){case v.TITLE:return d({},o,((t={})[r.type]=a,t.titleAttributes=d({},i),t));case v.BODY:return d({},o,{bodyAttributes:d({},i)});case v.HTML:return d({},o,{htmlAttributes:d({},i)});default:return d({},o,((n={})[r.type]=d({},i),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=d({},t);return Object.keys(e).forEach(function(t){var r;n=d({},n,((r={})[t]=e[t],r))}),n},n.warnOnInvalidChildren=function(e,t){return c()(w.some(function(t){return e.type===t}),"function"==typeof e.type?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+w.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),c()(!t||"string"==typeof t||Array.isArray(t)&&!t.some(function(e){return"string"!=typeof e}),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}</"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,o={};return r.Children.forEach(e,function(e){if(e&&e.props){var r=e.props,i=r.children,a=h(r,Z),s=Object.keys(a).reduce(function(e,t){return e[k[t]||t]=a[t],e},{}),l=e.type;switch("symbol"==typeof l?l=l.toString():n.warnOnInvalidChildren(e,i),l){case v.FRAGMENT:t=n.mapChildrenToProps(i,t);break;case v.LINK:case v.META:case v.NOSCRIPT:case v.SCRIPT:case v.STYLE:o=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:o,newChildProps:s,nestedChildren:i});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:s,nestedChildren:i})}}}),this.mapArrayTypeChildrenToProps(o,t)},n.render=function(){var e=this.props,t=e.children,n=h(e,J),o=d({},n),i=n.helmetData;return t&&(o=this.mapChildrenToProps(t,o)),!i||i instanceof $||(i=new $(i.context,i.instances)),i?r.createElement(Y,d({},o,{context:i.value,helmetData:void 0})):r.createElement(U.Consumer,null,function(e){return r.createElement(Y,d({},o,{context:e}))})},t}(r.Component);X.propTypes={base:i().object,bodyAttributes:i().object,children:i().oneOfType([i().arrayOf(i().node),i().node]),defaultTitle:i().string,defer:i().bool,encodeSpecialCharacters:i().bool,htmlAttributes:i().object,link:i().arrayOf(i().object),meta:i().arrayOf(i().object),noscript:i().arrayOf(i().object),onChangeClientState:i().func,script:i().arrayOf(i().object),style:i().arrayOf(i().object),title:i().string,titleAttributes:i().object,titleTemplate:i().string,prioritizeSeoTags:i().bool,helmetData:i().object},X.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},X.displayName="Helmet"},81604:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function o(e){const t={};return function e(n,o){Object.entries(n).forEach(([n,i])=>{const a=o?`${o}.${n}`:n;r(i)?e(i,a):t[a]=i})}(e),t}},82216:(e,t,n)=>{"use strict";n.d(t,{l:()=>s});var r=n(96540),o=n(31712);const i={desktop:"desktop",mobile:"mobile",ssr:"ssr"},a=996;function s({desktopBreakpoint:e=a}={}){const[t,n]=(0,r.useState)(()=>"ssr");return(0,r.useEffect)(()=>{function t(){n(function(e){if(!o.A.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>e?i.desktop:i.mobile}(e))}return t(),window.addEventListener("resize",t),()=>{window.removeEventListener("resize",t)}},[e]),t}},84030:(e,t,n)=>{"use strict";n.d(t,{AL:()=>u,s$:()=>p});var r=n(96540),o=n(97639),i=n(93512),a=n(4799),s=n(74848);const l=({title:e,siteTitle:t,titleDelimiter:n})=>{const r=e?.trim();return r&&r!==t?`${r} ${n} ${t}`:t},c=(0,r.createContext)(null);function u({formatter:e,children:t}){return(0,s.jsx)(c.Provider,{value:e,children:t})}function p(){const e=function(){const e=(0,r.useContext)(c);if(null===e)throw new a.dV("TitleFormatterProvider");return e}(),{siteConfig:t}=(0,o.A)(),{title:n,titleDelimiter:s}=t,{plugin:u}=(0,i.A)();return{format:t=>e({title:t,siteTitle:n,titleDelimiter:s,plugin:u,defaultFormatter:l})}}},84054:e=>{"use strict";e.exports=JSON.parse('{"/constellation/pr-preview/pr-4027/-530":{"__comp":"5e95c892","__context":{"plugin":"aba21aa0"}},"/constellation/pr-preview/pr-4027/2.22-fb0":{"__comp":"a7bd4aaa","__props":"911e2eea"},"/constellation/pr-preview/pr-4027/2.22-187":{"__comp":"a94703ab"},"/constellation/pr-preview/pr-4027/2.22/-38d":{"__comp":"17896441","content":"79e0c113"},"/constellation/pr-preview/pr-4027/2.22/architecture/attestation-dff":{"__comp":"17896441","content":"4b669f2d"},"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage-564":{"__comp":"17896441","content":"e0f39c0b"},"/constellation/pr-preview/pr-4027/2.22/architecture/images-872":{"__comp":"17896441","content":"a6a7cec0"},"/constellation/pr-preview/pr-4027/2.22/architecture/keys-027":{"__comp":"17896441","content":"53c1dfd4"},"/constellation/pr-preview/pr-4027/2.22/architecture/microservices-907":{"__comp":"17896441","content":"84353103"},"/constellation/pr-preview/pr-4027/2.22/architecture/networking-e4c":{"__comp":"17896441","content":"3fe7bb19"},"/constellation/pr-preview/pr-4027/2.22/architecture/observability-429":{"__comp":"17896441","content":"0428ff27"},"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration-363":{"__comp":"17896441","content":"6e43ec2e"},"/constellation/pr-preview/pr-4027/2.22/architecture/overview-d8e":{"__comp":"17896441","content":"bf976132"},"/constellation/pr-preview/pr-4027/2.22/architecture/versions-536":{"__comp":"17896441","content":"2dc3352a"},"/constellation/pr-preview/pr-4027/2.22/category/architecture-99a":{"__comp":"14eb3368","__props":"9ba5d544"},"/constellation/pr-preview/pr-4027/2.22/category/basics-b46":{"__comp":"14eb3368","__props":"acced080"},"/constellation/pr-preview/pr-4027/2.22/category/getting-started-5d8":{"__comp":"14eb3368","__props":"6fe48d2e"},"/constellation/pr-preview/pr-4027/2.22/category/reference-41f":{"__comp":"14eb3368","__props":"989930da"},"/constellation/pr-preview/pr-4027/2.22/category/workflows-03d":{"__comp":"14eb3368","__props":"54db543f"},"/constellation/pr-preview/pr-4027/2.22/getting-started/examples-2a2":{"__comp":"17896441","content":"8452cbfd"},"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/emojivoto-f17":{"__comp":"17896441","content":"462332ca"},"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/filestash-s3proxy-d7f":{"__comp":"17896441","content":"ded7ff97"},"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scaling-075":{"__comp":"17896441","content":"c33b0c87"},"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/online-boutique-160":{"__comp":"17896441","content":"a7be6a84"},"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-c6d":{"__comp":"17896441","content":"5e92d76a"},"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local-80b":{"__comp":"17896441","content":"d12af2ba"},"/constellation/pr-preview/pr-4027/2.22/getting-started/install-ad2":{"__comp":"17896441","content":"3bcf7932"},"/constellation/pr-preview/pr-4027/2.22/getting-started/marketplaces-c43":{"__comp":"17896441","content":"fb5790ab"},"/constellation/pr-preview/pr-4027/2.22/overview/clouds-8dd":{"__comp":"17896441","content":"3aba4a32"},"/constellation/pr-preview/pr-4027/2.22/overview/confidential-kubernetes-388":{"__comp":"17896441","content":"0b338d1c"},"/constellation/pr-preview/pr-4027/2.22/overview/license-b48":{"__comp":"17896441","content":"ae4682fc"},"/constellation/pr-preview/pr-4027/2.22/overview/performance/-559":{"__comp":"17896441","content":"8a026b6c"},"/constellation/pr-preview/pr-4027/2.22/overview/performance/application-599":{"__comp":"17896441","content":"7ae19400"},"/constellation/pr-preview/pr-4027/2.22/overview/performance/compute-e94":{"__comp":"17896441","content":"baf93e4b"},"/constellation/pr-preview/pr-4027/2.22/overview/performance/io-2bc":{"__comp":"17896441","content":"8ca353b4"},"/constellation/pr-preview/pr-4027/2.22/overview/product-821":{"__comp":"17896441","content":"061c4c8e"},"/constellation/pr-preview/pr-4027/2.22/overview/security-benefits-5c0":{"__comp":"17896441","content":"cda59bb1"},"/constellation/pr-preview/pr-4027/2.22/reference/cli-77d":{"__comp":"17896441","content":"5a6332a4"},"/constellation/pr-preview/pr-4027/2.22/reference/migration-280":{"__comp":"17896441","content":"b744c41b"},"/constellation/pr-preview/pr-4027/2.22/reference/slsa-9b2":{"__comp":"17896441","content":"4967aec5"},"/constellation/pr-preview/pr-4027/2.22/reference/terraform-89f":{"__comp":"17896441","content":"dae6bd30"},"/constellation/pr-preview/pr-4027/2.22/workflows/cert-manager-c0b":{"__comp":"17896441","content":"3b1b22d5"},"/constellation/pr-preview/pr-4027/2.22/workflows/config-632":{"__comp":"17896441","content":"0a66f7ff"},"/constellation/pr-preview/pr-4027/2.22/workflows/create-bd7":{"__comp":"17896441","content":"11dcff96"},"/constellation/pr-preview/pr-4027/2.22/workflows/lb-fa8":{"__comp":"17896441","content":"5dc5a687"},"/constellation/pr-preview/pr-4027/2.22/workflows/recovery-197":{"__comp":"17896441","content":"20a029f4"},"/constellation/pr-preview/pr-4027/2.22/workflows/reproducible-builds-bc4":{"__comp":"17896441","content":"e19825b3"},"/constellation/pr-preview/pr-4027/2.22/workflows/s3proxy-c88":{"__comp":"17896441","content":"5d6cdc31"},"/constellation/pr-preview/pr-4027/2.22/workflows/sbom-f31":{"__comp":"17896441","content":"2a05e475"},"/constellation/pr-preview/pr-4027/2.22/workflows/scale-961":{"__comp":"17896441","content":"4bfed142"},"/constellation/pr-preview/pr-4027/2.22/workflows/storage-4a9":{"__comp":"17896441","content":"dc614479"},"/constellation/pr-preview/pr-4027/2.22/workflows/terminate-90f":{"__comp":"17896441","content":"5aae01e0"},"/constellation/pr-preview/pr-4027/2.22/workflows/terraform-provider-489":{"__comp":"17896441","content":"c920f53d"},"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting-6b3":{"__comp":"17896441","content":"3ee8c4d1"},"/constellation/pr-preview/pr-4027/2.22/workflows/trusted-launch-71c":{"__comp":"17896441","content":"856c1b4a"},"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade-7d3":{"__comp":"17896441","content":"db1b10df"},"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli-ee3":{"__comp":"17896441","content":"70248ece"},"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cluster-c8e":{"__comp":"17896441","content":"ce803f35"},"/constellation/pr-preview/pr-4027/2.23-739":{"__comp":"a7bd4aaa","__props":"72c2c1f0"},"/constellation/pr-preview/pr-4027/2.23-7a4":{"__comp":"a94703ab"},"/constellation/pr-preview/pr-4027/2.23/-2a5":{"__comp":"17896441","content":"1e04dd29"},"/constellation/pr-preview/pr-4027/2.23/architecture/attestation-efc":{"__comp":"17896441","content":"36f09204"},"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage-1cc":{"__comp":"17896441","content":"74afccd1"},"/constellation/pr-preview/pr-4027/2.23/architecture/images-51c":{"__comp":"17896441","content":"2b3dcc9b"},"/constellation/pr-preview/pr-4027/2.23/architecture/keys-806":{"__comp":"17896441","content":"8ea786c8"},"/constellation/pr-preview/pr-4027/2.23/architecture/microservices-f58":{"__comp":"17896441","content":"a631f374"},"/constellation/pr-preview/pr-4027/2.23/architecture/networking-b9a":{"__comp":"17896441","content":"d4cfdd56"},"/constellation/pr-preview/pr-4027/2.23/architecture/observability-441":{"__comp":"17896441","content":"e97075f3"},"/constellation/pr-preview/pr-4027/2.23/architecture/orchestration-702":{"__comp":"17896441","content":"adfda302"},"/constellation/pr-preview/pr-4027/2.23/architecture/overview-b03":{"__comp":"17896441","content":"0c605e3b"},"/constellation/pr-preview/pr-4027/2.23/architecture/versions-7fa":{"__comp":"17896441","content":"f402a94e"},"/constellation/pr-preview/pr-4027/2.23/category/architecture-3a7":{"__comp":"14eb3368","__props":"6d0fae35"},"/constellation/pr-preview/pr-4027/2.23/category/basics-9d6":{"__comp":"14eb3368","__props":"6c830a9a"},"/constellation/pr-preview/pr-4027/2.23/category/getting-started-805":{"__comp":"14eb3368","__props":"4fce284f"},"/constellation/pr-preview/pr-4027/2.23/category/reference-705":{"__comp":"14eb3368","__props":"b80e9c3d"},"/constellation/pr-preview/pr-4027/2.23/category/workflows-5fe":{"__comp":"14eb3368","__props":"42298223"},"/constellation/pr-preview/pr-4027/2.23/getting-started/examples-1b6":{"__comp":"17896441","content":"76f884e3"},"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/emojivoto-508":{"__comp":"17896441","content":"543a522f"},"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/filestash-s3proxy-572":{"__comp":"17896441","content":"797a5fdc"},"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/horizontal-scaling-e8d":{"__comp":"17896441","content":"eae38991"},"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/online-boutique-704":{"__comp":"17896441","content":"533d31d4"},"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps-b5a":{"__comp":"17896441","content":"3305fd99"},"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps-local-a51":{"__comp":"17896441","content":"073bbd6a"},"/constellation/pr-preview/pr-4027/2.23/getting-started/install-903":{"__comp":"17896441","content":"8713d71c"},"/constellation/pr-preview/pr-4027/2.23/getting-started/marketplaces-493":{"__comp":"17896441","content":"28513d82"},"/constellation/pr-preview/pr-4027/2.23/overview/clouds-6b8":{"__comp":"17896441","content":"e344aa3d"},"/constellation/pr-preview/pr-4027/2.23/overview/confidential-kubernetes-801":{"__comp":"17896441","content":"9d4f835b"},"/constellation/pr-preview/pr-4027/2.23/overview/license-2e0":{"__comp":"17896441","content":"7c763686"},"/constellation/pr-preview/pr-4027/2.23/overview/performance/-7d1":{"__comp":"17896441","content":"074359f8"},"/constellation/pr-preview/pr-4027/2.23/overview/performance/application-897":{"__comp":"17896441","content":"f03f4c5d"},"/constellation/pr-preview/pr-4027/2.23/overview/performance/compute-325":{"__comp":"17896441","content":"e7c02e82"},"/constellation/pr-preview/pr-4027/2.23/overview/performance/io-71a":{"__comp":"17896441","content":"28a0f3ab"},"/constellation/pr-preview/pr-4027/2.23/overview/product-8f9":{"__comp":"17896441","content":"e91da414"},"/constellation/pr-preview/pr-4027/2.23/overview/security-benefits-833":{"__comp":"17896441","content":"3607c499"},"/constellation/pr-preview/pr-4027/2.23/reference/cli-089":{"__comp":"17896441","content":"d17f599b"},"/constellation/pr-preview/pr-4027/2.23/reference/migration-646":{"__comp":"17896441","content":"0b615bd7"},"/constellation/pr-preview/pr-4027/2.23/reference/slsa-4e0":{"__comp":"17896441","content":"0eb3e611"},"/constellation/pr-preview/pr-4027/2.23/reference/terraform-4bf":{"__comp":"17896441","content":"8a589188"},"/constellation/pr-preview/pr-4027/2.23/workflows/cert-manager-906":{"__comp":"17896441","content":"75a3ea9f"},"/constellation/pr-preview/pr-4027/2.23/workflows/config-3fc":{"__comp":"17896441","content":"60d3a1b7"},"/constellation/pr-preview/pr-4027/2.23/workflows/create-3d7":{"__comp":"17896441","content":"7cae3477"},"/constellation/pr-preview/pr-4027/2.23/workflows/lb-93d":{"__comp":"17896441","content":"e12b18ba"},"/constellation/pr-preview/pr-4027/2.23/workflows/recovery-892":{"__comp":"17896441","content":"dfb82530"},"/constellation/pr-preview/pr-4027/2.23/workflows/reproducible-builds-b45":{"__comp":"17896441","content":"dfb8a45d"},"/constellation/pr-preview/pr-4027/2.23/workflows/s3proxy-a8c":{"__comp":"17896441","content":"633fbb2f"},"/constellation/pr-preview/pr-4027/2.23/workflows/sbom-761":{"__comp":"17896441","content":"71dfee10"},"/constellation/pr-preview/pr-4027/2.23/workflows/scale-0e9":{"__comp":"17896441","content":"d2556545"},"/constellation/pr-preview/pr-4027/2.23/workflows/storage-91e":{"__comp":"17896441","content":"9010cc91"},"/constellation/pr-preview/pr-4027/2.23/workflows/terminate-231":{"__comp":"17896441","content":"142263a9"},"/constellation/pr-preview/pr-4027/2.23/workflows/terraform-provider-8a3":{"__comp":"17896441","content":"de51a3b8"},"/constellation/pr-preview/pr-4027/2.23/workflows/troubleshooting-be8":{"__comp":"17896441","content":"e8feb497"},"/constellation/pr-preview/pr-4027/2.23/workflows/trusted-launch-431":{"__comp":"17896441","content":"64c81f13"},"/constellation/pr-preview/pr-4027/2.23/workflows/upgrade-fde":{"__comp":"17896441","content":"925a7d08"},"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cli-a61":{"__comp":"17896441","content":"8d448ad2"},"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cluster-2d3":{"__comp":"17896441","content":"4cf171a2"},"/constellation/pr-preview/pr-4027/next-c46":{"__comp":"a7bd4aaa","__props":"574ee69f"},"/constellation/pr-preview/pr-4027/next-8d5":{"__comp":"a94703ab"},"/constellation/pr-preview/pr-4027/next/-32d":{"__comp":"17896441","content":"0e384e19"},"/constellation/pr-preview/pr-4027/next/architecture/attestation-74c":{"__comp":"17896441","content":"642ed902"},"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage-285":{"__comp":"17896441","content":"a3183fd7"},"/constellation/pr-preview/pr-4027/next/architecture/images-c23":{"__comp":"17896441","content":"487d2b28"},"/constellation/pr-preview/pr-4027/next/architecture/keys-c67":{"__comp":"17896441","content":"5bf0e48f"},"/constellation/pr-preview/pr-4027/next/architecture/microservices-65a":{"__comp":"17896441","content":"dcc7f694"},"/constellation/pr-preview/pr-4027/next/architecture/networking-df4":{"__comp":"17896441","content":"4cc5eb92"},"/constellation/pr-preview/pr-4027/next/architecture/observability-13d":{"__comp":"17896441","content":"927cf76e"},"/constellation/pr-preview/pr-4027/next/architecture/orchestration-840":{"__comp":"17896441","content":"b29fd7c7"},"/constellation/pr-preview/pr-4027/next/architecture/overview-f60":{"__comp":"17896441","content":"0b1ac180"},"/constellation/pr-preview/pr-4027/next/architecture/versions-405":{"__comp":"17896441","content":"72a880f4"},"/constellation/pr-preview/pr-4027/next/category/architecture-c2a":{"__comp":"14eb3368","__props":"9afa113a"},"/constellation/pr-preview/pr-4027/next/category/basics-2f7":{"__comp":"14eb3368","__props":"56806aed"},"/constellation/pr-preview/pr-4027/next/category/getting-started-420":{"__comp":"14eb3368","__props":"242e7908"},"/constellation/pr-preview/pr-4027/next/category/reference-968":{"__comp":"14eb3368","__props":"a4c009ef"},"/constellation/pr-preview/pr-4027/next/category/workflows-a7a":{"__comp":"14eb3368","__props":"786b68f5"},"/constellation/pr-preview/pr-4027/next/getting-started/examples-671":{"__comp":"17896441","content":"508a7d2f"},"/constellation/pr-preview/pr-4027/next/getting-started/examples/emojivoto-800":{"__comp":"17896441","content":"9be9ef65"},"/constellation/pr-preview/pr-4027/next/getting-started/examples/filestash-s3proxy-abb":{"__comp":"17896441","content":"6df30968"},"/constellation/pr-preview/pr-4027/next/getting-started/examples/horizontal-scaling-2ff":{"__comp":"17896441","content":"e61948c8"},"/constellation/pr-preview/pr-4027/next/getting-started/examples/online-boutique-780":{"__comp":"17896441","content":"80697fb2"},"/constellation/pr-preview/pr-4027/next/getting-started/first-steps-5be":{"__comp":"17896441","content":"a39aaf1d"},"/constellation/pr-preview/pr-4027/next/getting-started/first-steps-local-9ab":{"__comp":"17896441","content":"3b28b3cc"},"/constellation/pr-preview/pr-4027/next/getting-started/install-d95":{"__comp":"17896441","content":"2a2a0c40"},"/constellation/pr-preview/pr-4027/next/getting-started/marketplaces-772":{"__comp":"17896441","content":"31840164"},"/constellation/pr-preview/pr-4027/next/overview/clouds-39f":{"__comp":"17896441","content":"ec7c7126"},"/constellation/pr-preview/pr-4027/next/overview/confidential-kubernetes-92a":{"__comp":"17896441","content":"acf362b0"},"/constellation/pr-preview/pr-4027/next/overview/license-8d4":{"__comp":"17896441","content":"66e2533d"},"/constellation/pr-preview/pr-4027/next/overview/performance/-0ba":{"__comp":"17896441","content":"76b2ab15"},"/constellation/pr-preview/pr-4027/next/overview/performance/application-296":{"__comp":"17896441","content":"1036ee0b"},"/constellation/pr-preview/pr-4027/next/overview/performance/compute-069":{"__comp":"17896441","content":"b28da407"},"/constellation/pr-preview/pr-4027/next/overview/performance/io-bfc":{"__comp":"17896441","content":"9c1ba6d8"},"/constellation/pr-preview/pr-4027/next/overview/product-e17":{"__comp":"17896441","content":"4a51e885"},"/constellation/pr-preview/pr-4027/next/overview/security-benefits-82c":{"__comp":"17896441","content":"786c60fb"},"/constellation/pr-preview/pr-4027/next/reference/cli-ae6":{"__comp":"17896441","content":"91c76d4c"},"/constellation/pr-preview/pr-4027/next/reference/migration-6ee":{"__comp":"17896441","content":"0282ce66"},"/constellation/pr-preview/pr-4027/next/reference/slsa-06c":{"__comp":"17896441","content":"9b22caeb"},"/constellation/pr-preview/pr-4027/next/reference/terraform-d4c":{"__comp":"17896441","content":"3e0d8e9d"},"/constellation/pr-preview/pr-4027/next/workflows/cert-manager-67d":{"__comp":"17896441","content":"15c6e37c"},"/constellation/pr-preview/pr-4027/next/workflows/config-c37":{"__comp":"17896441","content":"86470a9a"},"/constellation/pr-preview/pr-4027/next/workflows/create-ab5":{"__comp":"17896441","content":"269ef64a"},"/constellation/pr-preview/pr-4027/next/workflows/lb-508":{"__comp":"17896441","content":"311067ef"},"/constellation/pr-preview/pr-4027/next/workflows/recovery-d15":{"__comp":"17896441","content":"ca9f0fb1"},"/constellation/pr-preview/pr-4027/next/workflows/reproducible-builds-f5e":{"__comp":"17896441","content":"70f89ddc"},"/constellation/pr-preview/pr-4027/next/workflows/s3proxy-ee9":{"__comp":"17896441","content":"592bfb5e"},"/constellation/pr-preview/pr-4027/next/workflows/sbom-463":{"__comp":"17896441","content":"cb054e22"},"/constellation/pr-preview/pr-4027/next/workflows/scale-f4c":{"__comp":"17896441","content":"358e1fce"},"/constellation/pr-preview/pr-4027/next/workflows/storage-b6e":{"__comp":"17896441","content":"25e50762"},"/constellation/pr-preview/pr-4027/next/workflows/terminate-372":{"__comp":"17896441","content":"6776993e"},"/constellation/pr-preview/pr-4027/next/workflows/terraform-provider-784":{"__comp":"17896441","content":"f8c8aa36"},"/constellation/pr-preview/pr-4027/next/workflows/troubleshooting-4bb":{"__comp":"17896441","content":"1b80620b"},"/constellation/pr-preview/pr-4027/next/workflows/trusted-launch-d61":{"__comp":"17896441","content":"452d9595"},"/constellation/pr-preview/pr-4027/next/workflows/upgrade-4c5":{"__comp":"17896441","content":"960959b3"},"/constellation/pr-preview/pr-4027/next/workflows/verify-cli-1e3":{"__comp":"17896441","content":"1c53691b"},"/constellation/pr-preview/pr-4027/next/workflows/verify-cluster-490":{"__comp":"17896441","content":"ca2d12cf"},"/constellation/pr-preview/pr-4027/-bdb":{"__comp":"a7bd4aaa","__props":"401e1ad9"},"/constellation/pr-preview/pr-4027/-be5":{"__comp":"a94703ab"},"/constellation/pr-preview/pr-4027/architecture/attestation-a81":{"__comp":"17896441","content":"3aca6029"},"/constellation/pr-preview/pr-4027/architecture/encrypted-storage-bb8":{"__comp":"17896441","content":"af08314d"},"/constellation/pr-preview/pr-4027/architecture/images-8a4":{"__comp":"17896441","content":"294c0512"},"/constellation/pr-preview/pr-4027/architecture/keys-cb3":{"__comp":"17896441","content":"a5863201"},"/constellation/pr-preview/pr-4027/architecture/microservices-22f":{"__comp":"17896441","content":"260d3cdf"},"/constellation/pr-preview/pr-4027/architecture/networking-b7c":{"__comp":"17896441","content":"3324b179"},"/constellation/pr-preview/pr-4027/architecture/observability-047":{"__comp":"17896441","content":"d89a6bd5"},"/constellation/pr-preview/pr-4027/architecture/orchestration-176":{"__comp":"17896441","content":"1890268c"},"/constellation/pr-preview/pr-4027/architecture/overview-61d":{"__comp":"17896441","content":"836c9f98"},"/constellation/pr-preview/pr-4027/architecture/versions-766":{"__comp":"17896441","content":"40c738e9"},"/constellation/pr-preview/pr-4027/category/architecture-e55":{"__comp":"14eb3368","__props":"95ca3cf4"},"/constellation/pr-preview/pr-4027/category/basics-f2f":{"__comp":"14eb3368","__props":"039005a9"},"/constellation/pr-preview/pr-4027/category/getting-started-c17":{"__comp":"14eb3368","__props":"a7e69b4a"},"/constellation/pr-preview/pr-4027/category/reference-d10":{"__comp":"14eb3368","__props":"48186bb1"},"/constellation/pr-preview/pr-4027/category/workflows-e68":{"__comp":"14eb3368","__props":"cea600d4"},"/constellation/pr-preview/pr-4027/getting-started/examples-93f":{"__comp":"17896441","content":"3962f62e"},"/constellation/pr-preview/pr-4027/getting-started/examples/emojivoto-988":{"__comp":"17896441","content":"cbcdb048"},"/constellation/pr-preview/pr-4027/getting-started/examples/filestash-s3proxy-e46":{"__comp":"17896441","content":"d0929cd6"},"/constellation/pr-preview/pr-4027/getting-started/examples/horizontal-scaling-0da":{"__comp":"17896441","content":"01f9c0c3"},"/constellation/pr-preview/pr-4027/getting-started/examples/online-boutique-df3":{"__comp":"17896441","content":"481538bf"},"/constellation/pr-preview/pr-4027/getting-started/first-steps-b4f":{"__comp":"17896441","content":"c2af115c"},"/constellation/pr-preview/pr-4027/getting-started/first-steps-local-e3a":{"__comp":"17896441","content":"1c0e8ae3"},"/constellation/pr-preview/pr-4027/getting-started/install-b1b":{"__comp":"17896441","content":"84de5ccf"},"/constellation/pr-preview/pr-4027/getting-started/marketplaces-d82":{"__comp":"17896441","content":"11b4c29f"},"/constellation/pr-preview/pr-4027/overview/clouds-90e":{"__comp":"17896441","content":"2a9ad702"},"/constellation/pr-preview/pr-4027/overview/confidential-kubernetes-ac0":{"__comp":"17896441","content":"42888a29"},"/constellation/pr-preview/pr-4027/overview/license-049":{"__comp":"17896441","content":"619bb71e"},"/constellation/pr-preview/pr-4027/overview/performance/-4be":{"__comp":"17896441","content":"4c9525de"},"/constellation/pr-preview/pr-4027/overview/performance/application-ad9":{"__comp":"17896441","content":"a7cbe781"},"/constellation/pr-preview/pr-4027/overview/performance/compute-822":{"__comp":"17896441","content":"d84515e5"},"/constellation/pr-preview/pr-4027/overview/performance/io-62f":{"__comp":"17896441","content":"97b147c7"},"/constellation/pr-preview/pr-4027/overview/product-772":{"__comp":"17896441","content":"a93f81ab"},"/constellation/pr-preview/pr-4027/overview/security-benefits-959":{"__comp":"17896441","content":"92236455"},"/constellation/pr-preview/pr-4027/reference/cli-4a8":{"__comp":"17896441","content":"fd1d3864"},"/constellation/pr-preview/pr-4027/reference/migration-a42":{"__comp":"17896441","content":"5672ef9d"},"/constellation/pr-preview/pr-4027/reference/slsa-cb5":{"__comp":"17896441","content":"da6dfe9f"},"/constellation/pr-preview/pr-4027/reference/terraform-ff6":{"__comp":"17896441","content":"8183fba6"},"/constellation/pr-preview/pr-4027/workflows/cert-manager-58a":{"__comp":"17896441","content":"a0c24a7b"},"/constellation/pr-preview/pr-4027/workflows/config-8a9":{"__comp":"17896441","content":"5e23635c"},"/constellation/pr-preview/pr-4027/workflows/create-e04":{"__comp":"17896441","content":"0bfd0c91"},"/constellation/pr-preview/pr-4027/workflows/lb-f21":{"__comp":"17896441","content":"3e6faa8e"},"/constellation/pr-preview/pr-4027/workflows/recovery-063":{"__comp":"17896441","content":"31cc4483"},"/constellation/pr-preview/pr-4027/workflows/reproducible-builds-cda":{"__comp":"17896441","content":"9bccdd10"},"/constellation/pr-preview/pr-4027/workflows/s3proxy-970":{"__comp":"17896441","content":"0c363123"},"/constellation/pr-preview/pr-4027/workflows/sbom-614":{"__comp":"17896441","content":"90e117e3"},"/constellation/pr-preview/pr-4027/workflows/scale-0d6":{"__comp":"17896441","content":"e0c6aa40"},"/constellation/pr-preview/pr-4027/workflows/storage-d91":{"__comp":"17896441","content":"794987bd"},"/constellation/pr-preview/pr-4027/workflows/terminate-48f":{"__comp":"17896441","content":"4f0549e0"},"/constellation/pr-preview/pr-4027/workflows/terraform-provider-472":{"__comp":"17896441","content":"68f29d4c"},"/constellation/pr-preview/pr-4027/workflows/troubleshooting-74c":{"__comp":"17896441","content":"9cbfbb7f"},"/constellation/pr-preview/pr-4027/workflows/trusted-launch-75f":{"__comp":"17896441","content":"837f4190"},"/constellation/pr-preview/pr-4027/workflows/upgrade-aa2":{"__comp":"17896441","content":"0cee1087"},"/constellation/pr-preview/pr-4027/workflows/verify-cli-8fa":{"__comp":"17896441","content":"15e5e9ad"},"/constellation/pr-preview/pr-4027/workflows/verify-cluster-995":{"__comp":"17896441","content":"3fddd266"},"/constellation/pr-preview/pr-4027/-d9c":{"__comp":"17896441","content":"66852f4d"}}')},85225:(e,t,n)=>{"use strict";n.d(t,{A:()=>c});n(96540);var r=n(34164),o=n(23230),i=n(19819),a=n(14783),s=n(37344),l=n(74848);function c({as:e,id:t,...n}){const c=(0,s.A)(),u=(0,i.v)(t);if("h1"===e||!t)return(0,l.jsx)(e,{...n,id:void 0});c.collectAnchor(t);const p=(0,o.T)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof n.children?n.children:t});return(0,l.jsxs)(e,{...n,className:(0,r.A)("anchor",u,n.className),id:t,children:[n.children,(0,l.jsx)(a.A,{className:"hash-link",to:`#${t}`,"aria-label":p,title:p,translate:"no",children:"\u200b"})]})}},85300:(e,t,n)=>{"use strict";n.r(t)},86185:(e,t,n)=>{"use strict";n.d(t,{A:()=>Pa});var r=n(96540),o=n(34164),i=n(33832),a=n(17153),s=n(56347),l=n(23230),c=n(54067),u=n(74848);const p="__docusaurus_skipToContent_fallback";function d(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,s.W6)(),n=(0,r.useCallback)(e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(p);t&&d(t)},[]);return(0,c.$)(({location:n})=>{e.current&&!n.hash&&"PUSH"===t&&d(e.current)}),{containerRef:e,onClick:n}}const m=(0,l.T)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function h(e){const t=e.children??m,{containerRef:n,onClick:r}=f();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":m,children:(0,u.jsx)("a",{...e,href:`#${p}`,onClick:r,children:t})})}var v=n(18630),g=n(19503);const b={skipToContent:"skipToContent_fXgn"};function y(){return(0,u.jsx)(h,{className:b.skipToContent})}var w=n(86957),x=n(40002);function k({width:e=21,height:t=21,color:n="currentColor",strokeWidth:r=1.2,className:o,...i}){return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:e,height:t,...i,children:(0,u.jsx)("g",{stroke:n,strokeWidth:r,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const _={closeButton:"closeButton_CVFx"};function S(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,l.T)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,o.A)("clean-btn close",_.closeButton,e.className),children:(0,u.jsx)(k,{width:14,height:14,strokeWidth:3.1})})}const E={content:"content_knG7"};function O(e){const{announcementBar:t}=(0,w.p)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,o.A)(E.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const j={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function P(){const{announcementBar:e}=(0,w.p)(),{isActive:t,close:n}=(0,x.M)();if(!t)return null;const{backgroundColor:r,textColor:i,isCloseable:a}=e;return(0,u.jsxs)("div",{className:(0,o.A)(v.G.announcementBar.container,j.announcementBar),style:{backgroundColor:r,color:i},role:"banner",children:[a&&(0,u.jsx)("div",{className:j.announcementBarPlaceholder}),(0,u.jsx)(O,{className:j.announcementBarContent}),a&&(0,u.jsx)(S,{onClick:n,className:j.announcementBarClose})]})}var C=n(61938),A=n(24245);var T=n(4799),I=n(70763);const N=r.createContext(null);function L({children:e}){const t=function(){const e=(0,C.M)(),t=(0,I.YL)(),[n,o]=(0,r.useState)(!1),i=null!==t.component,a=(0,T.ZC)(i);return(0,r.useEffect)(()=>{i&&!a&&o(!0)},[i,a]),(0,r.useEffect)(()=>{i?e.shown||o(!0):o(!1)},[e.shown,i]),(0,r.useMemo)(()=>[n,o],[n])}();return(0,u.jsx)(N.Provider,{value:t,children:e})}function R(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function D(){const e=(0,r.useContext)(N);if(!e)throw new T.dV("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,o=(0,r.useCallback)(()=>n(!1),[n]),i=(0,I.YL)();return(0,r.useMemo)(()=>({shown:t,hide:o,content:R(i)}),[o,i,t])}function F(e){return parseInt(r.version.split(".")[0],10)<19?{inert:e?"":void 0}:{inert:e}}function M({children:e,inert:t}){return(0,u.jsx)("div",{className:(0,o.A)(v.G.layout.navbar.mobileSidebar.panel,"navbar-sidebar__item menu"),...F(t),children:e})}function B({header:e,primaryMenu:t,secondaryMenu:n}){const{shown:r}=D();return(0,u.jsxs)("div",{className:(0,o.A)(v.G.layout.navbar.mobileSidebar.container,"navbar-sidebar"),children:[e,(0,u.jsxs)("div",{className:(0,o.A)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":r}),children:[(0,u.jsx)(M,{inert:r,children:t}),(0,u.jsx)(M,{inert:!r,children:n})]})]})}var z=n(7710),$=n(11062);function U(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function V(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}function Q(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"m12 21c4.971 0 9-4.029 9-9s-4.029-9-9-9-9 4.029-9 9 4.029 9 9 9zm4.95-13.95c1.313 1.313 2.05 3.093 2.05 4.95s-0.738 3.637-2.05 4.95c-1.313 1.313-3.093 2.05-4.95 2.05v-14c1.857 0 3.637 0.737 4.95 2.05z"})})}const H="toggle_vylO",W="toggleButton_gllP",q="toggleIcon_g3eP",G="systemToggleIcon_QzmC",K="lightToggleIcon_pyhR",Y="darkToggleIcon_wfgR",Z="toggleButtonDisabled_aARS";function J(e){switch(e){case null:return(0,l.T)({message:"system mode",id:"theme.colorToggle.ariaLabel.mode.system",description:"The name for the system color mode"});case"light":return(0,l.T)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"});case"dark":return(0,l.T)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"});default:throw new Error(`unexpected color mode ${e}`)}}function X(e){return(0,l.T)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the color mode toggle"},{mode:J(e)})}function ee(){return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(U,{"aria-hidden":!0,className:(0,o.A)(q,K)}),(0,u.jsx)(V,{"aria-hidden":!0,className:(0,o.A)(q,Y)}),(0,u.jsx)(Q,{"aria-hidden":!0,className:(0,o.A)(q,G)})]})}function te({className:e,buttonClassName:t,respectPrefersColorScheme:n,value:r,onChange:i}){const a=(0,$.A)();return(0,u.jsx)("div",{className:(0,o.A)(H,e),children:(0,u.jsx)("button",{className:(0,o.A)("clean-btn",W,!a&&Z,t),type:"button",onClick:()=>i(function(e,t){if(!t)return"dark"===e?"light":"dark";switch(e){case null:return"light";case"light":return"dark";case"dark":return null;default:throw new Error(`unexpected color mode ${e}`)}}(r,n)),disabled:!a,title:J(r),"aria-label":X(r),children:(0,u.jsx)(ee,{})})})}const ne=r.memo(te),re={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function oe({className:e}){const t=(0,w.p)().navbar.style,{disableSwitch:n,respectPrefersColorScheme:r}=(0,w.p)().colorMode,{colorModeChoice:o,setColorMode:i}=(0,z.G)();return n?null:(0,u.jsx)(ne,{className:e,buttonClassName:"dark"===t?re.darkNavbarColorModeToggle:void 0,respectPrefersColorScheme:r,value:o,onChange:i})}var ie=n(20020);function ae(){return(0,u.jsx)(ie.A,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function se(){const e=(0,C.M)();return(0,u.jsx)("button",{type:"button","aria-label":(0,l.T)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(k,{color:"var(--ifm-color-emphasis-600)"})})}function le(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(ae,{}),(0,u.jsx)(oe,{className:"margin-right--md"}),(0,u.jsx)(se,{})]})}var ce=n(14783),ue=n(98180),pe=n(40877);function de(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var fe=n(90716);function me({activeBasePath:e,activeBaseRegex:t,to:n,href:r,label:o,html:i,isDropdownLink:a,prependBaseUrlToHref:s,...l}){const c=(0,ue.Ay)(n),p=(0,ue.Ay)(e),d=(0,ue.Ay)(r,{forcePrependBaseUrl:!0}),f=o&&r&&!(0,pe.A)(r),m=i?{dangerouslySetInnerHTML:{__html:i}}:{children:(0,u.jsxs)(u.Fragment,{children:[o,f&&(0,u.jsx)(fe.A,{...a&&{width:12,height:12}})]})};return r?(0,u.jsx)(ce.A,{href:s?d:r,...l,...m}):(0,u.jsx)(ce.A,{to:c,isNavLink:!0,...(e||t)&&{isActive:(e,n)=>t?de(t,n.pathname):n.pathname.startsWith(p)},...l,...m})}function he({className:e,isDropdownItem:t,...n}){return(0,u.jsx)("li",{className:"menu__list-item",children:(0,u.jsx)(me,{className:(0,o.A)("menu__link",e),...n})})}function ve({className:e,isDropdownItem:t=!1,...n}){const r=(0,u.jsx)(me,{className:(0,o.A)(t?"dropdown__link":"navbar__item navbar__link",e),isDropdownLink:t,...n});return t?(0,u.jsx)("li",{children:r}):r}function ge({mobile:e=!1,position:t,...n}){const r=e?he:ve;return(0,u.jsx)(r,{...n,activeClassName:n.activeClassName??(e?"menu__link--active":"navbar__link--active")})}var be=n(94549),ye=n(80260),we=n(97639);const xe="dropdownNavbarItemMobile_J0Sd";function ke(e,t){return e.some(e=>function(e,t){return!!(0,ye.ys)(e.to,t)||!!de(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t))}function _e({collapsed:e,onClick:t}){return(0,u.jsx)("button",{"aria-label":e?(0,l.T)({id:"theme.navbar.mobileDropdown.collapseButton.expandAriaLabel",message:"Expand the dropdown",description:"The ARIA label of the button to expand the mobile dropdown navbar item"}):(0,l.T)({id:"theme.navbar.mobileDropdown.collapseButton.collapseAriaLabel",message:"Collapse the dropdown",description:"The ARIA label of the button to collapse the mobile dropdown navbar item"}),"aria-expanded":!e,type:"button",className:"clean-btn menu__caret",onClick:t})}function Se({items:e,className:t,position:n,onClick:i,...a}){const l=function(){const{siteConfig:{baseUrl:e}}=(0,we.A)(),{pathname:t}=(0,s.zy)();return t.replace(e,"/")}(),c=(0,ye.ys)(a.to,l),p=ke(e,l),{collapsed:d,toggleCollapsed:f}=function({active:e}){const{collapsed:t,toggleCollapsed:n,setCollapsed:o}=(0,be.u)({initialState:()=>!e});return(0,r.useEffect)(()=>{e&&o(!1)},[e,o]),{collapsed:t,toggleCollapsed:n}}({active:c||p}),m=a.to?void 0:"#";return(0,u.jsxs)("li",{className:(0,o.A)("menu__list-item",{"menu__list-item--collapsed":d}),children:[(0,u.jsxs)("div",{className:(0,o.A)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":c}),children:[(0,u.jsx)(me,{role:"button",className:(0,o.A)(xe,"menu__link menu__link--sublist",t),href:m,...a,onClick:e=>{"#"===m&&e.preventDefault(),f()},children:a.children??a.label}),(0,u.jsx)(_e,{collapsed:d,onClick:e=>{e.preventDefault(),f()}})]}),(0,u.jsx)(be.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:d,children:e.map((e,t)=>(0,r.createElement)(Qi,{mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active",...e,key:t}))})]})}function Ee({items:e,position:t,className:n,onClick:i,...a}){const s=(0,r.useRef)(null),[l,c]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{const e=e=>{s.current&&!s.current.contains(e.target)&&c(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}},[s]),(0,u.jsxs)("div",{ref:s,className:(0,o.A)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===t,"dropdown--show":l}),children:[(0,u.jsx)(me,{"aria-haspopup":"true","aria-expanded":l,role:"button",href:a.to?void 0:"#",className:(0,o.A)("navbar__link",n),...a,onClick:a.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),c(!l))},children:a.children??a.label}),(0,u.jsx)("ul",{className:"dropdown__menu",children:e.map((e,t)=>(0,r.createElement)(Qi,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t}))})]})}function Oe({mobile:e=!1,...t}){const n=e?Se:Ee;return(0,u.jsx)(n,{...t})}var je=n(2098),Pe=n(62814);function Ce({width:e=20,height:t=20,...n}){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:e,height:t,"aria-hidden":!0,...n,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const Ae="iconLanguage_nlXk";function Te(){const{siteConfig:e,i18n:{localeConfigs:t}}=(0,we.A)(),n=(0,je.o)(),r=(0,Pe.Hl)(e=>e.location.search),o=(0,Pe.Hl)(e=>e.location.hash),i=e=>{const n=t[e];if(!n)throw new Error(`Docusaurus bug, no locale config found for locale=${e}`);return n};return{getURL:(t,a)=>{const s=(0,Pe.jy)([r,a.queryString],"append");return`${(t=>i(t).url===e.url?`pathname://${n.createUrl({locale:t,fullyQualified:!1})}`:n.createUrl({locale:t,fullyQualified:!0}))(t)}${s}${o}`},getLabel:e=>i(e).label,getLang:e=>i(e).htmlLang}}var Ie=n(5338);function Ne(e,t){var n=void 0;return function(){for(var r=arguments.length,o=new Array(r),i=0;i<r;i++)o[i]=arguments[i];n&&clearTimeout(n),n=setTimeout(function(){return e.apply(void 0,o)},t)}}function Le(e){return{current:e}}function Re(e){return e!==Object(e)}function De(e,t){if(e===t)return!0;if(Re(e)||Re(t)||"function"==typeof e||"function"==typeof t)return e===t;if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n=0,r=Object.keys(e);n<r.length;n++){var o=r[n];if(!(o in t))return!1;if(!De(e[o],t[o]))return!1}return!0}var Fe=function(){};function Me(e){var t=e.item,n=e.items,r=void 0===n?[]:n;return{index:t.__autocomplete_indexName,items:[t],positions:[1+r.findIndex(function(e){return e.objectID===t.objectID})],queryID:t.__autocomplete_queryID,algoliaSource:["autocomplete"]}}function Be(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,i,a,s=[],l=!0,c=!1;try{if(i=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;l=!1}else for(;!(l=(r=i.call(n)).done)&&(s.push(r.value),s.length!==t);l=!0);}catch(u){c=!0,o=u}finally{try{if(!l&&null!=n.return&&(a=n.return(),Object(a)!==a))return}finally{if(c)throw o}}return s}}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return ze(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ze(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function ze(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}var $e=["items"],Ue=["items"];function Ve(e){return Ve="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Ve(e)}function Qe(e){return function(e){if(Array.isArray(e))return He(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return He(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return He(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function He(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function We(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function qe(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Ge(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?qe(Object(n),!0).forEach(function(t){Ke(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):qe(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Ke(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Ve(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Ve(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Ve(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Ye(e){return e.map(function(e){var t=e.items,n=We(e,$e);return Ge(Ge({},n),{},{objectIDs:(null==t?void 0:t.map(function(e){return e.objectID}))||n.objectIDs})})}function Ze(e){var t=function(e){var t=Be((e.version||"").split(".").map(Number),2),n=t[0],r=t[1];return n>=3||2===n&&r>=4||1===n&&r>=10}(e);function n(n,r,o){if(t&&void 0!==o){var i=o[0].__autocomplete_algoliaCredentials,a={"X-Algolia-Application-Id":i.appId,"X-Algolia-API-Key":i.apiKey};e.apply(void 0,[n].concat(Qe(r),[{headers:a}]))}else e.apply(void 0,[n].concat(Qe(r)))}return{init:function(t,n){e("init",{appId:t,apiKey:n})},setAuthenticatedUserToken:function(t){e("setAuthenticatedUserToken",t)},setUserToken:function(t){e("setUserToken",t)},clickedObjectIDsAfterSearch:function(){for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];t.length>0&&n("clickedObjectIDsAfterSearch",Ye(t),t[0].items)},clickedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];t.length>0&&n("clickedObjectIDs",Ye(t),t[0].items)},clickedFilters:function(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];n.length>0&&e.apply(void 0,["clickedFilters"].concat(n))},convertedObjectIDsAfterSearch:function(){for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];t.length>0&&n("convertedObjectIDsAfterSearch",Ye(t),t[0].items)},convertedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];t.length>0&&n("convertedObjectIDs",Ye(t),t[0].items)},convertedFilters:function(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];n.length>0&&e.apply(void 0,["convertedFilters"].concat(n))},viewedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];t.length>0&&t.reduce(function(e,t){var n=t.items,r=We(t,Ue);return[].concat(Qe(e),Qe(function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:20,n=[],r=0;r<e.objectIDs.length;r+=t)n.push(Ge(Ge({},e),{},{objectIDs:e.objectIDs.slice(r,r+t)}));return n}(Ge(Ge({},r),{},{objectIDs:(null==n?void 0:n.map(function(e){return e.objectID}))||r.objectIDs})).map(function(e){return{items:n,payload:e}})))},[]).forEach(function(e){var t=e.items;return n("viewedObjectIDs",[e.payload],t)})},viewedFilters:function(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];n.length>0&&e.apply(void 0,["viewedFilters"].concat(n))}}}function Je(e){var t=e.items.reduce(function(e,t){var n;return e[t.__autocomplete_indexName]=(null!==(n=e[t.__autocomplete_indexName])&&void 0!==n?n:[]).concat(t),e},{});return Object.keys(t).map(function(e){return{index:e,items:t[e],algoliaSource:["autocomplete"]}})}function Xe(e){return e.objectID&&e.__autocomplete_indexName&&e.__autocomplete_queryID}function et(e){return et="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},et(e)}function tt(e){return function(e){if(Array.isArray(e))return nt(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return nt(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return nt(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function nt(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function rt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function ot(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?rt(Object(n),!0).forEach(function(t){it(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):rt(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function it(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==et(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==et(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===et(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var at="2.15.0",st="https://cdn.jsdelivr.net/npm/search-insights@".concat(at,"/dist/search-insights.min.js"),lt=Ne(function(e){var t=e.onItemsChange,n=e.items,r=e.insights,o=e.state;t({insights:r,insightsEvents:Je({items:n}).map(function(e){return ot({eventName:"Items Viewed"},e)}),state:o})},400);function ct(e){var t=function(e){return ot({onItemsChange:function(e){var t=e.insights,n=e.insightsEvents,r=e.state;t.viewedObjectIDs.apply(t,tt(n.map(function(e){return ot(ot({},e),{},{algoliaSource:ut(e.algoliaSource,r.context)})})))},onSelect:function(e){var t=e.insights,n=e.insightsEvents,r=e.state;t.clickedObjectIDsAfterSearch.apply(t,tt(n.map(function(e){return ot(ot({},e),{},{algoliaSource:ut(e.algoliaSource,r.context)})})))},onActive:Fe,__autocomplete_clickAnalytics:!0},e)}(e),n=t.insightsClient,r=t.insightsInitParams,o=t.onItemsChange,i=t.onSelect,a=t.onActive,s=t.__autocomplete_clickAnalytics,l=n;if(n||function(e){if("undefined"!=typeof window)e({window:window})}(function(e){var t=e.window,n=t.AlgoliaAnalyticsObject||"aa";"string"==typeof n&&(l=t[n]),l||(t.AlgoliaAnalyticsObject=n,t[n]||(t[n]=function(){t[n].queue||(t[n].queue=[]);for(var e=arguments.length,r=new Array(e),o=0;o<e;o++)r[o]=arguments[o];t[n].queue.push(r)}),t[n].version=at,l=t[n],function(e){var t="[Autocomplete]: Could not load search-insights.js. Please load it manually following https://alg.li/insights-autocomplete";try{var n=e.document.createElement("script");n.async=!0,n.src=st,n.onerror=function(){console.error(t)},document.body.appendChild(n)}catch(r){console.error(t)}}(t))}),!l)return{};r&&l("init",ot({partial:!0},r));var c=Ze(l),u=Le([]),p=Ne(function(e){var t=e.state;if(t.isOpen){var n=t.collections.reduce(function(e,t){return[].concat(tt(e),tt(t.items))},[]).filter(Xe);De(u.current.map(function(e){return e.objectID}),n.map(function(e){return e.objectID}))||(u.current=n,n.length>0&<({onItemsChange:o,items:n,insights:c,state:t}))}},0);return{name:"aa.algoliaInsightsPlugin",subscribe:function(e){var t=e.setContext,n=e.onSelect,r=e.onActive;function o(e){t({algoliaInsightsPlugin:{__algoliaSearchParameters:ot(ot({},s?{clickAnalytics:!0}:{}),e?{userToken:pt(e)}:{}),insights:c}})}l("addAlgoliaAgent","insights-plugin"),o(),l("onUserTokenChange",function(e){o(e)}),l("getUserToken",null,function(e,t){o(t)}),n(function(e){var t=e.item,n=e.state,r=e.event,o=e.source;Xe(t)&&i({state:n,event:r,insights:c,item:t,insightsEvents:[ot({eventName:"Item Selected"},Me({item:t,items:o.getItems().filter(Xe)}))]})}),r(function(e){var t=e.item,n=e.source,r=e.state,o=e.event;Xe(t)&&a({state:r,event:o,insights:c,item:t,insightsEvents:[ot({eventName:"Item Active"},Me({item:t,items:n.getItems().filter(Xe)}))]})})},onStateChange:function(e){var t=e.state;p({state:t})},__autocomplete_pluginOptions:e}}function ut(){var e,t=arguments.length>1?arguments[1]:void 0;return[].concat(tt(arguments.length>0&&void 0!==arguments[0]?arguments[0]:[]),["autocomplete-internal"],tt(null!==(e=t.algoliaInsightsPlugin)&&void 0!==e&&e.__automaticInsights?["autocomplete-automatic"]:[]))}function pt(e){return"number"==typeof e?e.toString():e}var dt,ft=!0;function mt(e){return mt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},mt(e)}function ht(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function vt(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==mt(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==mt(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===mt(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function gt(e,t,n){var r,o=t.initialState;return{getState:function(){return o},dispatch:function(r,i){var a=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?ht(Object(n),!0).forEach(function(t){vt(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):ht(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}({},o);o=e(o,{type:r,props:t,payload:i}),n({state:o,prevState:a})},pendingRequests:(r=[],{add:function(e){return r.push(e),e.finally(function(){r=r.filter(function(t){return t!==e})})},cancelAll:function(){r.forEach(function(e){return e.cancel()})},isEmpty:function(){return 0===r.length},wait:function(e){return ft?(ft=!1,dt=e?Promise.race([Promise.all(r),new Promise(function(t){return setTimeout(t,e)})]):Promise.all(r),dt.then(function(){ft=!0})):dt}})}}function bt(e){return e.reduce(function(e,t){return e.concat(t)},[])}function yt(e){return yt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},yt(e)}function wt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function xt(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?wt(Object(n),!0).forEach(function(t){kt(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):wt(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function kt(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==yt(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==yt(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===yt(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function _t(e){return 0===e.collections.length?0:e.collections.reduce(function(e,t){return e+t.items.length},0)}var St=0;function Et(){return"autocomplete-".concat(St++)}function Ot(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function jt(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Ot(Object(n),!0).forEach(function(t){Pt(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Ot(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Pt(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Ct(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Ct(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Ct(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Ct(e){return Ct="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Ct(e)}function At(e){return At="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},At(e)}function Tt(e){return function(e){if(Array.isArray(e))return It(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return It(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return It(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function It(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function Nt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Lt(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Nt(Object(n),!0).forEach(function(t){Rt(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Nt(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Rt(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==At(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==At(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===At(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Dt(e,t){var n,r="undefined"!=typeof window?window:{},o=e.plugins||[];return Lt(Lt({debug:!1,openOnFocus:!1,enterKeyHint:void 0,ignoreCompositionEvents:!1,placeholder:"",autoFocus:!1,defaultActiveItemId:null,stallThreshold:300,insights:void 0,environment:r,shouldPanelOpen:function(e){return _t(e.state)>0},reshape:function(e){return e.sources}},e),{},{id:null!==(n=e.id)&&void 0!==n?n:Et(),plugins:o,initialState:Lt({activeItemId:null,query:"",completion:null,collections:[],isOpen:!1,status:"idle",context:{}},e.initialState),onStateChange:function(t){var n;null===(n=e.onStateChange)||void 0===n||n.call(e,t),o.forEach(function(e){var n;return null===(n=e.onStateChange)||void 0===n?void 0:n.call(e,t)})},onSubmit:function(t){var n;null===(n=e.onSubmit)||void 0===n||n.call(e,t),o.forEach(function(e){var n;return null===(n=e.onSubmit)||void 0===n?void 0:n.call(e,t)})},onReset:function(t){var n;null===(n=e.onReset)||void 0===n||n.call(e,t),o.forEach(function(e){var n;return null===(n=e.onReset)||void 0===n?void 0:n.call(e,t)})},getSources:function(n){return Promise.all([].concat(Tt(o.map(function(e){return e.getSources})),[e.getSources]).filter(Boolean).map(function(e){return function(e,t){var n=[];return Promise.resolve(e(t)).then(function(e){return Array.isArray(e),Promise.all(e.filter(function(e){return Boolean(e)}).map(function(e){if(e.sourceId,n.includes(e.sourceId))throw new Error("[Autocomplete] The `sourceId` ".concat(JSON.stringify(e.sourceId)," is not unique."));n.push(e.sourceId);var t={getItemInputValue:function(e){return e.state.query},getItemUrl:function(){},onSelect:function(e){(0,e.setIsOpen)(!1)},onActive:Fe,onResolve:Fe};Object.keys(t).forEach(function(e){t[e].__default=!0});var r=jt(jt({},t),e);return Promise.resolve(r)}))})}(e,n)})).then(function(e){return bt(e)}).then(function(e){return e.map(function(e){return Lt(Lt({},e),{},{onSelect:function(n){e.onSelect(n),t.forEach(function(e){var t;return null===(t=e.onSelect)||void 0===t?void 0:t.call(e,n)})},onActive:function(n){e.onActive(n),t.forEach(function(e){var t;return null===(t=e.onActive)||void 0===t?void 0:t.call(e,n)})},onResolve:function(n){e.onResolve(n),t.forEach(function(e){var t;return null===(t=e.onResolve)||void 0===t?void 0:t.call(e,n)})}})})})},navigator:Lt({navigate:function(e){var t=e.itemUrl;r.location.assign(t)},navigateNewTab:function(e){var t=e.itemUrl,n=r.open(t,"_blank","noopener");null==n||n.focus()},navigateNewWindow:function(e){var t=e.itemUrl;r.open(t,"_blank","noopener")}},e.navigator)})}function Ft(e){return Ft="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Ft(e)}function Mt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Bt(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Mt(Object(n),!0).forEach(function(t){zt(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Mt(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function zt(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Ft(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Ft(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Ft(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function $t(e){return $t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},$t(e)}function Ut(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Vt(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Ut(Object(n),!0).forEach(function(t){Qt(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Ut(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Qt(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==$t(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==$t(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===$t(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Ht(e){return function(e){if(Array.isArray(e))return Wt(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return Wt(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Wt(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Wt(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function qt(e){return Boolean(e.execute)}function Gt(e,t,n){if(o=e,Boolean(null==o?void 0:o.execute)){var r="algolia"===e.requesterId?Object.assign.apply(Object,[{}].concat(Ht(Object.keys(n.context).map(function(e){var t;return null===(t=n.context[e])||void 0===t?void 0:t.__algoliaSearchParameters})))):{};return Vt(Vt({},e),{},{requests:e.queries.map(function(n){return{query:"algolia"===e.requesterId?Vt(Vt({},n),{},{params:Vt(Vt({},r),n.params)}):n,sourceId:t,transformResponse:e.transformResponse}})})}var o;return{items:e,sourceId:t}}function Kt(e){var t=e.reduce(function(e,t){if(!qt(t))return e.push(t),e;var n=t.searchClient,r=t.execute,o=t.requesterId,i=t.requests,a=e.find(function(e){return qt(t)&&qt(e)&&e.searchClient===n&&Boolean(o)&&e.requesterId===o});if(a){var s;(s=a.items).push.apply(s,Ht(i))}else{var l={execute:r,requesterId:o,items:i,searchClient:n};e.push(l)}return e},[]).map(function(e){if(!qt(e))return Promise.resolve(e);var t=e,n=t.execute,r=t.items;return n({searchClient:t.searchClient,requests:r})});return Promise.all(t).then(function(e){return bt(e)})}function Yt(e,t,n){return t.map(function(t){var r,o=e.filter(function(e){return e.sourceId===t.sourceId}),i=o.map(function(e){return e.items}),a=o[0].transformResponse,s=a?a({results:r=i,hits:r.map(function(e){return e.hits}).filter(Boolean),facetHits:r.map(function(e){var t;return null===(t=e.facetHits)||void 0===t?void 0:t.map(function(e){return{label:e.value,count:e.count,_highlightResult:{label:{value:e.highlighted}}}})}).filter(Boolean)}):i;return t.onResolve({source:t,results:i,items:s,state:n.getState()}),Array.isArray(s),s.every(Boolean),'The `getItems` function from source "'.concat(t.sourceId,'" must return an array of items but returned ').concat(JSON.stringify(void 0),".\n\nDid you forget to return items?\n\nSee: https://www.algolia.com/doc/ui-libraries/autocomplete/core-concepts/sources/#param-getitems"),{source:t,items:s}})}function Zt(e,t){var n=t;return{then:function(t,r){return Zt(e.then(en(t,n,e),en(r,n,e)),n)},catch:function(t){return Zt(e.catch(en(t,n,e)),n)},finally:function(t){return t&&n.onCancelList.push(t),Zt(e.finally(en(t&&function(){return n.onCancelList=[],t()},n,e)),n)},cancel:function(){n.isCanceled=!0;var e=n.onCancelList;n.onCancelList=[],e.forEach(function(e){e()})},isCanceled:function(){return!0===n.isCanceled}}}function Jt(e){return Zt(new Promise(function(t,n){return e(t,n)}),{isCanceled:!1,onCancelList:[]})}function Xt(e){return Zt(e,{isCanceled:!1,onCancelList:[]})}function en(e,t,n){return e?function(n){return t.isCanceled?n:e(n)}:n}function tn(e){var t=function(e){var t=e.collections.map(function(e){return e.items.length}).reduce(function(e,t,n){var r=(e[n-1]||0)+t;return e.push(r),e},[]).reduce(function(t,n){return n<=e.activeItemId?t+1:t},0);return e.collections[t]}(e);if(!t)return null;var n=t.items[function(e){for(var t=e.state,n=e.collection,r=!1,o=0,i=0;!1===r;){var a=t.collections[o];if(a===n){r=!0;break}i+=a.items.length,o++}return t.activeItemId-i}({state:e,collection:t})],r=t.source;return{item:n,itemInputValue:r.getItemInputValue({item:n,state:e}),itemUrl:r.getItemUrl({item:n,state:e}),source:r}}function nn(e){return nn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},nn(e)}Jt.resolve=function(e){return Xt(Promise.resolve(e))},Jt.reject=function(e){return Xt(Promise.reject(e))};var rn=["event","nextState","props","query","refresh","store"];function on(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function an(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?on(Object(n),!0).forEach(function(t){sn(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):on(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function sn(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==nn(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==nn(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===nn(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function ln(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var cn,un,pn,dn=null,fn=(cn=-1,un=-1,pn=void 0,function(e){var t=++cn;return Promise.resolve(e).then(function(e){return pn&&t<un?pn:(un=t,pn=e,e)})});function mn(e){var t=e.event,n=e.nextState,r=void 0===n?{}:n,o=e.props,i=e.query,a=e.refresh,s=e.store,l=ln(e,rn);dn&&o.environment.clearTimeout(dn);var c=l.setCollections,u=l.setIsOpen,p=l.setQuery,d=l.setActiveItemId,f=l.setStatus,m=l.setContext;if(p(i),d(o.defaultActiveItemId),!i&&!1===o.openOnFocus){var h,v=s.getState().collections.map(function(e){return an(an({},e),{},{items:[]})});f("idle"),c(v),u(null!==(h=r.isOpen)&&void 0!==h?h:o.shouldPanelOpen({state:s.getState()}));var g=Xt(fn(v).then(function(){return Promise.resolve()}));return s.pendingRequests.add(g)}f("loading"),dn=o.environment.setTimeout(function(){f("stalled")},o.stallThreshold);var b=Xt(fn(o.getSources(an({query:i,refresh:a,state:s.getState()},l)).then(function(e){return Promise.all(e.map(function(e){return Promise.resolve(e.getItems(an({query:i,refresh:a,state:s.getState()},l))).then(function(t){return Gt(t,e.sourceId,s.getState())})})).then(Kt).then(function(t){var n,r=t.some(function(e){return function(e){return!Array.isArray(e)&&Boolean(null==e?void 0:e._automaticInsights)}(e.items)});r&&m({algoliaInsightsPlugin:an(an({},(null===(n=s.getState().context)||void 0===n?void 0:n.algoliaInsightsPlugin)||{}),{},{__automaticInsights:r})});return Yt(t,e,s)}).then(function(e){return function(e){var t=e.collections,n=e.props,r=e.state,o=t.reduce(function(e,t){return Bt(Bt({},e),{},zt({},t.source.sourceId,Bt(Bt({},t.source),{},{getItems:function(){return bt(t.items)}})))},{}),i=n.plugins.reduce(function(e,t){return t.reshape?t.reshape(e):e},{sourcesBySourceId:o,state:r}).sourcesBySourceId;return bt(n.reshape({sourcesBySourceId:i,sources:Object.values(i),state:r})).filter(Boolean).map(function(e){return{source:e,items:e.getItems()}})}({collections:e,props:o,state:s.getState()})})}))).then(function(e){var n;f("idle"),c(e);var p=o.shouldPanelOpen({state:s.getState()});u(null!==(n=r.isOpen)&&void 0!==n?n:o.openOnFocus&&!i&&p||p);var d=tn(s.getState());if(null!==s.getState().activeItemId&&d){var m=d.item,h=d.itemInputValue,v=d.itemUrl,g=d.source;g.onActive(an({event:t,item:m,itemInputValue:h,itemUrl:v,refresh:a,source:g,state:s.getState()},l))}}).finally(function(){f("idle"),dn&&o.environment.clearTimeout(dn)});return s.pendingRequests.add(b)}function hn(e,t,n){return[e,null==n?void 0:n.sourceId,t].filter(Boolean).join("-").replace(/\s/g,"")}function vn(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return gn(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return gn(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,o=function(){};return{s:o,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,a=!0,s=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return a=e.done,e},e:function(e){s=!0,i=e},f:function(){try{a||null==n.return||n.return()}finally{if(s)throw i}}}}function gn(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}var bn=function(e,t){var n,r=!1,o=[],i=vn(e);try{for(i.s();!(n=i.n()).done;){var a,s,l,c=null===(a=n.value.__autocomplete_pluginOptions)||void 0===a||null===(s=(l=a).awaitSubmit)||void 0===s?void 0:s.call(l);if("number"==typeof c)o.push(c);else if(!0===c){r=!0;break}}}catch(u){i.e(u)}finally{i.f()}return r?t.wait():o.length>0?t.wait(Math.max.apply(Math,o)):void 0};function yn(e){return yn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},yn(e)}var wn=["event","props","refresh","store"];function xn(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function kn(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?xn(Object(n),!0).forEach(function(t){_n(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):xn(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function _n(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==yn(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==yn(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===yn(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Sn(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var En=/((gt|sm)-|galaxy nexus)|samsung[- ]|samsungbrowser/i;function On(e){return e.nativeEvent||e}function jn(e){return jn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},jn(e)}var Pn=["props","refresh","store"],Cn=["inputElement","formElement","panelElement"],An=["inputElement"],Tn=["inputElement","maxLength"],In=["source"],Nn=["item","source"];function Ln(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Rn(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Ln(Object(n),!0).forEach(function(t){Dn(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Ln(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Dn(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==jn(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==jn(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===jn(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Fn(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function Mn(e){var t=e.props,n=e.refresh,r=e.store,o=Fn(e,Pn);return{getEnvironmentProps:function(e){var n=e.inputElement,o=e.formElement,i=e.panelElement;function a(e){!r.getState().isOpen&&r.pendingRequests.isEmpty()||e.target===n||!1===[o,i].some(function(t){return n=t,r=e.target,n===r||n.contains(r);var n,r})&&(r.dispatch("blur",null),t.debug||r.pendingRequests.cancelAll())}return Rn({onTouchStart:a,onMouseDown:a,onTouchMove:function(e){!1!==r.getState().isOpen&&n===t.environment.document.activeElement&&e.target!==n&&n.blur()}},Fn(e,Cn))},getRootProps:function(e){return Rn({role:"combobox","aria-expanded":r.getState().isOpen,"aria-haspopup":"listbox","aria-controls":r.getState().isOpen?r.getState().collections.map(function(e){var n=e.source;return hn(t.id,"list",n)}).join(" "):void 0,"aria-labelledby":hn(t.id,"label")},e)},getFormProps:function(e){e.inputElement;var i=Fn(e,An),a=function(i){var a;t.onSubmit(Rn({event:i,refresh:n,state:r.getState()},o)),r.dispatch("submit",null),null===(a=e.inputElement)||void 0===a||a.blur()};return Rn({action:"",noValidate:!0,role:"search",onSubmit:function(e){e.preventDefault();var n=bn(t.plugins,r.pendingRequests);void 0!==n?n.then(function(){return a(e)}):a(e)},onReset:function(i){var a;i.preventDefault(),t.onReset(Rn({event:i,refresh:n,state:r.getState()},o)),r.dispatch("reset",null),null===(a=e.inputElement)||void 0===a||a.focus()}},i)},getLabelProps:function(e){return Rn({htmlFor:hn(t.id,"input"),id:hn(t.id,"label")},e)},getInputProps:function(e){var i;function a(e){(t.openOnFocus||Boolean(r.getState().query))&&mn(Rn({event:e,props:t,query:r.getState().completion||r.getState().query,refresh:n,store:r},o)),r.dispatch("focus",null)}var s=e||{},l=(s.inputElement,s.maxLength),c=void 0===l?512:l,u=Fn(s,Tn),p=tn(r.getState()),d=function(e){return Boolean(e&&e.match(En))}((null===(i=t.environment.navigator)||void 0===i?void 0:i.userAgent)||""),f=t.enterKeyHint||(null!=p&&p.itemUrl&&!d?"go":"search");return Rn({"aria-autocomplete":"both","aria-activedescendant":r.getState().isOpen&&null!==r.getState().activeItemId?hn(t.id,"item-".concat(r.getState().activeItemId),null==p?void 0:p.source):void 0,"aria-controls":r.getState().isOpen?r.getState().collections.filter(function(e){return e.items.length>0}).map(function(e){var n=e.source;return hn(t.id,"list",n)}).join(" "):void 0,"aria-labelledby":hn(t.id,"label"),value:r.getState().completion||r.getState().query,id:hn(t.id,"input"),autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",enterKeyHint:f,spellCheck:"false",autoFocus:t.autoFocus,placeholder:t.placeholder,maxLength:c,type:"search",onChange:function(e){var i=e.currentTarget.value;t.ignoreCompositionEvents&&On(e).isComposing?o.setQuery(i):mn(Rn({event:e,props:t,query:i.slice(0,c),refresh:n,store:r},o))},onCompositionEnd:function(e){mn(Rn({event:e,props:t,query:e.currentTarget.value.slice(0,c),refresh:n,store:r},o))},onKeyDown:function(e){On(e).isComposing||function(e){var t=e.event,n=e.props,r=e.refresh,o=e.store,i=Sn(e,wn);if("ArrowUp"===t.key||"ArrowDown"===t.key){var a=function(){var e=tn(o.getState()),t=n.environment.document.getElementById(hn(n.id,"item-".concat(o.getState().activeItemId),null==e?void 0:e.source));t&&(t.scrollIntoViewIfNeeded?t.scrollIntoViewIfNeeded(!1):t.scrollIntoView(!1))},s=function(){var e=tn(o.getState());if(null!==o.getState().activeItemId&&e){var n=e.item,a=e.itemInputValue,s=e.itemUrl,l=e.source;l.onActive(kn({event:t,item:n,itemInputValue:a,itemUrl:s,refresh:r,source:l,state:o.getState()},i))}};t.preventDefault(),!1===o.getState().isOpen&&(n.openOnFocus||Boolean(o.getState().query))?mn(kn({event:t,props:n,query:o.getState().query,refresh:r,store:o},i)).then(function(){o.dispatch(t.key,{nextActiveItemId:n.defaultActiveItemId}),s(),setTimeout(a,0)}):(o.dispatch(t.key,{}),s(),a())}else if("Escape"===t.key)t.preventDefault(),o.dispatch(t.key,null),o.pendingRequests.cancelAll();else if("Tab"===t.key)o.dispatch("blur",null),o.pendingRequests.cancelAll();else if("Enter"===t.key){if(null===o.getState().activeItemId||o.getState().collections.every(function(e){return 0===e.items.length})){var l=bn(n.plugins,o.pendingRequests);return void(void 0!==l?l.then(o.pendingRequests.cancelAll):n.debug||o.pendingRequests.cancelAll())}t.preventDefault();var c=tn(o.getState()),u=c.item,p=c.itemInputValue,d=c.itemUrl,f=c.source;if(t.metaKey||t.ctrlKey)void 0!==d&&(f.onSelect(kn({event:t,item:u,itemInputValue:p,itemUrl:d,refresh:r,source:f,state:o.getState()},i)),n.navigator.navigateNewTab({itemUrl:d,item:u,state:o.getState()}));else if(t.shiftKey)void 0!==d&&(f.onSelect(kn({event:t,item:u,itemInputValue:p,itemUrl:d,refresh:r,source:f,state:o.getState()},i)),n.navigator.navigateNewWindow({itemUrl:d,item:u,state:o.getState()}));else if(t.altKey);else{if(void 0!==d)return f.onSelect(kn({event:t,item:u,itemInputValue:p,itemUrl:d,refresh:r,source:f,state:o.getState()},i)),void n.navigator.navigate({itemUrl:d,item:u,state:o.getState()});mn(kn({event:t,nextState:{isOpen:!1},props:n,query:p,refresh:r,store:o},i)).then(function(){f.onSelect(kn({event:t,item:u,itemInputValue:p,itemUrl:d,refresh:r,source:f,state:o.getState()},i))})}}}(Rn({event:e,props:t,refresh:n,store:r},o))},onFocus:a,onBlur:Fe,onClick:function(n){e.inputElement!==t.environment.document.activeElement||r.getState().isOpen||a(n)}},u)},getPanelProps:function(e){return Rn({onMouseDown:function(e){e.preventDefault()},onMouseLeave:function(){r.dispatch("mouseleave",null)}},e)},getListProps:function(e){var n=e||{},r=n.source,o=Fn(n,In);return Rn({role:"listbox","aria-labelledby":hn(t.id,"label"),id:hn(t.id,"list",r)},o)},getItemProps:function(e){var i=e.item,a=e.source,s=Fn(e,Nn);return Rn({id:hn(t.id,"item-".concat(i.__autocomplete_id),a),role:"option","aria-selected":r.getState().activeItemId===i.__autocomplete_id,onMouseMove:function(e){if(i.__autocomplete_id!==r.getState().activeItemId){r.dispatch("mousemove",i.__autocomplete_id);var t=tn(r.getState());if(null!==r.getState().activeItemId&&t){var a=t.item,s=t.itemInputValue,l=t.itemUrl,c=t.source;c.onActive(Rn({event:e,item:a,itemInputValue:s,itemUrl:l,refresh:n,source:c,state:r.getState()},o))}}},onMouseDown:function(e){e.preventDefault()},onClick:function(e){var s=a.getItemInputValue({item:i,state:r.getState()}),l=a.getItemUrl({item:i,state:r.getState()});(l?Promise.resolve():mn(Rn({event:e,nextState:{isOpen:!1},props:t,query:s,refresh:n,store:r},o))).then(function(){a.onSelect(Rn({event:e,item:i,itemInputValue:s,itemUrl:l,refresh:n,source:a,state:r.getState()},o))})}},s)}}}var Bn="1.19.4",zn=[{segment:"autocomplete-core",version:Bn}];function $n(e){return $n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},$n(e)}function Un(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Vn(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Un(Object(n),!0).forEach(function(t){Qn(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Un(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Qn(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==$n(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==$n(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===$n(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Hn(e){var t,n,r,o,i=e.plugins,a=e.options,s=null===(t=((null===(n=a.__autocomplete_metadata)||void 0===n?void 0:n.userAgents)||[])[0])||void 0===t?void 0:t.segment,l=s?Qn({},s,Object.keys((null===(r=a.__autocomplete_metadata)||void 0===r?void 0:r.options)||{})):{};return{plugins:i.map(function(e){return{name:e.name,options:Object.keys(e.__autocomplete_pluginOptions||[])}}),options:Vn({"autocomplete-core":Object.keys(a)},l),ua:zn.concat((null===(o=a.__autocomplete_metadata)||void 0===o?void 0:o.userAgents)||[])}}function Wn(e){var t,n=e.state;return!1===n.isOpen||null===n.activeItemId?null:(null===(t=tn(n))||void 0===t?void 0:t.itemInputValue)||null}function qn(e,t,n,r){if(!n)return null;if(e<0&&(null===t||null!==r&&0===t))return n+e;var o=(null===t?-1:t)+e;return o<=-1||o>=n?null===r?null:0:o}function Gn(e){return Gn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Gn(e)}function Kn(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Yn(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Kn(Object(n),!0).forEach(function(t){Zn(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Kn(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Zn(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Gn(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Gn(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Gn(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var Jn=function(e,t){switch(t.type){case"setActiveItemId":case"mousemove":return Yn(Yn({},e),{},{activeItemId:t.payload});case"setQuery":return Yn(Yn({},e),{},{query:t.payload,completion:null});case"setCollections":return Yn(Yn({},e),{},{collections:t.payload});case"setIsOpen":return Yn(Yn({},e),{},{isOpen:t.payload});case"setStatus":return Yn(Yn({},e),{},{status:t.payload});case"setContext":return Yn(Yn({},e),{},{context:Yn(Yn({},e.context),t.payload)});case"ArrowDown":var n=Yn(Yn({},e),{},{activeItemId:t.payload.hasOwnProperty("nextActiveItemId")?t.payload.nextActiveItemId:qn(1,e.activeItemId,_t(e),t.props.defaultActiveItemId)});return Yn(Yn({},n),{},{completion:Wn({state:n})});case"ArrowUp":var r=Yn(Yn({},e),{},{activeItemId:qn(-1,e.activeItemId,_t(e),t.props.defaultActiveItemId)});return Yn(Yn({},r),{},{completion:Wn({state:r})});case"Escape":return e.isOpen?Yn(Yn({},e),{},{activeItemId:null,isOpen:!1,completion:null}):Yn(Yn({},e),{},{activeItemId:null,query:"",status:"idle",collections:[]});case"submit":return Yn(Yn({},e),{},{activeItemId:null,isOpen:!1,status:"idle"});case"reset":return Yn(Yn({},e),{},{activeItemId:!0===t.props.openOnFocus?t.props.defaultActiveItemId:null,status:"idle",completion:null,query:""});case"focus":return Yn(Yn({},e),{},{activeItemId:t.props.defaultActiveItemId,isOpen:(t.props.openOnFocus||Boolean(e.query))&&t.props.shouldPanelOpen({state:e})});case"blur":return t.props.debug?e:Yn(Yn({},e),{},{isOpen:!1,activeItemId:null});case"mouseleave":return Yn(Yn({},e),{},{activeItemId:t.props.defaultActiveItemId});default:return"The reducer action ".concat(JSON.stringify(t.type)," is not supported."),e}};function Xn(e){return Xn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Xn(e)}function er(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function tr(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?er(Object(n),!0).forEach(function(t){nr(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):er(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function nr(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Xn(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Xn(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Xn(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function rr(e){var t=[],n=Dt(e,t),r=gt(Jn,n,function(e){var t,r,i=e.prevState,c=e.state;if(n.onStateChange(tr({prevState:i,state:c,refresh:a,navigator:n.navigator},o)),!l()&&null!==(t=c.context)&&void 0!==t&&null!==(r=t.algoliaInsightsPlugin)&&void 0!==r&&r.__automaticInsights&&!1!==n.insights){var u=ct({__autocomplete_clickAnalytics:!1});n.plugins.push(u),s([u])}}),o=function(e){var t=e.store;return{setActiveItemId:function(e){t.dispatch("setActiveItemId",e)},setQuery:function(e){t.dispatch("setQuery",e)},setCollections:function(e){var n=0,r=e.map(function(e){return xt(xt({},e),{},{items:bt(e.items).map(function(e){return xt(xt({},e),{},{__autocomplete_id:n++})})})});t.dispatch("setCollections",r)},setIsOpen:function(e){t.dispatch("setIsOpen",e)},setStatus:function(e){t.dispatch("setStatus",e)},setContext:function(e){t.dispatch("setContext",e)}}}({store:r}),i=Mn(tr({props:n,refresh:a,store:r,navigator:n.navigator},o));function a(){return mn(tr({event:new Event("input"),nextState:{isOpen:r.getState().isOpen},props:n,navigator:n.navigator,query:r.getState().query,refresh:a,store:r},o))}function s(e){e.forEach(function(e){var r;return null===(r=e.subscribe)||void 0===r?void 0:r.call(e,tr(tr({},o),{},{navigator:n.navigator,refresh:a,onSelect:function(e){t.push({onSelect:e})},onActive:function(e){t.push({onActive:e})},onResolve:function(e){t.push({onResolve:e})}}))})}function l(){return n.plugins.some(function(e){return"aa.algoliaInsightsPlugin"===e.name})}if(n.insights&&!l()){var c="boolean"==typeof n.insights?{}:n.insights;n.plugins.push(ct(c))}return s(n.plugins),function(e){var t,n,r=e.metadata,o=e.environment;if(null===(t=o.navigator)||void 0===t||null===(n=t.userAgent)||void 0===n?void 0:n.includes("Algolia Crawler")){var i=o.document.createElement("meta"),a=o.document.querySelector("head");i.name="algolia:metadata",setTimeout(function(){i.content=JSON.stringify(r),a.appendChild(i)},0)}}({metadata:Hn({plugins:n.plugins,options:e}),environment:n.environment}),tr(tr({refresh:a,navigator:n.navigator},i),o)}var or=function(e,t,n,r){var o;t[0]=0;for(var i=1;i<t.length;i++){var a=t[i++],s=t[i]?(t[0]|=a?1:2,n[t[i++]]):t[++i];3===a?r[0]=s:4===a?r[1]=Object.assign(r[1]||{},s):5===a?(r[1]=r[1]||{})[t[++i]]=s:6===a?r[1][t[++i]]+=s+"":a?(o=e.apply(s,or(e,s,n,["",null])),r.push(o),s[0]?t[0]|=2:(t[i-2]=0,t[i]=o)):r.push(s)}return r},ir=new Map;function ar(e){var t=ir.get(this);return t||(t=new Map,ir.set(this,t)),(t=or(this,t.get(e)||(t.set(e,t=function(e){for(var t,n,r=1,o="",i="",a=[0],s=function(e){1===r&&(e||(o=o.replace(/^\s*\n\s*|\s*\n\s*$/g,"")))?a.push(0,e,o):3===r&&(e||o)?(a.push(3,e,o),r=2):2===r&&"..."===o&&e?a.push(4,e,0):2===r&&o&&!e?a.push(5,0,!0,o):r>=5&&((o||!e&&5===r)&&(a.push(r,0,o,n),r=6),e&&(a.push(r,e,0,n),r=6)),o=""},l=0;l<e.length;l++){l&&(1===r&&s(),s(l));for(var c=0;c<e[l].length;c++)t=e[l][c],1===r?"<"===t?(s(),a=[a],r=3):o+=t:4===r?"--"===o&&">"===t?(r=1,o=""):o=t+o[0]:i?t===i?i="":o+=t:'"'===t||"'"===t?i=t:">"===t?(s(),r=1):r&&("="===t?(r=5,n=o,o=""):"/"===t&&(r<5||">"===e[l][c+1])?(s(),3===r&&(a=a[0]),r=a,(a=a[0]).push(2,0,r),r=0):" "===t||"\t"===t||"\n"===t||"\r"===t?(s(),r=2):o+=t),3===r&&"!--"===o&&(r=4,a=a[0])}return s(),a}(e)),t),arguments,[])).length>1?t:t[0]}var sr=function(e){var t=e.environment,n=t.document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("class","aa-SubmitIcon"),n.setAttribute("viewBox","0 0 24 24"),n.setAttribute("width","20"),n.setAttribute("height","20"),n.setAttribute("fill","currentColor");var r=t.document.createElementNS("http://www.w3.org/2000/svg","path");return r.setAttribute("d","M16.041 15.856c-0.034 0.026-0.067 0.055-0.099 0.087s-0.060 0.064-0.087 0.099c-1.258 1.213-2.969 1.958-4.855 1.958-1.933 0-3.682-0.782-4.95-2.050s-2.050-3.017-2.050-4.95 0.782-3.682 2.050-4.95 3.017-2.050 4.95-2.050 3.682 0.782 4.95 2.050 2.050 3.017 2.050 4.95c0 1.886-0.745 3.597-1.959 4.856zM21.707 20.293l-3.675-3.675c1.231-1.54 1.968-3.493 1.968-5.618 0-2.485-1.008-4.736-2.636-6.364s-3.879-2.636-6.364-2.636-4.736 1.008-6.364 2.636-2.636 3.879-2.636 6.364 1.008 4.736 2.636 6.364 3.879 2.636 6.364 2.636c2.125 0 4.078-0.737 5.618-1.968l3.675 3.675c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414z"),n.appendChild(r),n},lr=function(e){var t=e.environment,n=t.document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("class","aa-ClearIcon"),n.setAttribute("viewBox","0 0 24 24"),n.setAttribute("width","18"),n.setAttribute("height","18"),n.setAttribute("fill","currentColor");var r=t.document.createElementNS("http://www.w3.org/2000/svg","path");return r.setAttribute("d","M5.293 6.707l5.293 5.293-5.293 5.293c-0.391 0.391-0.391 1.024 0 1.414s1.024 0.391 1.414 0l5.293-5.293 5.293 5.293c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414l-5.293-5.293 5.293-5.293c0.391-0.391 0.391-1.024 0-1.414s-1.024-0.391-1.414 0l-5.293 5.293-5.293-5.293c-0.391-0.391-1.024-0.391-1.414 0s-0.391 1.024 0 1.414z"),n.appendChild(r),n},cr=function(e){var t=e.environment.document.createElementNS("http://www.w3.org/2000/svg","svg");t.setAttribute("class","aa-LoadingIcon"),t.setAttribute("viewBox","0 0 100 100"),t.setAttribute("width","20"),t.setAttribute("height","20"),t.innerHTML='<circle\n cx="50"\n cy="50"\n fill="none"\n r="35"\n stroke="currentColor"\n stroke-dasharray="164.93361431346415 56.97787143782138"\n stroke-width="6"\n>\n <animateTransform\n attributeName="transform"\n type="rotate"\n repeatCount="indefinite"\n dur="1s"\n values="0 50 50;90 50 50;180 50 50;360 50 50"\n keyTimes="0;0.40;0.65;1"\n />\n</circle>';return"pauseAnimations"in t&&function e(){t.parentElement?t.pauseAnimations():setTimeout(e,0)}(),t},ur=["ontouchstart","ontouchend","ontouchmove","ontouchcancel"];function pr(e,t,n){e[t]=null===n?"":"number"!=typeof n?n:n+"px"}function dr(e){this._listeners[e.type](e)}function fr(e,t,n){var r,o,i=e[t];if("style"===t)if("string"==typeof n)e.style=n;else if(null===n)e.style="";else for(t in n)i&&n[t]===i[t]||pr(e.style,t,n[t]);else"o"===t[0]&&"n"===t[1]?(r=t!==(t=t.replace(/Capture$/,"")),((o=t.toLowerCase())in e||ur.includes(o))&&(t=o),t=t.slice(2),e._listeners||(e._listeners={}),e._listeners[t]=n,n?i||e.addEventListener(t,dr,r):e.removeEventListener(t,dr,r)):"list"!==t&&"tagName"!==t&&"form"!==t&&"type"!==t&&"size"!==t&&"download"!==t&&"href"!==t&&t in e?e[t]=null==n?"":n:"function"!=typeof n&&"dangerouslySetInnerHTML"!==t&&(null==n||!1===n&&!/^ar/.test(t)?e.removeAttribute(t):e.setAttribute(t,n))}function mr(e){switch(e){case"onChange":return"onInput";case"onCompositionEnd":return"oncompositionend";default:return e}}function hr(e,t){for(var n in t)fr(e,mr(n),t[n])}function vr(e,t){for(var n in t)"o"===n[0]&&"n"===n[1]||fr(e,mr(n),t[n])}var gr=["children"];function br(e){return function(e){if(Array.isArray(e))return yr(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return yr(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return yr(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function yr(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function wr(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function xr(e){return function(t,n){var r=n.children,o=void 0===r?[]:r,i=wr(n,gr),a=e.document.createElement(t);return hr(a,i),a.append.apply(a,br(o)),a}}function kr(e){return kr="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},kr(e)}var _r=["autocompleteScopeApi","environment","classNames","getInputProps","getInputPropsCore","isDetached","state"];function Sr(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Er(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Sr(Object(n),!0).forEach(function(t){Or(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Sr(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Or(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==kr(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==kr(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===kr(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function jr(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function Pr(e){return Pr="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Pr(e)}function Cr(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Ar(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Cr(Object(n),!0).forEach(function(t){Tr(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Cr(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Tr(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Pr(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Pr(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Pr(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Ir(e){var t=e.autocomplete,n=e.autocompleteScopeApi,r=e.classNames,o=e.environment,i=e.isDetached,a=e.placeholder,s=void 0===a?"Search":a,l=e.propGetters,c=e.setIsModalOpen,u=e.state,p=e.translations,d=xr(o),f=l.getRootProps(Ar({state:u,props:t.getRootProps({})},n)),m=d("div",Ar({class:r.root},f)),h=d("div",{class:r.detachedContainer,onMouseDown:function(e){e.stopPropagation()}}),v=d("div",{class:r.detachedOverlay,children:[h],onMouseDown:function(){c(!1),t.setIsOpen(!1)}}),g=l.getLabelProps(Ar({state:u,props:t.getLabelProps({})},n)),b=d("button",{class:r.submitButton,type:"submit",title:p.submitButtonTitle,children:[sr({environment:o})]}),y=d("label",Ar({class:r.label,children:[b],ariaLabel:p.submitButtonTitle},g)),w=d("button",{class:r.clearButton,type:"reset",title:p.clearButtonTitle,children:[lr({environment:o})]}),x=d("div",{class:r.loadingIndicator,children:[cr({environment:o})]}),k=function(e){var t=e.autocompleteScopeApi,n=e.environment,r=(e.classNames,e.getInputProps),o=e.getInputPropsCore,i=e.isDetached,a=e.state,s=jr(e,_r),l=xr(n)("input",s),c=r(Er({state:a,props:o({inputElement:l}),inputElement:l},t));return hr(l,Er(Er({},c),{},{onKeyDown:function(e){i&&"Tab"===e.key||c.onKeyDown(e)}})),l}({class:r.input,environment:o,state:u,getInputProps:l.getInputProps,getInputPropsCore:t.getInputProps,autocompleteScopeApi:n,isDetached:i}),_=d("div",{class:r.inputWrapperPrefix,children:[y,x]}),S=d("div",{class:r.inputWrapperSuffix,children:[w]}),E=d("div",{class:r.inputWrapper,children:[k]}),O=l.getFormProps(Ar({state:u,props:t.getFormProps({inputElement:k})},n)),j=d("form",Ar({class:r.form,children:[_,E,S]},O)),P=l.getPanelProps(Ar({state:u,props:t.getPanelProps({})},n)),C=d("div",Ar({class:r.panel},P)),A=d("div",{class:r.detachedSearchButtonQuery,textContent:u.query}),T=d("div",{class:r.detachedSearchButtonPlaceholder,hidden:Boolean(u.query),textContent:s});if(i){var I=d("div",{class:r.detachedSearchButtonIcon,ariaLabel:p.detachedSearchButtonTitle,children:[sr({environment:o})]}),N=d("button",{type:"button",class:r.detachedSearchButton,title:p.detachedSearchButtonTitle,id:g.id,onClick:function(){c(!0)},children:[I,T,A]}),L=d("button",{type:"button",class:r.detachedCancelButton,textContent:p.detachedCancelButtonText,onTouchStart:function(e){e.stopPropagation()},onClick:function(){t.setIsOpen(!1),c(!1)}}),R=d("div",{class:r.detachedFormContainer,children:[j,L]});h.appendChild(R),m.appendChild(N)}else m.appendChild(j);return{detachedContainer:h,detachedOverlay:v,detachedSearchButtonQuery:A,detachedSearchButtonPlaceholder:T,inputWrapper:E,input:k,root:m,form:j,label:y,submitButton:b,clearButton:w,loadingIndicator:x,panel:C}}var Nr,Lr,Rr,Dr,Fr,Mr,Br,zr,$r,Ur,Vr,Qr={},Hr=[],Wr=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,qr=Array.isArray;function Gr(e,t){for(var n in t)e[n]=t[n];return e}function Kr(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function Yr(e,t,n){var r,o,i,a={};for(i in t)"key"==i?r=t[i]:"ref"==i?o=t[i]:a[i]=t[i];if(arguments.length>2&&(a.children=arguments.length>3?Nr.call(arguments,2):n),"function"==typeof e&&null!=e.defaultProps)for(i in e.defaultProps)void 0===a[i]&&(a[i]=e.defaultProps[i]);return Zr(e,a,r,o,null)}function Zr(e,t,n,r,o){var i={type:e,props:t,key:n,ref:r,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:null==o?++Rr:o,__i:-1,__u:0};return null==o&&null!=Lr.vnode&&Lr.vnode(i),i}function Jr(e){return e.children}function Xr(e,t){this.props=e,this.context=t}function eo(e,t){if(null==t)return e.__?eo(e.__,e.__i+1):null;for(var n;t<e.__k.length;t++)if(null!=(n=e.__k[t])&&null!=n.__e)return n.__e;return"function"==typeof e.type?eo(e):null}function to(e){var t,n;if(null!=(e=e.__)&&null!=e.__c){for(e.__e=e.__c.base=null,t=0;t<e.__k.length;t++)if(null!=(n=e.__k[t])&&null!=n.__e){e.__e=e.__c.base=n.__e;break}return to(e)}}function no(e){(!e.__d&&(e.__d=!0)&&Dr.push(e)&&!ro.__r++||Fr!=Lr.debounceRendering)&&((Fr=Lr.debounceRendering)||Mr)(ro)}function ro(){for(var e,t,n,r,o,i,a,s=1;Dr.length;)Dr.length>s&&Dr.sort(Br),e=Dr.shift(),s=Dr.length,e.__d&&(n=void 0,r=void 0,o=(r=(t=e).__v).__e,i=[],a=[],t.__P&&((n=Gr({},r)).__v=r.__v+1,Lr.vnode&&Lr.vnode(n),po(t.__P,n,r,t.__n,t.__P.namespaceURI,32&r.__u?[o]:null,i,null==o?eo(r):o,!!(32&r.__u),a),n.__v=r.__v,n.__.__k[n.__i]=n,mo(i,n,a),r.__e=r.__=null,n.__e!=o&&to(n)));ro.__r=0}function oo(e,t,n,r,o,i,a,s,l,c,u){var p,d,f,m,h,v,g,b=r&&r.__k||Hr,y=t.length;for(l=io(n,t,b,l,y),p=0;p<y;p++)null!=(f=n.__k[p])&&(d=-1==f.__i?Qr:b[f.__i]||Qr,f.__i=p,v=po(e,f,d,o,i,a,s,l,c,u),m=f.__e,f.ref&&d.ref!=f.ref&&(d.ref&&go(d.ref,null,f),u.push(f.ref,f.__c||m,f)),null==h&&null!=m&&(h=m),(g=!!(4&f.__u))||d.__k===f.__k?l=ao(f,l,e,g):"function"==typeof f.type&&void 0!==v?l=v:m&&(l=m.nextSibling),f.__u&=-7);return n.__e=h,l}function io(e,t,n,r,o){var i,a,s,l,c,u=n.length,p=u,d=0;for(e.__k=new Array(o),i=0;i<o;i++)null!=(a=t[i])&&"boolean"!=typeof a&&"function"!=typeof a?(l=i+d,(a=e.__k[i]="string"==typeof a||"number"==typeof a||"bigint"==typeof a||a.constructor==String?Zr(null,a,null,null,null):qr(a)?Zr(Jr,{children:a},null,null,null):null==a.constructor&&a.__b>0?Zr(a.type,a.props,a.key,a.ref?a.ref:null,a.__v):a).__=e,a.__b=e.__b+1,s=null,-1!=(c=a.__i=so(a,n,l,p))&&(p--,(s=n[c])&&(s.__u|=2)),null==s||null==s.__v?(-1==c&&(o>u?d--:o<u&&d++),"function"!=typeof a.type&&(a.__u|=4)):c!=l&&(c==l-1?d--:c==l+1?d++:(c>l?d--:d++,a.__u|=4))):e.__k[i]=null;if(p)for(i=0;i<u;i++)null!=(s=n[i])&&!(2&s.__u)&&(s.__e==r&&(r=eo(s)),bo(s,s));return r}function ao(e,t,n,r){var o,i;if("function"==typeof e.type){for(o=e.__k,i=0;o&&i<o.length;i++)o[i]&&(o[i].__=e,t=ao(o[i],t,n,r));return t}e.__e!=t&&(r&&(t&&e.type&&!t.parentNode&&(t=eo(e)),n.insertBefore(e.__e,t||null)),t=e.__e);do{t=t&&t.nextSibling}while(null!=t&&8==t.nodeType);return t}function so(e,t,n,r){var o,i,a,s=e.key,l=e.type,c=t[n],u=null!=c&&!(2&c.__u);if(null===c&&null==e.key||u&&s==c.key&&l==c.type)return n;if(r>(u?1:0))for(o=n-1,i=n+1;o>=0||i<t.length;)if(null!=(c=t[a=o>=0?o--:i++])&&!(2&c.__u)&&s==c.key&&l==c.type)return a;return-1}function lo(e,t,n){"-"==t[0]?e.setProperty(t,null==n?"":n):e[t]=null==n?"":"number"!=typeof n||Wr.test(t)?n:n+"px"}function co(e,t,n,r,o){var i,a;e:if("style"==t)if("string"==typeof n)e.style.cssText=n;else{if("string"==typeof r&&(e.style.cssText=r=""),r)for(t in r)n&&t in n||lo(e.style,t,"");if(n)for(t in n)r&&n[t]==r[t]||lo(e.style,t,n[t])}else if("o"==t[0]&&"n"==t[1])i=t!=(t=t.replace(zr,"$1")),a=t.toLowerCase(),t=a in e||"onFocusOut"==t||"onFocusIn"==t?a.slice(2):t.slice(2),e.l||(e.l={}),e.l[t+i]=n,n?r?n.u=r.u:(n.u=$r,e.addEventListener(t,i?Vr:Ur,i)):e.removeEventListener(t,i?Vr:Ur,i);else{if("http://www.w3.org/2000/svg"==o)t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!=t&&"height"!=t&&"href"!=t&&"list"!=t&&"form"!=t&&"tabIndex"!=t&&"download"!=t&&"rowSpan"!=t&&"colSpan"!=t&&"role"!=t&&"popover"!=t&&t in e)try{e[t]=null==n?"":n;break e}catch(e){}"function"==typeof n||(null==n||!1===n&&"-"!=t[4]?e.removeAttribute(t):e.setAttribute(t,"popover"==t&&1==n?"":n))}}function uo(e){return function(t){if(this.l){var n=this.l[t.type+e];if(null==t.t)t.t=$r++;else if(t.t<n.u)return;return n(Lr.event?Lr.event(t):t)}}}function po(e,t,n,r,o,i,a,s,l,c){var u,p,d,f,m,h,v,g,b,y,w,x,k,_,S,E,O,j=t.type;if(null!=t.constructor)return null;128&n.__u&&(l=!!(32&n.__u),i=[s=t.__e=n.__e]),(u=Lr.__b)&&u(t);e:if("function"==typeof j)try{if(g=t.props,b="prototype"in j&&j.prototype.render,y=(u=j.contextType)&&r[u.__c],w=u?y?y.props.value:u.__:r,n.__c?v=(p=t.__c=n.__c).__=p.__E:(b?t.__c=p=new j(g,w):(t.__c=p=new Xr(g,w),p.constructor=j,p.render=yo),y&&y.sub(p),p.props=g,p.state||(p.state={}),p.context=w,p.__n=r,d=p.__d=!0,p.__h=[],p._sb=[]),b&&null==p.__s&&(p.__s=p.state),b&&null!=j.getDerivedStateFromProps&&(p.__s==p.state&&(p.__s=Gr({},p.__s)),Gr(p.__s,j.getDerivedStateFromProps(g,p.__s))),f=p.props,m=p.state,p.__v=t,d)b&&null==j.getDerivedStateFromProps&&null!=p.componentWillMount&&p.componentWillMount(),b&&null!=p.componentDidMount&&p.__h.push(p.componentDidMount);else{if(b&&null==j.getDerivedStateFromProps&&g!==f&&null!=p.componentWillReceiveProps&&p.componentWillReceiveProps(g,w),!p.__e&&null!=p.shouldComponentUpdate&&!1===p.shouldComponentUpdate(g,p.__s,w)||t.__v==n.__v){for(t.__v!=n.__v&&(p.props=g,p.state=p.__s,p.__d=!1),t.__e=n.__e,t.__k=n.__k,t.__k.some(function(e){e&&(e.__=t)}),x=0;x<p._sb.length;x++)p.__h.push(p._sb[x]);p._sb=[],p.__h.length&&a.push(p);break e}null!=p.componentWillUpdate&&p.componentWillUpdate(g,p.__s,w),b&&null!=p.componentDidUpdate&&p.__h.push(function(){p.componentDidUpdate(f,m,h)})}if(p.context=w,p.props=g,p.__P=e,p.__e=!1,k=Lr.__r,_=0,b){for(p.state=p.__s,p.__d=!1,k&&k(t),u=p.render(p.props,p.state,p.context),S=0;S<p._sb.length;S++)p.__h.push(p._sb[S]);p._sb=[]}else do{p.__d=!1,k&&k(t),u=p.render(p.props,p.state,p.context),p.state=p.__s}while(p.__d&&++_<25);p.state=p.__s,null!=p.getChildContext&&(r=Gr(Gr({},r),p.getChildContext())),b&&!d&&null!=p.getSnapshotBeforeUpdate&&(h=p.getSnapshotBeforeUpdate(f,m)),E=u,null!=u&&u.type===Jr&&null==u.key&&(E=ho(u.props.children)),s=oo(e,qr(E)?E:[E],t,n,r,o,i,a,s,l,c),p.base=t.__e,t.__u&=-161,p.__h.length&&a.push(p),v&&(p.__E=p.__=null)}catch(e){if(t.__v=null,l||null!=i)if(e.then){for(t.__u|=l?160:128;s&&8==s.nodeType&&s.nextSibling;)s=s.nextSibling;i[i.indexOf(s)]=null,t.__e=s}else{for(O=i.length;O--;)Kr(i[O]);fo(t)}else t.__e=n.__e,t.__k=n.__k,e.then||fo(t);Lr.__e(e,t,n)}else null==i&&t.__v==n.__v?(t.__k=n.__k,t.__e=n.__e):s=t.__e=vo(n.__e,t,n,r,o,i,a,l,c);return(u=Lr.diffed)&&u(t),128&t.__u?void 0:s}function fo(e){e&&e.__c&&(e.__c.__e=!0),e&&e.__k&&e.__k.forEach(fo)}function mo(e,t,n){for(var r=0;r<n.length;r++)go(n[r],n[++r],n[++r]);Lr.__c&&Lr.__c(t,e),e.some(function(t){try{e=t.__h,t.__h=[],e.some(function(e){e.call(t)})}catch(e){Lr.__e(e,t.__v)}})}function ho(e){return"object"!=typeof e||null==e||e.__b&&e.__b>0?e:qr(e)?e.map(ho):Gr({},e)}function vo(e,t,n,r,o,i,a,s,l){var c,u,p,d,f,m,h,v=n.props,g=t.props,b=t.type;if("svg"==b?o="http://www.w3.org/2000/svg":"math"==b?o="http://www.w3.org/1998/Math/MathML":o||(o="http://www.w3.org/1999/xhtml"),null!=i)for(c=0;c<i.length;c++)if((f=i[c])&&"setAttribute"in f==!!b&&(b?f.localName==b:3==f.nodeType)){e=f,i[c]=null;break}if(null==e){if(null==b)return document.createTextNode(g);e=document.createElementNS(o,b,g.is&&g),s&&(Lr.__m&&Lr.__m(t,i),s=!1),i=null}if(null==b)v===g||s&&e.data==g||(e.data=g);else{if(i=i&&Nr.call(e.childNodes),v=n.props||Qr,!s&&null!=i)for(v={},c=0;c<e.attributes.length;c++)v[(f=e.attributes[c]).name]=f.value;for(c in v)if(f=v[c],"children"==c);else if("dangerouslySetInnerHTML"==c)p=f;else if(!(c in g)){if("value"==c&&"defaultValue"in g||"checked"==c&&"defaultChecked"in g)continue;co(e,c,null,f,o)}for(c in g)f=g[c],"children"==c?d=f:"dangerouslySetInnerHTML"==c?u=f:"value"==c?m=f:"checked"==c?h=f:s&&"function"!=typeof f||v[c]===f||co(e,c,f,v[c],o);if(u)s||p&&(u.__html==p.__html||u.__html==e.innerHTML)||(e.innerHTML=u.__html),t.__k=[];else if(p&&(e.innerHTML=""),oo("template"==t.type?e.content:e,qr(d)?d:[d],t,n,r,"foreignObject"==b?"http://www.w3.org/1999/xhtml":o,i,a,i?i[0]:n.__k&&eo(n,0),s,l),null!=i)for(c=i.length;c--;)Kr(i[c]);s||(c="value","progress"==b&&null==m?e.removeAttribute("value"):null!=m&&(m!==e[c]||"progress"==b&&!m||"option"==b&&m!=v[c])&&co(e,c,m,v[c],o),c="checked",null!=h&&h!=e[c]&&co(e,c,h,v[c],o))}return e}function go(e,t,n){try{if("function"==typeof e){var r="function"==typeof e.__u;r&&e.__u(),r&&null==t||(e.__u=e(t))}else e.current=t}catch(e){Lr.__e(e,n)}}function bo(e,t,n){var r,o;if(Lr.unmount&&Lr.unmount(e),(r=e.ref)&&(r.current&&r.current!=e.__e||go(r,null,t)),null!=(r=e.__c)){if(r.componentWillUnmount)try{r.componentWillUnmount()}catch(e){Lr.__e(e,t)}r.base=r.__P=null}if(r=e.__k)for(o=0;o<r.length;o++)r[o]&&bo(r[o],t,n||"function"!=typeof e.type);n||Kr(e.__e),e.__c=e.__=e.__e=void 0}function yo(e,t,n){return this.constructor(e,n)}function wo(e,t,n){var r,o,i,a;t==document&&(t=document.documentElement),Lr.__&&Lr.__(e,t),o=(r="function"==typeof n)?null:n&&n.__k||t.__k,i=[],a=[],po(t,e=(!r&&n||t).__k=Yr(Jr,null,[e]),o||Qr,Qr,t.namespaceURI,!r&&n?[n]:o?null:t.firstChild?Nr.call(t.childNodes):null,i,!r&&n?n:o?o.__e:t.firstChild,r,a),mo(i,e,a)}function xo(e,t){return t.reduce(function(e,t){return e&&e[t]},e)}Nr=Hr.slice,Lr={__e:function(e,t,n,r){for(var o,i,a;t=t.__;)if((o=t.__c)&&!o.__)try{if((i=o.constructor)&&null!=i.getDerivedStateFromError&&(o.setState(i.getDerivedStateFromError(e)),a=o.__d),null!=o.componentDidCatch&&(o.componentDidCatch(e,r||{}),a=o.__d),a)return o.__E=o}catch(t){e=t}throw e}},Rr=0,Xr.prototype.setState=function(e,t){var n;n=null!=this.__s&&this.__s!=this.state?this.__s:this.__s=Gr({},this.state),"function"==typeof e&&(e=e(Gr({},n),this.props)),e&&Gr(n,e),null!=e&&this.__v&&(t&&this._sb.push(t),no(this))},Xr.prototype.forceUpdate=function(e){this.__v&&(this.__e=!0,e&&this.__h.push(e),no(this))},Xr.prototype.render=Jr,Dr=[],Mr="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,Br=function(e,t){return e.__v.__b-t.__v.__b},ro.__r=0,zr=/(PointerCapture)$|Capture$/i,$r=0,Ur=uo(!1),Vr=uo(!0);function ko(e){var t=e.highlightedValue.split("__aa-highlight__"),n=t.shift(),r=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return{get:function(){return e},add:function(t){var n=e[e.length-1];(null==n?void 0:n.isHighlighted)===t.isHighlighted?e[e.length-1]={value:n.value+t.value,isHighlighted:n.isHighlighted}:e.push(t)}}}(n?[{value:n,isHighlighted:!1}]:[]);return t.forEach(function(e){var t=e.split("__/aa-highlight__");r.add({value:t[0],isHighlighted:!0}),""!==t[1]&&r.add({value:t[1],isHighlighted:!1})}),r.get()}function _o(e){return function(e){if(Array.isArray(e))return So(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return So(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return So(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function So(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function Eo(e){var t=e.hit,n=e.attribute,r=Array.isArray(n)?n:[n],o=xo(t,["_highlightResult"].concat(_o(r),["value"]));return"string"!=typeof o&&(o=xo(t,r)||""),ko({highlightedValue:o})}function Oo(e){var t=e.createElement,n=e.Fragment;function r(e){var r=e.hit,o=e.attribute,i=e.tagName,a=void 0===i?"mark":i;return t(n,{},Eo({hit:r,attribute:o}).map(function(e,n){return e.isHighlighted?t(a,{key:n},e.value):e.value}))}return r.__autocomplete_componentName="Highlight",r}var jo={"&":"&","<":"<",">":">",""":'"',"'":"'"},Po=new RegExp(/\w/i),Co=/&(amp|quot|lt|gt|#39);/g,Ao=RegExp(Co.source);function To(e,t){var n,r,o,i=e[t],a=(null===(n=e[t+1])||void 0===n?void 0:n.isHighlighted)||!0,s=(null===(r=e[t-1])||void 0===r?void 0:r.isHighlighted)||!0;return Po.test((o=i.value)&&Ao.test(o)?o.replace(Co,function(e){return jo[e]}):o)||s!==a?i.isHighlighted:s}function Io(e){return Io="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Io(e)}function No(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Lo(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?No(Object(n),!0).forEach(function(t){Ro(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):No(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Ro(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Io(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Io(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Io(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Do(e){return e.some(function(e){return e.isHighlighted})?e.map(function(t,n){return Lo(Lo({},t),{},{isHighlighted:!To(e,n)})}):e.map(function(e){return Lo(Lo({},e),{},{isHighlighted:!1})})}function Fo(e){var t=e.createElement,n=e.Fragment;function r(e){var r,o=e.hit,i=e.attribute,a=e.tagName,s=void 0===a?"mark":a;return t(n,{},(r={hit:o,attribute:i},Do(Eo(r))).map(function(e,n){return e.isHighlighted?t(s,{key:n},e.value):e.value}))}return r.__autocomplete_componentName="ReverseHighlight",r}function Mo(e){return function(e){if(Array.isArray(e))return Bo(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return Bo(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Bo(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Bo(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function zo(e){var t=e.hit,n=e.attribute,r=Array.isArray(n)?n:[n],o=xo(t,["_snippetResult"].concat(Mo(r),["value"]));return"string"!=typeof o&&(o=xo(t,r)||""),ko({highlightedValue:o})}function $o(e){var t=e.createElement,n=e.Fragment;function r(e){var r,o=e.hit,i=e.attribute,a=e.tagName,s=void 0===a?"mark":a;return t(n,{},(r={hit:o,attribute:i},Do(zo(r))).map(function(e,n){return e.isHighlighted?t(s,{key:n},e.value):e.value}))}return r.__autocomplete_componentName="ReverseSnippet",r}function Uo(e){var t=e.createElement,n=e.Fragment;function r(e){var r=e.hit,o=e.attribute,i=e.tagName,a=void 0===i?"mark":i;return t(n,{},zo({hit:r,attribute:o}).map(function(e,n){return e.isHighlighted?t(a,{key:n},e.value):e.value}))}return r.__autocomplete_componentName="Snippet",r}function Vo(e,t){if("string"==typeof t){var n=e.document.querySelector(t);return"The element ".concat(JSON.stringify(t)," is not in the document."),n}return t}function Qo(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.reduce(function(e,t){return Object.keys(t).forEach(function(n){var r=e[n],o=t[n];r!==o&&(e[n]=[r,o].filter(Boolean).join(" "))}),e},{})}function Ho(e){return Ho="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Ho(e)}var Wo=["classNames","container","getEnvironmentProps","getFormProps","getInputProps","getItemProps","getLabelProps","getListProps","getPanelProps","getRootProps","panelContainer","panelPlacement","render","renderNoResults","renderer","detachedMediaQuery","components","translations"];function qo(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Go(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?qo(Object(n),!0).forEach(function(t){Ko(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):qo(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Ko(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Ho(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Ho(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Ho(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Yo(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var Zo={clearButton:"aa-ClearButton",detachedCancelButton:"aa-DetachedCancelButton",detachedContainer:"aa-DetachedContainer",detachedFormContainer:"aa-DetachedFormContainer",detachedOverlay:"aa-DetachedOverlay",detachedSearchButton:"aa-DetachedSearchButton",detachedSearchButtonIcon:"aa-DetachedSearchButtonIcon",detachedSearchButtonPlaceholder:"aa-DetachedSearchButtonPlaceholder",detachedSearchButtonQuery:"aa-DetachedSearchButtonQuery",form:"aa-Form",input:"aa-Input",inputWrapper:"aa-InputWrapper",inputWrapperPrefix:"aa-InputWrapperPrefix",inputWrapperSuffix:"aa-InputWrapperSuffix",item:"aa-Item",label:"aa-Label",list:"aa-List",loadingIndicator:"aa-LoadingIndicator",panel:"aa-Panel",panelLayout:"aa-PanelLayout aa-Panel--scrollable",root:"aa-Autocomplete",source:"aa-Source",sourceFooter:"aa-SourceFooter",sourceHeader:"aa-SourceHeader",sourceNoResults:"aa-SourceNoResults",submitButton:"aa-SubmitButton"},Jo=function(e,t){var n=e.children;(0,e.render)(n,t)},Xo={createElement:Yr,Fragment:Jr,render:wo};function ei(e){var t=e.panelPlacement,n=e.container,r=e.form,o=e.environment,i=n.getBoundingClientRect(),a=(o.pageYOffset||o.document.documentElement.scrollTop||o.document.body.scrollTop||0)+i.top+i.height;switch(t){case"start":return{top:a,left:i.left};case"end":return{top:a,right:o.document.documentElement.clientWidth-(i.left+i.width)};case"full-width":return{top:a,left:0,right:0,width:"unset",maxWidth:"unset"};case"input-wrapper-width":var s=r.getBoundingClientRect();return{top:a,left:s.left,right:o.document.documentElement.clientWidth-(s.left+s.width),width:"unset",maxWidth:"unset"};default:throw new Error("[Autocomplete] The `panelPlacement` value ".concat(JSON.stringify(t)," is not valid."))}}function ti(e){return ti="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},ti(e)}function ni(){return ni=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},ni.apply(this,arguments)}function ri(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function oi(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?ri(Object(n),!0).forEach(function(t){ii(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):ri(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function ii(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==ti(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==ti(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===ti(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var ai=[{segment:"autocomplete-js",version:Bn}];function si(e){return function(e){if(Array.isArray(e))return li(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return li(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return li(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function li(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function ci(e){return ci="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},ci(e)}var ui=function(e){return e&&"object"===ci(e)&&"[object Object]"===Object.prototype.toString.call(e)};function pi(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.reduce(function(e,t){return Object.keys(t).forEach(function(n){var r=e[n],o=t[n];Array.isArray(r)&&Array.isArray(o)?e[n]=r.concat.apply(r,si(o)):ui(r)&&ui(o)?e[n]=pi(r,o):e[n]=o}),e},{})}function di(e){return di="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},di(e)}function fi(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function mi(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?fi(Object(n),!0).forEach(function(t){hi(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):fi(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function hi(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==di(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==di(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===di(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function vi(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,i,a,s=[],l=!0,c=!1;try{if(i=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;l=!1}else for(;!(l=(r=i.call(n)).done)&&(s.push(r.value),s.length!==t);l=!0);}catch(u){c=!0,o=u}finally{try{if(!l&&null!=n.return&&(a=n.return(),Object(a)!==a))return}finally{if(c)throw o}}return s}}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return gi(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return gi(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function gi(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}var bi=["components"];function yi(e){return yi="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},yi(e)}function wi(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function xi(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function ki(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?xi(Object(n),!0).forEach(function(t){_i(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):xi(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function _i(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==yi(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==yi(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===yi(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Si(e){var t,n=function(){var e=[],t=[];function n(n){e.push(n);var r=n();t.push(r)}return{runEffect:n,cleanupEffects:function(){var e=t;t=[],e.forEach(function(e){e()})},runEffects:function(){var t=e;e=[],t.forEach(function(e){n(e)})}}}(),r=n.runEffect,o=n.cleanupEffects,i=n.runEffects,a=(t=[],{reactive:function(e){var n=e(),r={_fn:e,_ref:{current:n},get value(){return this._ref.current},set value(e){this._ref.current=e}};return t.push(r),r},runReactives:function(){t.forEach(function(e){e._ref.current=e._fn()})}}),s=a.reactive,l=a.runReactives,c=Le(!1),u=Le(e),p=Le(void 0),d=s(function(){return function(e){var t,n=e.classNames,r=e.container,o=e.getEnvironmentProps,i=e.getFormProps,a=e.getInputProps,s=e.getItemProps,l=e.getLabelProps,c=e.getListProps,u=e.getPanelProps,p=e.getRootProps,d=e.panelContainer,f=e.panelPlacement,m=e.render,h=e.renderNoResults,v=e.renderer,g=e.detachedMediaQuery,b=e.components,y=e.translations,w=Yo(e,Wo),x="undefined"!=typeof window?window:{},k=Vo(x,r);k.tagName;var _=Go(Go({},Xo),v),S={Highlight:Oo(_),ReverseHighlight:Fo(_),ReverseSnippet:$o(_),Snippet:Uo(_)};return{renderer:{classNames:Qo(Zo,null!=n?n:{}),container:k,getEnvironmentProps:null!=o?o:function(e){return e.props},getFormProps:null!=i?i:function(e){return e.props},getInputProps:null!=a?a:function(e){return e.props},getItemProps:null!=s?s:function(e){return e.props},getLabelProps:null!=l?l:function(e){return e.props},getListProps:null!=c?c:function(e){return e.props},getPanelProps:null!=u?u:function(e){return e.props},getRootProps:null!=p?p:function(e){return e.props},panelContainer:d?Vo(x,d):x.document.body,panelPlacement:null!=f?f:"input-wrapper-width",render:null!=m?m:Jo,renderNoResults:h,renderer:_,detachedMediaQuery:null!=g?g:getComputedStyle(x.document.documentElement).getPropertyValue("--aa-detached-media-query"),components:Go(Go({},S),b),translations:Go(Go({},{clearButtonTitle:"Clear",detachedCancelButtonText:"Cancel",detachedSearchButtonTitle:"Search",submitButtonTitle:"Submit"}),y)},core:Go(Go({},w),{},{id:null!==(t=w.id)&&void 0!==t?t:Et(),environment:x})}}(u.current)}),f=s(function(){return d.value.core.environment.matchMedia(d.value.renderer.detachedMediaQuery).matches}),m=s(function(){return rr(ki(ki({},d.value.core),{},{onStateChange:function(e){var t,n,r;c.current=e.state.collections.some(function(e){return e.source.templates.noResults}),null===(t=p.current)||void 0===t||t.call(p,e),null===(n=(r=d.value.core).onStateChange)||void 0===n||n.call(r,e)},shouldPanelOpen:u.current.shouldPanelOpen||function(e){var t=e.state;if(f.value)return!0;var n=_t(t)>0;if(!d.value.core.openOnFocus&&!t.query)return n;var r=Boolean(c.current||d.value.renderer.renderNoResults);return!n&&r||n},__autocomplete_metadata:{userAgents:ai,options:e}}))}),h=Le(ki({collections:[],completion:null,context:{},isOpen:!1,query:"",activeItemId:null,status:"idle"},d.value.core.initialState)),v={getEnvironmentProps:d.value.renderer.getEnvironmentProps,getFormProps:d.value.renderer.getFormProps,getInputProps:d.value.renderer.getInputProps,getItemProps:d.value.renderer.getItemProps,getLabelProps:d.value.renderer.getLabelProps,getListProps:d.value.renderer.getListProps,getPanelProps:d.value.renderer.getPanelProps,getRootProps:d.value.renderer.getRootProps},g={setActiveItemId:m.value.setActiveItemId,setQuery:m.value.setQuery,setCollections:m.value.setCollections,setIsOpen:m.value.setIsOpen,setStatus:m.value.setStatus,setContext:m.value.setContext,refresh:m.value.refresh,navigator:m.value.navigator},b=s(function(){return ar.bind(d.value.renderer.renderer.createElement)}),y=s(function(){return Ir({autocomplete:m.value,autocompleteScopeApi:g,classNames:d.value.renderer.classNames,environment:d.value.core.environment,isDetached:f.value,placeholder:d.value.core.placeholder,propGetters:v,setIsModalOpen:_,state:h.current,translations:d.value.renderer.translations})});function w(){hr(y.value.panel,{style:f.value?{}:ei({panelPlacement:d.value.renderer.panelPlacement,container:y.value.root,form:y.value.form,environment:d.value.core.environment})})}function x(e){h.current=e;var t={autocomplete:m.value,autocompleteScopeApi:g,classNames:d.value.renderer.classNames,components:d.value.renderer.components,container:d.value.renderer.container,html:b.value,dom:y.value,panelContainer:f.value?y.value.detachedContainer:d.value.renderer.panelContainer,propGetters:v,state:h.current,renderer:d.value.renderer.renderer},n=!_t(e)&&!c.current&&d.value.renderer.renderNoResults||d.value.renderer.render;!function(e){var t=e.autocomplete,n=e.autocompleteScopeApi,r=e.dom,o=e.propGetters,i=e.state;vr(r.root,o.getRootProps(oi({state:i,props:t.getRootProps({})},n))),vr(r.input,o.getInputProps(oi({state:i,props:t.getInputProps({inputElement:r.input}),inputElement:r.input},n))),hr(r.label,{hidden:"stalled"===i.status}),hr(r.loadingIndicator,{hidden:"stalled"!==i.status}),a=r.loadingIndicator,s="stalled"===i.status,c="svg"===(null===(l=a.firstChild)||void 0===l?void 0:l.nodeName)?a.firstChild:null,c&&c.pauseAnimations&&c.unpauseAnimations&&(s?c.unpauseAnimations():c.pauseAnimations()),hr(r.clearButton,{hidden:!i.query}),hr(r.detachedSearchButtonQuery,{textContent:i.query}),hr(r.detachedSearchButtonPlaceholder,{hidden:Boolean(i.query)});var a,s,l,c}(t),function(e,t){var n=t.autocomplete,r=t.autocompleteScopeApi,o=t.classNames,i=t.html,a=t.dom,s=t.panelContainer,l=t.propGetters,c=t.state,u=t.components,p=t.renderer;if(c.isOpen){s.contains(a.panel)||"loading"===c.status||s.appendChild(a.panel),a.panel.classList.toggle("aa-Panel--stalled","stalled"===c.status);var d=c.collections.filter(function(e){var t=e.source,n=e.items;return t.templates.noResults||n.length>0}).map(function(e,t){var a=e.source,s=e.items;return p.createElement("section",{key:t,className:o.source,"data-autocomplete-source-id":a.sourceId},a.templates.header&&p.createElement("div",{className:o.sourceHeader},a.templates.header({components:u,createElement:p.createElement,Fragment:p.Fragment,items:s,source:a,state:c,html:i})),a.templates.noResults&&0===s.length?p.createElement("div",{className:o.sourceNoResults},a.templates.noResults({components:u,createElement:p.createElement,Fragment:p.Fragment,source:a,state:c,html:i})):p.createElement("ul",ni({className:o.list},l.getListProps(oi({state:c,props:n.getListProps({source:a})},r))),s.map(function(e){var t=n.getItemProps({item:e,source:a});return p.createElement("li",ni({key:t.id,className:o.item},l.getItemProps(oi({state:c,props:t},r))),a.templates.item({components:u,createElement:p.createElement,Fragment:p.Fragment,item:e,state:c,html:i}))})),a.templates.footer&&p.createElement("div",{className:o.sourceFooter},a.templates.footer({components:u,createElement:p.createElement,Fragment:p.Fragment,items:s,source:a,state:c,html:i})))}),f=p.createElement(p.Fragment,null,p.createElement("div",{className:o.panelLayout},d),p.createElement("div",{className:"aa-GradientBottom"})),m=d.reduce(function(e,t){return e[t.props["data-autocomplete-source-id"]]=t,e},{});e(oi(oi({children:f,state:c,sections:d,elements:m},p),{},{components:u,html:i},r),a.panel)}else s.contains(a.panel)&&s.removeChild(a.panel)}(n,t)}function k(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};o();var t,n,r=d.value.renderer,a=r.components,s=wi(r,bi);u.current=pi(s,d.value.core,{components:(t=a,n=function(e){return!e.value.hasOwnProperty("__autocomplete_componentName")},Object.entries(t).reduce(function(e,t){var r=vi(t,2),o=r[0],i=r[1];return n({key:o,value:i})?mi(mi({},e),{},hi({},o,i)):e},{})),initialState:h.current},e),l(),i(),m.value.refresh().then(function(){x(h.current)})}function _(e){e!==d.value.core.environment.document.body.contains(y.value.detachedOverlay)&&(e?(d.value.core.environment.document.body.appendChild(y.value.detachedOverlay),d.value.core.environment.document.body.classList.add("aa-Detached"),y.value.input.focus()):(d.value.core.environment.document.body.removeChild(y.value.detachedOverlay),d.value.core.environment.document.body.classList.remove("aa-Detached")))}return r(function(){var e=m.value.getEnvironmentProps({formElement:y.value.form,panelElement:y.value.panel,inputElement:y.value.input});return hr(d.value.core.environment,e),function(){hr(d.value.core.environment,Object.keys(e).reduce(function(e,t){return ki(ki({},e),{},_i({},t,void 0))},{}))}}),r(function(){var e=f.value?d.value.core.environment.document.body:d.value.renderer.panelContainer,t=f.value?y.value.detachedOverlay:y.value.panel;return f.value&&h.current.isOpen&&_(!0),x(h.current),function(){e.contains(t)&&(e.removeChild(t),e.classList.remove("aa-Detached"))}}),r(function(){var e=d.value.renderer.container;return e.appendChild(y.value.root),function(){e.removeChild(y.value.root)}}),r(function(){var e=Ne(function(e){x(e.state)},0);return p.current=function(t){var n=t.state,r=t.prevState;(f.value&&r.isOpen!==n.isOpen&&_(n.isOpen),f.value||!n.isOpen||r.isOpen||w(),n.query!==r.query)&&d.value.core.environment.document.querySelectorAll(".aa-Panel--scrollable").forEach(function(e){0!==e.scrollTop&&(e.scrollTop=0)});e({state:n})},function(){p.current=void 0}}),r(function(){var e=Ne(function(){var e=f.value;f.value=d.value.core.environment.matchMedia(d.value.renderer.detachedMediaQuery).matches,e!==f.value?k({}):requestAnimationFrame(w)},20);return d.value.core.environment.addEventListener("resize",e),function(){d.value.core.environment.removeEventListener("resize",e)}}),r(function(){if(!f.value)return function(){};function e(e){y.value.detachedContainer.classList.toggle("aa-DetachedContainer--modal",e)}function t(t){e(t.matches)}var n=d.value.core.environment.matchMedia(getComputedStyle(d.value.core.environment.document.documentElement).getPropertyValue("--aa-detached-modal-media-query"));e(n.matches);var r=Boolean(n.addEventListener);return r?n.addEventListener("change",t):n.addListener(t),function(){r?n.removeEventListener("change",t):n.removeListener(t)}}),r(function(){return requestAnimationFrame(w),function(){}}),ki(ki({},g),{},{update:k,destroy:function(){o()}})}const Ei=n(60774);Ei.tokenizer.separator=/[\s\-]+/;const Oi=Ei;var ji=n(689),Pi=n.n(ji);function Ci(){const e=(0,s.zy)(),t=(0,s.W6)(),{siteConfig:{baseUrl:n}}=(0,we.A)(),[o,i]=(0,r.useState)({terms:[],isDocsOrBlog:!1});return(0,r.useEffect)(()=>{if(!e.state?.cmfcmfhighlight||0===e.state.cmfcmfhighlight.terms.length)return;i(e.state.cmfcmfhighlight);const{cmfcmfhighlight:n,...r}=e.state;t.replace({...e,state:r})},[e.state?.cmfcmfhighlight,t,e]),(0,r.useEffect)(()=>{if(0===o.terms.length)return;const e=o.isDocsOrBlog?document.getElementsByTagName("article")[0]:document.getElementsByTagName("main")[0];if(!e)return;const t=new(Pi())(e),n={ignoreJoiners:!0};return t.mark(o.terms,n),()=>t.unmark(n)},[o,n]),null}var Ai=n(26503),Ti=n(61482);function Ii({document:e}){const[t,n]=e.sectionRoute.split("#");let r=t;return n&&(r+="#"+n),r}const Ni={documents:[],index:Oi(function(){this.ref("id"),this.field("title"),this.field("content")})};const Li=()=>{(0,r.useEffect)(()=>{if(!document)return;function e(){document.body.setAttribute("data-theme",document.documentElement.getAttribute("data-theme")??"")}const t=new MutationObserver(()=>{e()});return t.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme"]}),e(),()=>t.disconnect()},[]);const{siteConfig:{baseUrl:e}}=(0,we.A)(),{titleBoost:t,contentBoost:o,tagsBoost:i,parentCategoriesBoost:a,indexDocSidebarParentCategories:c,maxSearchResults:u}=(0,Ai.P_)("@cmfcmf/docusaurus-search-local"),p=(0,s.W6)(),{tags:d}=function(){const{i18n:e}=(0,we.A)(),t=n(19802).vF(),r=[Ti.C,...t];return{locale:e.currentLocale,tags:r}}(),f=(0,r.useRef)(d);(0,r.useEffect)(()=>{f.current=d},[d]);const m=(0,r.useRef)({}),h=async t=>{const n=m.current[t];switch(n?.state){case"ready":return n;case void 0:{const n=[];m.current[t]={state:"loading",callbacks:n};const r=await async function(e,t){{let r;try{const n=await fetch(`${e}search-index-${t}.json`);if(!n.ok)return Ni;r=await n.json()}catch(n){return Ni}return{documents:r.documents,index:Oi.Index.load(r.index)}}}(e,t);return n.forEach(e=>e(r)),m.current[t]={state:"ready",...r},r}case"loading":return new Promise(e=>{n.callbacks.push(e)})}},v=(0,l.T)({message:"cmfcmf/d-s-l.searchBar.placeholder",description:"Placeholder shown in the searchbar"}),g=(0,r.useRef)(null),b=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(g.current)return b.current=Si({container:g.current,placeholder:v,renderer:{createElement:r.createElement,Fragment:r.Fragment,render:(e,t)=>(0,Ie.createRoot)(t).render(e)},navigator:{navigate({item:e,itemUrl:t}){p.push(t,{cmfcmfhighlight:{terms:e.terms,isDocsOrBlog:"docs"===e.document.type||"blog"===e.document.type}})}},detachedMediaQuery:"",defaultActiveItemId:0,translations:{clearButtonTitle:(0,l.T)({message:"cmfcmf/d-s-l.searchBar.clearButtonTitle",description:"Title of the button to clear the current search input"}),detachedCancelButtonText:(0,l.T)({message:"cmfcmf/d-s-l.searchBar.detachedCancelButtonText",description:"Text of the button to close the detached search window"}),submitButtonTitle:(0,l.T)({message:"cmfcmf/d-s-l.searchBar.submitButtonTitle",description:"Title of the button to submit a new search"})},getSources:({query:e})=>[{sourceId:"search-results",templates:{item({item:e}){const t=Ii(e);return r.createElement("a",{href:t,className:"aa-ItemLink",onClick:n=>{n.preventDefault(),p.push(t,{cmfcmfhighlight:{terms:e.terms,isDocsOrBlog:"docs"===e.document.type||"blog"===e.document.type}})}},r.createElement("div",{className:"aa-ItemContent"},r.createElement("div",{className:"aa-ItemContentBody"},r.createElement("div",{className:"aa-ItemContentTitle"},e.document.sectionTitle),e.document.pageTitle!==e.document.sectionTitle&&r.createElement("div",{className:"aa-ItemContentDescription"},e.document.pageTitle))),r.createElement("div",{className:"aa-ItemActions"},r.createElement("button",{className:"aa-ItemActionButton aa-DesktopOnly aa-ActiveOnly",type:"button",title:"Select"},r.createElement("svg",{viewBox:"0 0 24 24",width:"20",height:"20",fill:"currentColor"},r.createElement("path",{d:"M18.984 6.984h2.016v6h-15.188l3.609 3.609-1.406 1.406-6-6 6-6 1.406 1.406-3.609 3.609h13.172v-4.031z"})))))},noResults:()=>r.createElement("div",{className:"aa-ItemContent"},r.createElement("div",{className:"aa-ItemContentBody"},(0,l.T)({message:"cmfcmf/d-s-l.searchBar.noResults",description:"message shown if no results are found"})))},getItemUrl:({item:e})=>Ii(e),async getItems(){const n=f.current,r=await Promise.all(n.map(e=>h(e))),s=(e=>Ei.tokenizer(e).map(e=>e.str))(e);return r.flatMap(({index:e,documents:n})=>e.query(e=>{e.term(s,{fields:["title"],boost:t}),e.term(s,{fields:["title"],boost:t,wildcard:Oi.Query.wildcard.TRAILING}),e.term(s,{fields:["content"],boost:o}),e.term(s,{fields:["content"],boost:o,wildcard:Oi.Query.wildcard.TRAILING}),e.term(s,{fields:["tags"],boost:i}),e.term(s,{fields:["tags"],boost:i,wildcard:Oi.Query.wildcard.TRAILING}),c&&(e.term(s,{fields:["sidebarParentCategories"],boost:a}),e.term(s,{fields:["sidebarParentCategories"],boost:a,wildcard:Oi.Query.wildcard.TRAILING}))}).slice(0,u).map(e=>({document:n.find(t=>t.id.toString()===e.ref),score:e.score,terms:s}))).sort((e,t)=>t.score-e.score).slice(0,u)}}]}),()=>b.current?.destroy()},[u]),r.createElement(r.Fragment,null,r.createElement(Ci,null),r.createElement("div",{className:"dsla-search-wrapper"},r.createElement("div",{className:"dsla-search-field",ref:g,"data-tags":d.join(",")})))},Ri={navbarSearchContainer:"navbarSearchContainer_Bca1"};function Di({children:e,className:t}){return(0,u.jsx)("div",{className:(0,o.A)(t,Ri.navbarSearchContainer),children:e})}var Fi=n(19802),Mi=n(45357);var Bi=n(86457);function zi({docsPluginId:e,configs:t}){return function(e,t){if(t){const n=new Map(e.map(e=>[e.name,e])),r=(t,r)=>{const o=n.get(t);if(!o)throw new Error(`No docs version exist for name '${t}', please verify your 'docsVersionDropdown' navbar item versions config.\nAvailable version names:\n- ${e.map(e=>`${e.name}`).join("\n- ")}`);return{version:o,label:r?.label??o.label}};return Array.isArray(t)?t.map(e=>r(e,void 0)):Object.entries(t).map(([e,t])=>r(e,t))}return e.map(e=>({version:e,label:e.label}))}((0,Fi.jh)(e),t)}function $i(e,t){return t.alternateDocVersions[e.name]??function(e){return e.docs.find(t=>t.id===e.mainDocId)}(e)}const Ui={default:ge,localeDropdown:function({mobile:e,dropdownItemsBefore:t,dropdownItemsAfter:n,queryString:r,...o}){const i=Te(),{i18n:{currentLocale:a,locales:s}}=(0,we.A)(),c=[...t,...s.map(t=>({label:i.getLabel(t),lang:i.getLang(t),to:i.getURL(t,{queryString:r}),target:"_self",autoAddBaseUrl:!1,className:t===a?e?"menu__link--active":"dropdown__link--active":""})),...n],p=e?(0,l.T)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):i.getLabel(a);return(0,u.jsx)(Oe,{...o,mobile:e,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(Ce,{className:Ae}),p]}),items:c})},search:function({mobile:e,className:t}){return e?null:(0,u.jsx)(Di,{className:t,children:(0,u.jsx)(Li,{})})},dropdown:Oe,html:function({value:e,className:t,mobile:n=!1,isDropdownItem:r=!1}){const i=r?"li":"div";return(0,u.jsx)(i,{className:(0,o.A)({navbar__item:!n&&!r,"menu__list-item":n},t),dangerouslySetInnerHTML:{__html:e}})},doc:function({docId:e,label:t,docsPluginId:n,...r}){const{activeDoc:o}=(0,Fi.zK)(n),i=(0,Mi.QB)(e,n),a=o?.path===i?.path;return null===i||i.unlisted&&!a?null:(0,u.jsx)(ge,{exact:!0,...r,isActive:()=>a||!!o?.sidebar&&o.sidebar===i.sidebar,label:t??i.id,to:i.path})},docSidebar:function({sidebarId:e,label:t,docsPluginId:n,...r}){const{activeDoc:o}=(0,Fi.zK)(n),i=(0,Mi.fW)(e,n).link;if(!i)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${e}" doesn't have anything to be linked to.`);return(0,u.jsx)(ge,{exact:!0,...r,isActive:()=>o?.sidebar===e,label:t??i.label,to:i.path})},docsVersion:function({label:e,to:t,docsPluginId:n,...r}){const o=(0,Mi.Vd)(n)[0],i=e??o.label,a=t??(e=>e.docs.find(t=>t.id===e.mainDocId))(o).path;return(0,u.jsx)(ge,{...r,label:i,to:a})},docsVersionDropdown:function({mobile:e,docsPluginId:t,dropdownActiveClassDisabled:n,dropdownItemsBefore:r,dropdownItemsAfter:o,versions:i,...a}){const s=(0,Pe.Hl)(e=>e.location.search),c=(0,Pe.Hl)(e=>e.location.hash),p=(0,Fi.zK)(t),{savePreferredVersionName:d}=(0,Bi.g1)(t),f=zi({docsPluginId:t,configs:i}),m=function({docsPluginId:e,versionItems:t}){return(0,Mi.Vd)(e).map(e=>t.find(t=>t.version===e)).filter(e=>void 0!==e)[0]??t[0]}({docsPluginId:t,versionItems:f}),h=[...r,...f.map(function({version:e,label:t}){return{label:t,to:`${$i(e,p).path}${s}${c}`,isActive:()=>e===p.activeVersion,onClick:()=>d(e.name)}}),...o],v=e&&h.length>1?(0,l.T)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):m.label,g=e&&h.length>1?void 0:$i(m.version,p).path;return h.length<=1?(0,u.jsx)(ge,{...a,mobile:e,label:v,to:g,isActive:n?()=>!1:void 0}):(0,u.jsx)(Oe,{...a,mobile:e,label:v,to:g,items:h,isActive:n?()=>!1:void 0})}},Vi=Ui;function Qi({type:e,...t}){const n=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(e,t),r=Vi[n];if(!r)throw new Error(`No NavbarItem component found for type "${e}".`);return(0,u.jsx)(r,{...t})}function Hi(){const e=(0,C.M)(),t=(0,w.p)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map((t,n)=>(0,r.createElement)(Qi,{mobile:!0,...t,onClick:()=>e.toggle(),key:n}))})}function Wi(e){return(0,u.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,u.jsx)(l.A,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function qi(){const e=0===(0,w.p)().navbar.items.length,t=D();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)(Wi,{onClick:()=>t.hide()}),t.content]})}function Gi(){const e=(0,C.M)();return function(e=!0){(0,r.useEffect)(()=>(document.body.style.overflow=e?"hidden":"visible",()=>{document.body.style.overflow="visible"}),[e])}(e.shown),e.shouldRender?(0,u.jsx)(B,{header:(0,u.jsx)(le,{}),primaryMenu:(0,u.jsx)(Hi,{}),secondaryMenu:(0,u.jsx)(qi,{})}):null}const Ki={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Yi(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,o.A)("navbar-sidebar__backdrop",e.className)})}function Zi({children:e}){const{navbar:{hideOnScroll:t,style:n}}=(0,w.p)(),i=(0,C.M)(),{navbarRef:a,isNavbarVisible:s}=function(e){const[t,n]=(0,r.useState)(e),o=(0,r.useRef)(!1),i=(0,r.useRef)(0),a=(0,r.useCallback)(e=>{null!==e&&(i.current=e.getBoundingClientRect().height)},[]);return(0,A.Mq)(({scrollY:t},r)=>{if(!e)return;if(t<i.current)return void n(!0);if(o.current)return void(o.current=!1);const a=r?.scrollY,s=document.documentElement.scrollHeight-i.current,l=window.innerHeight;a&&t>=a?n(!1):t+l<s&&n(!0)}),(0,c.$)(t=>{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return o.current=!0,void n(!1);n(!0)}),{navbarRef:a,isNavbarVisible:t}}(t);return(0,u.jsxs)("nav",{ref:a,"aria-label":(0,l.T)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,o.A)(v.G.layout.navbar.container,"navbar","navbar--fixed-top",t&&[Ki.navbarHideable,!s&&Ki.navbarHidden],{"navbar--dark":"dark"===n,"navbar--primary":"primary"===n,"navbar-sidebar--show":i.shown}),children:[e,(0,u.jsx)(Yi,{onClick:i.toggle}),(0,u.jsx)(Gi,{})]})}var Ji=n(34176);const Xi="right";function ea({width:e=30,height:t=30,className:n,...r}){return(0,u.jsx)("svg",{className:n,width:e,height:t,viewBox:"0 0 30 30","aria-hidden":"true",...r,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function ta(){const{toggle:e,shown:t}=(0,C.M)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,l.T)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(ea,{})})}const na={colorModeToggle:"colorModeToggle_DEke"};function ra({items:e}){return(0,u.jsx)(u.Fragment,{children:e.map((e,t)=>(0,u.jsx)(Ji.k2,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,u.jsx)(Qi,{...e})},t))})}function oa({left:e,right:t}){return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:(0,o.A)(v.G.layout.navbar.containerLeft,"navbar__items"),children:e}),(0,u.jsx)("div",{className:(0,o.A)(v.G.layout.navbar.containerRight,"navbar__items navbar__items--right"),children:t})]})}function ia(){const e=(0,C.M)(),t=(0,w.p)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??Xi)}return[e.filter(t),e.filter(e=>!t(e))]}(t),o=t.find(e=>"search"===e.type);return(0,u.jsx)(oa,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(ta,{}),(0,u.jsx)(ae,{}),(0,u.jsx)(ra,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(ra,{items:r}),(0,u.jsx)(oe,{className:na.colorModeToggle}),!o&&(0,u.jsx)(Di,{children:(0,u.jsx)(Li,{})})]})})}function aa(){return(0,u.jsx)(Zi,{children:(0,u.jsx)(ia,{})})}function sa({item:e}){const{to:t,href:n,label:r,prependBaseUrlToHref:i,className:a,...s}=e,l=(0,ue.Ay)(t),c=(0,ue.Ay)(n,{forcePrependBaseUrl:!0});return(0,u.jsxs)(ce.A,{className:(0,o.A)("footer__link-item",a),...n?{href:i?c:n}:{to:l},...s,children:[r,n&&!(0,pe.A)(n)&&(0,u.jsx)(fe.A,{})]})}function la({item:e}){return e.html?(0,u.jsx)("li",{className:(0,o.A)("footer__item",e.className),dangerouslySetInnerHTML:{__html:e.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(sa,{item:e})},e.href??e.to)}function ca({column:e}){return(0,u.jsxs)("div",{className:(0,o.A)(v.G.layout.footer.column,"col footer__col",e.className),children:[(0,u.jsx)("div",{className:"footer__title",children:e.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:e.items.map((e,t)=>(0,u.jsx)(la,{item:e},t))})]})}function ua({columns:e}){return(0,u.jsx)("div",{className:"row footer__links",children:e.map((e,t)=>(0,u.jsx)(ca,{column:e},t))})}function pa(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function da({item:e}){return e.html?(0,u.jsx)("span",{className:(0,o.A)("footer__link-item",e.className),dangerouslySetInnerHTML:{__html:e.html}}):(0,u.jsx)(sa,{item:e})}function fa({links:e}){return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:e.map((t,n)=>(0,u.jsxs)(r.Fragment,{children:[(0,u.jsx)(da,{item:t}),e.length!==n+1&&(0,u.jsx)(pa,{})]},n))})})}function ma({links:e}){return function(e){return"title"in e[0]}(e)?(0,u.jsx)(ua,{columns:e}):(0,u.jsx)(fa,{links:e})}var ha=n(40975);const va="footerLogoLink_BH7S";function ga({logo:e}){const{withBaseUrl:t}=(0,ue.hH)(),n={light:t(e.src),dark:t(e.srcDark??e.src)};return(0,u.jsx)(ha.A,{className:(0,o.A)("footer__logo",e.className),alt:e.alt,sources:n,width:e.width,height:e.height,style:e.style})}function ba({logo:e}){return e.href?(0,u.jsx)(ce.A,{href:e.href,className:va,target:e.target,children:(0,u.jsx)(ga,{logo:e})}):(0,u.jsx)(ga,{logo:e})}function ya({copyright:e}){return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:e}})}function wa({style:e,links:t,logo:n,copyright:r}){return(0,u.jsx)("footer",{className:(0,o.A)(v.G.layout.footer.container,"footer",{"footer--dark":"dark"===e}),children:(0,u.jsxs)("div",{className:"container container-fluid",children:[t,(n||r)&&(0,u.jsxs)("div",{className:"footer__bottom text--center",children:[n&&(0,u.jsx)("div",{className:"margin-bottom--sm",children:n}),r]})]})})}function xa(){const{footer:e}=(0,w.p)();if(!e)return null;const{copyright:t,links:n,logo:r,style:o}=e;return(0,u.jsx)(wa,{style:o,links:n&&n.length>0&&(0,u.jsx)(ma,{links:n}),logo:r&&(0,u.jsx)(ba,{logo:r}),copyright:t&&(0,u.jsx)(ya,{copyright:t})})}const ka=r.memo(xa),_a=(0,T.fM)([z.a,x.o,A.Tv,Bi.VQ,a.Jx,function({children:e}){return(0,u.jsx)(I.y_,{children:(0,u.jsx)(C.e,{children:(0,u.jsx)(L,{children:e})})})}]);function Sa({children:e}){return(0,u.jsx)(_a,{children:e})}var Ea=n(85225);function Oa({error:e,tryAgain:t}){return(0,u.jsx)("main",{className:"container margin-vert--xl",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,u.jsx)(Ea.A,{as:"h1",className:"hero__title",children:(0,u.jsx)(l.A,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,u.jsx)("div",{className:"margin-vert--lg",children:(0,u.jsx)(Ji.a2,{onClick:t,className:"button button--primary shadow--lw"})}),(0,u.jsx)("hr",{}),(0,u.jsx)("div",{className:"margin-vert--md",children:(0,u.jsx)(Ji.bq,{error:e})})]})})})}const ja={mainWrapper:"mainWrapper_z2l0"};function Pa(e){const{children:t,noFooter:n,wrapperClassName:r,title:s,description:l}=e;return(0,g.J)(),(0,u.jsxs)(Sa,{children:[(0,u.jsx)(a.be,{title:s,description:l}),(0,u.jsx)(y,{}),(0,u.jsx)(P,{}),(0,u.jsx)(aa,{}),(0,u.jsx)("div",{id:p,className:(0,o.A)(v.G.layout.main.container,v.G.wrapper.main,ja.mainWrapper,r),children:(0,u.jsx)(i.A,{fallback:e=>(0,u.jsx)(Oa,{...e}),children:t})}),!n&&(0,u.jsx)(ka,{})]})}},86457:(e,t,n)=>{"use strict";n.d(t,{VQ:()=>v,XK:()=>y,g1:()=>b});var r=n(96540),o=n(19802),i=n(44598),a=n(86957),s=n(69900),l=n(4799),c=n(74848);const u=e=>`docs-preferred-version-${e}`,p={save:(e,t,n)=>{(0,s.Wf)(u(e),{persistence:t}).set(n)},read:(e,t)=>(0,s.Wf)(u(e),{persistence:t}).get(),clear:(e,t)=>{(0,s.Wf)(u(e),{persistence:t}).del()}},d=e=>Object.fromEntries(e.map(e=>[e,{preferredVersionName:null}]));const f=r.createContext(null);function m(){const e=(0,o.Gy)(),t=(0,a.p)().docs.versionPersistence,n=(0,r.useMemo)(()=>Object.keys(e),[e]),[i,s]=(0,r.useState)(()=>d(n));(0,r.useEffect)(()=>{s(function({pluginIds:e,versionPersistence:t,allDocsData:n}){function r(e){const r=p.read(e,t);return n[e].versions.some(e=>e.name===r)?{preferredVersionName:r}:(p.clear(e,t),{preferredVersionName:null})}return Object.fromEntries(e.map(e=>[e,r(e)]))}({allDocsData:e,versionPersistence:t,pluginIds:n}))},[e,t,n]);return[i,(0,r.useMemo)(()=>({savePreferredVersion:function(e,n){p.save(e,t,n),s(t=>({...t,[e]:{preferredVersionName:n}}))}}),[t])]}function h({children:e}){const t=m();return(0,c.jsx)(f.Provider,{value:t,children:e})}function v({children:e}){return(0,c.jsx)(h,{children:e})}function g(){const e=(0,r.useContext)(f);if(!e)throw new l.dV("DocsPreferredVersionContextProvider");return e}function b(e=i.W){const t=(0,o.ht)(e),[n,a]=g(),{preferredVersionName:s}=n[e];return{preferredVersion:t.versions.find(e=>e.name===s)??null,savePreferredVersionName:(0,r.useCallback)(t=>{a.savePreferredVersion(e,t)},[a,e])}}function y(){const e=(0,o.Gy)(),[t]=g();function n(n){const r=e[n],{preferredVersionName:o}=t[n];return r.versions.find(e=>e.name===o)??null}const r=Object.keys(e);return Object.fromEntries(r.map(e=>[e,n(e)]))}},86957:(e,t,n)=>{"use strict";n.d(t,{p:()=>o});var r=n(97639);function o(){return(0,r.A)().siteConfig.themeConfig}},90716:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});n(96540);var r=n(23230);const o={iconExternalLink:"iconExternalLink_nPIU"};var i=n(74848);const a="#theme-svg-external-link";function s({width:e=13.5,height:t=13.5}){return(0,i.jsx)("svg",{width:e,height:t,"aria-label":(0,r.T)({id:"theme.IconExternalLink.ariaLabel",message:"(opens in new tab)",description:"The ARIA label for the external link icon"}),className:o.iconExternalLink,children:(0,i.jsx)("use",{href:a})})}},91704:(e,t,n)=>{"use strict";n.d(t,{n:()=>s,r:()=>l});var r=n(96540),o=n(4799),i=n(74848);const a=r.createContext(null);function s({children:e,version:t}){return(0,i.jsx)(a.Provider,{value:t,children:e})}function l(){const e=(0,r.useContext)(a);if(null===e)throw new o.dV("DocsVersionProvider");return e}},92413:(e,t,n)=>{"use strict";n.d(t,{A:()=>d});n(96540);var r=n(53259),o=n.n(r),i=n(84054);const a={"01f9c0c3":[()=>n.e(8806).then(n.bind(n,55730)),"@site/versioned_docs/version-2.24/getting-started/examples/horizontal-scaling.md",55730],"0282ce66":[()=>n.e(2559).then(n.bind(n,47410)),"@site/docs/reference/migration.md",47410],"039005a9":[()=>n.e(6996).then(n.t.bind(n,74333,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-category-basics-8c7.json",74333],"0428ff27":[()=>n.e(5116).then(n.bind(n,21581)),"@site/versioned_docs/version-2.22/architecture/observability.md",21581],"061c4c8e":[()=>n.e(9727).then(n.bind(n,44225)),"@site/versioned_docs/version-2.22/overview/product.md",44225],"073bbd6a":[()=>n.e(5514).then(n.bind(n,94145)),"@site/versioned_docs/version-2.23/getting-started/first-steps-local.md",94145],"074359f8":[()=>n.e(8295).then(n.bind(n,19101)),"@site/versioned_docs/version-2.23/overview/performance/performance.md",19101],"0a66f7ff":[()=>n.e(7335).then(n.bind(n,20672)),"@site/versioned_docs/version-2.22/workflows/config.md",20672],"0b1ac180":[()=>n.e(5863).then(n.bind(n,13336)),"@site/docs/architecture/overview.md",13336],"0b338d1c":[()=>n.e(8043).then(n.bind(n,63398)),"@site/versioned_docs/version-2.22/overview/confidential-kubernetes.md",63398],"0b615bd7":[()=>n.e(7320).then(n.bind(n,57723)),"@site/versioned_docs/version-2.23/reference/migration.md",57723],"0bfd0c91":[()=>n.e(470).then(n.bind(n,30778)),"@site/versioned_docs/version-2.24/workflows/create.md",30778],"0c363123":[()=>n.e(7934).then(n.bind(n,47380)),"@site/versioned_docs/version-2.24/workflows/s3proxy.md",47380],"0c605e3b":[()=>n.e(2307).then(n.bind(n,43888)),"@site/versioned_docs/version-2.23/architecture/overview.md",43888],"0cee1087":[()=>n.e(1086).then(n.bind(n,7688)),"@site/versioned_docs/version-2.24/workflows/upgrade.md",7688],"0e384e19":[()=>n.e(3976).then(n.bind(n,73700)),"@site/docs/intro.md",73700],"0eb3e611":[()=>n.e(9912).then(n.bind(n,99434)),"@site/versioned_docs/version-2.23/reference/slsa.md",99434],"1036ee0b":[()=>n.e(1603).then(n.bind(n,63764)),"@site/docs/overview/performance/application.md",63764],"11b4c29f":[()=>n.e(945).then(n.bind(n,44845)),"@site/versioned_docs/version-2.24/getting-started/marketplaces.md",44845],"11dcff96":[()=>n.e(1799).then(n.bind(n,46377)),"@site/versioned_docs/version-2.22/workflows/create.md",46377],"142263a9":[()=>n.e(3531).then(n.bind(n,2135)),"@site/versioned_docs/version-2.23/workflows/terminate.md",2135],"14eb3368":[()=>Promise.all([n.e(1869),n.e(6969)]).then(n.bind(n,63790)),"@theme/DocCategoryGeneratedIndexPage",63790],"15c6e37c":[()=>n.e(1268).then(n.bind(n,75514)),"@site/docs/workflows/cert-manager.md",75514],"15e5e9ad":[()=>n.e(1298).then(n.bind(n,62663)),"@site/versioned_docs/version-2.24/workflows/verify-cli.md",62663],17896441:[()=>Promise.all([n.e(1869),n.e(2093),n.e(8401)]).then(n.bind(n,86829)),"@theme/DocItem",86829],"1890268c":[()=>n.e(8488).then(n.bind(n,89691)),"@site/versioned_docs/version-2.24/architecture/orchestration.md",89691],"1b80620b":[()=>n.e(3452).then(n.bind(n,20895)),"@site/docs/workflows/troubleshooting.md",20895],"1c0e8ae3":[()=>n.e(663).then(n.bind(n,87187)),"@site/versioned_docs/version-2.24/getting-started/first-steps-local.md",87187],"1c53691b":[()=>n.e(5845).then(n.bind(n,6110)),"@site/docs/workflows/verify-cli.md",6110],"1e04dd29":[()=>n.e(4318).then(n.bind(n,2702)),"@site/versioned_docs/version-2.23/intro.md",2702],"20a029f4":[()=>n.e(5343).then(n.bind(n,80438)),"@site/versioned_docs/version-2.22/workflows/recovery.md",80438],"242e7908":[()=>n.e(6510).then(n.t.bind(n,26696,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-next-category-getting-started-455.json",26696],"25e50762":[()=>n.e(7625).then(n.bind(n,37789)),"@site/docs/workflows/storage.md",37789],"260d3cdf":[()=>n.e(9619).then(n.bind(n,16301)),"@site/versioned_docs/version-2.24/architecture/microservices.md",16301],"269ef64a":[()=>n.e(6664).then(n.bind(n,35080)),"@site/docs/workflows/create.md",35080],"28513d82":[()=>n.e(9612).then(n.bind(n,62453)),"@site/versioned_docs/version-2.23/getting-started/marketplaces.md",62453],"28a0f3ab":[()=>n.e(4954).then(n.bind(n,90809)),"@site/versioned_docs/version-2.23/overview/performance/io.md",90809],"294c0512":[()=>n.e(3339).then(n.bind(n,44780)),"@site/versioned_docs/version-2.24/architecture/images.md",44780],"2a05e475":[()=>n.e(3610).then(n.bind(n,75806)),"@site/versioned_docs/version-2.22/workflows/sbom.md",75806],"2a2a0c40":[()=>n.e(7292).then(n.bind(n,48672)),"@site/docs/getting-started/install.md",48672],"2a9ad702":[()=>n.e(6879).then(n.bind(n,71985)),"@site/versioned_docs/version-2.24/overview/clouds.md",71985],"2b3dcc9b":[()=>n.e(1793).then(n.bind(n,7248)),"@site/versioned_docs/version-2.23/architecture/images.md",7248],"2dc3352a":[()=>n.e(4616).then(n.bind(n,93432)),"@site/versioned_docs/version-2.22/architecture/versions.md",93432],"311067ef":[()=>n.e(7856).then(n.bind(n,66565)),"@site/docs/workflows/lb.md",66565],31840164:[()=>n.e(3440).then(n.bind(n,73865)),"@site/docs/getting-started/marketplaces.md",73865],"31cc4483":[()=>n.e(2398).then(n.bind(n,38967)),"@site/versioned_docs/version-2.24/workflows/recovery.md",38967],"3305fd99":[()=>n.e(3092).then(n.bind(n,293)),"@site/versioned_docs/version-2.23/getting-started/first-steps.md",293],"3324b179":[()=>n.e(9528).then(n.bind(n,54567)),"@site/versioned_docs/version-2.24/architecture/networking.md",54567],"358e1fce":[()=>n.e(9427).then(n.bind(n,3946)),"@site/docs/workflows/scale.md",3946],"3607c499":[()=>n.e(3772).then(n.bind(n,74085)),"@site/versioned_docs/version-2.23/overview/security-benefits.md",74085],"36f09204":[()=>n.e(5423).then(n.bind(n,86057)),"@site/versioned_docs/version-2.23/architecture/attestation.md",86057],"3962f62e":[()=>n.e(4200).then(n.bind(n,37537)),"@site/versioned_docs/version-2.24/getting-started/examples.md",37537],"3aba4a32":[()=>n.e(1902).then(n.bind(n,88892)),"@site/versioned_docs/version-2.22/overview/clouds.md",88892],"3aca6029":[()=>n.e(4394).then(n.bind(n,38693)),"@site/versioned_docs/version-2.24/architecture/attestation.md",38693],"3b1b22d5":[()=>n.e(3456).then(n.bind(n,81788)),"@site/versioned_docs/version-2.22/workflows/cert-manager.md",81788],"3b28b3cc":[()=>n.e(8205).then(n.bind(n,27006)),"@site/docs/getting-started/first-steps-local.md",27006],"3bcf7932":[()=>n.e(8048).then(n.bind(n,34842)),"@site/versioned_docs/version-2.22/getting-started/install.md",34842],"3e0d8e9d":[()=>n.e(7861).then(n.bind(n,21071)),"@site/docs/reference/terraform.md",21071],"3e6faa8e":[()=>n.e(3280).then(n.bind(n,31327)),"@site/versioned_docs/version-2.24/workflows/lb.md",31327],"3ee8c4d1":[()=>n.e(6032).then(n.bind(n,54648)),"@site/versioned_docs/version-2.22/workflows/troubleshooting.md",54648],"3fddd266":[()=>n.e(9414).then(n.bind(n,73129)),"@site/versioned_docs/version-2.24/workflows/verify-cluster.md",73129],"3fe7bb19":[()=>n.e(7018).then(n.bind(n,42605)),"@site/versioned_docs/version-2.22/architecture/networking.md",42605],"401e1ad9":[()=>n.e(1006).then(n.t.bind(n,29318,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-e34.json",29318],"40c738e9":[()=>n.e(8598).then(n.bind(n,6106)),"@site/versioned_docs/version-2.24/architecture/versions.md",6106],42298223:[()=>n.e(7373).then(n.t.bind(n,2391,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-2-23-category-workflows-39f.json",2391],"42888a29":[()=>n.e(2719).then(n.bind(n,60911)),"@site/versioned_docs/version-2.24/overview/confidential-kubernetes.md",60911],"452d9595":[()=>n.e(2560).then(n.bind(n,96759)),"@site/docs/workflows/trusted-launch.md",96759],"462332ca":[()=>n.e(4723).then(n.bind(n,41755)),"@site/versioned_docs/version-2.22/getting-started/examples/emojivoto.md",41755],"481538bf":[()=>n.e(9732).then(n.bind(n,70037)),"@site/versioned_docs/version-2.24/getting-started/examples/online-boutique.md",70037],"48186bb1":[()=>n.e(1671).then(n.t.bind(n,33686,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-category-reference-6a6.json",33686],"487d2b28":[()=>n.e(4244).then(n.bind(n,64602)),"@site/docs/architecture/images.md",64602],"4967aec5":[()=>n.e(909).then(n.bind(n,82112)),"@site/versioned_docs/version-2.22/reference/slsa.md",82112],"4a51e885":[()=>n.e(9514).then(n.bind(n,85076)),"@site/docs/overview/product.md",85076],"4b669f2d":[()=>n.e(386).then(n.bind(n,12268)),"@site/versioned_docs/version-2.22/architecture/attestation.md",12268],"4bfed142":[()=>n.e(417).then(n.bind(n,54775)),"@site/versioned_docs/version-2.22/workflows/scale.md",54775],"4c9525de":[()=>n.e(7356).then(n.bind(n,63344)),"@site/versioned_docs/version-2.24/overview/performance/performance.md",63344],"4cc5eb92":[()=>n.e(3340).then(n.bind(n,11551)),"@site/docs/architecture/networking.md",11551],"4cf171a2":[()=>n.e(9442).then(n.bind(n,96588)),"@site/versioned_docs/version-2.23/workflows/verify-cluster.md",96588],"4f0549e0":[()=>n.e(1734).then(n.bind(n,55256)),"@site/versioned_docs/version-2.24/workflows/terminate.md",55256],"4fce284f":[()=>n.e(1201).then(n.t.bind(n,26761,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-2-23-category-getting-started-d2d.json",26761],"508a7d2f":[()=>n.e(1376).then(n.bind(n,22396)),"@site/docs/getting-started/examples.md",22396],"533d31d4":[()=>n.e(6822).then(n.bind(n,7189)),"@site/versioned_docs/version-2.23/getting-started/examples/online-boutique.md",7189],"53c1dfd4":[()=>n.e(4085).then(n.bind(n,62913)),"@site/versioned_docs/version-2.22/architecture/keys.md",62913],"543a522f":[()=>n.e(557).then(n.bind(n,30439)),"@site/versioned_docs/version-2.23/getting-started/examples/emojivoto.md",30439],"54db543f":[()=>n.e(9074).then(n.t.bind(n,31798,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-2-22-category-workflows-a2e.json",31798],"5672ef9d":[()=>n.e(9767).then(n.bind(n,50283)),"@site/versioned_docs/version-2.24/reference/migration.md",50283],"56806aed":[()=>n.e(7274).then(n.t.bind(n,51480,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-next-category-basics-4d9.json",51480],"574ee69f":[()=>n.e(7078).then(n.t.bind(n,78009,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-next-881.json",78009],"592bfb5e":[()=>n.e(867).then(n.bind(n,48886)),"@site/docs/workflows/s3proxy.md",48886],"5a6332a4":[()=>n.e(5096).then(n.bind(n,43053)),"@site/versioned_docs/version-2.22/reference/cli.md",43053],"5aae01e0":[()=>n.e(249).then(n.bind(n,11480)),"@site/versioned_docs/version-2.22/workflows/terminate.md",11480],"5bf0e48f":[()=>n.e(8917).then(n.bind(n,60602)),"@site/docs/architecture/keys.md",60602],"5d6cdc31":[()=>n.e(2662).then(n.bind(n,43995)),"@site/versioned_docs/version-2.22/workflows/s3proxy.md",43995],"5dc5a687":[()=>n.e(2762).then(n.bind(n,35385)),"@site/versioned_docs/version-2.22/workflows/lb.md",35385],"5e23635c":[()=>n.e(1901).then(n.bind(n,68074)),"@site/versioned_docs/version-2.24/workflows/config.md",68074],"5e92d76a":[()=>n.e(292).then(n.bind(n,2201)),"@site/versioned_docs/version-2.22/getting-started/first-steps.md",2201],"5e95c892":[()=>n.e(9647).then(n.bind(n,83124)),"@theme/DocsRoot",83124],"60d3a1b7":[()=>n.e(6665).then(n.bind(n,97536)),"@site/versioned_docs/version-2.23/workflows/config.md",97536],"619bb71e":[()=>n.e(9698).then(n.bind(n,86942)),"@site/versioned_docs/version-2.24/overview/license.md",86942],"633fbb2f":[()=>n.e(3325).then(n.bind(n,67532)),"@site/versioned_docs/version-2.23/workflows/s3proxy.md",67532],"642ed902":[()=>n.e(5541).then(n.bind(n,48162)),"@site/docs/architecture/attestation.md",48162],"64c81f13":[()=>n.e(2733).then(n.bind(n,3048)),"@site/versioned_docs/version-2.23/workflows/trusted-launch.md",3048],"66852f4d":[()=>n.e(6850).then(n.bind(n,62129)),"@site/versioned_docs/version-2.24/intro.md",62129],"66e2533d":[()=>n.e(1523).then(n.bind(n,89786)),"@site/docs/overview/license.md",89786],"6776993e":[()=>n.e(9023).then(n.bind(n,62708)),"@site/docs/workflows/terminate.md",62708],"68f29d4c":[()=>n.e(8865).then(n.bind(n,11355)),"@site/versioned_docs/version-2.24/workflows/terraform-provider.md",11355],"6c830a9a":[()=>n.e(402).then(n.t.bind(n,25313,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-2-23-category-basics-48c.json",25313],"6d0fae35":[()=>n.e(6897).then(n.t.bind(n,29554,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-2-23-category-architecture-7cd.json",29554],"6df30968":[()=>n.e(6823).then(n.bind(n,6074)),"@site/docs/getting-started/examples/filestash-s3proxy.md",6074],"6e43ec2e":[()=>n.e(2928).then(n.bind(n,74186)),"@site/versioned_docs/version-2.22/architecture/orchestration.md",74186],"6fe48d2e":[()=>n.e(8619).then(n.t.bind(n,64496,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-2-22-category-getting-started-e6a.json",64496],"70248ece":[()=>n.e(6373).then(n.bind(n,23925)),"@site/versioned_docs/version-2.22/workflows/verify-cli.md",23925],"70f89ddc":[()=>n.e(8428).then(n.bind(n,99197)),"@site/docs/workflows/reproducible-builds.md",99197],"71dfee10":[()=>n.e(832).then(n.bind(n,26640)),"@site/versioned_docs/version-2.23/workflows/sbom.md",26640],"72a880f4":[()=>n.e(3533).then(n.bind(n,13589)),"@site/docs/architecture/versions.md",13589],"72c2c1f0":[()=>n.e(301).then(n.t.bind(n,94773,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-2-23-2fd.json",94773],"74afccd1":[()=>n.e(5128).then(n.bind(n,56386)),"@site/versioned_docs/version-2.23/architecture/encrypted-storage.md",56386],"75a3ea9f":[()=>n.e(3132).then(n.bind(n,43916)),"@site/versioned_docs/version-2.23/workflows/cert-manager.md",43916],"76b2ab15":[()=>n.e(1415).then(n.bind(n,19645)),"@site/docs/overview/performance/performance.md",19645],"76f884e3":[()=>n.e(9766).then(n.bind(n,21798)),"@site/versioned_docs/version-2.23/getting-started/examples.md",21798],"786b68f5":[()=>n.e(3539).then(n.t.bind(n,89016,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-next-category-workflows-6c3.json",89016],"786c60fb":[()=>n.e(253).then(n.bind(n,83789)),"@site/docs/overview/security-benefits.md",83789],"794987bd":[()=>n.e(2947).then(n.bind(n,73955)),"@site/versioned_docs/version-2.24/workflows/storage.md",73955],"797a5fdc":[()=>n.e(5249).then(n.bind(n,81113)),"@site/versioned_docs/version-2.23/getting-started/examples/filestash-s3proxy.md",81113],"79e0c113":[()=>n.e(6912).then(n.bind(n,92364)),"@site/versioned_docs/version-2.22/intro.md",92364],"7ae19400":[()=>n.e(6154).then(n.bind(n,42383)),"@site/versioned_docs/version-2.22/overview/performance/application.md",42383],"7c763686":[()=>n.e(9075).then(n.bind(n,93939)),"@site/versioned_docs/version-2.23/overview/license.md",93939],"7cae3477":[()=>n.e(8784).then(n.bind(n,62840)),"@site/versioned_docs/version-2.23/workflows/create.md",62840],"80697fb2":[()=>n.e(1067).then(n.bind(n,36045)),"@site/docs/getting-started/examples/online-boutique.md",36045],"8183fba6":[()=>n.e(304).then(n.bind(n,12008)),"@site/versioned_docs/version-2.24/reference/terraform.md",12008],"836c9f98":[()=>n.e(6407).then(n.bind(n,59519)),"@site/versioned_docs/version-2.24/architecture/overview.md",59519],"837f4190":[()=>n.e(4613).then(n.bind(n,71800)),"@site/versioned_docs/version-2.24/workflows/trusted-launch.md",71800],84353103:[()=>n.e(2908).then(n.bind(n,96428)),"@site/versioned_docs/version-2.22/architecture/microservices.md",96428],"8452cbfd":[()=>n.e(6851).then(n.bind(n,11476)),"@site/versioned_docs/version-2.22/getting-started/examples.md",11476],"84de5ccf":[()=>n.e(1897).then(n.bind(n,91810)),"@site/versioned_docs/version-2.24/getting-started/install.md",91810],"856c1b4a":[()=>n.e(4263).then(n.bind(n,45577)),"@site/versioned_docs/version-2.22/workflows/trusted-launch.md",45577],"86470a9a":[()=>n.e(8569).then(n.bind(n,72601)),"@site/docs/workflows/config.md",72601],"8713d71c":[()=>n.e(7083).then(n.bind(n,91974)),"@site/versioned_docs/version-2.23/getting-started/install.md",91974],"8a026b6c":[()=>n.e(2301).then(n.bind(n,38628)),"@site/versioned_docs/version-2.22/overview/performance/performance.md",38628],"8a589188":[()=>n.e(9579).then(n.bind(n,68212)),"@site/versioned_docs/version-2.23/reference/terraform.md",68212],"8ca353b4":[()=>n.e(7466).then(n.bind(n,3010)),"@site/versioned_docs/version-2.22/overview/performance/io.md",3010],"8d448ad2":[()=>n.e(4100).then(n.bind(n,75535)),"@site/versioned_docs/version-2.23/workflows/verify-cli.md",75535],"8ea786c8":[()=>n.e(9509).then(n.bind(n,76832)),"@site/versioned_docs/version-2.23/architecture/keys.md",76832],"9010cc91":[()=>n.e(6135).then(n.bind(n,53693)),"@site/versioned_docs/version-2.23/workflows/storage.md",53693],"90e117e3":[()=>n.e(8994).then(n.bind(n,59331)),"@site/versioned_docs/version-2.24/workflows/sbom.md",59331],"911e2eea":[()=>n.e(998).then(n.t.bind(n,59387,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-2-22-f7d.json",59387],"91c76d4c":[()=>n.e(8238).then(n.bind(n,47571)),"@site/docs/reference/cli.md",47571],92236455:[()=>n.e(1031).then(n.bind(n,30843)),"@site/versioned_docs/version-2.24/overview/security-benefits.md",30843],"925a7d08":[()=>n.e(2813).then(n.bind(n,58096)),"@site/versioned_docs/version-2.23/workflows/upgrade.md",58096],"927cf76e":[()=>n.e(1226).then(n.bind(n,9902)),"@site/docs/architecture/observability.md",9902],"95ca3cf4":[()=>n.e(337).then(n.t.bind(n,27574,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-category-architecture-0c2.json",27574],"960959b3":[()=>n.e(84).then(n.bind(n,97039)),"@site/docs/workflows/upgrade.md",97039],"97b147c7":[()=>n.e(7193).then(n.bind(n,16796)),"@site/versioned_docs/version-2.24/overview/performance/io.md",16796],"989930da":[()=>n.e(2190).then(n.t.bind(n,41287,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-2-22-category-reference-02f.json",41287],"9afa113a":[()=>n.e(8996).then(n.t.bind(n,87171,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-next-category-architecture-47a.json",87171],"9b22caeb":[()=>n.e(4071).then(n.bind(n,3259)),"@site/docs/reference/slsa.md",3259],"9ba5d544":[()=>n.e(1789).then(n.t.bind(n,89673,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-2-22-category-architecture-0f8.json",89673],"9bccdd10":[()=>n.e(6067).then(n.bind(n,58263)),"@site/versioned_docs/version-2.24/workflows/reproducible-builds.md",58263],"9be9ef65":[()=>n.e(1470).then(n.bind(n,65305)),"@site/docs/getting-started/examples/emojivoto.md",65305],"9c1ba6d8":[()=>n.e(8003).then(n.bind(n,99462)),"@site/docs/overview/performance/io.md",99462],"9cbfbb7f":[()=>n.e(9308).then(n.bind(n,88528)),"@site/versioned_docs/version-2.24/workflows/troubleshooting.md",88528],"9d4f835b":[()=>n.e(4672).then(n.bind(n,59678)),"@site/versioned_docs/version-2.23/overview/confidential-kubernetes.md",59678],a0c24a7b:[()=>n.e(8889).then(n.bind(n,31804)),"@site/versioned_docs/version-2.24/workflows/cert-manager.md",31804],a3183fd7:[()=>n.e(656).then(n.bind(n,79402)),"@site/docs/architecture/encrypted-storage.md",79402],a39aaf1d:[()=>n.e(7227).then(n.bind(n,75001)),"@site/docs/getting-started/first-steps.md",75001],a4c009ef:[()=>n.e(6257).then(n.t.bind(n,93963,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-next-category-reference-989.json",93963],a5863201:[()=>n.e(2993).then(n.bind(n,22705)),"@site/versioned_docs/version-2.24/architecture/keys.md",22705],a631f374:[()=>n.e(9770).then(n.bind(n,76978)),"@site/versioned_docs/version-2.23/architecture/microservices.md",76978],a6a7cec0:[()=>n.e(6599).then(n.bind(n,63791)),"@site/versioned_docs/version-2.22/architecture/images.md",63791],a7bd4aaa:[()=>n.e(7098).then(n.bind(n,22881)),"@theme/DocVersionRoot",22881],a7be6a84:[()=>n.e(1275).then(n.bind(n,99835)),"@site/versioned_docs/version-2.22/getting-started/examples/online-boutique.md",99835],a7cbe781:[()=>n.e(5757).then(n.bind(n,83015)),"@site/versioned_docs/version-2.24/overview/performance/application.md",83015],a7e69b4a:[()=>n.e(8146).then(n.t.bind(n,7210,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-category-getting-started-dc5.json",7210],a93f81ab:[()=>n.e(7218).then(n.bind(n,1338)),"@site/versioned_docs/version-2.24/overview/product.md",1338],a94703ab:[()=>Promise.all([n.e(1869),n.e(9048)]).then(n.bind(n,59818)),"@theme/DocRoot",59818],aba21aa0:[()=>n.e(5742).then(n.t.bind(n,27093,19)),"@generated/docusaurus-plugin-content-docs/default/__plugin.json",27093],acced080:[()=>n.e(1587).then(n.t.bind(n,48609,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-2-22-category-basics-08f.json",48609],acf362b0:[()=>n.e(1516).then(n.bind(n,9127)),"@site/docs/overview/confidential-kubernetes.md",9127],adfda302:[()=>n.e(6144).then(n.bind(n,40602)),"@site/versioned_docs/version-2.23/architecture/orchestration.md",40602],ae4682fc:[()=>n.e(308).then(n.bind(n,56746)),"@site/versioned_docs/version-2.22/overview/license.md",56746],af08314d:[()=>n.e(3182).then(n.bind(n,53996)),"@site/versioned_docs/version-2.24/architecture/encrypted-storage.md",53996],b28da407:[()=>n.e(1187).then(n.bind(n,90447)),"@site/docs/overview/performance/compute.md",90447],b29fd7c7:[()=>n.e(4591).then(n.bind(n,61795)),"@site/docs/architecture/orchestration.md",61795],b744c41b:[()=>n.e(7317).then(n.bind(n,9597)),"@site/versioned_docs/version-2.22/reference/migration.md",9597],b80e9c3d:[()=>n.e(2829).then(n.t.bind(n,42333,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-2-23-category-reference-c15.json",42333],baf93e4b:[()=>n.e(6457).then(n.bind(n,25946)),"@site/versioned_docs/version-2.22/overview/performance/compute.md",25946],bf976132:[()=>n.e(8395).then(n.bind(n,21668)),"@site/versioned_docs/version-2.22/architecture/overview.md",21668],c2af115c:[()=>n.e(6567).then(n.bind(n,17020)),"@site/versioned_docs/version-2.24/getting-started/first-steps.md",17020],c33b0c87:[()=>n.e(8518).then(n.bind(n,8519)),"@site/versioned_docs/version-2.22/getting-started/examples/horizontal-scaling.md",8519],c920f53d:[()=>n.e(1155).then(n.bind(n,52406)),"@site/versioned_docs/version-2.22/workflows/terraform-provider.md",52406],ca2d12cf:[()=>n.e(9343).then(n.bind(n,50045)),"@site/docs/workflows/verify-cluster.md",50045],ca9f0fb1:[()=>n.e(8255).then(n.bind(n,45488)),"@site/docs/workflows/recovery.md",45488],cb054e22:[()=>n.e(9032).then(n.bind(n,80233)),"@site/docs/workflows/sbom.md",80233],cbcdb048:[()=>n.e(2843).then(n.bind(n,61985)),"@site/versioned_docs/version-2.24/getting-started/examples/emojivoto.md",61985],cda59bb1:[()=>n.e(3526).then(n.bind(n,24565)),"@site/versioned_docs/version-2.22/overview/security-benefits.md",24565],ce803f35:[()=>n.e(7496).then(n.bind(n,88365)),"@site/versioned_docs/version-2.22/workflows/verify-cluster.md",88365],cea600d4:[()=>n.e(234).then(n.t.bind(n,637,19)),"@generated/docusaurus-plugin-content-docs/default/p/constellation-pr-preview-pr-4027-category-workflows-e9e.json",637],d0929cd6:[()=>n.e(8748).then(n.bind(n,24258)),"@site/versioned_docs/version-2.24/getting-started/examples/filestash-s3proxy.md",24258],d12af2ba:[()=>n.e(946).then(n.bind(n,85502)),"@site/versioned_docs/version-2.22/getting-started/first-steps-local.md",85502],d17f599b:[()=>n.e(4678).then(n.bind(n,95806)),"@site/versioned_docs/version-2.23/reference/cli.md",95806],d2556545:[()=>n.e(3405).then(n.bind(n,59043)),"@site/versioned_docs/version-2.23/workflows/scale.md",59043],d4cfdd56:[()=>n.e(3101).then(n.bind(n,45069)),"@site/versioned_docs/version-2.23/architecture/networking.md",45069],d84515e5:[()=>n.e(7730).then(n.bind(n,6032)),"@site/versioned_docs/version-2.24/overview/performance/compute.md",6032],d89a6bd5:[()=>n.e(6516).then(n.bind(n,67743)),"@site/versioned_docs/version-2.24/architecture/observability.md",67743],da6dfe9f:[()=>n.e(4222).then(n.bind(n,36444)),"@site/versioned_docs/version-2.24/reference/slsa.md",36444],dae6bd30:[()=>n.e(680).then(n.bind(n,584)),"@site/versioned_docs/version-2.22/reference/terraform.md",584],db1b10df:[()=>n.e(3501).then(n.bind(n,4628)),"@site/versioned_docs/version-2.22/workflows/upgrade.md",4628],dc614479:[()=>n.e(5739).then(n.bind(n,50988)),"@site/versioned_docs/version-2.22/workflows/storage.md",50988],dcc7f694:[()=>n.e(4801).then(n.bind(n,13573)),"@site/docs/architecture/microservices.md",13573],de51a3b8:[()=>n.e(1618).then(n.bind(n,9122)),"@site/versioned_docs/version-2.23/workflows/terraform-provider.md",9122],ded7ff97:[()=>n.e(6389).then(n.bind(n,13749)),"@site/versioned_docs/version-2.22/getting-started/examples/filestash-s3proxy.md",13749],dfb82530:[()=>n.e(8585).then(n.bind(n,60270)),"@site/versioned_docs/version-2.23/workflows/recovery.md",60270],dfb8a45d:[()=>n.e(5267).then(n.bind(n,28161)),"@site/versioned_docs/version-2.23/workflows/reproducible-builds.md",28161],e0c6aa40:[()=>n.e(9529).then(n.bind(n,30312)),"@site/versioned_docs/version-2.24/workflows/scale.md",30312],e0f39c0b:[()=>n.e(1279).then(n.bind(n,71882)),"@site/versioned_docs/version-2.22/architecture/encrypted-storage.md",71882],e12b18ba:[()=>n.e(6065).then(n.bind(n,72309)),"@site/versioned_docs/version-2.23/workflows/lb.md",72309],e19825b3:[()=>n.e(7284).then(n.bind(n,12927)),"@site/versioned_docs/version-2.22/workflows/reproducible-builds.md",12927],e344aa3d:[()=>n.e(3884).then(n.bind(n,56465)),"@site/versioned_docs/version-2.23/overview/clouds.md",56465],e61948c8:[()=>n.e(9341).then(n.bind(n,26058)),"@site/docs/getting-started/examples/horizontal-scaling.md",26058],e7c02e82:[()=>n.e(3939).then(n.bind(n,91015)),"@site/versioned_docs/version-2.23/overview/performance/compute.md",91015],e8feb497:[()=>n.e(9673).then(n.bind(n,83158)),"@site/versioned_docs/version-2.23/workflows/troubleshooting.md",83158],e91da414:[()=>n.e(1610).then(n.bind(n,16572)),"@site/versioned_docs/version-2.23/overview/product.md",16572],e97075f3:[()=>n.e(853).then(n.bind(n,1397)),"@site/versioned_docs/version-2.23/architecture/observability.md",1397],eae38991:[()=>n.e(7570).then(n.bind(n,60621)),"@site/versioned_docs/version-2.23/getting-started/examples/horizontal-scaling.md",60621],ec7c7126:[()=>n.e(4425).then(n.bind(n,74776)),"@site/docs/overview/clouds.md",74776],f03f4c5d:[()=>n.e(7726).then(n.bind(n,77259)),"@site/versioned_docs/version-2.23/overview/performance/application.md",77259],f402a94e:[()=>n.e(1220).then(n.bind(n,50955)),"@site/versioned_docs/version-2.23/architecture/versions.md",50955],f8c8aa36:[()=>n.e(3465).then(n.bind(n,3028)),"@site/docs/workflows/terraform-provider.md",3028],fb5790ab:[()=>n.e(9361).then(n.bind(n,21601)),"@site/versioned_docs/version-2.22/getting-started/marketplaces.md",21601],fd1d3864:[()=>n.e(3289).then(n.bind(n,26064)),"@site/versioned_docs/version-2.24/reference/cli.md",26064]};var s=n(74848);function l({error:e,retry:t,pastDelay:n}){return e?(0,s.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,s.jsx)("p",{children:String(e)}),(0,s.jsx)("div",{children:(0,s.jsx)("button",{type:"button",onClick:t,children:"Retry"})})]}):n?(0,s.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,s.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,s.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,s.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var c=n(81604),u=n(23363);function p(e,t){if("*"===e)return o()({loading:l,loader:()=>n.e(179).then(n.bind(n,72560)),modules:["@theme/NotFound"],webpack:()=>[72560],render(e,t){const n=e.default;return(0,s.jsx)(u.W,{value:{plugin:{name:"native",id:"default"}},children:(0,s.jsx)(n,{...t})})}});const r=i[`${e}-${t}`],p={},d=[],f=[],m=(0,c.A)(r);return Object.entries(m).forEach(([e,t])=>{const n=a[t];n&&(p[e]=n[0],d.push(n[1]),f.push(n[2]))}),o().Map({loading:l,loader:p,modules:d,webpack:()=>f,render(t,n){const o=JSON.parse(JSON.stringify(r));Object.entries(t).forEach(([t,n])=>{const r=n.default;if(!r)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof r&&"function"!=typeof r||Object.keys(n).filter(e=>"default"!==e).forEach(e=>{r[e]=n[e]});let i=o;const a=t.split(".");a.slice(0,-1).forEach(e=>{i=i[e]}),i[a[a.length-1]]=r});const i=o.__comp;delete o.__comp;const a=o.__context;delete o.__context;const l=o.__props;return delete o.__props,(0,s.jsx)(u.W,{value:a,children:(0,s.jsx)(i,{...o,...l,...n})})}})}const d=[{path:"/constellation/pr-preview/pr-4027/",component:p("/constellation/pr-preview/pr-4027/","530"),routes:[{path:"/constellation/pr-preview/pr-4027/2.22",component:p("/constellation/pr-preview/pr-4027/2.22","fb0"),routes:[{path:"/constellation/pr-preview/pr-4027/2.22",component:p("/constellation/pr-preview/pr-4027/2.22","187"),routes:[{path:"/constellation/pr-preview/pr-4027/2.22/",component:p("/constellation/pr-preview/pr-4027/2.22/","38d"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/architecture/attestation",component:p("/constellation/pr-preview/pr-4027/2.22/architecture/attestation","dff"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage",component:p("/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage","564"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/architecture/images",component:p("/constellation/pr-preview/pr-4027/2.22/architecture/images","872"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/architecture/keys",component:p("/constellation/pr-preview/pr-4027/2.22/architecture/keys","027"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/architecture/microservices",component:p("/constellation/pr-preview/pr-4027/2.22/architecture/microservices","907"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/architecture/networking",component:p("/constellation/pr-preview/pr-4027/2.22/architecture/networking","e4c"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/architecture/observability",component:p("/constellation/pr-preview/pr-4027/2.22/architecture/observability","429"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration",component:p("/constellation/pr-preview/pr-4027/2.22/architecture/orchestration","363"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/architecture/overview",component:p("/constellation/pr-preview/pr-4027/2.22/architecture/overview","d8e"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/architecture/versions",component:p("/constellation/pr-preview/pr-4027/2.22/architecture/versions","536"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/category/architecture",component:p("/constellation/pr-preview/pr-4027/2.22/category/architecture","99a"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/category/basics",component:p("/constellation/pr-preview/pr-4027/2.22/category/basics","b46"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/category/getting-started",component:p("/constellation/pr-preview/pr-4027/2.22/category/getting-started","5d8"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/category/reference",component:p("/constellation/pr-preview/pr-4027/2.22/category/reference","41f"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/category/workflows",component:p("/constellation/pr-preview/pr-4027/2.22/category/workflows","03d"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/getting-started/examples",component:p("/constellation/pr-preview/pr-4027/2.22/getting-started/examples","2a2"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/emojivoto",component:p("/constellation/pr-preview/pr-4027/2.22/getting-started/examples/emojivoto","f17"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/filestash-s3proxy",component:p("/constellation/pr-preview/pr-4027/2.22/getting-started/examples/filestash-s3proxy","d7f"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scaling",component:p("/constellation/pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scaling","075"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/online-boutique",component:p("/constellation/pr-preview/pr-4027/2.22/getting-started/examples/online-boutique","160"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps",component:p("/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps","c6d"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local",component:p("/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local","80b"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/getting-started/install",component:p("/constellation/pr-preview/pr-4027/2.22/getting-started/install","ad2"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/getting-started/marketplaces",component:p("/constellation/pr-preview/pr-4027/2.22/getting-started/marketplaces","c43"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/overview/clouds",component:p("/constellation/pr-preview/pr-4027/2.22/overview/clouds","8dd"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/overview/confidential-kubernetes",component:p("/constellation/pr-preview/pr-4027/2.22/overview/confidential-kubernetes","388"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/overview/license",component:p("/constellation/pr-preview/pr-4027/2.22/overview/license","b48"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/overview/performance/",component:p("/constellation/pr-preview/pr-4027/2.22/overview/performance/","559"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/overview/performance/application",component:p("/constellation/pr-preview/pr-4027/2.22/overview/performance/application","599"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/overview/performance/compute",component:p("/constellation/pr-preview/pr-4027/2.22/overview/performance/compute","e94"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/overview/performance/io",component:p("/constellation/pr-preview/pr-4027/2.22/overview/performance/io","2bc"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/overview/product",component:p("/constellation/pr-preview/pr-4027/2.22/overview/product","821"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/overview/security-benefits",component:p("/constellation/pr-preview/pr-4027/2.22/overview/security-benefits","5c0"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/reference/cli",component:p("/constellation/pr-preview/pr-4027/2.22/reference/cli","77d"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/reference/migration",component:p("/constellation/pr-preview/pr-4027/2.22/reference/migration","280"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/reference/slsa",component:p("/constellation/pr-preview/pr-4027/2.22/reference/slsa","9b2"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/reference/terraform",component:p("/constellation/pr-preview/pr-4027/2.22/reference/terraform","89f"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/workflows/cert-manager",component:p("/constellation/pr-preview/pr-4027/2.22/workflows/cert-manager","c0b"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/workflows/config",component:p("/constellation/pr-preview/pr-4027/2.22/workflows/config","632"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/workflows/create",component:p("/constellation/pr-preview/pr-4027/2.22/workflows/create","bd7"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/workflows/lb",component:p("/constellation/pr-preview/pr-4027/2.22/workflows/lb","fa8"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/workflows/recovery",component:p("/constellation/pr-preview/pr-4027/2.22/workflows/recovery","197"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/workflows/reproducible-builds",component:p("/constellation/pr-preview/pr-4027/2.22/workflows/reproducible-builds","bc4"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/workflows/s3proxy",component:p("/constellation/pr-preview/pr-4027/2.22/workflows/s3proxy","c88"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/workflows/sbom",component:p("/constellation/pr-preview/pr-4027/2.22/workflows/sbom","f31"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/workflows/scale",component:p("/constellation/pr-preview/pr-4027/2.22/workflows/scale","961"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/workflows/storage",component:p("/constellation/pr-preview/pr-4027/2.22/workflows/storage","4a9"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/workflows/terminate",component:p("/constellation/pr-preview/pr-4027/2.22/workflows/terminate","90f"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/workflows/terraform-provider",component:p("/constellation/pr-preview/pr-4027/2.22/workflows/terraform-provider","489"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting",component:p("/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting","6b3"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/workflows/trusted-launch",component:p("/constellation/pr-preview/pr-4027/2.22/workflows/trusted-launch","71c"),exact:!0},{path:"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade",component:p("/constellation/pr-preview/pr-4027/2.22/workflows/upgrade","7d3"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli",component:p("/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli","ee3"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cluster",component:p("/constellation/pr-preview/pr-4027/2.22/workflows/verify-cluster","c8e"),exact:!0,sidebar:"docs"}]}]},{path:"/constellation/pr-preview/pr-4027/2.23",component:p("/constellation/pr-preview/pr-4027/2.23","739"),routes:[{path:"/constellation/pr-preview/pr-4027/2.23",component:p("/constellation/pr-preview/pr-4027/2.23","7a4"),routes:[{path:"/constellation/pr-preview/pr-4027/2.23/",component:p("/constellation/pr-preview/pr-4027/2.23/","2a5"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/architecture/attestation",component:p("/constellation/pr-preview/pr-4027/2.23/architecture/attestation","efc"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage",component:p("/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storage","1cc"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/architecture/images",component:p("/constellation/pr-preview/pr-4027/2.23/architecture/images","51c"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/architecture/keys",component:p("/constellation/pr-preview/pr-4027/2.23/architecture/keys","806"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/architecture/microservices",component:p("/constellation/pr-preview/pr-4027/2.23/architecture/microservices","f58"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/architecture/networking",component:p("/constellation/pr-preview/pr-4027/2.23/architecture/networking","b9a"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/architecture/observability",component:p("/constellation/pr-preview/pr-4027/2.23/architecture/observability","441"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/architecture/orchestration",component:p("/constellation/pr-preview/pr-4027/2.23/architecture/orchestration","702"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/architecture/overview",component:p("/constellation/pr-preview/pr-4027/2.23/architecture/overview","b03"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/architecture/versions",component:p("/constellation/pr-preview/pr-4027/2.23/architecture/versions","7fa"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/category/architecture",component:p("/constellation/pr-preview/pr-4027/2.23/category/architecture","3a7"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/category/basics",component:p("/constellation/pr-preview/pr-4027/2.23/category/basics","9d6"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/category/getting-started",component:p("/constellation/pr-preview/pr-4027/2.23/category/getting-started","805"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/category/reference",component:p("/constellation/pr-preview/pr-4027/2.23/category/reference","705"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/category/workflows",component:p("/constellation/pr-preview/pr-4027/2.23/category/workflows","5fe"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/getting-started/examples",component:p("/constellation/pr-preview/pr-4027/2.23/getting-started/examples","1b6"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/emojivoto",component:p("/constellation/pr-preview/pr-4027/2.23/getting-started/examples/emojivoto","508"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/filestash-s3proxy",component:p("/constellation/pr-preview/pr-4027/2.23/getting-started/examples/filestash-s3proxy","572"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/horizontal-scaling",component:p("/constellation/pr-preview/pr-4027/2.23/getting-started/examples/horizontal-scaling","e8d"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/getting-started/examples/online-boutique",component:p("/constellation/pr-preview/pr-4027/2.23/getting-started/examples/online-boutique","704"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps",component:p("/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps","b5a"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps-local",component:p("/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps-local","a51"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/getting-started/install",component:p("/constellation/pr-preview/pr-4027/2.23/getting-started/install","903"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/getting-started/marketplaces",component:p("/constellation/pr-preview/pr-4027/2.23/getting-started/marketplaces","493"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/overview/clouds",component:p("/constellation/pr-preview/pr-4027/2.23/overview/clouds","6b8"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/overview/confidential-kubernetes",component:p("/constellation/pr-preview/pr-4027/2.23/overview/confidential-kubernetes","801"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/overview/license",component:p("/constellation/pr-preview/pr-4027/2.23/overview/license","2e0"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/overview/performance/",component:p("/constellation/pr-preview/pr-4027/2.23/overview/performance/","7d1"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/overview/performance/application",component:p("/constellation/pr-preview/pr-4027/2.23/overview/performance/application","897"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/overview/performance/compute",component:p("/constellation/pr-preview/pr-4027/2.23/overview/performance/compute","325"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/overview/performance/io",component:p("/constellation/pr-preview/pr-4027/2.23/overview/performance/io","71a"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/overview/product",component:p("/constellation/pr-preview/pr-4027/2.23/overview/product","8f9"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/overview/security-benefits",component:p("/constellation/pr-preview/pr-4027/2.23/overview/security-benefits","833"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/reference/cli",component:p("/constellation/pr-preview/pr-4027/2.23/reference/cli","089"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/reference/migration",component:p("/constellation/pr-preview/pr-4027/2.23/reference/migration","646"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/reference/slsa",component:p("/constellation/pr-preview/pr-4027/2.23/reference/slsa","4e0"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/reference/terraform",component:p("/constellation/pr-preview/pr-4027/2.23/reference/terraform","4bf"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/workflows/cert-manager",component:p("/constellation/pr-preview/pr-4027/2.23/workflows/cert-manager","906"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/workflows/config",component:p("/constellation/pr-preview/pr-4027/2.23/workflows/config","3fc"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/workflows/create",component:p("/constellation/pr-preview/pr-4027/2.23/workflows/create","3d7"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/workflows/lb",component:p("/constellation/pr-preview/pr-4027/2.23/workflows/lb","93d"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/workflows/recovery",component:p("/constellation/pr-preview/pr-4027/2.23/workflows/recovery","892"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/workflows/reproducible-builds",component:p("/constellation/pr-preview/pr-4027/2.23/workflows/reproducible-builds","b45"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/workflows/s3proxy",component:p("/constellation/pr-preview/pr-4027/2.23/workflows/s3proxy","a8c"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/workflows/sbom",component:p("/constellation/pr-preview/pr-4027/2.23/workflows/sbom","761"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/workflows/scale",component:p("/constellation/pr-preview/pr-4027/2.23/workflows/scale","0e9"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/workflows/storage",component:p("/constellation/pr-preview/pr-4027/2.23/workflows/storage","91e"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/workflows/terminate",component:p("/constellation/pr-preview/pr-4027/2.23/workflows/terminate","231"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/workflows/terraform-provider",component:p("/constellation/pr-preview/pr-4027/2.23/workflows/terraform-provider","8a3"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/workflows/troubleshooting",component:p("/constellation/pr-preview/pr-4027/2.23/workflows/troubleshooting","be8"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/workflows/trusted-launch",component:p("/constellation/pr-preview/pr-4027/2.23/workflows/trusted-launch","431"),exact:!0},{path:"/constellation/pr-preview/pr-4027/2.23/workflows/upgrade",component:p("/constellation/pr-preview/pr-4027/2.23/workflows/upgrade","fde"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cli",component:p("/constellation/pr-preview/pr-4027/2.23/workflows/verify-cli","a61"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/2.23/workflows/verify-cluster",component:p("/constellation/pr-preview/pr-4027/2.23/workflows/verify-cluster","2d3"),exact:!0,sidebar:"docs"}]}]},{path:"/constellation/pr-preview/pr-4027/next",component:p("/constellation/pr-preview/pr-4027/next","c46"),routes:[{path:"/constellation/pr-preview/pr-4027/next",component:p("/constellation/pr-preview/pr-4027/next","8d5"),routes:[{path:"/constellation/pr-preview/pr-4027/next/",component:p("/constellation/pr-preview/pr-4027/next/","32d"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/architecture/attestation",component:p("/constellation/pr-preview/pr-4027/next/architecture/attestation","74c"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage",component:p("/constellation/pr-preview/pr-4027/next/architecture/encrypted-storage","285"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/architecture/images",component:p("/constellation/pr-preview/pr-4027/next/architecture/images","c23"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/architecture/keys",component:p("/constellation/pr-preview/pr-4027/next/architecture/keys","c67"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/architecture/microservices",component:p("/constellation/pr-preview/pr-4027/next/architecture/microservices","65a"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/architecture/networking",component:p("/constellation/pr-preview/pr-4027/next/architecture/networking","df4"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/architecture/observability",component:p("/constellation/pr-preview/pr-4027/next/architecture/observability","13d"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/architecture/orchestration",component:p("/constellation/pr-preview/pr-4027/next/architecture/orchestration","840"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/architecture/overview",component:p("/constellation/pr-preview/pr-4027/next/architecture/overview","f60"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/architecture/versions",component:p("/constellation/pr-preview/pr-4027/next/architecture/versions","405"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/category/architecture",component:p("/constellation/pr-preview/pr-4027/next/category/architecture","c2a"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/category/basics",component:p("/constellation/pr-preview/pr-4027/next/category/basics","2f7"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/category/getting-started",component:p("/constellation/pr-preview/pr-4027/next/category/getting-started","420"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/category/reference",component:p("/constellation/pr-preview/pr-4027/next/category/reference","968"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/category/workflows",component:p("/constellation/pr-preview/pr-4027/next/category/workflows","a7a"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/getting-started/examples",component:p("/constellation/pr-preview/pr-4027/next/getting-started/examples","671"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/getting-started/examples/emojivoto",component:p("/constellation/pr-preview/pr-4027/next/getting-started/examples/emojivoto","800"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/getting-started/examples/filestash-s3proxy",component:p("/constellation/pr-preview/pr-4027/next/getting-started/examples/filestash-s3proxy","abb"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/getting-started/examples/horizontal-scaling",component:p("/constellation/pr-preview/pr-4027/next/getting-started/examples/horizontal-scaling","2ff"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/getting-started/examples/online-boutique",component:p("/constellation/pr-preview/pr-4027/next/getting-started/examples/online-boutique","780"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/getting-started/first-steps",component:p("/constellation/pr-preview/pr-4027/next/getting-started/first-steps","5be"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/getting-started/first-steps-local",component:p("/constellation/pr-preview/pr-4027/next/getting-started/first-steps-local","9ab"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/getting-started/install",component:p("/constellation/pr-preview/pr-4027/next/getting-started/install","d95"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/getting-started/marketplaces",component:p("/constellation/pr-preview/pr-4027/next/getting-started/marketplaces","772"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/overview/clouds",component:p("/constellation/pr-preview/pr-4027/next/overview/clouds","39f"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/overview/confidential-kubernetes",component:p("/constellation/pr-preview/pr-4027/next/overview/confidential-kubernetes","92a"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/overview/license",component:p("/constellation/pr-preview/pr-4027/next/overview/license","8d4"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/overview/performance/",component:p("/constellation/pr-preview/pr-4027/next/overview/performance/","0ba"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/overview/performance/application",component:p("/constellation/pr-preview/pr-4027/next/overview/performance/application","296"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/overview/performance/compute",component:p("/constellation/pr-preview/pr-4027/next/overview/performance/compute","069"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/overview/performance/io",component:p("/constellation/pr-preview/pr-4027/next/overview/performance/io","bfc"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/overview/product",component:p("/constellation/pr-preview/pr-4027/next/overview/product","e17"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/overview/security-benefits",component:p("/constellation/pr-preview/pr-4027/next/overview/security-benefits","82c"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/reference/cli",component:p("/constellation/pr-preview/pr-4027/next/reference/cli","ae6"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/reference/migration",component:p("/constellation/pr-preview/pr-4027/next/reference/migration","6ee"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/reference/slsa",component:p("/constellation/pr-preview/pr-4027/next/reference/slsa","06c"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/reference/terraform",component:p("/constellation/pr-preview/pr-4027/next/reference/terraform","d4c"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/workflows/cert-manager",component:p("/constellation/pr-preview/pr-4027/next/workflows/cert-manager","67d"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/workflows/config",component:p("/constellation/pr-preview/pr-4027/next/workflows/config","c37"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/workflows/create",component:p("/constellation/pr-preview/pr-4027/next/workflows/create","ab5"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/workflows/lb",component:p("/constellation/pr-preview/pr-4027/next/workflows/lb","508"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/workflows/recovery",component:p("/constellation/pr-preview/pr-4027/next/workflows/recovery","d15"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/workflows/reproducible-builds",component:p("/constellation/pr-preview/pr-4027/next/workflows/reproducible-builds","f5e"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/workflows/s3proxy",component:p("/constellation/pr-preview/pr-4027/next/workflows/s3proxy","ee9"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/workflows/sbom",component:p("/constellation/pr-preview/pr-4027/next/workflows/sbom","463"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/workflows/scale",component:p("/constellation/pr-preview/pr-4027/next/workflows/scale","f4c"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/workflows/storage",component:p("/constellation/pr-preview/pr-4027/next/workflows/storage","b6e"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/workflows/terminate",component:p("/constellation/pr-preview/pr-4027/next/workflows/terminate","372"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/workflows/terraform-provider",component:p("/constellation/pr-preview/pr-4027/next/workflows/terraform-provider","784"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/workflows/troubleshooting",component:p("/constellation/pr-preview/pr-4027/next/workflows/troubleshooting","4bb"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/workflows/trusted-launch",component:p("/constellation/pr-preview/pr-4027/next/workflows/trusted-launch","d61"),exact:!0},{path:"/constellation/pr-preview/pr-4027/next/workflows/upgrade",component:p("/constellation/pr-preview/pr-4027/next/workflows/upgrade","4c5"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/workflows/verify-cli",component:p("/constellation/pr-preview/pr-4027/next/workflows/verify-cli","1e3"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/next/workflows/verify-cluster",component:p("/constellation/pr-preview/pr-4027/next/workflows/verify-cluster","490"),exact:!0,sidebar:"docs"}]}]},{path:"/constellation/pr-preview/pr-4027/",component:p("/constellation/pr-preview/pr-4027/","bdb"),routes:[{path:"/constellation/pr-preview/pr-4027/",component:p("/constellation/pr-preview/pr-4027/","be5"),routes:[{path:"/constellation/pr-preview/pr-4027/architecture/attestation",component:p("/constellation/pr-preview/pr-4027/architecture/attestation","a81"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/architecture/encrypted-storage",component:p("/constellation/pr-preview/pr-4027/architecture/encrypted-storage","bb8"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/architecture/images",component:p("/constellation/pr-preview/pr-4027/architecture/images","8a4"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/architecture/keys",component:p("/constellation/pr-preview/pr-4027/architecture/keys","cb3"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/architecture/microservices",component:p("/constellation/pr-preview/pr-4027/architecture/microservices","22f"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/architecture/networking",component:p("/constellation/pr-preview/pr-4027/architecture/networking","b7c"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/architecture/observability",component:p("/constellation/pr-preview/pr-4027/architecture/observability","047"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/architecture/orchestration",component:p("/constellation/pr-preview/pr-4027/architecture/orchestration","176"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/architecture/overview",component:p("/constellation/pr-preview/pr-4027/architecture/overview","61d"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/architecture/versions",component:p("/constellation/pr-preview/pr-4027/architecture/versions","766"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/category/architecture",component:p("/constellation/pr-preview/pr-4027/category/architecture","e55"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/category/basics",component:p("/constellation/pr-preview/pr-4027/category/basics","f2f"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/category/getting-started",component:p("/constellation/pr-preview/pr-4027/category/getting-started","c17"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/category/reference",component:p("/constellation/pr-preview/pr-4027/category/reference","d10"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/category/workflows",component:p("/constellation/pr-preview/pr-4027/category/workflows","e68"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/getting-started/examples",component:p("/constellation/pr-preview/pr-4027/getting-started/examples","93f"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/getting-started/examples/emojivoto",component:p("/constellation/pr-preview/pr-4027/getting-started/examples/emojivoto","988"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/getting-started/examples/filestash-s3proxy",component:p("/constellation/pr-preview/pr-4027/getting-started/examples/filestash-s3proxy","e46"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/getting-started/examples/horizontal-scaling",component:p("/constellation/pr-preview/pr-4027/getting-started/examples/horizontal-scaling","0da"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/getting-started/examples/online-boutique",component:p("/constellation/pr-preview/pr-4027/getting-started/examples/online-boutique","df3"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/getting-started/first-steps",component:p("/constellation/pr-preview/pr-4027/getting-started/first-steps","b4f"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/getting-started/first-steps-local",component:p("/constellation/pr-preview/pr-4027/getting-started/first-steps-local","e3a"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/getting-started/install",component:p("/constellation/pr-preview/pr-4027/getting-started/install","b1b"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/getting-started/marketplaces",component:p("/constellation/pr-preview/pr-4027/getting-started/marketplaces","d82"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/overview/clouds",component:p("/constellation/pr-preview/pr-4027/overview/clouds","90e"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/overview/confidential-kubernetes",component:p("/constellation/pr-preview/pr-4027/overview/confidential-kubernetes","ac0"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/overview/license",component:p("/constellation/pr-preview/pr-4027/overview/license","049"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/overview/performance/",component:p("/constellation/pr-preview/pr-4027/overview/performance/","4be"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/overview/performance/application",component:p("/constellation/pr-preview/pr-4027/overview/performance/application","ad9"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/overview/performance/compute",component:p("/constellation/pr-preview/pr-4027/overview/performance/compute","822"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/overview/performance/io",component:p("/constellation/pr-preview/pr-4027/overview/performance/io","62f"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/overview/product",component:p("/constellation/pr-preview/pr-4027/overview/product","772"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/overview/security-benefits",component:p("/constellation/pr-preview/pr-4027/overview/security-benefits","959"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/reference/cli",component:p("/constellation/pr-preview/pr-4027/reference/cli","4a8"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/reference/migration",component:p("/constellation/pr-preview/pr-4027/reference/migration","a42"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/reference/slsa",component:p("/constellation/pr-preview/pr-4027/reference/slsa","cb5"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/reference/terraform",component:p("/constellation/pr-preview/pr-4027/reference/terraform","ff6"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/workflows/cert-manager",component:p("/constellation/pr-preview/pr-4027/workflows/cert-manager","58a"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/workflows/config",component:p("/constellation/pr-preview/pr-4027/workflows/config","8a9"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/workflows/create",component:p("/constellation/pr-preview/pr-4027/workflows/create","e04"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/workflows/lb",component:p("/constellation/pr-preview/pr-4027/workflows/lb","f21"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/workflows/recovery",component:p("/constellation/pr-preview/pr-4027/workflows/recovery","063"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/workflows/reproducible-builds",component:p("/constellation/pr-preview/pr-4027/workflows/reproducible-builds","cda"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/workflows/s3proxy",component:p("/constellation/pr-preview/pr-4027/workflows/s3proxy","970"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/workflows/sbom",component:p("/constellation/pr-preview/pr-4027/workflows/sbom","614"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/workflows/scale",component:p("/constellation/pr-preview/pr-4027/workflows/scale","0d6"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/workflows/storage",component:p("/constellation/pr-preview/pr-4027/workflows/storage","d91"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/workflows/terminate",component:p("/constellation/pr-preview/pr-4027/workflows/terminate","48f"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/workflows/terraform-provider",component:p("/constellation/pr-preview/pr-4027/workflows/terraform-provider","472"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/workflows/troubleshooting",component:p("/constellation/pr-preview/pr-4027/workflows/troubleshooting","74c"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/workflows/trusted-launch",component:p("/constellation/pr-preview/pr-4027/workflows/trusted-launch","75f"),exact:!0},{path:"/constellation/pr-preview/pr-4027/workflows/upgrade",component:p("/constellation/pr-preview/pr-4027/workflows/upgrade","aa2"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/workflows/verify-cli",component:p("/constellation/pr-preview/pr-4027/workflows/verify-cli","8fa"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/workflows/verify-cluster",component:p("/constellation/pr-preview/pr-4027/workflows/verify-cluster","995"),exact:!0,sidebar:"docs"},{path:"/constellation/pr-preview/pr-4027/",component:p("/constellation/pr-preview/pr-4027/","d9c"),exact:!0,sidebar:"docs"}]}]}]},{path:"*",component:p("*")}]},93512:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});var r=n(96540),o=n(23363);function i(){const e=r.useContext(o.o);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}},94549:(e,t,n)=>{"use strict";n.d(t,{N:()=>h,u:()=>l});var r=n(96540),o=n(36494),i=n(36350),a=n(74848);const s="ease-in-out";function l({initialState:e}){const[t,n]=(0,r.useState)(e??!1),o=(0,r.useCallback)(()=>{n(e=>!e)},[]);return{collapsed:t,setCollapsed:n,toggleCollapsed:o}}const c={display:"none",overflow:"hidden",height:"0px"},u={display:"block",overflow:"visible",height:"auto"};function p(e,t){const n=t?c:u;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function d({collapsibleRef:e,collapsed:t,animation:n}){const o=(0,r.useRef)(!1);(0,r.useEffect)(()=>{const r=e.current;function a(){const e=r.scrollHeight,t=n?.duration??function(e){if((0,i.O)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(e);return{transition:`height ${t}ms ${n?.easing??s}`,height:`${e}px`}}function l(){const e=a();r.style.transition=e.transition,r.style.height=e.height}if(!o.current)return p(r,t),void(o.current=!0);return r.style.willChange="height",function(){const e=requestAnimationFrame(()=>{t?(l(),requestAnimationFrame(()=>{r.style.height=c.height,r.style.overflow=c.overflow})):(r.style.display="block",requestAnimationFrame(()=>{l()}))});return()=>cancelAnimationFrame(e)}()},[e,t,n])}function f({as:e="div",collapsed:t,children:n,animation:o,onCollapseTransitionEnd:i,className:s}){const l=(0,r.useRef)(null);return d({collapsibleRef:l,collapsed:t,animation:o}),(0,a.jsx)(e,{ref:l,onTransitionEnd:e=>{"height"===e.propertyName&&(p(l.current,t),i?.(t))},className:s,children:n})}function m({collapsed:e,...t}){const[n,i]=(0,r.useState)(!e),[s,l]=(0,r.useState)(e);return(0,o.A)(()=>{e||i(!0)},[e]),(0,o.A)(()=>{n&&l(e)},[n,e]),n?(0,a.jsx)(f,{...t,collapsed:s}):null}function h({lazy:e,...t}){const n=e?m:f;return(0,a.jsx)(n,{...t})}},96540:(e,t,n)=>{"use strict";e.exports=n(15287)},97639:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});var r=n(96540),o=n(53366);function i(){return(0,r.useContext)(o.o)}},98180:(e,t,n)=>{"use strict";n.d(t,{Ay:()=>s,hH:()=>a});var r=n(96540),o=n(97639),i=n(40877);function a(){const{siteConfig:e}=(0,o.A)(),{baseUrl:t,url:n}=e,a=e.future.experimental_router,s=(0,r.useCallback)((e,r)=>function({siteUrl:e,baseUrl:t,url:n,options:{forcePrependBaseUrl:r=!1,absolute:o=!1}={},router:a}){if(!n||n.startsWith("#")||(0,i.z)(n))return n;if("hash"===a)return n.startsWith("/")?`.${n}`:`./${n}`;if(r)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const s=n.startsWith(t)?n:t+n.replace(/^\//,"");return o?e+s:s}({siteUrl:n,baseUrl:t,url:e,options:r,router:a}),[n,t,a]);return{withBaseUrl:s}}function s(e,t={}){const{withBaseUrl:n}=a();return n(e,t)}},98587:(e,t,n)=>{"use strict";function r(e,t){if(null==e)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==t.indexOf(r))continue;n[r]=e[r]}return n}n.d(t,{A:()=>r})}},e=>{e.O(0,[1869],()=>{return t=2117,e(e.s=t);var t});e.O()}]); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/js/main.6a3f64be.js.LICENSE.txt b/pr-preview/pr-4027/assets/js/main.6a3f64be.js.LICENSE.txt deleted file mode 100644 index c9b81c42a..000000000 --- a/pr-preview/pr-4027/assets/js/main.6a3f64be.js.LICENSE.txt +++ /dev/null @@ -1,120 +0,0 @@ -/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress - * @license MIT */ - -/*! - * lunr.Builder - * Copyright (C) 2020 Oliver Nightingale - */ - -/*! - * lunr.Index - * Copyright (C) 2020 Oliver Nightingale - */ - -/*! - * lunr.Pipeline - * Copyright (C) 2020 Oliver Nightingale - */ - -/*! - * lunr.Set - * Copyright (C) 2020 Oliver Nightingale - */ - -/*! - * lunr.TokenSet - * Copyright (C) 2020 Oliver Nightingale - */ - -/*! - * lunr.Vector - * Copyright (C) 2020 Oliver Nightingale - */ - -/*! - * lunr.stemmer - * Copyright (C) 2020 Oliver Nightingale - * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt - */ - -/*! - * lunr.stopWordFilter - * Copyright (C) 2020 Oliver Nightingale - */ - -/*! - * lunr.tokenizer - * Copyright (C) 2020 Oliver Nightingale - */ - -/*! - * lunr.trimmer - * Copyright (C) 2020 Oliver Nightingale - */ - -/*! - * lunr.utils - * Copyright (C) 2020 Oliver Nightingale - */ - -/*!*************************************************** -* mark.js v8.11.1 -* https://markjs.io/ -* Copyright (c) 2014–2018, Julian Kühnel -* Released under the MIT license https://git.io/vwTVl -*****************************************************/ - -/** - * @license React - * react-dom.production.min.js - * - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -/** - * @license React - * react-jsx-runtime.production.min.js - * - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -/** - * @license React - * react.production.min.js - * - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -/** - * @license React - * scheduler.production.min.js - * - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -/** - * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 - * Copyright (C) 2020 Oliver Nightingale - * @license MIT - */ - -/** @license React v16.13.1 - * react-is.production.min.js - * - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ diff --git a/pr-preview/pr-4027/assets/js/runtime~main.ddabc591.js b/pr-preview/pr-4027/assets/js/runtime~main.ddabc591.js deleted file mode 100644 index 2793827e8..000000000 --- a/pr-preview/pr-4027/assets/js/runtime~main.ddabc591.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{"use strict";var e,a,c,d,f,b={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var c=t[e]={exports:{}};return b[e].call(c.exports,c,c.exports,r),c.exports}r.m=b,e=[],r.O=(a,c,d,f)=>{if(!c){var b=1/0;for(i=0;i<e.length;i++){for(var[c,d,f]=e[i],t=!0,o=0;o<c.length;o++)(!1&f||b>=f)&&Object.keys(r.O).every(e=>r.O[e](c[o]))?c.splice(o--,1):(t=!1,f<b&&(b=f));if(t){e.splice(i--,1);var n=d();void 0!==n&&(a=n)}}return a}f=f||0;for(var i=e.length;i>0&&e[i-1][2]>f;i--)e[i]=e[i-1];e[i]=[c,d,f]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},c=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,d){if(1&d&&(e=this(e)),8&d)return e;if("object"==typeof e&&e){if(4&d&&e.__esModule)return e;if(16&d&&"function"==typeof e.then)return e}var f=Object.create(null);r.r(f);var b={};a=a||[null,c({}),c([]),c(c)];for(var t=2&d&&e;("object"==typeof t||"function"==typeof t)&&!~a.indexOf(t);t=c(t))Object.getOwnPropertyNames(t).forEach(a=>b[a]=()=>e[a]);return b.default=()=>e,r.d(f,b),f},r.d=(e,a)=>{for(var c in a)r.o(a,c)&&!r.o(e,c)&&Object.defineProperty(e,c,{enumerable:!0,get:a[c]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((a,c)=>(r.f[c](e,a),a),[])),r.u=e=>"assets/js/"+({84:"960959b3",234:"cea600d4",249:"5aae01e0",253:"786c60fb",292:"5e92d76a",301:"72c2c1f0",304:"8183fba6",308:"ae4682fc",337:"95ca3cf4",386:"4b669f2d",402:"6c830a9a",417:"4bfed142",470:"0bfd0c91",557:"543a522f",656:"a3183fd7",663:"1c0e8ae3",680:"dae6bd30",832:"71dfee10",853:"e97075f3",867:"592bfb5e",909:"4967aec5",945:"11b4c29f",946:"d12af2ba",998:"911e2eea",1006:"401e1ad9",1031:"92236455",1067:"80697fb2",1086:"0cee1087",1155:"c920f53d",1187:"b28da407",1201:"4fce284f",1220:"f402a94e",1226:"927cf76e",1268:"15c6e37c",1275:"a7be6a84",1279:"e0f39c0b",1298:"15e5e9ad",1376:"508a7d2f",1415:"76b2ab15",1470:"9be9ef65",1516:"acf362b0",1523:"66e2533d",1587:"acced080",1603:"1036ee0b",1610:"e91da414",1618:"de51a3b8",1671:"48186bb1",1734:"4f0549e0",1789:"9ba5d544",1793:"2b3dcc9b",1799:"11dcff96",1897:"84de5ccf",1901:"5e23635c",1902:"3aba4a32",2190:"989930da",2301:"8a026b6c",2307:"0c605e3b",2398:"31cc4483",2559:"0282ce66",2560:"452d9595",2662:"5d6cdc31",2719:"42888a29",2733:"64c81f13",2762:"5dc5a687",2813:"925a7d08",2829:"b80e9c3d",2843:"cbcdb048",2908:"84353103",2928:"6e43ec2e",2947:"794987bd",2993:"a5863201",3092:"3305fd99",3101:"d4cfdd56",3132:"75a3ea9f",3182:"af08314d",3280:"3e6faa8e",3289:"fd1d3864",3325:"633fbb2f",3339:"294c0512",3340:"4cc5eb92",3405:"d2556545",3440:"31840164",3452:"1b80620b",3456:"3b1b22d5",3465:"f8c8aa36",3501:"db1b10df",3526:"cda59bb1",3531:"142263a9",3533:"72a880f4",3539:"786b68f5",3610:"2a05e475",3772:"3607c499",3884:"e344aa3d",3939:"e7c02e82",3976:"0e384e19",4071:"9b22caeb",4085:"53c1dfd4",4100:"8d448ad2",4200:"3962f62e",4222:"da6dfe9f",4244:"487d2b28",4263:"856c1b4a",4318:"1e04dd29",4394:"3aca6029",4425:"ec7c7126",4591:"b29fd7c7",4613:"837f4190",4616:"2dc3352a",4672:"9d4f835b",4678:"d17f599b",4723:"462332ca",4801:"dcc7f694",4954:"28a0f3ab",5096:"5a6332a4",5116:"0428ff27",5128:"74afccd1",5249:"797a5fdc",5267:"dfb8a45d",5343:"20a029f4",5423:"36f09204",5514:"073bbd6a",5541:"642ed902",5739:"dc614479",5742:"aba21aa0",5757:"a7cbe781",5845:"1c53691b",5863:"0b1ac180",6032:"3ee8c4d1",6065:"e12b18ba",6067:"9bccdd10",6135:"9010cc91",6144:"adfda302",6154:"7ae19400",6257:"a4c009ef",6373:"70248ece",6389:"ded7ff97",6407:"836c9f98",6457:"baf93e4b",6510:"242e7908",6516:"d89a6bd5",6567:"c2af115c",6599:"a6a7cec0",6664:"269ef64a",6665:"60d3a1b7",6822:"533d31d4",6823:"6df30968",6850:"66852f4d",6851:"8452cbfd",6879:"2a9ad702",6897:"6d0fae35",6912:"79e0c113",6969:"14eb3368",6996:"039005a9",7018:"3fe7bb19",7078:"574ee69f",7083:"8713d71c",7098:"a7bd4aaa",7193:"97b147c7",7218:"a93f81ab",7227:"a39aaf1d",7274:"56806aed",7284:"e19825b3",7292:"2a2a0c40",7317:"b744c41b",7320:"0b615bd7",7335:"0a66f7ff",7356:"4c9525de",7373:"42298223",7466:"8ca353b4",7496:"ce803f35",7570:"eae38991",7625:"25e50762",7726:"f03f4c5d",7730:"d84515e5",7856:"311067ef",7861:"3e0d8e9d",7934:"0c363123",8003:"9c1ba6d8",8043:"0b338d1c",8048:"3bcf7932",8146:"a7e69b4a",8205:"3b28b3cc",8238:"91c76d4c",8255:"ca9f0fb1",8295:"074359f8",8395:"bf976132",8401:"17896441",8428:"70f89ddc",8488:"1890268c",8518:"c33b0c87",8569:"86470a9a",8585:"dfb82530",8598:"40c738e9",8619:"6fe48d2e",8748:"d0929cd6",8784:"7cae3477",8806:"01f9c0c3",8865:"68f29d4c",8889:"a0c24a7b",8917:"5bf0e48f",8994:"90e117e3",8996:"9afa113a",9023:"6776993e",9032:"cb054e22",9048:"a94703ab",9074:"54db543f",9075:"7c763686",9308:"9cbfbb7f",9341:"e61948c8",9343:"ca2d12cf",9361:"fb5790ab",9414:"3fddd266",9427:"358e1fce",9442:"4cf171a2",9509:"8ea786c8",9514:"4a51e885",9528:"3324b179",9529:"e0c6aa40",9579:"8a589188",9612:"28513d82",9619:"260d3cdf",9647:"5e95c892",9673:"e8feb497",9698:"619bb71e",9727:"061c4c8e",9732:"481538bf",9766:"76f884e3",9767:"5672ef9d",9770:"a631f374",9912:"0eb3e611"}[e]||e)+"."+{84:"3b66f9f2",165:"fdd19a26",179:"98ad7c3b",234:"27bcd6a1",249:"4eb12944",253:"d7dfd23a",291:"ab24d400",292:"c9131055",301:"b96352b6",304:"e63b4420",308:"bd09743d",337:"101fccad",386:"a0ccaa76",402:"2ca9c905",417:"f1329705",470:"25d5f4dd",557:"17585bbf",617:"55c4d8c0",656:"fe04cf76",663:"89100639",680:"317266e3",832:"81e5ecaf",853:"f1e5a2f5",867:"1f7a9f64",909:"cea229a8",945:"5f60ca1d",946:"d07f7408",998:"bded8e4c",1e3:"89c3dd98",1006:"fd632f9c",1031:"90a907d5",1067:"341f256e",1086:"21f6746b",1155:"e05afb5e",1187:"5321d36a",1201:"af8f5e7c",1203:"72b741a7",1220:"b74542ad",1226:"74a50cde",1268:"d85a6cae",1275:"cd4ab870",1279:"4e546576",1298:"32e35ac7",1376:"d99914e5",1415:"bf48cdb7",1470:"a4121f91",1516:"e0ac5608",1523:"3c4f9e07",1587:"7d6c4195",1603:"bc80d0c2",1610:"45776acc",1618:"9944225e",1671:"517b63ea",1734:"456cfea0",1741:"d9ca137f",1746:"4ae2d600",1789:"2ed729cc",1793:"bd88b6ce",1799:"801ce7eb",1897:"ae4c6c22",1901:"096a5bd0",1902:"42c67689",2093:"f4a3364b",2130:"b53d8919",2190:"0bf1c4b6",2235:"460f34f9",2279:"aea29fbb",2291:"abd3c57a",2301:"c06d830e",2307:"36848557",2325:"4b61ab01",2334:"ad641aac",2398:"6741e272",2559:"cb3fb8b2",2560:"8d32ca6b",2662:"4cfde06b",2719:"52b6655b",2733:"d0a432fb",2762:"7b3d863e",2813:"3942d153",2821:"b92d32c5",2829:"370d4b83",2843:"23aba831",2908:"8406d97f",2928:"a12e9194",2947:"fa5e8276",2993:"f48869f7",3003:"ac806f1f",3092:"2ac95a3b",3101:"00a30674",3132:"4aa32bc7",3182:"13910ef0",3280:"77fa12c2",3289:"4d1ac871",3325:"fefad383",3339:"1a966ee8",3340:"4f588dea",3405:"5917dc82",3440:"0097030a",3452:"8be59223",3456:"476e1074",3465:"3ddbab78",3488:"ebdc9158",3490:"91814865",3501:"841d69f7",3526:"59d1e222",3531:"262679e8",3533:"9f7828f1",3539:"8a000b59",3610:"bd72699c",3624:"7bf76120",3772:"bb98fd49",3815:"705487db",3884:"4b5c7ca5",3939:"81e18f1c",3976:"e9a6d738",4071:"35fb7596",4085:"9a270882",4100:"cf755472",4200:"52655f48",4222:"06480c68",4244:"a63fd0a2",4250:"0d4c2516",4263:"b9ee9d40",4318:"b8b7e365",4379:"4c9173a3",4394:"1291f65f",4425:"e5eb60ab",4591:"bc2a3e28",4613:"ddddc1c3",4616:"943010bc",4672:"c5fd6606",4678:"9b1c9ad5",4723:"224a53bd",4801:"211d37d3",4802:"9da541ee",4954:"4e0d0da1",4981:"bdd615e7",5096:"55cef70a",5116:"9f4bd7a8",5128:"fff6f3ba",5249:"4a0c0d7a",5267:"047a71dd",5343:"19707c04",5423:"6566cb4d",5480:"a964935e",5514:"de1348f1",5541:"5ef7e201",5739:"12c43ec2",5742:"7466539b",5757:"1cd695b6",5845:"0108663e",5863:"5fc2d03f",5901:"f3704c6f",5955:"645e55a4",5996:"cdc792ad",6032:"cff371e1",6065:"4cd83c4c",6067:"e2550a45",6135:"a4630109",6144:"e01c344d",6154:"00557006",6241:"826bee80",6257:"37cd2124",6319:"ec99954f",6366:"060304b1",6373:"ce4c28e6",6389:"f6bb64a4",6407:"fba690cd",6457:"fe36f378",6510:"2e5b368b",6516:"49be83be",6567:"6aae2899",6599:"e9c36e1f",6664:"cc437b10",6665:"20628eac",6822:"7f39540d",6823:"12fac903",6850:"0306c16e",6851:"5b138794",6879:"a6e81067",6897:"5f40d092",6912:"dcc2b313",6969:"770f55ac",6992:"6bbbbe26",6996:"e980c3d6",7018:"4ae2f002",7078:"4e5121f7",7083:"e522f149",7098:"125c3d24",7193:"309aa812",7218:"12d75ad1",7227:"36d99927",7274:"deac1270",7284:"868862f3",7292:"118b00b5",7317:"b5d06d0f",7320:"252ed8ba",7335:"c540accf",7356:"7cf5dfaf",7373:"9ca426d3",7466:"fbda2fc6",7496:"cb1c2349",7570:"c73f15f5",7592:"ee6b88a7",7625:"f7764672",7726:"387e7682",7730:"c5d1d300",7856:"a0fdf84a",7861:"ceac1b01",7873:"2b83eb4c",7928:"292d9849",7934:"1f1d7162",8003:"45404959",8043:"6cb8df9a",8048:"910a9d7e",8142:"22a8eb00",8146:"72ef9c11",8205:"94d205c2",8238:"1cd3611e",8249:"7b68bdca",8255:"84fd3f3c",8295:"c3c68ee5",8395:"8fa4d51e",8401:"bf9de707",8428:"a8ec7c51",8488:"ccf2c28e",8518:"43e2e2a5",8565:"6b3d8208",8569:"ad9a737e",8585:"9fdb1b02",8598:"e56e6bc5",8619:"ad8f8319",8731:"ae3eb0c0",8748:"10e4a498",8756:"289e5e3c",8784:"a2bd8629",8806:"252afaac",8865:"2d54c93a",8889:"92c74a89",8917:"1b0be145",8948:"b0417531",8994:"d0992f85",8996:"a30bc4f8",9023:"3d373e8f",9032:"1fe4c9a7",9048:"2a6d89c3",9074:"c4bc0cc5",9075:"e696c7b8",9308:"d905e7bc",9341:"95e47401",9343:"4f360de1",9361:"c2bf914e",9412:"3eb2f25f",9414:"5afedcea",9427:"78bd25aa",9442:"e11e2998",9509:"db908d2a",9510:"4d014fd7",9514:"f99201b8",9528:"8b5fa325",9529:"9043ab1e",9579:"5249ea68",9612:"46a0c6a0",9619:"4f1fe1d9",9647:"8e057c80",9673:"3097bda1",9698:"87871acc",9727:"6d11960a",9732:"3429f708",9766:"86f1f394",9767:"f3f7d6e3",9770:"cb614d21",9912:"16087d6f"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),d={},f="constellation-docs:",r.l=(e,a,c,b)=>{if(d[e])d[e].push(a);else{var t,o;if(void 0!==c)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var l=n[i];if(l.getAttribute("src")==e||l.getAttribute("data-webpack")==f+c){t=l;break}}t||(o=!0,(t=document.createElement("script")).charset="utf-8",r.nc&&t.setAttribute("nonce",r.nc),t.setAttribute("data-webpack",f+c),t.src=e),d[e]=[a];var u=(a,c)=>{t.onerror=t.onload=null,clearTimeout(s);var f=d[e];if(delete d[e],t.parentNode&&t.parentNode.removeChild(t),f&&f.forEach(e=>e(c)),a)return a(c)},s=setTimeout(u.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=u.bind(null,t.onerror),t.onload=u.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/constellation/pr-preview/pr-4027/",r.gca=function(e){return e={17896441:"8401",31840164:"3440",42298223:"7373",84353103:"2908",92236455:"1031","960959b3":"84",cea600d4:"234","5aae01e0":"249","786c60fb":"253","5e92d76a":"292","72c2c1f0":"301","8183fba6":"304",ae4682fc:"308","95ca3cf4":"337","4b669f2d":"386","6c830a9a":"402","4bfed142":"417","0bfd0c91":"470","543a522f":"557",a3183fd7:"656","1c0e8ae3":"663",dae6bd30:"680","71dfee10":"832",e97075f3:"853","592bfb5e":"867","4967aec5":"909","11b4c29f":"945",d12af2ba:"946","911e2eea":"998","401e1ad9":"1006","80697fb2":"1067","0cee1087":"1086",c920f53d:"1155",b28da407:"1187","4fce284f":"1201",f402a94e:"1220","927cf76e":"1226","15c6e37c":"1268",a7be6a84:"1275",e0f39c0b:"1279","15e5e9ad":"1298","508a7d2f":"1376","76b2ab15":"1415","9be9ef65":"1470",acf362b0:"1516","66e2533d":"1523",acced080:"1587","1036ee0b":"1603",e91da414:"1610",de51a3b8:"1618","48186bb1":"1671","4f0549e0":"1734","9ba5d544":"1789","2b3dcc9b":"1793","11dcff96":"1799","84de5ccf":"1897","5e23635c":"1901","3aba4a32":"1902","989930da":"2190","8a026b6c":"2301","0c605e3b":"2307","31cc4483":"2398","0282ce66":"2559","452d9595":"2560","5d6cdc31":"2662","42888a29":"2719","64c81f13":"2733","5dc5a687":"2762","925a7d08":"2813",b80e9c3d:"2829",cbcdb048:"2843","6e43ec2e":"2928","794987bd":"2947",a5863201:"2993","3305fd99":"3092",d4cfdd56:"3101","75a3ea9f":"3132",af08314d:"3182","3e6faa8e":"3280",fd1d3864:"3289","633fbb2f":"3325","294c0512":"3339","4cc5eb92":"3340",d2556545:"3405","1b80620b":"3452","3b1b22d5":"3456",f8c8aa36:"3465",db1b10df:"3501",cda59bb1:"3526","142263a9":"3531","72a880f4":"3533","786b68f5":"3539","2a05e475":"3610","3607c499":"3772",e344aa3d:"3884",e7c02e82:"3939","0e384e19":"3976","9b22caeb":"4071","53c1dfd4":"4085","8d448ad2":"4100","3962f62e":"4200",da6dfe9f:"4222","487d2b28":"4244","856c1b4a":"4263","1e04dd29":"4318","3aca6029":"4394",ec7c7126:"4425",b29fd7c7:"4591","837f4190":"4613","2dc3352a":"4616","9d4f835b":"4672",d17f599b:"4678","462332ca":"4723",dcc7f694:"4801","28a0f3ab":"4954","5a6332a4":"5096","0428ff27":"5116","74afccd1":"5128","797a5fdc":"5249",dfb8a45d:"5267","20a029f4":"5343","36f09204":"5423","073bbd6a":"5514","642ed902":"5541",dc614479:"5739",aba21aa0:"5742",a7cbe781:"5757","1c53691b":"5845","0b1ac180":"5863","3ee8c4d1":"6032",e12b18ba:"6065","9bccdd10":"6067","9010cc91":"6135",adfda302:"6144","7ae19400":"6154",a4c009ef:"6257","70248ece":"6373",ded7ff97:"6389","836c9f98":"6407",baf93e4b:"6457","242e7908":"6510",d89a6bd5:"6516",c2af115c:"6567",a6a7cec0:"6599","269ef64a":"6664","60d3a1b7":"6665","533d31d4":"6822","6df30968":"6823","66852f4d":"6850","8452cbfd":"6851","2a9ad702":"6879","6d0fae35":"6897","79e0c113":"6912","14eb3368":"6969","039005a9":"6996","3fe7bb19":"7018","574ee69f":"7078","8713d71c":"7083",a7bd4aaa:"7098","97b147c7":"7193",a93f81ab:"7218",a39aaf1d:"7227","56806aed":"7274",e19825b3:"7284","2a2a0c40":"7292",b744c41b:"7317","0b615bd7":"7320","0a66f7ff":"7335","4c9525de":"7356","8ca353b4":"7466",ce803f35:"7496",eae38991:"7570","25e50762":"7625",f03f4c5d:"7726",d84515e5:"7730","311067ef":"7856","3e0d8e9d":"7861","0c363123":"7934","9c1ba6d8":"8003","0b338d1c":"8043","3bcf7932":"8048",a7e69b4a:"8146","3b28b3cc":"8205","91c76d4c":"8238",ca9f0fb1:"8255","074359f8":"8295",bf976132:"8395","70f89ddc":"8428","1890268c":"8488",c33b0c87:"8518","86470a9a":"8569",dfb82530:"8585","40c738e9":"8598","6fe48d2e":"8619",d0929cd6:"8748","7cae3477":"8784","01f9c0c3":"8806","68f29d4c":"8865",a0c24a7b:"8889","5bf0e48f":"8917","90e117e3":"8994","9afa113a":"8996","6776993e":"9023",cb054e22:"9032",a94703ab:"9048","54db543f":"9074","7c763686":"9075","9cbfbb7f":"9308",e61948c8:"9341",ca2d12cf:"9343",fb5790ab:"9361","3fddd266":"9414","358e1fce":"9427","4cf171a2":"9442","8ea786c8":"9509","4a51e885":"9514","3324b179":"9528",e0c6aa40:"9529","8a589188":"9579","28513d82":"9612","260d3cdf":"9619","5e95c892":"9647",e8feb497:"9673","619bb71e":"9698","061c4c8e":"9727","481538bf":"9732","76f884e3":"9766","5672ef9d":"9767",a631f374:"9770","0eb3e611":"9912"}[e]||e,r.p+r.u(e)},(()=>{var e={5354:0,1869:0};r.f.j=(a,c)=>{var d=r.o(e,a)?e[a]:void 0;if(0!==d)if(d)c.push(d[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var f=new Promise((c,f)=>d=e[a]=[c,f]);c.push(d[2]=f);var b=r.p+r.u(a),t=new Error;r.l(b,c=>{if(r.o(e,a)&&(0!==(d=e[a])&&(e[a]=void 0),d)){var f=c&&("load"===c.type?"missing":c.type),b=c&&c.target&&c.target.src;t.message="Loading chunk "+a+" failed.\n("+f+": "+b+")",t.name="ChunkLoadError",t.type=f,t.request=b,d[1](t)}},"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,c)=>{var d,f,[b,t,o]=c,n=0;if(b.some(a=>0!==e[a])){for(d in t)r.o(t,d)&&(r.m[d]=t[d]);if(o)var i=o(r)}for(a&&a(c);n<b.length;n++)f=b[n],r.o(e,f)&&e[f]&&e[f][0](),e[f]=0;return r.O(i)},c=globalThis.webpackChunkconstellation_docs=globalThis.webpackChunkconstellation_docs||[];c.forEach(a.bind(null,0)),c.push=a.bind(null,c.push.bind(c))})()})(); \ No newline at end of file diff --git a/pr-preview/pr-4027/assets/terminate-cluster.cast b/pr-preview/pr-4027/assets/terminate-cluster.cast deleted file mode 100644 index 321005093..000000000 --- a/pr-preview/pr-4027/assets/terminate-cluster.cast +++ /dev/null @@ -1,146 +0,0 @@ -{"version": 2, "width": 199, "height": 20, "timestamp": 1703675724, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}} -[0.003821, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[0.004444, "o", "#"] -[0.136229, "o", " "] -[0.186275, "o", "S"] -[0.236401, "o", "t"] -[0.307468, "o", "e"] -[0.357602, "o", "p"] -[0.407687, "o", " "] -[0.52779, "o", "1"] -[0.577939, "o", ":"] -[0.628003, "o", " "] -[0.678102, "o", "D"] -[0.785195, "o", "e"] -[0.835354, "o", "l"] -[0.917439, "o", "e"] -[0.967534, "o", "t"] -[1.017628, "o", "e"] -[1.067752, "o", " "] -[1.142842, "o", "C"] -[1.231966, "o", "o"] -[1.282062, "o", "n"] -[1.406167, "o", "s"] -[1.456274, "o", "t"] -[1.517366, "o", "e"] -[1.623448, "o", "l"] -[1.673552, "o", "l"] -[1.7236, "o", "a"] -[1.773715, "o", "t"] -[1.82384, "o", "i"] -[1.873926, "o", "o"] -[1.924014, "o", "n"] -[1.974102, "o", " "] -[2.024239, "o", "c"] -[2.074327, "o", "l"] -[2.124421, "o", "u"] -[2.174511, "o", "s"] -[2.224644, "o", "t"] -[2.274745, "o", "e"] -[2.410815, "o", "r\r\n\u001b[?2004l\r"] -[2.410919, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[3.411419, "o", "c"] -[3.47645, "o", "o"] -[3.526541, "o", "n"] -[3.592638, "o", "s"] -[3.642736, "o", "t"] -[3.729842, "o", "e"] -[3.779954, "o", "l"] -[3.830038, "o", "l"] -[3.888166, "o", "a"] -[3.938244, "o", "t"] -[4.044389, "o", "i"] -[4.094483, "o", "o"] -[4.144593, "o", "n"] -[4.194592, "o", " "] -[4.295774, "o", "t"] -[4.345884, "o", "e"] -[4.402033, "o", "r"] -[4.520134, "o", "m"] -[4.602195, "o", "i"] -[4.776347, "o", "n"] -[4.826422, "o", "a"] -[4.943547, "o", "t"] -[4.993655, "o", "e\r\n\u001b[?2004l\r"] -[5.022077, "o", "You are about to terminate a Constellation cluster.\r\nAll of its associated resources will be DESTROYED.\r\nThis action is irreversible and ALL DATA WILL BE LOST.\r\nDo you want to continue? [y/n]: "] -[6.022582, "o", "y\r\n"] -[220.660336, "o", "Your Constellation cluster was terminated successfully.\r\n"] -[220.661951, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[220.662116, "o", "#"] -[220.712361, "o", " "] -[220.953524, "o", "D"] -[221.059622, "o", "e"] -[221.117733, "o", "l"] -[221.189896, "o", "e"] -[221.23999, "o", "t"] -[221.290148, "o", "e"] -[221.340253, "o", " "] -[221.423394, "o", "m"] -[221.473505, "o", "a"] -[221.631651, "o", "s"] -[221.681726, "o", "t"] -[221.731891, "o", "e"] -[221.781934, "o", "r"] -[221.832052, "o", "s"] -[221.887179, "o", "e"] -[221.93733, "o", "c"] -[221.987438, "o", "r"] -[222.147636, "o", "e"] -[222.197733, "o", "t"] -[222.247788, "o", " "] -[222.334942, "o", "t"] -[222.385054, "o", "o"] -[222.435166, "o", " "] -[222.485299, "o", "f"] -[222.535455, "o", "i"] -[222.585591, "o", "n"] -[222.635745, "o", "a"] -[222.685791, "o", "l"] -[222.806975, "o", "i"] -[222.857105, "o", "z"] -[222.907205, "o", "e"] -[222.957314, "o", " "] -[223.007463, "o", "d"] -[223.10865, "o", "e"] -[223.158698, "o", "l"] -[223.208848, "o", "e"] -[223.259032, "o", "t"] -[223.312129, "o", "i"] -[223.387271, "o", "o"] -[223.439369, "o", "n\r\n\u001b[?2004l\r"] -[223.43943, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[224.439913, "o", "r"] -[224.50707, "o", "m"] -[224.557155, "o", " "] -[224.610303, "o", "c"] -[224.660429, "o", "o"] -[224.710521, "o", "n"] -[224.779669, "o", "s"] -[224.829762, "o", "t"] -[224.909953, "o", "e"] -[224.960083, "o", "l"] -[225.12122, "o", "l"] -[225.171332, "o", "a"] -[225.221447, "o", "t"] -[225.271551, "o", "i"] -[225.385705, "o", "o"] -[225.435837, "o", "n"] -[225.485957, "o", "-"] -[225.536071, "o", "m"] -[225.586194, "o", "a"] -[225.636264, "o", "s"] -[225.686388, "o", "t"] -[225.748544, "o", "e"] -[225.798641, "o", "r"] -[225.848791, "o", "s"] -[225.898912, "o", "e"] -[225.949039, "o", "c"] -[225.999149, "o", "r"] -[226.049294, "o", "e"] -[226.123411, "o", "t"] -[226.173527, "o", "."] -[226.254679, "o", "j"] -[226.30479, "o", "s"] -[226.388908, "o", "o"] -[226.439112, "o", "n\r\n\u001b[?2004l\r"] -[226.440068, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] diff --git a/pr-preview/pr-4027/assets/verify-cli.cast b/pr-preview/pr-4027/assets/verify-cli.cast deleted file mode 100644 index d8b33e204..000000000 --- a/pr-preview/pr-4027/assets/verify-cli.cast +++ /dev/null @@ -1,813 +0,0 @@ -{"version": 2, "width": 199, "height": 20, "timestamp": 1703674587, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}} -[0.004036, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[0.00454, "o", "#"] -[0.136422, "o", " "] -[0.186496, "o", "S"] -[0.236643, "o", "t"] -[0.307752, "o", "e"] -[0.357809, "o", "p"] -[0.408009, "o", " "] -[0.528038, "o", "1"] -[0.57813, "o", ":"] -[0.628284, "o", " "] -[0.678373, "o", "I"] -[0.785492, "o", "n"] -[0.835591, "o", "s"] -[0.917712, "o", "t"] -[0.967809, "o", "a"] -[1.017919, "o", "l"] -[1.186017, "o", "l"] -[1.236136, "o", " "] -[1.325214, "o", "S"] -[1.375349, "o", "L"] -[1.499453, "o", "S"] -[1.549549, "o", "A"] -[1.599663, "o", " "] -[1.705732, "o", "v"] -[1.755864, "o", "e"] -[1.805969, "o", "r"] -[1.856055, "o", "i"] -[1.906194, "o", "f"] -[1.956289, "o", "i"] -[2.006401, "o", "e"] -[2.107494, "o", "r\r\n\u001b[?2004l\r"] -[2.107605, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[3.108, "o", "c"] -[3.158074, "o", "u"] -[3.208205, "o", "r"] -[3.258285, "o", "l"] -[3.308417, "o", " "] -[3.358507, "o", "-"] -[3.494607, "o", "s"] -[3.55172, "o", "L"] -[3.616839, "o", "O"] -[3.666961, "o", " "] -[3.733047, "o", "h"] -[3.783076, "o", "t"] -[3.870249, "o", "t"] -[3.920355, "o", "p"] -[3.970469, "o", "s"] -[4.020549, "o", ":"] -[4.070675, "o", "/"] -[4.176737, "o", "/"] -[4.226839, "o", "g"] -[4.276971, "o", "i"] -[4.357024, "o", "t"] -[4.458172, "o", "h"] -[4.508288, "o", "u"] -[4.564381, "o", "b"] -[4.614455, "o", "."] -[4.696596, "o", "c"] -[4.870675, "o", "o"] -[4.920807, "o", "m"] -[4.970913, "o", "/"] -[5.020971, "o", "s"] -[5.144117, "o", "l"] -[5.194246, "o", "s"] -[5.43533, "o", "a"] -[5.485447, "o", "-"] -[5.543557, "o", "f"] -[5.615647, "o", "r"] -[5.665764, "o", "a"] -[5.715849, "o", "m"] -[5.765951, "o", "e"] -[5.849046, "o", "w"] -[5.899178, "o", "o"] -[6.05732, "o", "r"] -[6.107387, "o", "k"] -[6.15751, "o", "/"] -[6.207618, "o", "s"] -[6.257724, "o", "l"] -[6.312833, "o", "s"] -[6.362891, "o", "a"] -[6.413029, "o", "-"] -[6.573163, "o", "v"] -[6.623248, "o", "e"] -[6.810385, "o", "r"] -[6.897478, "o", "i"] -[6.947609, "o", "f"] -[6.997679, "o", "i"] -[7.047814, "o", "e"] -[7.097888, "o", "r"] -[7.148021, "o", "/"] -[7.198087, "o", "r"] -[7.248222, "o", "e"] -[7.369284, "o", "l"] -[7.419395, "o", "e"] -[7.469527, "o", "a"] -[7.524686, "o", "s"] -[7.57473, "o", "e"] -[7.675831, "o", "s"] -[7.725926, "o", "/"] -[7.776038, "o", "l"] -[7.826123, "o", "a"] -[7.879235, "o", "t"] -[7.954339, "o", "e"] -[8.006397, "o", "s"] -[8.05655, "o", "t"] -[8.106625, "o", "/"] -[8.156743, "o", "d"] -[8.209861, "o", "o"] -[8.259954, "o", "w"] -[8.310043, "o", "n"] -[8.379166, "o", "l"] -[8.429264, "o", "o"] -[8.509405, "o", "a"] -[8.559447, "o", "d"] -[8.609562, "o", "/"] -[8.659671, "o", "s"] -[8.709764, "o", "l"] -[8.759921, "o", "s"] -[8.874, "o", "a"] -[8.924102, "o", "-"] -[8.99921, "o", "v"] -[9.049314, "o", "e"] -[9.099402, "o", "r"] -[9.14952, "o", "i"] -[9.199612, "o", "f"] -[9.261734, "o", "i"] -[9.311807, "o", "e"] -[9.361942, "o", "r"] -[9.41203, "o", "-"] -[9.462148, "o", "l"] -[9.512254, "o", "i"] -[9.562358, "o", "n"] -[9.636469, "o", "u"] -[9.686562, "o", "x"] -[9.736677, "o", "-"] -[9.786778, "o", "a"] -[9.870888, "o", "m"] -[9.920992, "o", "d"] -[10.006102, "o", "6"] -[10.056228, "o", "4\r\n\u001b[?2004l\r"] -[10.83884, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[10.839099, "o", "s"] -[10.889223, "o", "u"] -[10.979329, "o", "d"] -[11.070438, "o", "o"] -[11.12053, "o", " "] -[11.170659, "o", "i"] -[11.220766, "o", "n"] -[11.32484, "o", "s"] -[11.474003, "o", "t"] -[11.524092, "o", "a"] -[11.574165, "o", "l"] -[11.624263, "o", "l"] -[11.674289, "o", " "] -[11.724447, "o", "s"] -[11.789571, "o", "l"] -[11.839663, "o", "s"] -[11.926776, "o", "a"] -[11.976882, "o", "-"] -[12.031992, "o", "v"] -[12.082066, "o", "e"] -[12.277215, "o", "r"] -[12.449313, "o", "i"] -[12.499416, "o", "f"] -[12.549512, "o", "i"] -[12.632595, "o", "e"] -[12.682632, "o", "r"] -[12.732789, "o", "-"] -[12.782884, "o", "l"] -[12.833024, "o", "i"] -[12.883122, "o", "n"] -[12.933216, "o", "u"] -[12.983311, "o", "x"] -[13.033429, "o", "-"] -[13.083541, "o", "a"] -[13.13365, "o", "m"] -[13.183742, "o", "d"] -[13.23386, "o", "6"] -[13.283962, "o", "4"] -[13.33407, "o", " "] -[13.384178, "o", "/"] -[13.434286, "o", "u"] -[13.512371, "o", "s"] -[13.562449, "o", "r"] -[13.612534, "o", "/"] -[13.662662, "o", "l"] -[13.712779, "o", "o"] -[13.762857, "o", "c"] -[13.922948, "o", "a"] -[13.997092, "o", "l"] -[14.047204, "o", "/"] -[14.097293, "o", "b"] -[14.147407, "o", "i"] -[14.205567, "o", "n"] -[14.255645, "o", "/"] -[14.305748, "o", "s"] -[14.355855, "o", "l"] -[14.405975, "o", "s"] -[14.471063, "o", "a"] -[14.521178, "o", "-"] -[14.673229, "o", "v"] -[14.973393, "o", "e"] -[15.098469, "o", "r"] -[15.148599, "o", "i"] -[15.198681, "o", "f"] -[15.24878, "o", "i"] -[15.298884, "o", "e"] -[15.349042, "o", "r\r\n\u001b[?2004l\r"] -[15.372162, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[16.372653, "o", "#"] -[16.422657, "o", " "] -[16.472805, "o", "S"] -[16.522862, "o", "t"] -[16.573003, "o", "e"] -[16.657011, "o", "p"] -[16.707185, "o", " "] -[16.81232, "o", "2"] -[16.862426, "o", ":"] -[16.925516, "o", " "] -[17.058634, "o", "D"] -[17.1147, "o", "o"] -[17.164812, "o", "w"] -[17.217931, "o", "n"] -[17.268026, "o", "l"] -[17.345167, "o", "o"] -[17.395202, "o", "a"] -[17.445343, "o", "d"] -[17.495448, "o", " "] -[17.545545, "o", "C"] -[17.595635, "o", "o"] -[17.645803, "o", "n"] -[17.69587, "o", "s"] -[17.746007, "o", "t"] -[17.796087, "o", "e"] -[17.864206, "o", "l"] -[17.914215, "o", "l"] -[17.964343, "o", "a"] -[18.014421, "o", "t"] -[18.064553, "o", "i"] -[18.131661, "o", "o"] -[18.181755, "o", "n"] -[18.231876, "o", " "] -[18.302949, "o", "C"] -[18.461091, "o", "L"] -[18.538175, "o", "I"] -[18.588264, "o", " "] -[18.638349, "o", "a"] -[18.692454, "o", "n"] -[18.742563, "o", "d"] -[18.792665, "o", " "] -[18.842766, "o", "p"] -[19.0129, "o", "r"] -[19.062989, "o", "o"] -[19.113108, "o", "v"] -[19.163194, "o", "e"] -[19.213318, "o", "n"] -[19.33145, "o", "a"] -[19.381515, "o", "n"] -[19.437635, "o", "c"] -[19.487692, "o", "e\r\n\u001b[?2004l\r"] -[19.487835, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[20.488206, "o", "c"] -[20.562293, "o", "u"] -[20.612377, "o", "r"] -[20.678526, "o", "l"] -[20.728611, "o", " "] -[20.830744, "o", "-"] -[20.903826, "o", "s"] -[21.012945, "o", "L"] -[21.072046, "o", "O"] -[21.122141, "o", " "] -[21.172243, "o", "h"] -[21.222366, "o", "t"] -[21.293417, "o", "t"] -[21.34358, "o", "p"] -[21.540715, "o", "s"] -[21.590749, "o", ":"] -[21.656855, "o", "/"] -[21.706987, "o", "/"] -[21.92115, "o", "g"] -[21.971204, "o", "i"] -[22.021325, "o", "t"] -[22.071434, "o", "h"] -[22.142549, "o", "u"] -[22.192631, "o", "b"] -[22.242749, "o", "."] -[22.292845, "o", "c"] -[22.407959, "o", "o"] -[22.458051, "o", "m"] -[22.508157, "o", "/"] -[22.55825, "o", "e"] -[22.608382, "o", "d"] -[22.658485, "o", "g"] -[22.708595, "o", "e"] -[22.758753, "o", "l"] -[22.808856, "o", "e"] -[22.858937, "o", "s"] -[22.909048, "o", "s"] -[22.959138, "o", "s"] -[23.009238, "o", "y"] -[23.090365, "o", "s"] -[23.140466, "o", "/"] -[23.224602, "o", "c"] -[23.311677, "o", "o"] -[23.361771, "o", "n"] -[23.543871, "o", "s"] -[23.625969, "o", "t"] -[23.696098, "o", "e"] -[23.746145, "o", "l"] -[23.796313, "o", "l"] -[23.846396, "o", "a"] -[23.896517, "o", "t"] -[23.946604, "o", "i"] -[24.045732, "o", "o"] -[24.095818, "o", "n"] -[24.145929, "o", "/"] -[24.19609, "o", "r"] -[24.246194, "o", "e"] -[24.296292, "o", "l"] -[24.346388, "o", "e"] -[24.396503, "o", "a"] -[24.446571, "o", "s"] -[24.496712, "o", "e"] -[24.546813, "o", "s"] -[24.59694, "o", "/"] -[24.647003, "o", "l"] -[24.703116, "o", "a"] -[24.816297, "o", "t"] -[24.866358, "o", "e"] -[24.93547, "o", "s"] -[24.985531, "o", "t"] -[25.035649, "o", "/"] -[25.085721, "o", "d"] -[25.199862, "o", "o"] -[25.256966, "o", "w"] -[25.307067, "o", "n"] -[25.358187, "o", "l"] -[25.408287, "o", "o"] -[25.536394, "o", "a"] -[25.646532, "o", "d"] -[25.69662, "o", "/"] -[25.746734, "o", "c"] -[25.796816, "o", "o"] -[25.846951, "o", "n"] -[25.897059, "o", "s"] -[26.068166, "o", "t"] -[26.14026, "o", "e"] -[26.190353, "o", "l"] -[26.240519, "o", "l"] -[26.356613, "o", "a"] -[26.472726, "o", "t"] -[26.522826, "o", "i"] -[26.573028, "o", "o"] -[26.623055, "o", "n"] -[26.673156, "o", "-"] -[26.741276, "o", "l"] -[26.791381, "o", "i"] -[26.841508, "o", "n"] -[26.892594, "o", "u"] -[26.942668, "o", "x"] -[26.992815, "o", "-"] -[27.05791, "o", "a"] -[27.108074, "o", "m"] -[27.158082, "o", "d"] -[27.208208, "o", "6"] -[27.258355, "o", "4\r\n\u001b[?2004l\r"] -[27.947176, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[27.947448, "o", "c"] -[28.030593, "o", "u"] -[28.081746, "o", "r"] -[28.131861, "o", "l"] -[28.18195, "o", " "] -[28.255058, "o", "-"] -[28.318205, "o", "s"] -[28.36827, "o", "L"] -[28.418377, "o", "O"] -[28.468478, "o", " "] -[28.518512, "o", "h"] -[28.610681, "o", "t"] -[28.660794, "o", "t"] -[28.717914, "o", "p"] -[28.786017, "o", "s"] -[28.836116, "o", ":"] -[28.886224, "o", "/"] -[28.936285, "o", "/"] -[28.986504, "o", "g"] -[29.041612, "o", "i"] -[29.144711, "o", "t"] -[29.194811, "o", "h"] -[29.317912, "o", "u"] -[29.367988, "o", "b"] -[29.418088, "o", "."] -[29.539231, "o", "c"] -[29.616322, "o", "o"] -[29.666503, "o", "m"] -[29.716544, "o", "/"] -[29.766695, "o", "e"] -[29.816774, "o", "d"] -[29.866885, "o", "g"] -[29.940003, "o", "e"] -[29.994097, "o", "l"] -[30.062214, "o", "e"] -[30.112293, "o", "s"] -[30.162413, "o", "s"] -[30.212508, "o", "s"] -[30.315663, "o", "y"] -[30.365806, "o", "s"] -[30.415869, "o", "/"] -[30.465976, "o", "c"] -[30.516083, "o", "o"] -[30.566192, "o", "n"] -[30.700334, "o", "s"] -[30.75044, "o", "t"] -[30.800555, "o", "e"] -[30.882637, "o", "l"] -[31.10477, "o", "l"] -[31.156845, "o", "a"] -[31.206932, "o", "t"] -[31.25708, "o", "i"] -[31.342178, "o", "o"] -[31.392285, "o", "n"] -[31.442392, "o", "/"] -[31.492516, "o", "r"] -[31.542606, "o", "e"] -[31.592708, "o", "l"] -[31.720857, "o", "e"] -[31.770946, "o", "a"] -[31.825086, "o", "s"] -[31.965188, "o", "e"] -[32.017269, "o", "s"] -[32.067394, "o", "/"] -[32.117485, "o", "l"] -[32.167612, "o", "a"] -[32.222706, "o", "t"] -[32.303792, "o", "e"] -[32.35392, "o", "s"] -[32.404015, "o", "t"] -[32.454093, "o", "/"] -[32.504231, "o", "d"] -[32.58228, "o", "o"] -[32.632375, "o", "w"] -[32.682523, "o", "n"] -[32.746566, "o", "l"] -[32.796728, "o", "o"] -[32.849803, "o", "a"] -[32.89992, "o", "d"] -[32.949989, "o", "/"] -[33.000137, "o", "c"] -[33.076209, "o", "o"] -[33.133332, "o", "n"] -[33.24744, "o", "s"] -[33.400592, "o", "t"] -[33.450639, "o", "e"] -[33.500747, "o", "l"] -[33.550865, "o", "l"] -[33.645976, "o", "a"] -[33.753073, "o", "t"] -[33.803192, "o", "i"] -[33.853225, "o", "o"] -[33.939357, "o", "n"] -[33.989478, "o", "."] -[34.039587, "o", "i"] -[34.089697, "o", "n"] -[34.139777, "o", "t"] -[34.18988, "o", "o"] -[34.240003, "o", "t"] -[34.290032, "o", "o"] -[34.340137, "o", "."] -[34.390195, "o", "j"] -[34.440284, "o", "s"] -[34.490345, "o", "o"] -[34.558508, "o", "n"] -[34.608603, "o", "l\r\n\u001b[?2004l\r"] -[35.478619, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[36.479061, "o", "#"] -[36.529102, "o", " "] -[36.714251, "o", "S"] -[36.764324, "o", "t"] -[36.814432, "o", "e"] -[36.864554, "o", "p"] -[36.914634, "o", " "] -[36.989759, "o", "3"] -[37.039864, "o", ":"] -[37.089953, "o", " "] -[37.218025, "o", "V"] -[37.339179, "o", "e"] -[37.389254, "o", "r"] -[37.463359, "o", "i"] -[37.541502, "o", "f"] -[37.627597, "o", "y"] -[37.677701, "o", " "] -[37.727803, "o", "p"] -[37.777913, "o", "r"] -[37.828015, "o", "o"] -[37.911124, "o", "v"] -[37.961185, "o", "e"] -[38.011306, "o", "n"] -[38.093415, "o", "a"] -[38.150469, "o", "n"] -[38.213603, "o", "c"] -[38.263694, "o", "e\r\n\u001b[?2004l\r"] -[38.263829, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[39.264242, "o", "s"] -[39.334319, "o", "l"] -[39.384431, "o", "s"] -[39.434553, "o", "a"] -[39.484656, "o", "-"] -[39.540765, "o", "v"] -[39.590857, "o", "e"] -[39.640976, "o", "r"] -[39.691089, "o", "i"] -[39.84824, "o", "f"] -[40.019372, "o", "i"] -[40.069438, "o", "e"] -[40.125559, "o", "r"] -[40.175627, "o", " "] -[40.225789, "o", "v"] -[40.275891, "o", "e"] -[40.325998, "o", "r"] -[40.403112, "o", "i"] -[40.453193, "o", "f"] -[40.519301, "o", "y"] -[40.569404, "o", "-"] -[40.61951, "o", "a"] -[40.669603, "o", "r"] -[40.802716, "o", "t"] -[40.852817, "o", "i"] -[40.902919, "o", "f"] -[40.953025, "o", "a"] -[41.084147, "o", "c"] -[41.19826, "o", "t"] -[41.248342, "o", " "] -[41.333462, "o", "c"] -[41.400624, "o", "o"] -[41.45069, "o", "n"] -[41.500797, "o", "s"] -[41.614917, "o", "t"] -[41.665004, "o", "e"] -[41.778123, "o", "l"] -[41.858263, "o", "l"] -[41.908347, "o", "a"] -[41.958453, "o", "t"] -[42.028563, "o", "i"] -[42.078755, "o", "o"] -[42.12884, "o", "n"] -[42.178933, "o", "-"] -[42.229029, "o", "l"] -[42.279094, "o", "i"] -[42.329226, "o", "n"] -[42.379332, "o", "u"] -[42.429438, "o", "x"] -[42.479537, "o", "-"] -[42.529646, "o", "a"] -[42.590747, "o", "m"] -[42.669864, "o", "d"] -[42.719955, "o", "6"] -[42.770061, "o", "4"] -[42.820156, "o", " "] -[42.870327, "o", "-"] -[42.92045, "o", "-"] -[42.970528, "o", "p"] -[43.020648, "o", "r"] -[43.095734, "o", "o"] -[43.145848, "o", "v"] -[43.247957, "o", "e"] -[43.313099, "o", "n"] -[43.363188, "o", "a"] -[43.413265, "o", "n"] -[43.58544, "o", "c"] -[43.635504, "o", "e"] -[43.685607, "o", "-"] -[43.735736, "o", "p"] -[43.785821, "o", "a"] -[43.886963, "o", "t"] -[43.937046, "o", "h"] -[43.987146, "o", " "] -[44.037226, "o", "c"] -[44.121355, "o", "o"] -[44.17145, "o", "n"] -[44.221593, "o", "s"] -[44.271637, "o", "t"] -[44.321766, "o", "e"] -[44.376868, "o", "l"] -[44.426962, "o", "l"] -[44.560102, "o", "a"] -[44.610144, "o", "t"] -[44.660275, "o", "i"] -[44.71037, "o", "o"] -[44.760473, "o", "n"] -[44.810585, "o", "."] -[44.860706, "o", "i"] -[44.910767, "o", "n"] -[44.9609, "o", "t"] -[45.011013, "o", "o"] -[45.061109, "o", "t"] -[45.11519, "o", "o"] -[45.165304, "o", "."] -[45.296454, "o", "j"] -[45.346521, "o", "s"] -[45.407649, "o", "o"] -[45.457735, "o", "n"] -[45.507902, "o", "l"] -[45.557962, "o", " "] -[45.608053, "o", "-"] -[45.658162, "o", "-"] -[45.708273, "o", "s"] -[45.822397, "o", "o"] -[45.872465, "o", "u"] -[45.922582, "o", "r"] -[45.97269, "o", "c"] -[46.022794, "o", "e"] -[46.072893, "o", "-"] -[46.123013, "o", "u"] -[46.225142, "o", "r"] -[46.27524, "o", "i"] -[46.325343, "o", " "] -[46.375406, "o", "g"] -[46.44856, "o", "i"] -[46.498639, "o", "t"] -[46.548766, "o", "h"] -[46.598869, "o", "u"] -[46.648984, "o", "b"] -[46.699126, "o", "."] -[46.749173, "o", "c"] -[46.799292, "o", "o"] -[46.889399, "o", "m"] -[46.939484, "o", "/"] -[47.021624, "o", "e"] -[47.07172, "o", "d"] -[47.171837, "o", "g"] -[47.221925, "o", "e"] -[47.272033, "o", "l"] -[47.322127, "o", "e"] -[47.419249, "o", "s"] -[47.469339, "o", "s"] -[47.519452, "o", "s"] -[47.569547, "o", "y"] -[47.619666, "o", "s"] -[47.669786, "o", "/"] -[47.772993, "o", "c"] -[47.823, "o", "o"] -[47.873098, "o", "n"] -[47.954195, "o", "s"] -[48.0043, "o", "t"] -[48.05443, "o", "e"] -[48.104505, "o", "l"] -[48.154623, "o", "l"] -[48.258749, "o", "a"] -[48.31683, "o", "t"] -[48.366944, "o", "i"] -[48.483045, "o", "o"] -[48.533144, "o", "n\r\n\u001b[?2004l\r"] -[49.335338, "o", "Verified signature against tlog entry index 57885093 at URL: https://rekor.sigstore.dev/api/v1/log/entries/24296fb24b8ad77a78f50198d0b0a4554049eec73d59a7e5e1f895c4ad5b3d202c62132aea18c4c1\r\n"] -[49.349461, "o", "Verified build using builder \"https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v1.9.0\" at commit 1d05f438ffa564d2e4ac3b071dbaf322e6d954ab\r\nVerifying artifact constellation-linux-amd64: PASSED\r\n\r\nPASSED: Verified SLSA provenance\r\n"] -[49.350696, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[49.350872, "o", "#"] -[49.401022, "o", " "] -[49.451237, "o", "S"] -[49.501261, "o", "t"] -[49.591428, "o", "e"] -[49.641525, "o", "p"] -[49.691629, "o", " "] -[49.741693, "o", "4"] -[49.79182, "o", ":"] -[49.886917, "o", " "] -[49.937036, "o", "I"] -[50.025111, "o", "n"] -[50.08623, "o", "s"] -[50.182343, "o", "t"] -[50.343467, "o", "a"] -[50.393546, "o", "l"] -[50.51966, "o", "l"] -[50.569734, "o", " "] -[50.619894, "o", "t"] -[50.670013, "o", "h"] -[50.720095, "o", "e"] -[50.7702, "o", " "] -[50.820323, "o", "C"] -[50.870433, "o", "L"] -[50.995579, "o", "I\r\n\u001b[?2004l\r"] -[50.995627, "o", "\u001b[?2004h"] -[50.995743, "o", "\u001b[38;2;139;4;221m$\u001b[0m "] -[51.996149, "o", "s"] -[52.050207, "o", "u"] -[52.100327, "o", "d"] -[52.150387, "o", "o"] -[52.200522, "o", " "] -[52.250618, "o", "i"] -[52.300732, "o", "n"] -[52.380832, "o", "s"] -[52.430902, "o", "t"] -[52.481038, "o", "a"] -[52.531129, "o", "l"] -[52.581232, "o", "l"] -[52.631309, "o", " "] -[52.705492, "o", "c"] -[52.755569, "o", "o"] -[52.843666, "o", "n"] -[52.893795, "o", "s"] -[52.995901, "o", "t"] -[53.046011, "o", "e"] -[53.142094, "o", "l"] -[53.23122, "o", "l"] -[53.330348, "o", "a"] -[53.404454, "o", "t"] -[53.467566, "o", "i"] -[53.517633, "o", "o"] -[53.567768, "o", "n"] -[53.617875, "o", "-"] -[53.667986, "o", "l"] -[53.784085, "o", "i"] -[53.834192, "o", "n"] -[54.033356, "o", "u"] -[54.08346, "o", "x"] -[54.133557, "o", "-"] -[54.183666, "o", "a"] -[54.233756, "o", "m"] -[54.283884, "o", "d"] -[54.379993, "o", "6"] -[54.430107, "o", "4"] -[54.480217, "o", " "] -[54.53029, "o", "/"] -[54.580429, "o", "u"] -[54.630513, "o", "s"] -[54.680659, "o", "r"] -[54.730762, "o", "/"] -[54.780844, "o", "l"] -[54.836972, "o", "o"] -[54.924054, "o", "c"] -[54.974166, "o", "a"] -[55.024298, "o", "l"] -[55.074406, "o", "/"] -[55.18749, "o", "b"] -[55.315578, "o", "i"] -[55.615744, "o", "n"] -[55.665855, "o", "/"] -[55.716954, "o", "c"] -[55.767026, "o", "o"] -[56.050153, "o", "n"] -[56.100236, "o", "s"] -[56.21236, "o", "t"] -[56.267461, "o", "e"] -[56.317549, "o", "l"] -[56.368677, "o", "l"] -[56.434788, "o", "a"] -[56.484867, "o", "t"] -[56.535006, "o", "i"] -[56.625075, "o", "o"] -[56.753129, "o", "n\r\n\u001b[?2004l\r"] -[56.786535, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[57.786967, "o", "#"] -[57.837066, "o", " "] -[57.887144, "o", "D"] -[57.986273, "o", "o"] -[58.036354, "o", "n"] -[58.086476, "o", "e"] -[58.136575, "o", "!"] -[58.224681, "o", " "] -[58.274788, "o", "Y"] -[58.337896, "o", "o"] -[58.390972, "o", "u"] -[58.441103, "o", " "] -[58.491206, "o", "c"] -[58.541277, "o", "a"] -[58.591411, "o", "n"] -[58.641516, "o", " "] -[58.691628, "o", "n"] -[58.751733, "o", "o"] -[58.801851, "o", "w"] -[58.851969, "o", " "] -[58.911044, "o", "u"] -[58.961123, "o", "s"] -[59.011257, "o", "e"] -[59.061363, "o", " "] -[59.12652, "o", "t"] -[59.185589, "o", "h"] -[59.286705, "o", "e"] -[59.336784, "o", " "] -[59.386882, "o", "v"] -[59.446964, "o", "e"] -[59.497085, "o", "r"] -[59.596274, "o", "i"] -[59.646336, "o", "f"] -[59.737469, "o", "i"] -[59.787561, "o", "e"] -[59.981692, "o", "d"] -[60.031767, "o", " "] -[60.10389, "o", "C"] -[60.186941, "o", "L"] -[60.306082, "o", "I\r\n\u001b[?2004l\r"] -[60.306124, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] -[61.306557, "o", "c"] -[61.356611, "o", "o"] -[61.406688, "o", "n"] -[61.456814, "o", "s"] -[61.535927, "o", "t"] -[61.60803, "o", "e"] -[61.658174, "o", "l"] -[61.708252, "o", "l"] -[61.758334, "o", "a"] -[61.808441, "o", "t"] -[61.858536, "o", "i"] -[61.91863, "o", "o"] -[61.975698, "o", "n"] -[62.025846, "o", " "] -[62.115954, "o", "-"] -[62.16603, "o", "h\r\n\u001b[?2004l\r"] -[62.195248, "o", "Manage your Constellation cluster.\r\n\r\n"] -[62.195729, "o", "Usage:\r\n constellation [command]\r\n\r\nAvailable Commands:\r\n config Work with the Constellation configuration file\r\n apply Apply a configuration to a Constellation cluster\r\n mini Manage MiniConstellation clusters\r\n status Show status of a Constellation cluster\r\n verify Verify the confidential properties of a Constellation cluster\r\n upgrade Find and apply upgrades to your Constellation cluster\r\n recover Recover a completely stopped Constellation cluster\r\n terminate Terminate a Constellation cluster\r\n iam Work with the IAM configuration on your cloud provider\r\n version Display version of this CLI\r\n help Help about any command\r\n completion Generate the autocompletion script for the specified shell\r\n\r\nFlags:\r\n --debug enable debug logging\r\n --force disable version compatibility checks - might result in corrupted clusters\r\n -h, --help help for constellation\r\n --tf-log string Terraform lo"] -[62.195843, "o", "g level (default \"NONE\")\r\n -C, --workspace string path to the Constellation workspace\r\n\r\nUse \"constellation [command] --help\" for more information about a command.\r\n"] -[62.197435, "o", "\u001b[?2004h\u001b[38;2;139;4;221m$\u001b[0m "] diff --git a/pr-preview/pr-4027/category/architecture/index.html b/pr-preview/pr-4027/category/architecture/index.html deleted file mode 100644 index 1fdbffa42..000000000 --- a/pr-preview/pr-4027/category/architecture/index.html +++ /dev/null @@ -1,16 +0,0 @@ -<!doctype html> -<html lang="en" dir="ltr" class="docs-wrapper plugin-docs plugin-id-default docs-version-2.24 docs-doc-page" data-has-hydrated="false"> -<head> -<meta charset="UTF-8"> -<meta name="generator" content="Docusaurus v3.9.2"> -<title data-rh="true">Architecture | Constellation - - - - - - - -

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/category/basics/index.html b/pr-preview/pr-4027/category/basics/index.html deleted file mode 100644 index 84f835966..000000000 --- a/pr-preview/pr-4027/category/basics/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Basics | Constellation - - - - - - - -
    Version: 2.24

    Basics

    📄️ Security benefits

    Constellation implements the Confidential Kubernetes concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be verified.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/category/getting-started/index.html b/pr-preview/pr-4027/category/getting-started/index.html deleted file mode 100644 index cf51cb9ad..000000000 --- a/pr-preview/pr-4027/category/getting-started/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Getting started | Constellation - - - - - - - - - - \ No newline at end of file diff --git a/pr-preview/pr-4027/category/reference/index.html b/pr-preview/pr-4027/category/reference/index.html deleted file mode 100644 index d835655f8..000000000 --- a/pr-preview/pr-4027/category/reference/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Reference | Constellation - - - - - - - - - - \ No newline at end of file diff --git a/pr-preview/pr-4027/category/workflows/index.html b/pr-preview/pr-4027/category/workflows/index.html deleted file mode 100644 index cf3f77c57..000000000 --- a/pr-preview/pr-4027/category/workflows/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Workflows | Constellation - - - - - - - -
    Version: 2.24

    Workflows

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/getting-started/examples/emojivoto/index.html b/pr-preview/pr-4027/getting-started/examples/emojivoto/index.html deleted file mode 100644 index dd9e8a53d..000000000 --- a/pr-preview/pr-4027/getting-started/examples/emojivoto/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - -Emojivoto | Constellation - - - - - - - -
    Version: 2.24

    Emojivoto

    -

    Emojivoto is a simple and fun application that's well suited to test the basic functionality of your cluster.

    -emojivoto - Web UI -
      -
    1. Deploy the application: -
      kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment
      -
    2. -
    3. Wait until it becomes available: -
      kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments
      -
    4. -
    5. Forward the web service to your machine: -
      kubectl -n emojivoto port-forward svc/web-svc 8080:80
      -
    6. -
    7. Visit http://localhost:8080
    8. -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/getting-started/examples/filestash-s3proxy/index.html b/pr-preview/pr-4027/getting-started/examples/filestash-s3proxy/index.html deleted file mode 100644 index 44e1c3658..000000000 --- a/pr-preview/pr-4027/getting-started/examples/filestash-s3proxy/index.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - -Deploying Filestash | Constellation - - - - - - - -
    Version: 2.24

    Deploying Filestash

    -

    Filestash is a web frontend for different storage backends, including S3. -It's a useful application to showcase s3proxy in action.

    -
      -
    1. Deploy s3proxy as described in Deployment.
    2. -
    3. Create a deployment file for Filestash with one pod:
    4. -
    -
    cat << EOF > "deployment-filestash.yaml"
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: filestash
    spec:
    replicas: 1
    selector:
    matchLabels:
    app: filestash
    template:
    metadata:
    labels:
    app: filestash
    spec:
    hostAliases:
    - ip: $(kubectl get svc s3proxy-service -o=jsonpath='{.spec.clusterIP}')
    hostnames:
    - "s3.us-east-1.amazonaws.com"
    - "s3.us-east-2.amazonaws.com"
    - "s3.us-west-1.amazonaws.com"
    - "s3.us-west-2.amazonaws.com"
    - "s3.eu-north-1.amazonaws.com"
    - "s3.eu-south-1.amazonaws.com"
    - "s3.eu-south-2.amazonaws.com"
    - "s3.eu-west-1.amazonaws.com"
    - "s3.eu-west-2.amazonaws.com"
    - "s3.eu-west-3.amazonaws.com"
    - "s3.eu-central-1.amazonaws.com"
    - "s3.eu-central-2.amazonaws.com"
    - "s3.ap-northeast-1.amazonaws.com"
    - "s3.ap-northeast-2.amazonaws.com"
    - "s3.ap-northeast-3.amazonaws.com"
    - "s3.ap-east-1.amazonaws.com"
    - "s3.ap-southeast-1.amazonaws.com"
    - "s3.ap-southeast-2.amazonaws.com"
    - "s3.ap-southeast-3.amazonaws.com"
    - "s3.ap-southeast-4.amazonaws.com"
    - "s3.ap-south-1.amazonaws.com"
    - "s3.ap-south-2.amazonaws.com"
    - "s3.me-south-1.amazonaws.com"
    - "s3.me-central-1.amazonaws.com"
    - "s3.il-central-1.amazonaws.com"
    - "s3.af-south-1.amazonaws.com"
    - "s3.ca-central-1.amazonaws.com"
    - "s3.sa-east-1.amazonaws.com"
    containers:
    - name: filestash
    image: machines/filestash:latest
    ports:
    - containerPort: 8334
    volumeMounts:
    - name: ca-cert
    mountPath: /etc/ssl/certs/kube-ca.crt
    subPath: kube-ca.crt
    volumes:
    - name: ca-cert
    secret:
    secretName: s3proxy-tls
    items:
    - key: ca.crt
    path: kube-ca.crt
    EOF
    -

    The pod spec includes the hostAliases key, which adds an entry to the pod's /etc/hosts. -The entry forwards all requests for any of the currently defined AWS regions to the Kubernetes service s3proxy-service. -If you followed the s3proxy Deployment guide, this service points to a s3proxy pod.

    -

    The deployment specifies all regions explicitly to prevent accidental data leaks. -If one of your buckets were located in a region that's not part of the hostAliases key, traffic towards those buckets would not be redirected to s3proxy. -Similarly, if you want to exclude data for specific regions from going through s3proxy you can remove those regions from the deployment.

    -

    The spec also includes a volume mount for the TLS certificate and adds it to the pod's certificate trust store. -The volume is called ca-cert. -The key ca.crt of that volume is mounted to /etc/ssl/certs/kube-ca.crt, which is the default certificate trust store location for that container's OpenSSL library. -Not adding the CA certificate will result in TLS authentication errors.

    -
      -
    1. Apply the file: kubectl apply -f deployment-filestash.yaml
    2. -
    -

    Afterward, you can use a port forward to access the Filestash pod: -kubectl port-forward pod/$(kubectl get pod --selector='app=filestash' -o=jsonpath='{.items[*].metadata.name}') 8334:8334

    -
      -
    1. -

      After browsing to localhost:8443, Filestash will ask you to set an administrator password. -After setting it, you can directly leave the admin area by clicking the blue cloud symbol in the top left corner. -Subsequently, you can select S3 as storage backend and enter your credentials. -This will bring you to an overview of your buckets. -If you want to deploy Filestash in production, take a look at its documentation.

      -
    2. -
    3. -

      To see the logs of s3proxy intercepting requests made to S3, run: kubectl logs -f pod/$(kubectl get pod --selector='app=s3proxy' -o=jsonpath='{.items[*].metadata.name}') -Look out for log messages labeled intercepting. -There is one such log message for each message that's encrypted, decrypted, or blocked.

      -
    4. -
    5. -

      Once you have uploaded a file with Filestash, you should be able to view the file in Filestash. -However, if you go to the AWS S3 Web UI and download the file you just uploaded in Filestash, you won't be able to read it. -Another way to spot encrypted files without downloading them is to click on a file, scroll to the Metadata section, and look for the header named x-amz-meta-constellation-encryption. -This header holds the encrypted data encryption key of the object and is only present on objects that are encrypted by s3proxy.

      -
    6. -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/getting-started/examples/horizontal-scaling/index.html b/pr-preview/pr-4027/getting-started/examples/horizontal-scaling/index.html deleted file mode 100644 index b2affee28..000000000 --- a/pr-preview/pr-4027/getting-started/examples/horizontal-scaling/index.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - -Horizontal Pod Autoscaling | Constellation - - - - - - - -
    Version: 2.24

    Horizontal Pod Autoscaling

    -

    This example demonstrates Constellation's autoscaling capabilities. It's based on the Kubernetes HorizontalPodAutoscaler Walkthrough. During the following steps, Constellation will spawn new VMs on demand, verify them, add them to the cluster, and delete them again when the load has settled down.

    -

    Requirements

    -

    The cluster needs to be initialized with Kubernetes 1.23 or later. In addition, autoscaling must be enabled to enable Constellation to assign new nodes dynamically.

    -

    Just for this example specifically, the cluster should have as few worker nodes in the beginning as possible. Start with a small cluster with only one low-powered node for the control-plane node and one low-powered worker node.

    -
    info

    We tested the example using instances of types Standard_DC4as_v5 on Azure and n2d-standard-4 on GCP.

    -

    Setup

    -
      -
    1. -

      Install the Kubernetes Metrics Server:

      -
      kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
      -
    2. -
    3. -

      Deploy the HPA example server that's supposed to be scaled under load.

      -

      This manifest is similar to the one from the Kubernetes HPA walkthrough, but with increased CPU limits and requests to facilitate the triggering of node scaling events.

      -
      cat <<EOF | kubectl apply -f -
      apiVersion: apps/v1
      kind: Deployment
      metadata:
      name: php-apache
      spec:
      selector:
      matchLabels:
      run: php-apache
      replicas: 1
      template:
      metadata:
      labels:
      run: php-apache
      spec:
      containers:
      - name: php-apache
      image: registry.k8s.io/hpa-example
      ports:
      - containerPort: 80
      resources:
      limits:
      cpu: 900m
      requests:
      cpu: 600m
      ---
      apiVersion: v1
      kind: Service
      metadata:
      name: php-apache
      labels:
      run: php-apache
      spec:
      ports:
      - port: 80
      selector:
      run: php-apache
      EOF
      -
    4. -
    5. -

      Create a HorizontalPodAutoscaler.

      -

      Set an average CPU usage across all Pods of 20% to see one additional worker node being created later. Note that the CPU usage isn't related to the host CPU usage, but rather to the requested CPU capacities (20% of 600 milli-cores CPU across all Pods). See the original tutorial for more information on the HPA configuration.

      -
      kubectl autoscale deployment php-apache --cpu-percent=20 --min=1 --max=10
      -
    6. -
    7. -

      Create a Pod that generates load on the server:

      -
      kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while true; do wget -q -O- http://php-apache; done"
      -
    8. -
    9. -

      Wait a few minutes until new nodes are added to the cluster. You can monitor the state of the HorizontalPodAutoscaler, the list of nodes, and the behavior of the autoscaler.

      -
    10. -
    11. -

      To stop the load generator, press CTRL+C and run:

      -
      kubectl delete pod load-generator
      -
    12. -
    13. -

      The cluster-autoscaler checks every few minutes if nodes are underutilized. It will taint such candidates for removal and wait additional 10 minutes before the nodes are eventually removed and deallocated. The whole process can take about 20 minutes.

      -
    14. -
    -

    Monitoring

    -
    tip

    For better observability, run the listed commands in different tabs in your terminal.

    -

    You can watch the status of the HorizontalPodAutoscaler with the current CPU usage, the target CPU limit, and the number of replicas created with:

    -
    kubectl get hpa php-apache --watch
    -

    From time to time compare the list of nodes to check the behavior of the autoscaler:

    -
    kubectl get nodes
    -

    For deeper insights, see the logs of the autoscaler Pod, which contains more details about the scaling decision process:

    -
    kubectl logs -f deployment/constellation-cluster-autoscaler -n kube-system
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/getting-started/examples/index.html b/pr-preview/pr-4027/getting-started/examples/index.html deleted file mode 100644 index 10f3322f8..000000000 --- a/pr-preview/pr-4027/getting-started/examples/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - -Examples | Constellation - - - - - - - -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/getting-started/examples/online-boutique/index.html b/pr-preview/pr-4027/getting-started/examples/online-boutique/index.html deleted file mode 100644 index 6e59a99b1..000000000 --- a/pr-preview/pr-4027/getting-started/examples/online-boutique/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -Online Boutique | Constellation - - - - - - - -
    Version: 2.24

    Online Boutique

    -

    Online Boutique is an e-commerce demo application by Google consisting of 11 separate microservices. In this demo, Constellation automatically sets up a load balancer on your CSP, making it easy to expose services from your confidential cluster.

    -Online Boutique - Web UI -
      -
    1. Create a namespace: -
      kubectl create ns boutique
      -
    2. -
    3. Deploy the application: -
      kubectl apply -n boutique -f https://github.com/GoogleCloudPlatform/microservices-demo/raw/main/release/kubernetes-manifests.yaml
      -
    4. -
    5. Wait for all services to become available: -
      kubectl wait --for=condition=available --timeout=300s -n boutique --all deployments
      -
    6. -
    7. Get the frontend's external IP address: -
      $ kubectl get service frontend-external -n boutique | awk '{print $4}'
      EXTERNAL-IP
      <your-ip>
      -(<your-ip> is a placeholder for the IP assigned by your CSP.)
    8. -
    9. Enter the IP from the result in your browser to browse the online shop.
    10. -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/getting-started/first-steps-local/index.html b/pr-preview/pr-4027/getting-started/first-steps-local/index.html deleted file mode 100644 index 877f03aee..000000000 --- a/pr-preview/pr-4027/getting-started/first-steps-local/index.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - - -First steps with a local cluster | Constellation - - - - - - - -
    Version: 2.24

    First steps with a local cluster

    -

    A local cluster lets you deploy and test Constellation without a cloud subscription. -You have two options:

    -
      -
    • Use MiniConstellation to automatically deploy a two-node cluster.
    • -
    • For more fine-grained control, create the cluster using the QEMU provider.
    • -
    -

    Both options use virtualization to create a local cluster with control-plane nodes and worker nodes. They don't require hardware with Confidential VM (CVM) support. For attestation, they currently use a software-based vTPM provided by KVM/QEMU.

    -

    You need an x64 machine with a Linux OS. -You can use a VM, but it needs nested virtualization.

    -

    Prerequisites

    -
      -
    • Machine requirements: -
        -
      • An x86-64 CPU with at least 4 cores (6 cores are recommended)
      • -
      • At least 4 GB RAM (6 GB are recommended)
      • -
      • 20 GB of free disk space
      • -
      • Hardware virtualization enabled in the BIOS/UEFI (often referred to as Intel VT-x or AMD-V/SVM) / nested-virtualization support when using a VM
      • -
      -
    • -
    • Software requirements: - -
    • -
    -

    Software installation on Ubuntu

    -
    # install Docker
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    sudo apt update
    sudo apt install docker-ce
    # install other dependencies
    sudo apt install xsltproc
    sudo snap install kubectl --classic
    # install Constellation CLI
    curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-amd64
    sudo install constellation-linux-amd64 /usr/local/bin/constellation
    # do not drop forwarded packages
    sudo iptables -P FORWARD ACCEPT
    -

    Create a cluster

    -

    With the constellation mini command, you can deploy and test Constellation locally. This mode is called MiniConstellation. Conceptually, MiniConstellation is similar to MicroK8s, K3s, and minikube.

    caution

    MiniConstellation has specific soft- and hardware requirements such as a Linux OS running on an x86-64 CPU. Pay attention to all prerequisites when setting up.

    note

    Since MiniConstellation runs on your local system, cloud features such as load balancing, -attaching persistent storage, or autoscaling aren't available.

    The following creates your MiniConstellation cluster (may take up to 10 minutes to complete):

    constellation mini up

    This will configure your current directory as the workspace for this cluster. -All constellation commands concerning this cluster need to be issued from this directory.

    -

    Connect to the cluster

    -

    Your cluster initially consists of a single control-plane node:

    -
    $ kubectl get nodes
    NAME STATUS ROLES AGE VERSION
    control-plane-0 Ready control-plane 66s v1.24.6
    -

    Additional nodes will request to join the cluster shortly. Before each additional node is allowed to join the cluster, its state is verified using remote attestation by the JoinService. -If verification passes successfully, the new node receives keys and certificates to join the cluster.

    -

    You can follow this process by viewing the logs of the JoinService:

    -
    $ kubectl logs -n kube-system daemonsets/join-service -f
    {"level":"INFO","ts":"2022-10-14T09:32:20Z","caller":"cmd/main.go:48","msg":"Constellation Node Join Service","version":"2.1.0","cloudProvider":"qemu"}
    {"level":"INFO","ts":"2022-10-14T09:32:20Z","logger":"validator","caller":"watcher/validator.go:96","msg":"Updating expected measurements"}
    ...
    -

    Once all nodes have joined your cluster, it may take a couple of minutes for all resources to become available. -You can check on the state of your cluster by running the following:

    -
    $ kubectl get nodes
    NAME STATUS ROLES AGE VERSION
    control-plane-0 Ready control-plane 2m59s v1.24.6
    worker-0 Ready <none> 32s v1.24.6
    -

    Deploy a sample application

    -
      -
    1. Deploy the emojivoto app
    2. -
    -
    kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment
    -
      -
    1. Expose the frontend service locally
    2. -
    -
    kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments
    kubectl -n emojivoto port-forward svc/web-svc 8080:80 &
    curl http://localhost:8080
    kill %1
    -

    Terminate your cluster

    -

    Once you are done, you can clean up the created resources using the following command:

    constellation mini down

    This will destroy your cluster and clean up your workspace. -The VM image and cluster configuration file (constellation-conf.yaml) will be kept and may be reused to create new clusters.

    -

    Troubleshooting

    -

    Make sure to use the latest release and check out the known issues.

    -

    VMs have no internet access / CLI remains in "Initializing cluster" state

    -

    iptables rules may prevent your VMs from accessing the internet. -Make sure your rules aren't dropping forwarded packages.

    -

    List your rules:

    -
    sudo iptables -S
    -

    The output may look similar to the following:

    -
    -P INPUT ACCEPT
    -P FORWARD DROP
    -P OUTPUT ACCEPT
    -N DOCKER
    -N DOCKER-ISOLATION-STAGE-1
    -N DOCKER-ISOLATION-STAGE-2
    -N DOCKER-USER
    -

    If your FORWARD chain is set to DROP, you need to update your rules:

    -
    sudo iptables -P FORWARD ACCEPT
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/getting-started/first-steps/index.html b/pr-preview/pr-4027/getting-started/first-steps/index.html deleted file mode 100644 index 3f09a6f94..000000000 --- a/pr-preview/pr-4027/getting-started/first-steps/index.html +++ /dev/null @@ -1,90 +0,0 @@ - - - - - -First steps with Constellation | Constellation - - - - - - - -
    Version: 2.24

    First steps with Constellation

    -

    The following steps guide you through the process of creating a cluster and deploying a sample app. This example assumes that you have successfully installed and set up Constellation, -and have access to a cloud subscription.

    -
    tip

    If you don't have a cloud subscription, you can also set up a local Constellation cluster using virtualization for testing.

    -
    note

    If you encounter any problem with the following steps, make sure to use the latest release and check out the known issues.

    -

    Create a cluster

    -
      -
    1. -

      Create the configuration file and state file for your cloud provider. If you are following the steps of this guide, there is no need to edit the file.

      -
      constellation config generate aws
      -
    2. -
    3. -

      Create your IAM configuration.

      -
      constellation iam create aws --zone=us-east-2a --prefix=constellTest --update-config

      This command creates IAM configuration for the AWS zone us-east-2a using the prefix constellTest for all named resources being created. It also updates the configuration file constellation-conf.yaml in your current directory with the IAM values filled in.

      Depending on the attestation variant selected on config generation, different regions are available. -AMD SEV-SNP machines (requires the default attestation variant awsSEVSNP) are currently available in the following regions:

        -
      • eu-west-1
      • -
      • us-east-2
      • -

      You can find a list of regions that support AMD SEV-SNP in AWS's documentation.

      NitroTPM machines (requires the attestation variant awsNitroTPM) are available in all regions. -Constellation OS images are currently replicated to the following regions:

        -
      • eu-central-1
      • -
      • eu-west-1
      • -
      • eu-west-3
      • -
      • us-east-2
      • -
      • ap-south-1
      • -

      If you require the OS image to be available in another region, let us know.

      You can find a list of all regions in AWS's documentation.

      -
      tip

      To learn about all options you have for managing IAM resources and Constellation configuration, see the Configuration workflow.

      -
    4. -
    -
      -
    1. -

      Create the cluster. constellation apply uses options set in constellation-conf.yaml. -If you want to manually manage your cloud resources, for example by using Terraform, follow the corresponding instructions in the Create workflow.

      -
      tip

      On Azure, you may need to wait 15+ minutes at this point for role assignments to propagate.

      -
      constellation apply -y
      -

      This should look similar to the following:

      -
      $ constellation apply -y
      Checking for infrastructure changes
      The following Constellation cluster will be created:
      3 control-plane nodes of type n2d-standard-4 will be created.
      1 worker node of type n2d-standard-4 will be created.
      Creating
      Cloud infrastructure created successfully
      Your Constellation master secret was successfully written to ./constellation-mastersecret.json
      Connecting
      Initializing cluster
      Installing Kubernetes components
      Your Constellation cluster was successfully initialized.

      Constellation cluster identifier g6iMP5wRU1b7mpOz2WEISlIYSfdAhB0oNaOg6XEwKFY=
      Kubernetes configuration constellation-admin.conf

      You can now connect to your cluster by executing:
      export KUBECONFIG="$PWD/constellation-admin.conf"
      -

      The cluster's identifier will be different in your output. -Keep constellation-mastersecret.json somewhere safe. -This will allow you to recover your cluster in case of a disaster.

      -
      info

      Depending on your CSP and region, constellation apply may take 10+ minutes to complete.

      -
    2. -
    3. -

      Configure kubectl.

      -
      export KUBECONFIG="$PWD/constellation-admin.conf"
      -
    4. -
    -

    Deploy a sample application

    -
      -
    1. -

      Deploy the emojivoto app

      -
      kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment
      -
    2. -
    3. -

      Expose the frontend service locally

      -
      kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments
      kubectl -n emojivoto port-forward svc/web-svc 8080:80 &
      curl http://localhost:8080
      kill %1
      -
    4. -
    -

    Terminate your cluster

    -

    Use the CLI to terminate your cluster. If you manually used Terraform to manage your cloud resources, follow the corresponding instructions in the Terminate workflow.

    -
    constellation terminate
    -

    This should give the following output:

    -
    $ constellation terminate
    You are about to terminate a Constellation cluster.
    All of its associated resources will be DESTROYED.
    This action is irreversible and ALL DATA WILL BE LOST.
    Do you want to continue? [y/n]:
    -

    Confirm with y to terminate the cluster:

    -
    Terminating ...
    Your Constellation cluster was terminated successfully.
    -

    Optionally, you can also delete your IAM resources.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/getting-started/install/index.html b/pr-preview/pr-4027/getting-started/install/index.html deleted file mode 100644 index bb44cd8e3..000000000 --- a/pr-preview/pr-4027/getting-started/install/index.html +++ /dev/null @@ -1,239 +0,0 @@ - - - - - -Installation and setup | Constellation - - - - - - - -
    Version: 2.24

    Installation and setup

    -

    Constellation runs entirely in your cloud environment and can be controlled via a dedicated command-line interface (CLI) or a Terraform provider.

    -

    Prerequisites

    -

    Make sure the following requirements are met:

    -
      -
    • Your machine is running Linux, macOS, or Windows
    • -
    • You have admin rights on your machine
    • -
    • kubectl is installed
    • -
    • Your CSP is Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), or STACKIT
    • -
    -

    Install the Constellation CLI

    -
    tip

    If you prefer to use Terraform, you can alternatively use the Terraform provider to manage the cluster's lifecycle.

    -

    The CLI executable is available at GitHub. -Install it with the following commands:

    -
      -
    1. Download the CLI:
    2. -
    curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-amd64
      -
    1. -

      Verify the signature (optional)

      -
    2. -
    3. -

      Install the CLI to your PATH:

      -
    4. -
    sudo install constellation-linux-amd64 /usr/local/bin/constellation
    -
    tip

    The CLI supports autocompletion for various shells. To set it up, run constellation completion and follow the given steps.

    -

    Set up cloud credentials

    -

    Constellation makes authenticated calls to the CSP API. Therefore, you need to set up Constellation with the credentials for your CSP.

    -
    tip

    If you don't have a cloud subscription, you can also set up a local Constellation cluster using virtualization for testing.

    -

    Required permissions

    -

    To set up a Constellation cluster, you need to perform two tasks that require permissions: create the infrastructure and create roles for cluster nodes. Both of these actions can be performed by different users, e.g., an administrator to create roles and a DevOps engineer to create the infrastructure.

    To create the IAM configuration for Constellation, you need the following permissions:

    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Action": [
    "ec2:DescribeAccountAttributes",
    "iam:AddRoleToInstanceProfile",
    "iam:AttachRolePolicy",
    "iam:CreateInstanceProfile",
    "iam:CreatePolicy",
    "iam:CreateRole",
    "iam:DeleteInstanceProfile",
    "iam:DeletePolicy",
    "iam:DeletePolicyVersion",
    "iam:DeleteRole",
    "iam:DetachRolePolicy",
    "iam:GetInstanceProfile",
    "iam:GetPolicy",
    "iam:GetPolicyVersion",
    "iam:GetRole",
    "iam:ListAttachedRolePolicies",
    "iam:ListInstanceProfilesForRole",
    "iam:ListPolicyVersions",
    "iam:ListRolePolicies",
    "iam:PassRole",
    "iam:RemoveRoleFromInstanceProfile",
    "sts:GetCallerIdentity"
    ],
    "Resource": "*"
    }
    ]
    }

    The built-in AdministratorAccess policy is a superset of these permissions.

    To create a Constellation cluster, see the permissions of main.tf.

    The built-in PowerUserAccess policy is a superset of these permissions.

    Follow Amazon's guide on understanding and managing policies.

    -

    Authentication

    -

    You need to authenticate with your CSP. The following lists the required steps for testing and production environments.

    -
    note

    The steps for a testing environment are simpler. However, they may expose secrets to the CSP. If in doubt, follow the production steps.

    -

    Testing

    You can use the AWS CloudShell. Make sure you are authorized to use it.

    Production

    Use the latest version of the AWS CLI on a trusted machine:

    aws configure

    Options and first steps are described in the AWS CLI documentation.

    -

    Next steps

    -

    You are now ready to deploy your first confidential Kubernetes cluster and application.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/getting-started/marketplaces/index.html b/pr-preview/pr-4027/getting-started/marketplaces/index.html deleted file mode 100644 index 693a83aae..000000000 --- a/pr-preview/pr-4027/getting-started/marketplaces/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - -Using Constellation via Cloud Marketplaces | Constellation - - - - - - - -
    Version: 2.24

    Using Constellation via Cloud Marketplaces

    -

    Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please contact us.

    -

    This document explains how to run Constellation with the dynamically billed cloud marketplace images.

    -

    To use Constellation's marketplace images, ensure that you are subscribed to the marketplace offering through the web portal.

    Then, enable the use of marketplace images in your Constellation constellation-conf.yaml config file:

    yq eval -i ".provider.aws.useMarketplaceImage = true" constellation-conf.yaml
    -

    Ensure that the cluster uses an official release image version (i.e., .image=vX.Y.Z in the constellation-conf.yaml file).

    -

    From there, you can proceed with the cluster creation as usual.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/gtagman.js b/pr-preview/pr-4027/gtagman.js deleted file mode 100644 index 57bf6717a..000000000 --- a/pr-preview/pr-4027/gtagman.js +++ /dev/null @@ -1,5 +0,0 @@ -(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': -new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], -j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= -'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); -})(window,document,'script','dataLayer','GTM-NF9NM7V'); diff --git a/pr-preview/pr-4027/img/BannerConstellationanimated.svg b/pr-preview/pr-4027/img/BannerConstellationanimated.svg deleted file mode 100644 index f937f69a0..000000000 --- a/pr-preview/pr-4027/img/BannerConstellationanimated.svg +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pr-preview/pr-4027/img/concept.svg b/pr-preview/pr-4027/img/concept.svg deleted file mode 100644 index 2286ff308..000000000 --- a/pr-preview/pr-4027/img/concept.svg +++ /dev/null @@ -1,201 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pr-preview/pr-4027/img/favicon.ico b/pr-preview/pr-4027/img/favicon.ico deleted file mode 100644 index 243eb926dd4846ad1b87f3254d1469d07cfc1242..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 zcmc&*d3aUD6~7^S2uTQJAuI`jK*+w6eI@%s0)%~+kcg5XAt4DMk9~;{K-}7Xt+uxA zw$-m{+dmq$bw$xCiv3!R*4ln5YQZHaWO{y=H_!X-o4N13B!0bLCUfuHv(34)oO9+p zMR8GFm82wv>ImijC`HLo6eS|U{2ZVt?^0U;)p+0HrYHvqAevwZMOjM)?dmo2S~c4L zE4xc#a+|VFB-X{h8krgX$;8MBmwm>254m}`G8EjS4etO0Sm2Dd9L~@y-B}uyxhnm^ z$?=mexwyD6!gZ#N%P~+ zRP`1~C8d+*gnT^` z*_^?h6chSYMQ2fovvP{y^ILKb{g67B^~-CV=TKow?tYO>j<#j4Ouc)I>zHAU^D%B? zXx;Hqi@TTm@MsY4>~(X0;i$Y?xa>75p2K_tr;TUDt@-TwUth-#y}z5?d9{z-#ZFjC z-)9F|`=4%P^Y>M;h>U3t)5SWKwI<^pt!(!0^P95|JF54nyhyhBiDnylwX%!ud(O18 zv?a+5--+ZgERe;~u~gPxQ0mBd4+!&DbuE(3nYP_;Y-iI_rWneP{&|h_8mj6kD>c%6 zt*O?>k##1vJenQ9aL_U~oRL=qd;7P?Sk=xlW^W(Fx&#?zeMn!P@`Sx_N%M)_apm}^ z$*%3svfCEf?L)@$w8up9mvt4T+S^mpm!&v8&b9J6a=+rv#fD=EV_URO!>%&YeR%3r zcKYjHyLtyq%OmSq)s9kz{?1*I%8G8xW9#l&!47|5vWt&C=3JL)*axyTUe|_^7E4Nb{XTs5^7`FuGc#aX+Z~Jv7u5rkQFlXKFnR2_K=b8 zE4tk^Y1nq(u3W~)LtdPgzAkAikkSRe$gBt{UD)14PpR5IFWzX~D!4vJ%45&l-Hhgwl!snk(ev`# z8>RG{A6_S=4Vi0qmB;2ZW!);G%iB8t+$NLM5~X~wW=_ux|CH0w*Rd6Iq`HUgqK6;u zGwjqmz7y|>4Tox^d}w}r92h?STN&Td_9CJDcMkP2zfeCZT^T*2_O2Ih67p(!biI^M zU_{`zhz-c-F6^xn((L{BUMWo(Eqm>2?_MtCwexI;l-JlmpR0&($Y{eJ5v`m1|Gra- zBco-n-P_-bQ9Og)@K}@8Si)W>!^OI7B>&>R2BG}$Ph>Plqdj1c$Y{EI zyQ{G!+55_F@xBY+%EM>$;wLixXosI6d+#6Sf0g_`>HJMwoGjEo#?4q+c)Bcgw!ty5>{r7cc+DR*Pm zX(OEZ`>TcWV+_G|Gs69$-<8}{a1`-OBl~Uq)BvmXOuwGi?x`Gh9}q{u9`9(ZL#q$S z+_0~D4z(%dD@g5U;H>=766rTUf9elZJ1s+8RSY|I>4-|V_domC(o+jqWTxC+*2<3i zsmYU7`Q%vEU*>)&gi{U`Y`#GmxK*FJB1rjRjlxaTm~B;wK2&O7a&`EXh~m#I&Zn`yry`^Q@}MU z=mX}fZ2Zb(v)A7GWV7mvB7V{Iz#5w|hWVGhHUl=EFn)zT;M^m0wqxfM@zpWx$cKAu z_}G(E{~l{l(dK*xy&x{p@ocMTI(^-jB_7h(m`qI_I^?l;|Un+rAq*s1(POme23gTNC%Tw99pRZs?{w4n= zr@lPOTAylBZDZew*Ty*sVbPOJ_Y`lvLj8PE1G`!(y!l1e>hxb~;4M5HX@gD?yFsii zWnm(V%Adg~uC0y_BYgOE`tgN%7LgJDybf<4J=?uVr}sGX9f+V){nW$n`R0{m?L3Q2Ct7D^xJ% zy{U}KbuE7*?GbynH!&0T5%zm{>XeJQO_}#qAF7TV6`_Vn1m`)q8?sKr7ll8q#>E1> zhp?YQxBj7iS3_q9Uk*>7dLgYb`Q@V4yknv>py9A*tlyQ9h8T@%M0MDpq9Cfw1{4L6 zan`RWh;Y%L`VWI&*{vv7P!}i)ffK^_^%r>dSCj$Np5NE~cy?73UYqdjqA2#&ztqlaRS$%x>V?`>J)!Quh7UbLAJFR*(w9ZgX1ya%D}qWP z6-%C006h%zs_Ur>L4H+SWz0F`Hj$m6#wZcz!#&!_cRYvKJz$5)#s&@Jk!;F0jn451 z3F@&Fz{XY1d8@Reh%__2tI|~IM>#)FJHuBi1MZ=li2QO4KPhkcLNjwC8J+d1J`imFalyV)c+jGlMb6#Dsfd0@&pTvR5F=aBrr$Utz}YL}CmaW7 z6!68nU)pK|kFk`wshd# zT{b=n))lOic}>};xJfM4P);R#MeG#kE z5b!H3qv z*n39IQcDB(7}HujzK3et;8*JLW);k|!qdXb?lH%Z%YpgA>FMLBqH{Xn>2m~;7bfFl zuN`9+eme4x5IfVtW8R7MfAGDVEiyy)^3D<~JS~lp++#lw<*4ASlj{uiuGcz*>*z>$ z0~aiceZ>Ysa2G}r^Ys~hZ@3GL4@rLbH z*;A_Sw^(m(8@$B|r}MeCw`i=qL43%Yvc6yk`A!&XvmX$YDig*S&h?PL(D|1(hPWKo z*X|d$veiFXs`eFoABRT_Su5w^5BGdToiDV;*w;M?Tu~ zk%za3cCD!p@kbl<5E2zE{1%SzXiu5Wsl?P%>isl6& zaXN-I_BYDi`~$&j`|=$y z^dF%4(NB>J6cdFIP!tC*4&QIaAE26Ox)NR3K9*I)cUQ*9x)}A@T z=Y_qFg5N%HI`D%*131tJKL=L#cJm&I+-ul-oR^w=KzV_n0onMzg>%{9nL+gV6xGkd zd*lX)a$K=SLMFgq4+oC=jm*E#s@YwkzT5QM4HmwfKdd$wvsHZ968LS52v^@m``93jwX>#_7|4cS ztya%*L!(11v?(t38e$*N4QRlQ;@=*A3371}*MOgezM&0y7~`h|sQijs3mOPdL3|DP zDCpacSGK9}z~KdLu-9R;qK$OfPw-=?D2O{yzW!%)Ymp7I;5#7~AHTW57=Wz++>H;d zMW2yJHl2!kfd=Anyf4&fp~dfg$u}?ETGUU^m#Mr-#hr@P1$|&_2S)`B!WV{35)?Uc tkk-xDi`w!Q67WPSWmJ5DI2cYbU)r(zDJE*7l?X+4@%Q}%Ge8Bn{{sJ z1Tp8K|6#nrjd%?HNR3c1K|8A^oUHjBU2KxKq-Y?B2~vSS zcK z>rl0}+|fI>H*7cJV(L6x%C^ofVG~a&d5-F5%uIAl^1I>uO=dN$GgtJ=JR&?K+%T@Q{*dZ<8Fk>e z#;dqa>*rOf#BZN|4H>h4QvFSlx#>=P=Yh+2-^Uq`Bb4vGFxcF>hbzaa->LMTKg>ae zpZ0!oA77{SD;K<1g1>2S-r>+jUu>Gw2WB{5l(Dg}paz&iiNO_0Jq&-BVzL*!zZ3tS z{199Iy=e}KXw+J8q<3bK#pp^QBg4=d&S4=q*P+vO@v|=h1~T^q{|?Rs-+p;>aEo7& z(t|R%Ur!w6u1k_PIf%s_S*@S(q@3q*7)6rm^qqJ$;mqcu`_W>M!Kz@r_|2dl+yH;?g)R@(MO~D8%dBroO3ne$!wC2lZhic8#-{!}ke+vGw z)UoS3v5lm0>_QIfOMXVUt~xvGSL7M%5xFGPw%OlHh(wSieDHm$gKutt;DNzn3+A9e zBr>J{{h}_%%PHw>8lvpZ%<9-s*2`vCGZt%8^Hi{@UxD9KllH)VtNWqdU&_85x(V4{ zmIu=?zKR}i&T4J#%6hW+E%%+eghW2Al);|A%1x+jMH6V~N0-*fdr=Jrfe zPFdFB5RH_4o%iI$RI*9!ea`nUz2k&){eGcZD=QJ)EXz-CxdlzZHo14 zi~@ZU#-|pGoqKomIyn`LFbKmOz%rQsj`QH5kh~w(v*vEbO~$l>^_BGTkwMy_f!@t- zkAu!WTfZsAI#ypA;rj7s-)q*7virw-B%?hT$fp$G@a_;S2v}-ms4FLD^=Y-K6pA)2 z!)`r&P;cb+fwP)~ujOkd!6wa&j~!*7uvCWwRng)=aQOYg z+RQrE3)E|YyQ_!$I5h|^>BFfe`8s+0J`?zl?xEj93$&Xve;F3Ezqz|!R-YS8NPbs( zsTH;bRNmf%0l{FY1S2PgyZagMP4171f1EOzxh>s0yv-sJ)}d{CIe8!xD?>C69XG!$ zI2&jyaNBl6>`=S~`fx`J05w2S#>6$;Y*glwt0vk|R3%zifExNO_;U7`jD;t*(|QMg zpJ500DBoq*Wvbt3;P80KvMU6`DN&t;MS{KFmX!s?$V#F~+&ysO%}cvVpE9651rz?G zdm3sV)uv>(6Ss|Uxz8JKieF6EMy*Sw#~6g6=x2A)=XNpWk6+TL?#++k+jiXQ zdMQ0k^M#Ra@%SbS4y!)bpDXgq32Aw$W9rByQJ#v&zBkO_2uc{tkkM=f1`{VSbb7Xf z_+H^Y^k}4UvU@E`usQbu2iP`WZS~uIoR*s+)i~bvv>Ocm1zU25Pas903AmLP+U&%O zV4d=754RKa?^8po$?jTFJyM zGcz-M&rJV>WtdL&M}0dg|6$3ug-S+t)O%w45S_N2CFTl$J5D|lsU4h{nBc1pMIzg9 z&`%y|;49;HI`5B6O7#xQ=45`8?ywRJbzot^Vb=dO$H+Lk2HU90YOtIw>Uw)9*=R&e z1{>oehLFgOXuHYUmfwWInR!Oh6-z7QIK~P%uvk~8!~T^^PVD!=u;4sM0R(esgx|MbrAq41IMpz$!B=r`KAB|kXZdv$)H^VYM9Gx(VU!&<+zu21og zN9YS)-be3dAJ6;j>4E+CnziAr>h2`^gv~TmFcRq>)^lS;w2~(>$b>c^rPkbFb-Qxvlxo5d#1S91cf| zKa@ku^nItl1QKa0RpnVp11|NrgS+-rv%hTgvgO^R+x>L<0j0iwg&OBf}7% zKM|p#5yTP313J@jpBZTuAAo0sv-0}sMA&QlTYn!e?)9jN6M}1Cq6NUKbUTUuyN>La zhN?{iwQm+JjlurFH$Eful3sJ-B>pxT43MsxKjDGi!9{@yvY?-7OXPKM|J%xuxw{y8A zacnm<@n7zT9tD(H>o;ebn3(*toQ<1kJI%4^f7?lbBZ~eCtSBE~U@-J9*J{$MuR9x79H}cyN^<#s0#^W6K?yC8Z;s4SZyf&ZG)aiY zpt?0B54Yk$+ZZP4J$5#&MU;PjRk_!h@^!H>f&?I@B&C+VWlMQSU7Pmhl-@+1dpKBz zED}h|<@s96+fG>!N9wgR zl1U)Uo(PlWa`<;sbU=)i598?wssQM=yT1ao?x#&|h7LX}0^olgw$L1+0p*AFzq1U`m#On0F6Egh-sN2W$x^2OEBXBSVOU5I(I zt$ZEwTZZdOHiEu4)>0e#h|6@E%*g3$r!d=qbNHeE=I14&b+$kkNC_%8I;rYxLL2+h zPht1xlaAwB#_)M|M?6_4!#lw(N+@m$_d}TMx3(=78GXBRr%@jUlgl zkh5NswYRUDR{v_E7DF8;=D6!u;3mUHdLc&y5vIFe88Mb1J|9am8n(v1e0*_t&P8iz z-|bw>^!}tMFFCMkID(tTG4k$9?+twi)sgS#GNU6*)gf1`c#SuqCCra_jeRqZRxpdH z8#$nKOxs(@@;}fJP|6ibnQcYlv6faO`6%9EkoHtK3`B@1)y#YCw_50r(q?@IwqzY8 znX23IxG?@;If)0pg)m!}aIM=$sWGlGi!tQhj?$4u3KWKRaIl%ARGWXX*{NDf)x+b+ zR6!8KV1458R%8!#e}0pGT{oQIXS!Fl!hpkx6BAq#e3b=Zwk(b2--EU>Jqa3}oA}ru zV1R6cErxi%&y9T2ZMo*709Gt~WK(%~Qr@BH5fCk@CM&%c1(t}1W+fmVj1vNf5>X$h zmT;C4LcBHth7{Y{rD;6JNZI?QM0cR_-zVkSO^zGiIa1PVX%PIz82L~!y~xg8x4A8uNf}!R*BLp{BD4=Var|#DWB0P3LM#(yBi)tw-F(!R75U^>yR&CKYdAZSI}w0{ zp8W_dBl~dPdQ$Q5LX?~T->1eT)=*nxRe#wSb2*N1R(^**z{oTe^2d`qXJwQxb*?31 zf<=aRhI0t4y;$?f$SCGlMG$}#B@w0$%>Y)a0fR!h zSgO_qODEEMA3q9RNpmfS8uy{U@Q_|{AuLbw##CthW<@X8za`kLEmS{h-@7h&=6Xul zj0`f9MVGBqQ|r~^g6aLOH0D0(91H3|S!jon z{vpM8SYssg@`eY9T!xQY1eCqO*N5aUy378jyBR}Mm<(%Do@)TkgrBPbZX;)LkSq^> zUI7NQZeA0>8H!w~(cxFA8WtTdqWs$s>g4?IlM1XE`|x>wM-{~nYm7Gc2+FJFW_Bw- zJf<5~LSnJZsBIOqG~v8MgWu~!A$F|r3Q}ODNqAb}wnQp;MpfI9Q)c*ooG^B71R6D2 z65EUr&pw41!-<*w?~(OYu$jh)IhT*@M6a17ym%gOh<0IEDtnbqRA|{efv`oIKApd{ zR#rl~%*{qwh|S>CtJ6IR;{wmp1D^^u`F9Wlt#t8FD^uKS?F(@G#u|c`;N*%w9p@__I9@R=a3Ugpp8O^7%i~X6!qc1`Nh*g zSI68U2{yYD0pQ_f)=oC~V%vLf#YzEg-@F}TtyWFU9j?F*XJyvqeVRa8P#XvlBS1eL z!gBhTt4Gg4)_>s9@#lX*2Nt@xmUR~(k*B04L)qGt$Bb}VtNb7A9T}*|S(A0Sl-lwf z^B|1a85;y>@t{8mV3tIw<>E&99fLh}I4}W0Mh-%|HeQY#h~3r>9T9cw)`=gV{-nrh+yc9sEvMg)JZ zI8_{QnO0GMs!tY32~DyHhNs921S&x8p~TK;t}c#D`R)2}Vxs0s@B5}__1K@OOOVv8 zOaf^5NKGEiHMK~Y5TJ9V2HC+yV+W{iIB^9E09n&)-O#kU{<6^eqKDE?@3DT>_t!Yr z;LP{=|2!A^=ANSbv7E`xOxeX&465&7vg?CRCu%p|`IJK(qrP89%)OVBGZGLbB!^hsZxPSOzkWS`+VaFbwHEGcHzqpn8ru#);Sk$&*R5- ziX^9}st!q#2Q1#z-0ttF5{5dkd+$iJqya8tg`-26BklBTeK!QV2I11j2Ts3GNk*yJ zHXiK|r0#s?^Y&QeVDL(2+2gx3(UcJHN5vbE5{7#FXaVLb?~eKFj&~Y$-Y@fi4OyGD zX790|F-vccgOm(TLH>avidLqENR@Jt`cj6HgtF+h*`LVXvzh>}jc^^J9&9E8d`J+D z79Vd^jIyU;$XR9f^J@hxjp{GTGOkfC1j(W$@m{}D)M4ga&GVgS>cBjq`|4A(kGlu4 zOa0kZvnAMu-DVh*Y!W{ib_pRCTA^2C+fDkMqlL_be3UsJiI6PW97?zd+w$3kP589*!G6Zp z1AhlH5aINAeXQ9_hZiEx=ZOyqzhA%D63QY9StDq>Yzl>>+Z;$LL>-1n z@xun=2MSXeDrQl-xNUDhf%C%w`Igfr)2QK&#Lvc*rOk zGg{)}_?7+ZUDkJv6tNXgPL+Wqp9nEa(o{IqV7Vmx{M#ekE7QAc+`S#;_V~M2#Yuc@ z*;r7C5XJ#YegoqeVj^QZ{52?+^;FN``(}&Od~WPNSFjSMVdQfd+as{8{r<#DCgDj| zlJmp{Ze-C!nx)zMmym7#UdsX@3q~b$q6#iD`v4~vTGh9f*1048gZ`p0V@)g;y7y>qN`Vg}NmIVF5DK@03v?cdNN;#!ujm38?K1~Ax7MXq*G5l!wU;!brA&OZ;mmHIV665a3+CR2!0#I zFKvO-az#3jN~Sb?^58b%2|MyEFHJ;de5 zu9b>F1R~7qpNx5Z+!9tIgoZ~3Cr%!ZJFcBioRun6#F)Hn8)f>e1XM8h0KZR6*)SG$ zh_^fAzYyGP2a4GL(Hc1PdAIM`X8XGR)!;QF%H3o4qg#9JY}(n@W~9O)^K1!0Dzyjn z6iN>#E@20USfR6?5v%)rwocAip;uo0A2^-;XzdYbjWDta?H04qo6w@W+^?Oni_C1h z)5m9}PYCrxbhqiBp)+v_9Nk2ldZz=k){2NV#gi&<1-J;it&ZRpw>RXHWm)Si(=R)D zZ9E+x@=1+`01j?3hC3_O2mA5!ZaodD;n)T3GERrot=23?dhwoI(Y;x;5!-j`t&cD< z$vi@|RchznURxFIN@3FfRgpHTGe^>RRcOZqdxk-W>0}IKF&jkCNB!vsi_dQ8tJ{vp zgKqoDXxcOOMI}7W`I2)TZeyTsscmxTDz5eEu=$J%+<-C)>m#9@fCT)$!xKdWc7M?? z-};p)`R(2RHcwzvF*q1yM+xzABUIrB^Ck@>fIOc+MG%a=6$5ciX%y2GQw~9c?{7Mr z)n82~aaQz~KpmUBCj|}c$qDY(*n1;m*KGkgEc(BOyhOVqUK@`;Jw4ooAk{t%tAT9H z6M{AoY{XL#8d4t~xeX9R`FU+PU1p4v{XAH}l76^2s7E$Au61|>ZUnE(dU8J@V^KBK_6larc~b#mT6{)Ey6L^8Co#k`OD z31tFp@{YlInaouQMh!3|jT(|bMZ_CrwEA(r%eCD8%8qU~u#p)$8k6t0w_B5A2pfB4tjWGmB zq|wD5+3mVThgLydIge2BTIzR{kp07{dQFFqr%?&)-Ka(r$I1+O&E{tLC??tb{z!-FsFj8*-|qysG7Y zmtxv=G^Gp4gE1_uBR6OZxU)6QkNw-6mIn1as|wWcMN> zr<^00OC9Y0MgZcyMQ`zH5-Tv}$*{1O2ZO)I^%I7F;+FnhCzFnIon!G(6LC?LoQ7~C z*b(CeV)}^*-9@qHgA$gDqRub&7u$>m4a;9MrkVYT0n?0~ip#szVVuA!(d=M*IpxRr z%A19K_o8zG_?Z(~;1K#rA1Fq*YGF>TR^4UQc5Ip5YjPtRxY<+TZ(Dh26JPE%fWh zD9vAwPg#4kCR*1+?@`IhA48!lsF6*g<>|>5r+DPshH62d?V5AiXh(jJYF$4xQ@y*G z-$j{fUh#bDuE4QP&30h|mlYApNcp3=*q97N2X^hK5^yyzJH zWP9nt+pHbjy<4esq*g9TEXVJt$q}j5n{MZJKbt19B+11C=OKKB5Cg0k7<uxoy zmxqULO0wMD};pQi$HzxubnG#Cw(pg$d zi9V{WohQDW&0V1b8?uC}8jBesUJpF7)8ju*Kj|9eO4OR-sD8`qAOd|~!BqnRf8*)& z6lGO=k4FCF^;sH0)c~6Ii3hjr$H6(pZmYz78KQOgD88+~yp3&6Iwen$c~ejx@g{5c z@rzQUGRGA9r{4?8QO~v9kpHlW#V#iAR^{I!{RbI3NKI!6=Q8r2!SN5n!los^V9c^q zhw!3^8WT~hyrDKwjL9eeiTs1OE+rn?@HM}GJOyT`rtZ%>=s+Csp|nf2PRegBHN=02 zJN`Ef05=8TWacl>x8*uHO;L-g_3<=24;9fgMSJMimM)E3sj~+^`&s@ntNQVq(P!o)`9VqO+G6%Wh)_uZtg&g46Fg#cq14dS!4g%XR{9(bP8KWy@ z_rEABVhp+vc@oHzMtH0|gwfw%cyXw#!l}8bYS!cm?UbP!CK5!u`<$WOpSNS!RDKzx zQ5UWczABn9BgY7|$s4bLpavX4ZiyB$V71A@$7xk*6CRuSyw|ArHB)Fn8Q?i-HNK&N zPm%gS_F4aFJgYT#YZJLq)Xmp6PbY+^12xb!5rZ4o&*C&b1uSP_v^Nyyf1C7{di*ad zi{-;r3nxvL%MrY;e>?ERv9kUa+EIGNlUO7gbHqJcM>SvP z$XgQ?kIa89u6|vwug}zsQ%OY`t>m+Z6BpkC63$+@_B|Rzd4&J|q)IcTfUb(b#=<~N zJBH2lse`~Xn>LN=nw21jq=&;y)o;7;(cDgCz0gZ2+TWnOBJ-OGU-etGd_KJS@-9^K zv(T*+I-2v|&Y4dMFBkFp_z-Pzv!BlwL8>K^F&lN7NN3#O=<4x`a{CoJQ9Ph$?wq9P zWbk_D^;Y)Ler1ko-Zx-0HZ8a1@_~DR^zhB^y1N0J(}_OQlQQ0s z2X0EsCLqy>mVZWR(eIk=#xp+w;$xzH)W3%q=g1d1!9zi9 z?Opq^?>IR;Z+P7bbI2GFd4LFH2axd-V7A{o3EwtMwFHx`EtWsr`2yP2{ zSnzmC|EgoK@eLC(hCL$?-@L{6uMJU>OTTN?vQA!!f6`kz-8%>fVbSMWIHvQv!^-0N zlcA6AAf5wBTzms4>05tchv)HZ@_FG>6B-}-R(C@WZl}u4t8*l(RBT^byKh8PZUVI` zX#hY%pK3_mB<<9B?p<(VQkT>T8m=Wwwt^T?a1b-~SJ`#w7Ix^!xCv6x7U~-W77yBX)$@($>OpB1DNH+sQipgC6Ou z^!H!Fw!lCIi^~oC?>Y!f!?C>){pAJI^afo7&I3LP^IBk~^W3NXgVIXZhVQwmK|2=N zq1~b9(uc>^c>CJp@E~P9dz*A>ZULCs*(yvC*JD<=cG?a7BBUfnl&xg8N7sa+AL$k0gCmldo{YC~C zlNc%MJUp{kh{5+*l-QQ3A+5NvMOf6JX6L`bTc3$D3CTn-$3s9DQ79E7WWj{D}eir5kf4qR~3c z=<_+OkB>M4gfLg`%2!8jAv4p*RH7OGJhl)pIIwo+`$E;l;GyXDm$kxlm%B-T5$ikDU;+<;u(eZ9}!g*6nd_2|V=JG?^dvt}R0yauyGpuJJk zrt30;L4!y0qn^)f0Pi}ezfPHaKJ0rqpBdCPLIh?R0MKUif1CR|he=5?a(!CGrs8zy za@n&DsN19JZ=Vs`{@W$&NjE69My@Y>b8SdZx+w&}FcwvP)s<(i59#y$(ITPbKU8b< zug7eEI?V{a^TxhADH{=6KUczd9&&e3=nc5niUf8WLo%{Etk6;pfjK4yY(Dxt`r7*- zcE!golC@2_Pn!6P8ln;H%l?D;l1n*^{x;Xk)lnE}To2**HQ)2AR^oU!vbK;rTy23F zl{ZQ;IA8#24xm**5e1EzsI6~#@0l%=zTvjf_ckNTl6Dbl^iP^9X#C|CL@Opc|QpJy6R@L%NKaT%BlP_whc(h@GaTh$7@BBe>lq0 zK^JV+$p+dfcQ{KEAL+v5oicecrZc<&co(u`xZ~En6UEaefi^}^1KT+t-itg6=|4Qr z86P+iilXV&8wid1=3cJg&qVR532}{s>Bb>t7QCWADydo-y7+4^AfkwxY!viQLE?%Nk|&x61qPM&0pJwp}nCi@*T8#`fB zX9mcw-}c-vQzlzpI8x?FY!VQG{7W!C`f9ITUsR->IowYa$@p4{p`q0F#7Ke1Guf!r z+JsXQ&KX0mYW5*%+^y90I;Y`m`TkDiOqn*%zu@}$+E#Yd?X%0evjf#bII&vB6DBrc z!nxI0+;p0tm_flC>~H0=v_mynd3Ny`C&HO`Yp?6STG9!Bt}3V2P@?HIcpQBe{N46W zetWJ1+?=Z~;P5`8*-G$1_H6wh#Pg-83c<3nYRj2vefQ^~4khx!C@kKfcqUBfi&?^H zXGX)e85_V`+uDuKbJVf8TG4PPmpcopRV(*Pu{bjEUbR1crd zwWNFfjD>|3^jCuL#yz(O0a4MZP^0tIEOu?xThB)@S!#t5L9t zjW;+xq(|~0$x|P=|FXKD#Hi(aV%{D)`~qdP(UAa&Afu=p=^(MHRZ+?d`)wY{^!dvV zp&ec;5@@j+r~>*77v6Z&`Z&3G+}7MGdA1hYaP}|hhR1Y?%Uq0T>haVP}WI&E8%JUX&1!cu2r&%bWj&7nu z!b9m>E*|?Uy|$ppN1M|=$_FVaghYrkoQQvYJ+W*}2Ows;e#z97Pz^4^#Uw+zyU$_q zcf+$~LF>(M&zwW6nx^@e0IDHL9_MFjH$g#AejrwHCr(m=wnS*Y*kPR>Y=eOqMu^B# z_{gd&>K21t+;3UhKw@;nP|BmGf}0juX75vNW&4&`fCsP40K|fca$@Z6lfgtqVbic$ zRxa_hpdbEpGrokk%@Q)6>53ndejdo)9iH7SoB`g0qaBcY)FL$CPYace=_0}-y>S}v z^}#+gVg$x>RaP|?xM;b(lDD8YGbE3F1dvC&>h4E`|GmG<>?{aXF*fQ3zF5~6(!;Mo ztr)dYM)vrXEXG!+yzJuK+05=9Cyl6*%pG1|w@x!otl6ll84uaOcDRxOrr8VeSac$B zG#urj3C_j~s$4K}P5`uc%NmOPH#?OLVs1oMC?d#WyQrwCnszl7@0@Sk`6a{iz|k^# zg{}1NNI)rZJcamzVJBOM4T*pG`fsyx%P{p6O$g-7%oqa+mS`uQ!Bk#4?Kn=2_trn0vpw!LP~lIFxewknIxMm zvma(#TS3ov#*0jbYHjX{gkA88*|RjpY~gg)6S zRe;Ywj8j4WihMAhK>g9hOJWjB8qNvp6UDB8}>A^i8QN_$i*V{u@q!abw{Ura@AgI+uA0|h^rMCjH5)e_?TnP4o( zjR$6G=__;+O56oB(H=4cZ=W(tyrmnR(XX#xY)tk^+1;`Tz?khN7a@k|9<}|-*C#HV z0oIHI8)M80CsU!!HXjeOXX8)#6Pb;qLylRsh4QsKnO~aT3V4LnogH=#Ys{wVUlserIF7;kxV&z7F}b?&mlh=xqj6Xq&Zewn zO$%faj^((eps$ewWI_Z+S)8;w<$?d;9aJ2Bm%Zg4J#8f@-dz7|0^<)j`U`M$3$mw7{A|1oi6kYyFNVkl+rMlR6*6ij>5RLSY0aPw~ zMkg?Dx)NK+A@%KNm8O_ZuToMNnvw5B6Tr{(3_t#0p;gsqALo9W!AN&IRZ$kr1pB;* z>kP%maJO+8WwR8&U!P>};r8)SSYbN>i<#j{05}}Tm6#KtbFh`6fRaRZ9I2<=j=pd! z6Ffydc34q@+o;QaX`k~THeXJ!KwX&^tk9i(02P@@=N%bfi0~`1^|68kBOZLXhd~De zR0T?kU_eeX(P#co&2fGCJYIZk@)fL)3fPP;zgBy`R`S?9C;@HeRTgXG2O+4 zOvGM3l)RHS-|!BQC$KD=x?=oXMz0V4xzRb@?vr^B$n(j+!k>Bjp5rIs{YE3728J#A zzwNQeS=z;r+GHD+^YPVQPdoTBX>4%68=?6&PfhXp^^eSbtB@7CoF6MCYJ%JKZ-Kx= z4=N7bWN&%*eC{*{{PkXxI)s7-fmLENh>d@}u-m)*UBQ^Qp8In7vKpCUJUI#fQ|U$l z`j$a#^NDUOrNm{O5x~KUH%W|~e08h9;-DlF<`X4#MS`G6ec=izE!u(%p`*w*Ag56CL~qjNJ%M?FL=sg zOT~zu$5ZoVbqP{?8lt`vmLFR7qpUpNd53B;bMAFz2cFZ}>VnyZ_n@c=rtCI)7s7Q# zpZMyf@dM_RueG`L`oahw-96~2dBI_J0E^WCL|d-^EmwzeDpr#5yQO{(Dn&w6S<0I? zos`+gC?-zwR7zUys?C-WFb}JZGV0bA2waE6x+r<;O{{E63%hDOuI*|Vm+QPjQ^J8E zKA#k!trG2CIJ|^g?Y}#JSF)T%KYDhq0n!Fo>U{5@!%M001Gd4fTJHDxzpVsU8FB0L z;3Ibh^$@?sJzL_`isPRD`Y`6tW zMKZROMPb5pw6EW{yi)^&Wkb_PI=Fy(lD^P?F2|7=ie8$NBN#7aMm$iX;T)4MO9SOf zr|GH4wk772zC!4t!};U!`->OdWxLR0Adg;tXh1>9fc6+FCa<@+!qMFN=JGyL1i7O0 zMiZ~yI>7iHdyjyEvMQCwAty@+QzzS-FK?K)+mdio$=*f%az7A04(oQI^3$k8CMTmk zv5#xvjc?`!CTLGK6v`UV@>MSqPT_$Wnm6Bf6SC+#43Z8Pnhwvm$fh2^KafkX)9r5= zAqRhFyNCv`xZt;oCd|j5Uxij<38QrB9`3R0I&FrCg3M*v`pWIkrH@43gsVbGO7>Hz z#0k}PeHB@B@0D@)_fuEmy0Ys$?I~Q@Cvalhhnn}heO55pc$LXOjJ9$EFEA;|O1u_e zxS|5>PL%7$C$@Mevr|?8F1J!2YQ8MC$z2X=l=KF@OyxeloH++bD>RBUC=nVh{*#bY zuP4b(a#V4|1uBevC-@pf&Hah`vnb9FjRGQaz}sU<V2FN zzh#mz;+v3P2t3u~$mCa1h|uKJ-pcJE69&lMYxyq&!~;bjiD3XyXqWze<#OQtwoH}S z5p<&k=WnSjU;E$XL>49)W%T+QF>H82p-mli7TB-Jg8Lp%1~&1huJG0j=#0Oa{C)~@ zew1#9ikH&K4bW|^NS`#h&0f98DTOyn&<8^~LFSop0vbMxqiy|F00eD)J(W(t=@ZRY z)p%fWWWUxgLXrM~Y$~{bfUSz&2A6_>kf_$E$x^LFK?75rgIs`zHRJEHRv0%Zm~{so z`5R3(){->dgEY_IzAch_)mwghEF2VTd}jpzB7Ag6#p$A%Nd7bgz+8qkLyWC|+cbl^ zEW>3C!-U!B>n<((1!{~OmDO)8mkA9)Hps-4TQ1MQJ5kl=m)rJ3(JQYuyP;@|O0$2h z$i_A+lf>JezQ1?D>oma^qoiYZ6P`p?HAs=ntz>;3)tB}!Ug%ju>$&w0`zmH|Ge|1sk% z)VO3@I~kT7Msoq!Xx~_@6;*+&G~Aai2oC z(Ox9HyVMZO^P}Tap(zb8{uU|uTHnQ&i{0eO(PO{-p$3d%ZNwW}017c*^)=2dSCy0~ zkXuZsvUpEZvfk4ach|2_t5 zFFf0`%nXygGbsUH4|(9EN*vZx`~cy;{=)Z41;u&Tik|*E6PJi$w*B=9rGFN^q-J^?g?zCdni{f{ue5 z1@HWw9wXv51+f6gcRY>%E!h+E2#mk5KYwmKbv5E~F861583u`B&AQ10sdJpXIor$~ zbM1dp7|D#%jp4HDFcT%Plc~fbC-}?UdGa$1seDU?gIP+N%y4AkS)~Uq(c44cr0Ymf z000dMMJF93`T{bs^$$SuFDgtS+Jf(SmWS~e&(k!yMZe&+b$)l%dM~X{`hube{0LBW zVzo50u-S!2==$6N7NDQISFf(+4x`9Xy7sTZ#L|}J(VfRMX|}4*k~E$-Ut)ONT9a@a z$UiA}#4>PbT`u#I!jk)ZU@eZfm`;BxCwu?bc`$5DEM3`**UyWc-`fQb&7hajuQq`G zB7A9$?gqz=jOUKR;7t?-PCVgBQ9@<1zt1_5Al`AR#PRwWW|wbPb$LUDPdtB_LX;R( z#Xnugh=`$<*vuMsS=*F5W z`*?Y@kWk0V=0p`LYYW+Gy$t+*Fd{j1nmN=5O%V}=rNvO3RM4Kn5{pxHDV^B)eOHIfl#I}L{8 z0_Hg|q};3~%Qptzp_6QSt>sGE7&#loG}EkKj%j5Q@3R|ALcl0OdwLw(K~aU{J-a6> z(B7(LhFy@JjP5T=D5YhXcGSB|+^>HMSmMq3+y{ubp+k|Q#v!#}Jn=r1E>duFP5qj$ z$Nr@tt;RHk=Lrm=gltP1EhnUjp?u!;;kOKW$x&MaZiIJ09lh^5&Wdc$;bV|6+)3t#~HH47i-{(a7Vf7{0` zk+bdkheJD22e4GoWqLwJ%81;s%aNSo2&&VN zj_G7;p=b%$Wc~@p##ucsR@ddvm@hp+-wbC~3QC>dF(3|Ku6U|)HFVn4Y7{kiD15j# z7{EdcOP~w}16&W~d_SYRJY>0BazrANJEHe*4To!%;3qwNXH+p2nmf7cJD;$!ff#Yq zlesr%YWC5&@EpUKV0LKN*2M~-f$E?PKTfjRCrmgPfd1V7&3RWSaXzfU_@-!p!=4g+ zVdJV!<@0#+O;9hfxc3pxY50E3N^x=Ic1JY_3BK@5GE0fEw22?|!f0`LzGQhva2-SH zzNto31Qx{8Q7N&Xk;zD3r4F(%jJ{KH=VqIVXZ=4rCl|n6!j=4gIVzC#{oA6S^M*@$ zSQtR!WalN+U-)PCSe}gk2NS1YIdSuk$0xmDWm z_jhTo(8;S2=;W7L!VP@7v@{x`r9U_`8|p0X$VlB#q>m$&0mE6MQn2@7gQ!O=-L%F@lUNzid^DBJx{AU z`*sQh2|B^lqx(s4a|n8B(MFw3uB9BW^5vy4m{vxUCphuvRb{N{+B3cTiTA@aOOVB1 zVU=zZsi0|~kP{P6YrDSg%XH!pKW24w9cp%Tx2^EpqxNgcTQJr6J7(dfg7$K!rm3yE zl{F|%m2H2DzU^2T3@Q#hSWFT~2+;l{P#xSc24HsXOlz1KG|)hA z=HL2)V9#Awa+r`Mi>AH!yE&P5iK~@d``|*g5S3+4;6|L3BEl@Sw#^xvSoB!2GpAZ0 zvw>`3F^i;P5S5ML$YRcWUxO1Ac)zcYEA}=RZE62R;`kaArP0A-VHVKb7&i_6>h>KbxSBS}2L5;9K(FWx{qtaew@|pV1sSOO1JQ()=7EATJ6ob)0WbV&n z;()Jq+YOA3HYguD3>;`4J*HYYZ$=+5Aeg`W^%_pW(aH9w#)J7utruUp|D;_!64~N% z*w19CAfo7&nLFj710(~6vBb`_@3P#>oTc2?O)eofi~`u8tL+yk@@HK%^>#t(|5k4q zlJ_ajEbT%Yd!{SNL8I{YRN&;gjZ-2xa49v=C>}u^X)0xKn8qR~J;G8E-Rg?u=t3J9 z$C$JX$?vwmH@_+DXg*_CGgSEW@GWS#^n^ON+@OOZf6W{0z?Z`OGL5v|_h) zs9MK6HTZP6*2L-4)I2mxr%~hi)U!3pa(g}Gpmv!m_ARK5iy!kgmg?(2*j!>kd+G{j zRb>sjwxoOyPft=4dfun7+$Q!?uJ2tiu3Ge)0DCZa>EbjaeR3^oVie%N=hZ17nkY(w ztLlnN2c@unPk(L(S{)5!WQNG$9-RL2@bUb4*XK@3kCoA(W||sP`(bvQyy$yP<=*v2FHf;3}V7E?ymb5L2j+gxSFuv=OhW)Li0|+44rTsWmPyVdh-?+(P^6UJc!y;y?1Mj_HXF zTpRW$&+p`j>5I2kWxJAQNNHB2Ri42L0`~Gq&OMIA3b@3ZH65o$_5y>-kxh^}ZdBb` zr6jlMn0MqVF_X?>Px9x9nQAr5C~7;2n^52bYH@KRApyxJKC<~b?M?0j;_`p@J-;tj zMbgMP->8^x+NMh-miFAbhI9@YPpC#+GvAPsluG$yl7z?fBc2 zqqv0ksSWOp#?BcTjS=3e2P)Jm*}4!!71wgW)>Z#Jt=gzsug)`h0t8Ejpt%Z{7iPFqg>Nn-c=GJwltYw=5v0`_|fOQOi zigdD~y!1-b9AA%&{JT<5u^>|Fe33lWZhpP-T*Rw@x`#5+BZ&T(4c|PSR5yBV2|MnJ z6$|B09-?bkx&cLJVb%VA4VjrEBEH5)DIdONw_~PI#8N?oKPPE54T=v>BV`ZYotjO` z$w1MTwHpo0MJ56++M2~Spq7{KdsfpX7`N+xr?(xN={}ABQHMC;yd-&3 zSMPds@OI!@yP}N0HnIN(3@Z>rnLeq$`h~vb4`8}vU!psE3yK1abi41|O~r%)wda?$ z1}m$`AMgHpQbormmArMBhSAbZl~x+5UxqMt_FJ zS=ka~*mA~zIO1C9!NbluO;t`Uu&Y`!E~$$X7T*luGUKU`HLPWgo>o=%)b)RFLVZ71c^JW}_m zLBAux_54iGPVQqFHqSK#vA$mXBFaeHF>5S%y|SjozU|j$QWc$Y`bcPYq_zIbC*tH> zTHf?aE|u!e3mPt~`8DZtVrI4NJ^h1cqlB4rJ^yXm2<#RHQz z&Z_Jf@*wuX6js`D_#NAml!Qi3VPT9ss7HWNr!J6>gaZ7*0#SZFl+uNVvIsHpW&76!k$auks`9e3$K zL0U;M1r$M(@sxZ=E9-n`r=8jZVx(4VEM&}NMDj@A`fsB$m-@|N>~>G}oU4k8Ny|zU zx66cTa$qw@42kGUsgU~CPRVLu?w%|xc~`WiXRe6h8AHsVHh#S+K2FG=1G(eXtI}SU zzB``X69FPrS`VSd@3-ME@fi3M&LK$MlZjHcP;HL;p}Cfd@*06)qcf)YGounBPvxb< z8{6ZqYY?@Qyd$YlneQBGKPdPSmc>)9pIlYWZZP5at(=1W;H#bb!MCR6Ew>aq21&K8`U;J89^*&H7Yw;Db;q&w5ia}w66@}&JpG{7 z0aER8IhVtSK7ZrpZ9|Y+x{;s}?wRFY(*cFtH}3>+{2s&84kkNh<9+KRM&J&Vj6A{! z46DJJJ!`$T2gEb$pW3#(2G?UtM;a6*VApOP_R`n&kJMf{7o*N?*2?WPI2I4Sxw=p4yDKXpib2K#M|_4IT#F`#yIl5+ zZ)GMH12ZHW12=NFz4F3klo#f=X^X4P_ z-Y#Rs^^&sB`IboxBKSR$62wienIGp-w2&yAin@V^_tX6Po3l#D=U>JM)~4$ZD9>{lMyd^oU# zmW#}m#LimIOWmllE>E^`t(SrWc^%k_aGJCwb#4ovY}Jx=}eOxn{mdRIj0<@#AqCDI)9QmZ7M5$R*YLLW-X>~u~XfBwd7Rim#RT~ zIkEq4#ctngcxQ1Ta-Qr6Il@3=*HFo#p~IGGy?$qF5<}hK+uU0|*Sc`sz&r)@0gH?@ zMRVILb)spX^V{sD9w$$vm^3mLaF3cbneOhsoqc3aRW&Evx4g>~%C44)Uzq>UbJqFP z2ceMCu@^%j4X+<+gjw|Jl{awjw|w9>xjP(&XLVX6;re@Byp<|ZLwhIejbUmejBg=6 z9bM0QblSHQGg{W8?`a@}x@11E`@T-ma>wtEj*WX7^e@pNsUyTXd( z!AI4s^RmLOjU(ADeATAq4M}Nqh<_yKgzj9*v?h*5?0S@S9Rt2{L=Nnl10puE-Q0^$ zt%+G-p3^SF*-Jh8qRM_r*er`FMo8_fTtpJkrp3RB)lROZTWVyZnUrv*W9IapmckOp z_pjesnlm$RiAETg*C(aXA|bJSdjZ+EEcO#2B812arHk=Z*`|&tj-c5N7Gt}9XKiEU zAS=d7DN^p3R@eGM3L2>i!N3oTv;-6 zA|ld&;#_$`asu66Q6@)3(vjB%i1wrf;ZeyUolYh-6( zrhrU!FK{N`+ssB+~K4<9(?Q(2L!M|_np zqQG~{pr^cIyHU3GozYWit3^X5)jK=lPSov2qZ{t_=>9FYelU}#ofe@c$FsD#pS;Lpe?IGvtdE{_`-q1((j#(aM2 z%>}E`5jq4*cHyis&Y{KfcgVvAaJ>f6c=v9RD6_YO0A0U~6T`n(0$H-RbvKq$1hJ2U zMV-7XJ;o_w*H0m0A-=M{U2C@nQoIyXBVeb!73I^LK@D6+5%XjzX_pZD5=SAzyj@fq za_>jlMFV>rtCRO`EKvVzYxK_=pxUEkE%ljju9hsYB{4Q2$Mf)a7ZDkL*Xdn%x_K5J zJjOey(j?KLU&D!og{v1eR1W%^EOO}eH`0b%2^`_jKZq2@Nw>v#c)@<(Mqf@pE?;r0|ces?-X>LUM7bX78pgMCaSVMZ_{ABi8Lx@`6{h58>t1`4)>`C`P4M(*RF)pcu{JpZt$}?Y?=6Nw2+cLE9@-T zgr|YPwZ~T-k;k_C{{0)-Ipu%sNp<_wL00J@*A8pIDYq#pR1LY&mTusi<*cM%{h|MyW`+VdhM>sfse z@W_tG_3-7UChzosc&=O}MUpSHmAbcQ;N7+Z)0FMIpK7g)oy=EdKiqEw>m7@Ckn23H z$m@fPv=(N^zg2Aiq&-wxpjSmW@9Fm)gXL-5HdP6Rz(A_|V@l1yVdb6Re^HbuP=Gu@ z{2CG<`*Zj^3K@^-?HFQ`=$@GC?q9t$+xjDl_i*XfipyNgx7f-D?R{z<4j}P{Rx6%SmWYhxBk9ifx9~Zg(NEE= zfu0Bg$1lkApMp~2Sj1|JW=-~!lYGnLcoU8yisxm^imNLvyrrG{n~s)g<7>nG$Dmc%rj=)%6O`fF4{zZ z807Nt^pR_!5wZWfO$-h{z>{UIAn6R%%4-m-Zv;ln+_r88FT1V>jzpJLz%1jY=hUU* z9r*EGKFhWjy_W?JQIT`>x)8r6|6CS0&@Hd0yQ<&XHukW=nCB_=PcA%$L_^LdC&ztT zT+QI>h^Qfy^lxsKFWCMU4fXy}N)A%K9)DIaWHublKILhZlL5uCqLG$}7rXNd)JOW9 zd2;s9Ca<4AdpXgHtwOS%`8{_G5s80QZ`*O~v2ao1w9Sb# zkO6Z*xNZrf%sdR|HT2~3g8NiZ}kTpzu4Qc74 zm+|+D+}{4x*4@6m6fUF&>T;<^kE(}YP4BsCJ?G$+H+((C+;=K=>Rfy=t170Jk<}IZ zO;Rn=hsU&j;I8GqU0?$S0?D;Ye|cAb2P@=s z)axSr0kB_3IR+q7h|Xj!Jl!i+?+T@R>h2s9nHkwxUZQ5vmAzbEKkfc4Ud3^ak6x*`T(g2U;rjTwNfwAq1R=zu8;bLxw(VPR3P^W0WjpE;1aAywk!NaQ>MW5D zf;_o7mi=ELI*QSw5o4uHqjZ6e%+B4>$COtYElVjZvz6{YjF~R(%BV>0w^x58EhGN~ zY}+<wVuyVy_mL7;|0E0#+mYUeTTZO?cEKiyUHN_9kAI#aU~}9 zh^*C)0TIOec3gX^#LcbDVxf`_`{REvY}qlJ50)6o|6%Jt8HK4$;tv*I=r3HrRti-sq%9lN9QfaKdUl*zrD>a6G*(YF zbpcyA2l4H)PWAl;KeYU!Z|>;GoU?lRd{QH{Z*Nd;FzrqHPaCyJd#TUw+St$viP4ZL zN{)y=-KZXe7hF)uioW;Y`W?d`b`^tok32%aK3OgV@xzvxOYIl5M6wP(Z-lYXii}#P^7a!W1^2u*NEkdE8ceFFdsW?-= zfmbQ#PfGV5JHTuYSg!e){7BH31+*H)Of+pP2@LcZkeBVv&5EWkcUhz;Vz02?$zGfU z+;-_e#)(>1l^l6@Rh#`8E5tjFM5jBkTe%^uCts zT}bYl-^&81A?ac`ZQ}2hRMso(9rkA^|0|E2-CkRb%Ph#Lw?EFoaM6IPzn`MeNa{F& zl;rg;qC0Zz?5!+yrL}0#vBx((7foBMhDmT2#U9wL-%%>lkAg)Mw^%jCXXm+MyeW$r+881`zrW#Wf0_YhoSZ+y*~XTM`AB4h+~_SkNgDP0H1}?}2cb zcK`X&cak&(fIT9;ZN`Gt_lA6sqF)VaBB1wCWJ7Sdxy|{UGmkUU*66K~j<5>jq@1ET zQQ$QqqTyuEoz%gt*30N!T;wt{f4KIBm@!2#fFX$#>3u!g$fu;VuvA`!27nf-sPqM^ z?Ngw=kc?cF!gs4@JHIIE7G26KkE)QFr1xS-VK!+@ZhF4nWyihmEt#)+Z`D@>3gS}Ds%qDhNbMC zyjsZSPP_EGJ}rKhjiOUZxu<&L%6#e7Mtx@fWKNo{^VspYjgaB^#U4CQ%feX&ZdsMN zXu)OQWxeBo>gzE)JLbMKqAPuoKdU0MgVtDpWU&P2`68ulEAE7>F{0Nxxn{E9qojVY zc`4h|mR)*R&%41?;cL1g_d&{8C6}+{4c{6gI)F zj5fT<{(M5HyeTw6WLti$F4bpt^$>nR#?6?-6mgTd?sqBwXpxgcsQNm0lpN-0L)WN3 zi$G>!CZN=&ICh^i`K$;)fI0l7$wnctWE`OAGCz{R_cLng`ZLVM0I%~4~ z_BC!jd$8+7* zNanqrrAJm(dV`A4ZVu!EuXwlrEZLcMFKC&SkG9-fK94QtXk9y+Gmitp&moE8Xvmn#!gpkG->FyDcp|vo+~N3#D%QXz(*SzmpzW z60hwT3k`U3->_=B%&#M?Bw3zr$_t z4kUhj-3#LR&|RMUaA9a8pj)U=3Ni))b?pL*8SnHtt6TRF{&hYmf1_qS-WivX*9J+w zl5=}sq@bh$XG9MckkPZyld+?c@i||vSJ9To9PlSKu}ANu15_XifEVD3AtH}xBIL;l zIOi8Qc(%BvXo%bzJBoBiL?jDmEqLY;n%6aLn~zwZLvyKfky zy*ppvvR=$6P+FucLf7tbH)K(AZJcy%7(io}J&*TnKb6(B%LzB=$Dpl{4%=M&&jI9t zDPa8b4*Hj##^s|c_om-5ST&Yzk@C%*YMwiT{raV$e|7Ku#`TKpJz$Ja)Yo}u=5(r4 zcur-9^^Eew5K|fFsXldcOmEw5x8t7pV*?uT;WvID`G95XSP2n5+xt(#!==*>uHB#J zH=jPrM!sK)TYKOtds%dilJopQ&sL=4unaiE@6Y>s<1fssrzG7PkBR3QoI!qXi*QjY4fKd!5}GA~}WzoPPVeN0_siFEs`e$n&p|C&se+S?Vo zH-}T~kWn}7xOu@PzP=s3P{KJ~u`{@{_^P=omY{8!l1EnxiQ=bz2GMn^bjBE!6EFHe z+{Ldh(+sq~O)~~G`GnIg9F9*YrSE;0+sLWaaQTdW^~^3$XC0_VFS*X%DL(b!sX%G6 zIIHJDSZw()XEDhGRa?PA|27`8Sr1(wUe1~N{MuG~hb90t;wNqgu9hF6xGDeH6`6>_R;mS}rNAV?zDcn|De zX>XT!W*EvB0B$gn1Q0N+-xF>1GrZx_8LLsGX3BE@cZ#9m4UK$d=tSk|lb>$T&%5rb zzTUarx;742_Q-KYe)cs_w?TE>#o7;$DxzHz&E0D^y3Fsu9c!oH7v`Wqdyoaa9%1)- z1NF7Z(DKdd7M}ghw<*EcyLSJAZ?|x@xQ5OETOiH?uAL0>tB}>gxJPT@k(S3^cjPg; zKXq|(wQx-!Q0k^lxEWOEyx4>V#U4Y&FjW-CW-KjA{~ekr(8UO7+godpYLx_aUG?i3 z?Wzu3f4(f z(Lsws<+AM|>6y)z0>?P?XLpyvX*aDG3YaeY=PIt33yJdLkBSN=KO86u~@!(OU3lJS93}*BKgGqVGK0jy52CFb>)Xo)*vFECRxQZ=1o(lf>U^qjRE)Zc>#1QZ9hGi|qE3s_)lNj!jL0e&~J} z@nM{rJ*XCA9<0V{ba60f2dY#I;Xkj*=X62$X1M@EMdH_$kkzdAy0t&*{cM!^>=kT! z@5KW(9c`=WRjf|*#*AOtro;o&zOJ;?>aDbYcvdYX+5?~0kT+|wyS%#QshJ8XH>9pc zfX}DqGn%0(8YnKRW!V zf*lp-IQnkIY$ifgAjktPg+n9 z*2_fqe-CXL!}-Y#Z7GjOF}0oCeAQsufqF`V02{$l3eYHc#ucssIk;Vy=Pq% ze^nsPDi5qA4DRhkEjw=|k@||SSPCgz*jq3>gzvrRm+s&*UKD9w2D>R9j~btLfKn8+; zR-PNK%LW!NTw?k%%UVy6F^ZHdSW4cdK}cMWh-vDp>pNLVvzs?K#{YQK## z4{8>bPruZSJ-Zl=wuW{DouH^Vn(geANLxOI>9WWMn1KEpEl7{7~-=#a7$d-IpAkOPg;?o@VE4n|*1!&?!F><32CwWA{0E54BJL!C!P{9f?Vs*iI`=lCh@Y=fL=0|8Q>;n{gy_XWO8^JewA7l~fXo5XtG z3D!e5Se_GOb#oA^^HG%j^R}f~cZHb$UI6El$x65P1|(byR<6C%Y+JRY!@9{$RvXV& zx?>-+k?Chxv~>RFxfhzWb1w>>7)p1W&YXxEo2BUcp@(27!>K1790e5_){c(4-Mx&+ zs6XC(1&F}zZPiKQT}HqWMF*F-4ENM6#$eNv}HI%yE9b2U#7uxm}Mo1L&nE@Q!5u7lM>`LIDUjEseQgu;mPBp z$X9jD2dXHl9#HapM{+$zv}au~GYK#l>~^*PO=>rM3W?6pPZaUE5PmMTg|1w@;AWhK z0Hc0UPa&$mXu)O5rxewOp(L?sUeY#p(s^u2O!nhAHhogA!o7c)9pd>c+wMj|>86CL z^U8%>(+1&Nwl$(yEcBMwHhbuvxNqH!Su0q1mPg_$LHG`ZMq+DwSo&;pQO34zxSRGq z1!=z0RE%qmmq7;K*gsKzYw<0Tvp+iUv z%rDc4vVBf%pVvKt)cqLutPzL)!=U|9>!$#Yx~wjfDgoOH!1)B3{mNtI!wvl*x4nFb z*L~V&aD%5Z3-_0J`W9CO_yr(gK)iiRlkVgeFfUeMNZb&Ptb&u zkJ}0j^1aJsS8@}JwLArP0yFTMP-lsSKsP@-O1n()kWz6bpCSwYKj$yt(7i(9iTLmi zk2RMpI9pA|5jzK9hlu{#uHw&3*&+Lm-R*7A+Pjhq2ri0hWXy?W0&=8~Wh3!wK4wL< ze1A)WXZRZtj{i!cgQp*_NR>97Xudj_k<28R)4X;MAL9{wgmUUXr1;zFx52^n!FUTk zGIAwIH@Ej2U7zJG>t6HDp|Mh){wPhWyLBD=;WY5y%)$oZf1falkmF1#$hi+NE?V26 zh!}wy(PO&8^L1{@oP9K2Fhjr2_1uByg<*<7bk07J$PX&>~q0D$lt z@-d;TxJ*SIkH=`>04LFzU(#z&fhFsKWb}Jnl;?6a&yMoZkxk5HeJK zmGjb@)pzfXxe$i-)15q4z{??2Uz9wx)1l+7BIIVFI+ugXFHwV7rv&$vk(47M7O+j$$J7)WTM)Nqsy;6`Ou% zhex6gDj(u*MnW@b(;w3A-2q}Vrju!`)Ghx(VZYNZP*%rQPMk(# zBUr;?)cf|VaE8(Q2y~wT{X{j&!ri6-R%ld5{#xfZQq&X}8v6}dWuE$u#E6tR_IexArjlTogj@iiBRIYqvs?qrX(igjjaH4@)T_p}WDy4Yz) zTr1|lfEBKkT@0_imrl!J`F(8|KDM~!<}xwCyw>rG4hjb> zHqyB_uYCJ$Z7xaLEzz`mdD@Ad@?6IFNg~7(;7zxAkqr(>yoYd(=qV=2*M2G56{GJh zG-a=_MK4!91dV@Ixmjggwn<9)ANc)Sfazw&Zl+{$?$Zzzs+6S9rWf^nLA|z}^bPFd z*u0&_@$=_^Q!t)Gy6dc2a|(&Z2bk@;%g|Fkv3uh1Gqefd90p0W+mXGyrvYk7|D0E- zN)GzPIWNZgt_-~cZe*gxEsGAQ_0ZJ1l9qOYlzz7?dN7mm^(s>PyD;;mMEW&0wo=#6 z`e*e)dt43z7p9@|f?^f9TLKo(4egc5{pAEqP4~F9$z)V0sx|0+2+27i$1%0hDOx8B zR&)E;_lm1xbx4sioUMFX|C0*~?FK|IKR`OW#TWBjfcRIRgy`>;A#K3_5r5|$m0VU9 zF16IX{)-ZO+Caktnx_d=bA`hM2U~jqug7GFkv*RSqkkl?soY#xAJ4u(3cR~nt==+x zde`|8Jv|y$(1u@|SV(`VeN}ArKIfL3$K`1vF;$l>pLSM$)`t)o_CI)5AB&5^v1voT98T{ST$ed?k6!J&uiZBCH7h z$oMhF6lT-yh5`mjaKj?5UY-!A>t7?f;>KD{gngmdAzIJaj~_pF>n%LrD0k-a`^CGl zJ?gMEgTG=2Jf_&AyoP>A4qo>y8NCJ^i7$p2X>9nT@0MQwgsZQw zPhi(ZsAjI>_V%~D9=oN$#{kOM|8TkhM?42zDBP>b!FJ%GP=_?&jUu`*$cP zA2EAQa;s%|xXv^FvRc?1ws2oebpmaJC1g(02`-C!Qa9Zq#^#9cd_o_;4!z1q_f{d? zMc;e>u@(~=7KF{v{wboDRZ--cCmJvsh`|;CYn?%qnv^Vpe<(T^pgnl{HqYhEHIzWB zeM&G1p4VNx@D zpZQbpoBQ3yPJfn-0%(>WwtgT*@|taisHZuxVmCx8o&sha1=j)N0WKpMKAq*c4Jf$- zx%%LV%kQrH!j15Jj6)3bsWmDwdK%9b$&|B{hG?9~aLXP*xfQ@QkoR-{-ZOZg2KmM} zXZiE8DGB9u=r$;Q@Af21fR6I?`vY~o!?T`FF)<#clC-(c-}nJ~hN&0g7Ut~=axdNM z-i?wE;%U4UrG-dzImRmmYA-p_Zj-{>YXEgYk*GI?muo-d_-FC9^!O~h(0|a^H?SXY zFyHg}YYmjF#fDR96=f~|b{@jh=+gB;TQuZ?Q>R1Q#UC>-#ZWXac{~{o8uDU2AoVFa z57Em+||Lr|TPvU++(&pD{ zk6*;tI<9vYDqNxm4gx=*8X32LKj8oTkz^~hfSR_{r0SKWu&lAvlO(cb*Z8LxX3s6`nmyI-Tp$qGkvVvGea zr?aZcW#xyyhk3##I5NvJoa=P8`Tk;Rr_@HJX=tk4zP}m*Pz`;Et z2>=P8+!e&v7N~SK{9JbLNVm%|r;yu?DO&u$dXTTyY#Ikwup+xN@YgQpDGo(~Wnkg5 z+QjCzk_sVH1sm*CQ)XDP0#$Z26oULd3s4lBZ3V`nAp z>Q8q0LrEjmbu&vD)_O~7#LlhQqlif0M&(OJ%u5wF<+ng-0B28BwY+dEt*X5BP}V8%=+}FsJIU(uny!Rgj%^D$?ez?M!rXV;Oo{Ny2!W4KyQum-QhRj zvN%x9>oU*cJ(M1`f=Z&Wh`XChjSsR%i#$7js>a+}QtYoxO@zPpXP|UF zC_TQi{qHLFp#8$1S~Jw23te%X)H~OH7yYAgB%9$dWiisgCiU{b+`|#R3pMo59Z-FM zN+rSzcjDdlO4Z&aB+36#rS5Y{tml6>Zz$h0^#Y3}1AgSVs0);Gum_IoEEm%!Hzs$s zc@XQ~9XV=sioZH+2R@?E5VPP}u;e~G6ZyNu7MmxY)wwzlIZ|>)K93{&21RO0wr$)X zS4tR%soFYGya#bZY%`zFam~!N(BmYceyVVF=QEL5JdB#9jb%Y?>PyMGKl+egpclB4 zz?jXn@RYXntX@bX#-3)pW;?qUGh6iL1LvBi$excU_kv|-q>sv>UqRj^Rg|&v+C80^ zN^~DmAVr)X8f>p|VCYq)+J*@Si-A2J+xeB2|5RP~yLecDz|Qj_yG{%?v&SLB(-!*~ z<(c6MeB~@%6)sfh2$~@RQ6SogX zqSwD8KrK*bXL;S1P4nzS|SkY2u4t0S#UJaHnEocV+{6CAL?tQ6SKTX5Qo@rHV$G zYdjvM1aj}P9*_KJ`2+ATlzFr7wItl0_rVK+!y|t9VBKrBgQj1QtC#@z^KX9`oHkBi z`H`o`AB>ozqob{ag=^(OF!tr>z9)It57(g})IL#vMIxi}N?7~%m-@XeJ;+{}-y6Xf z6iEOa_c{^`F2aAUaP2uh@qfla^kZ@*eKYI#S&EHGpPD1JlNyx1^t$mVMDJbr0C$nh zAoE~3cDww4W`em8tSd;c_H=|z=r|4itQ|v$>-P?*j)Sr*ZRGw_W0KbuJiKpGKIGBVojZkDv+MY(>j0e>$hO%ZPB9(_@OEj0aQq2H=q_{nGB(IO%oLyL+G!t zkALY0h>H6y205AzZ6?P`g@0KKSvd^R9`V`UzCw!3i}d(oyOBLzz!1>c5H89T5tl_` zD9iud`7h^~c>{{IwfpexwRLSr1ZxAWWEJzP8wUn|!EOK-Z#;Ady59Bk5iinm>1>f- z_<`Wdf2jXXF|q6Jh?2_zG2+iQYPJf%4i{W_tRp&x)DHgoc>eI2=-PYd$lD@)0PBTE z5PuL%65aHS&P4>BcKb6UI7$>pLLCdJdFkjfTsFBwXK^OVG(r75VgTOO2CD7dwOn%K z_GCbG>v=2(JIsq6GkFVVdDAUaslH1C{tEkiVr83qJo>kq&i=Lv^m?gUPsp9IezCPe zvGw!#UtfT_x`nqt9tym+^xIfzu4ccdA@XZqqD?HK7adE3@kBKD z5qkum+}Zk3v=>f_oOgAfR4G1=c$o|g9D_Xe4X=oz(LZIl7;}hj*} z6OizOD%vd$lSVQYP6B6>`~C(zcqb+&=s-r-v0Puk?1|C4X86+g+=O;Z68Zct6R^rxn*jtx) z?EGQZA7QX%&c(^+-w_$s3LTCAtp?sU_*E3~Zd{T-0}NJxi=|3`0af?^VgNmZLy0{z z959X!`2$|g{O&wPB$&^=5IUS-m>*NSb#4C-7vP6V$)`i5y{9a1RwDb`xMwTwBx0n+ znfhmDIG8&kSkNH^wsIOOHo!>!B?R}vpzA~^OAZ#<+cPFcG&E<)xg=|AfGF@uPK=5l z06$;|99CV(6?T)cFYP&NqL-0Pp?Q5Set0ZwjCL;yEB~}w-SXc(J8S1APvLYtd6C6Z zp|d~7kb}D82sz2d0a}VlOwQTK?ymO0uA(WJRdhI**l%e`eloxJa-RSb8Vt@{Q<#eW|5%dm~})BI8fjqPU$W%$RZ&v=h@n2$XZ*^@Y! z+xvjN4B?ql zFZF|h(@-RNjO=^D8+0j!V%-Qhj99K&VF%TNqSHsR5U~U61JnvQtSwVr{Z|P{e0z)m zFKLHA2H7@SFjYoZMu^AfSH`5`C=ksYwgP@%qeGk;%kc}>m%RE2%~XMFgO=AoOfyE}CzDADl!+S|{k$4gE)#&Q8U>g2_W> zbf)k^ABgl3ljQK!h|EH&V&3XqtJT*!|Fy@~LJ785t;zcPe zjShVQhbr{C{2A1wZ?eC&Tf4)a@`^I%_C+L~&Qxt5jS1wD1x+T+?d|ekjQrbZ=2r5G z&i~ZCfUGusWiR^QMe>^O`wC??%w04PAn9lZDv7FG2AJZ@KG^{@c}K_}O66PlcioVV zB~U&{9m_h0QpwuHd|_DEG%f3Ym&j)(6Wc|w54??kITaEX4qj3(-o~|Rz}@nnuvH6G z^~F`;qgvLuE535|`D*)tiGroCNfDS5|9%btdX$Vfqf;u2y9uOy($j5MPnK*|4w9o! zr^EQ+S<0iAoVX)Ucd&RF`qsP7XSsJGog*E#P_EgdAQ=9}TVK2y(=*djxK&xLmvWyn z=80X|5k#V=GPTzp4pRF8D8j(BTY=w|`MA*unKOhNlCkBs#2DFCR5c&|pcjMe{mM^m zK72m@SwPG0pDlr1(N@&CK)I6G)wT?L7!PyuEWC03^#~&Vg$UW}&}=}3SC^G=5`|l=Ox4(2? z$Eu(4jhp-)kD3e+tk}vO{9E4K{ubC714?WZ^EDgBU_k@D(J4TfziZOwm%!bO9q-vF zV7azwP5yFx-j2C<;3gk2LiI7EVU*eW*}ws4&Aq!oc0L?r)De^iyoYp*8k%SCWPL+h zhL3+=!UQ&5wpuB#yswc-L|&Kb`4uDaJ3stCkV38hD(6KMJ3(8%?_>Fyu20Iy$cJRc zVi2PGnf1oL0Xe5=5JOy&OxVHbl)5VFC%mo$42sTx0t-^fx-Y~-^y`q$8Lpr%wIM*L zufBUxna3N5t8e;3R-QzD__K|YNK_F{-xOigR&0;^Y*6hH4Om=Q7w;nT=FSPaperAQ zEUjh_j2EiwM{g`tzV~eBmP{P1U~j?OE*!C*s&XQah!uN;31ZYMh%*0C{A`H9+uQpL z(UneFEb>{!p!QE=W7Ur^L!M04s`j5dq<{Rr7K{J>DWo{x?qJjKFtV(fG0DzjlE2+% zbz_xZ#)p2L!6>i!*wJp~etpy@Jh&2tPvL9|?1|2tFq?)CErg$=b$V#`k^JizVdD;U ztoA8l#G6_k=He^&v>kYy4)Yy_x_q`!Hny%T)(KM>R;^$5I@k1_jLE8|XMS|EV$WTZ5x~4I2O^ypFwgIA-if7*EGNA?EV?wOZ4Gf z_%|H0js4u31#0bL-csx`xWW_0D4P4!UMvMG zXkm*=4my$?X}3nyT4^3IqL?t*{X`|9#hxf3qJ5_54>2On0n+N5Q9~7GUw$yjt+mYM z<%FiN4$D@0ik+92dp@O%NUl6ZZn!W)>0;CDW>??g@Z}gif^gn4c$Q+M$*ZxFtC2Ko z17BqE3P7LM&TY5d6cREz@wo{ideVDY1cUfWzWwwT)!)`?(`s?{OYAN0VrD|AuU(6P zNJ}kp$`zqs{WE-ym|!`_izZ0-7({sPq8ivMJz@HDY4n;c>4Df^s*7L8R$h!Rz9>C{ ze4g}oij)(Jn3T z8WV^N1Ag3&Ia^F^lNI!E(XE&ii9)Wf&fW~;8=gW7GYC9by+^EaJ)JAY&*yngC~+tL zv6p+G8_MR@Jh}9?fP-pS7bbMAPr!RWHpP5Q%jZgc-qy9kv;OTEXVEK9`Y)u2*N-6T zFnmyMoDxFDo)Sex#tIMnlDCnh{%DKL;8$tw@y7iq?Xsf+A$)yS&_DKte|CAj;1qJt zkB*$`kq-DA_*g?I-lWG{v4wl)U0I~tJa^f^O`N2{OTTAiOf8nd_4#>hq@SCXnW$ww zEHFv^2XI$mTYY^q#$H0QLhM0 z0scFXJ(1CE1)n%vz_~%w(ElfQ%-J=zsD{^+B(Ga7oAo#ii71Uq4QHncoAEZtG7`PtO#~`DuJgEF`bjLd2)l zXyvU2gn`q7CBASOXWCw*HpXx(*yY6LvP{Ya$4Ky8HdYIB8__2tYG3bV!n!$J87r;x zOU&ah9Ra)iqRK1HctVP2a{34$iqs9M-=gH|CT&d4-_`GBi>q&B2U(FzQ^08|DDbfhdM#UKWfK=%GLpn{vN&{L+lB& zTpv^&TPDA7!ZwXw2pj{nKRn`7n#qMWRIFy52_2dW0UU!KfoLx;U|l2qn-JGgv!0>$SW_{Dq3g0RLt%{=ylz86@JG>^YV+KT9~;b z^yoauh>%5RQpd$Ok0rKN?c4Hi)g;jmk+2;|aPW`J?omiY2V;HbQyYsWkh)pnN*l-{d(-hP#TR?an-K>3Xp3Zh4DQeG~7u4oEP`9zYxInt)t z9N^g;@iw{!iha&T$OY~`bLw-Y;Z1#i&D@(>#gX%acOgm9Q*?L%p`VIACKn1r)OI%vs-|!J{%z#b94DBvr_Qc~WxoR>&Fz(B-0r)Oo__ z`pvgZPD3|32}hoW?O6 zQtf*I}1lcph2s!pYgp4T)*R5ADs~m-jRvFQyN3X4;G3L{A$QW}0J1dvjW`9Iq9-IhyZOm7tGw{cx^iF{n zPYpGAMiSVn*VRicr;+`C)-Y*+1QHOOv?TLbB5dM}={$D~02cO7`)7GwLkSe$Vrh9X z-;m$$euMg<6)h1H|E&hlE9w%2K7y@9#n5bHRRz`U;qwUjx6_kk|*QmR1 z&|_!L1A?5f09jsgL0-K*(N!@Qn>T3DKygpZ^#+tqvvgsk2FZsl6Ikg6JFFCbHBUZb5*4qA1#9kO= zx8v)>+a!`OAsDyXi`0fvHHFQRu>c=AfN9>QuEPesarGpw&PD{39X>k%8HU1-P^unw zcV76LpfN&LL|1y6#j#X~iZtArmy!h)naaUwnVTh<(gGaFBkR0tm+u9*L)k|W2LFDw zfV&?R;l{zWi0ET&6a=V#>&Kt-M7>h|77TY8vip>Ogc?OFfbfP-$?70StnF#2FJJQo z%kx7wIG@i41reM6kGC)X%<_)=x1+U2?U!dE&u;%}#NOc*=jhc65GVX)N7~e($a|R0 z!wz)<2I3%!b?K_wHcmq5CHeb@>g$-4wURWcCC1loo)g^wAOGexr>khl`uM)fe37)N zk&H+}hhHBFz0qCOhN_y5uKm0?wFUE2#mKt%*aMFc@5q(NFzK@lnG zZV72g$-PAdR6^;-qPsgp1ZkxkBoDQbZuU2p&-?v2*L9A^wbz<+j=aY`#>}Wkvw`oB z_V2y~eQL2NTaA#oiu{}#F)1eI%}A+)?Ba%$;T2TQZ(Lvs7n3juONYrC8l6%V@-RQYneXv!V|h@dG}`?-^Hm0#~wOiyW^ z;G4lCeeLS8RS$H#M;Y87<8|%_=4i%9P znU1<2P~3Ws%|7`4U&gPDE_AzF-=IbAk#|)rZDZkF&4D5d!-<*O@Rw!M8y0?`zr3x* z51UN&PWc(V*np%k5-1;Hx%}$A&2Wd1C|R~64T&-&c#ROWS!G(?PQ>226uo@sc`hD9 zh?Hf0Qy@3h>9Ma}=E+}vCi19V0Y!uBKMGGLwkFo!M0i2S8DjL`Jli7i^>Kt;sZ1-r zqI?hXXX9(_h*z@BRWj3?h;aN#8D#*fy-R7eJ_mY4?~`~54y*qPYnNn z)3cm8R7EWo*&`q!H7FlIa(MSinI1{k);V&-o4ok}pGcs2a8-<3gXGQm;M?FD>OThQ z*8inBHZkHL3O9GpmHfMe*9-6Mt7>|9)>PL)HgtGt1U-zP1ic$=g{XU&EIUt({FR1q zMc2lIU(heDq{40mzJ(Ua_H^pAz^VA1QV{!d&i%pX!sb~Nv8w0Bxs*8#A{4$>9C^`Q zOMJj5Fn1p=*;-vHrQbc8@7fiY(`oS`j-!~S86rV^*-Ri(k$Od4VnxP2Fd6Mnw?&Ad z;E|E5XsHRSCh^7mWWs+<_}cmY^7T0Z+)Vtn!|xIh>^|Tz5P$~y8&d#dDST!>3BjO z1dE5*s3npbO+T<-3Po3Fc+-Fwc0=aKE#x(&*eO=rA|R9R38eH@50ie)A>Flh-aRid zw&Yjk*$5DmJV(z0efwy%+O>^H@eGZ1N_VcEyMhQ`fH|J8v@O+0LQlM!Xi66QmxId+ z;2Kfj^}1Ni(QsWrRX(NI+NsW*f8UPC`q@ZZIb)Uk9LzQ@>{^b>T|hmjqxxaCU){Fd z2uohG=wFf((odX+2I$uhy6~x0U+gr{2UbQ}w=euv{LDM4pvTBe2=za zUXt6T&G` zINC`(aR2)3pPV?2e|8mY{b-P+d6?}sH=QA2fJU8J^1jzT6ae1Bv@4&5(PR0EPs^u5 zTt5M*u2B>6gXQnUZn%yqES)>NE6Ey)?_Z%QuZ}{WJlbakmLd;eYu?V$uNfpDQwJyz z1e8xUr=As7{j>1z8HZ>E6~)X@rpfzEWi~J)ty^wx-1wp8=y2n^;i7V}l$6;P!$V+hv0HTA^T#V5y^p zSdDbdoIv~i9GBSrIuetf4{{fNCr6-_$(>k;M7X-O&&X4q$x$7R0C?=yfd#?B(2##f z|LszASpKvlT9w0oH#fR4N;~1V4r!x*K}~(ZDUSizv6oR zig65r1hVQaGE^@iSB)*?XalI4fw-gm)hwPmp|$TKB%)9S`k{KJ=MK}>HQZ{*^H|9g zh7>NV`}Hd7xfTfan;hT`Kli?%w$W7KIO5)Hy!2~A>x`m%dgXAsPuXn(KQ(EmD&`#ed58DVm=CAugj)WD3@1A~5DX^5) zJJt=H14^sot>&MF9OxQvH9;-mbz0YVVl04Y*)umK2&8C?k;z9vdUS)d^^$0Bkk;~T z*ntQ>39Xy+p|`=Y2CBxU=&*^q1%Y6E%q)pqTmcB<1t5B2>lcu(1aL)YV$uL%JmGHW z2*RVjk!t`UJVKFjX|(x_)Suc+MqQ3>*d|=_=Xu>=~v8%X^>kfw@Pjs->+xbblXg~ z<}~u9j(cq+-U$&MLo2P<(i({Wr^V9VOf-rk{;Y3(*ZPMPJ>Mk4zf%^6$So_}xM$Do(Jkj{jHlSz%{pcH zP;*4JicIDfgwyxSI8ZiCpyL^PF-`DH@XJ&XiBpB0QT5C$(-0!tdL3ga3c@7{KZ+i}X%J=UYkcZVg{(G^phGdyH?inI z02w@<^6xmcU|(t)z^i9uwm{`?xn?I;dkWzZW*PU$ghMIk%yVK9@aszaFj%({87z9Z zr(HMDXc6=?{i^4A9XSBOwtFW(RS1C;ZA+`01Li{GMS6018WLbtpisCBQs zT}*2XGaiyls~gUXW)Cwr=n@2`w7N)tZiIO{>Vun^j zw{{3^1hvG)i-Da~einJ*xF6byqLQS}EEBGk9Py|Pu%CYCD;{~4x^zEL0JE`U28<^D z728aOPWgo^y61Vk^^8V10AYqb9R-}&W~N#NO~_2xy!3M|3#`vLJqxb(~Y~itOM`mwqxS&!(l3 zp7Qo6i^BWL%|c>VKmK&+_ZoUbf0hgQVjbKLkcQvlSu4IBd5sUHIWV-Nss->g%J&`I z6@%=OMlKe2j$~u)B@HrY+wY9>yKFWj%cD=fc(z!#E&~Ddr_SA$iqV5m>|i~DT!+cn z$#m__=d6)@T!kz5V4~Z^WEi$SL$^w+Bk}-5^K_7;$LB|(bSRmYf*A!(W?+^b`o6j} zxxQr7#8FQ=ig;f&8s1$rmaxnh5_YwWvM3>2cgA7?rPalcLU(T9`Lv@Yr~|@YO$8+< zvA0bvO8Pq-IVb;|pN?bov6|7Umy;PPK@Pt9wmYmVCp=W zWhxvRTDgLlMw;u~S;cUn1mxdi!#OJs4qyYRDU+#$(r5AA6vT*P79vEps$ou(|_r!&lM+tY&A=|m* zRoAa`zR0tt{$YoZe&zG^OhRW>gCDxr9y{3^D=7|I{P}0<9xk_%Nr=vu5iq=8<_hRM zbdP#*LMmH$BW<2d;`K-!h49rRe51<=(}$Mw14jPq9?~?(^08xcA@oOeJ(jpk8sXZN z9hnx&Elt!3!CA&;3@@rFcQyH)U(Fem{e+DO1bXRk8t~$zf*w9p{4a0Ucs@XSZ}gMI zL2I};SDJNT@);r-OSOQ~+9ude+O|TMZ)4Fdg*wpGh@dd9flJq{*ojL78pq@00$MmB zIL!~@T<)QatB)nze@^U$ZFEPS+j4#(r30mHa5}f|^Su?A&jjWZJbxR%Z>C=O5ggR# z_GV>Ag}1-tI^_%nd%Nh?k@}@A^8MJCQXe6B=2Rw>s!u$4_bwtP@(HQ}#<(Dv#2>!g zq&&*W0ke2g&SZfZ=e6tS5E$IHMxWbQew|YkIgwITqNis#1W%|i^Rmm$9}b*EUrXTD zi81<#y-ZNH)u*^<1=Syrz-X%ZvE5MDyt7*y0nQt0n9lNqN)vAh3W`x;tZ|Ij%DrIG zr=L;xh7F2Q`|L5m1z_>5;{9hK_bKm)Tv*R!I_tr*X|m!QmJogCYa+=Dso~wjJ6mqs zaJmr%9P-hlUatXA1qLtHq)^1RaFwrt{H z*HMC=^i|UKHM`?xVo+SDusXRc)`3|jM0gZfyyvMdDsiJqRQzW(IXx|B#D&=OA;xIJ z?EBuK$ywNiQZxz-a1hQTAZl1_mP9cO*F!p%EEFt(ncx(&NNGnmaV2kTjfzfYrbguOY@wgWPy;UgWZH zq}6hzYek>58Z>?Q@O;)|$~!~TPHaqPm&WH!=zpiqq*RNK4j}$*JtKJ~%DgY`JEFU1 zR`;wL{R#%os-X%TAn>=@`occ5v2J{tsOyTPc(kk>ffRLHVoaX%@xeVfUMG49 z;cVFg!k1AoA2xTSs+FXOksN`Jx-*SS$oD?=-|2~~g$yUZO$R#vx7eH;-L?YrPm$dd zkoPd1Gy1+`Mbwu&E2>fTf#lP57mhYnOV^R37teFBWC)v<7OtH-cIZmrzzKhw*_+S_ zB^5EfcpiC`#)olB`Ugh6xV7``s15SGrYAwIwj(7LTK5?Y*^SSYcG4yu$$d0DLmg70 zoTuq-gGOl;5Ta=g4MD>Vf=KXzAJ}hQK^dtLOZE%h|7S;9*gB4dALm`nC&03c;1;B6 zF7ePpoVUNb779YtsuPvcMqjOqmVwj|hB>CM6|S?%dEp(`@}>1A^EJgQ@6{yMfEbu9 zpUQ0}+|ngD;L<6|UcX!Qy%T3cdZumFrx`4sl&V`HI_^;CQYbMI63(@EbUr2YCl4Iq z-#;&*QB^9aKy;;6u?w?q_0f>qm=K$qn%bXTFm!NY%d;MuP7Adnvk0By$sE-$D6{u` z*1H6r4I5MP-`tP5XA8DyFy^I+>mL_@X?PT7fXQmgFOv2yopec5e`L6L^@X>%v9LsW z@+r=H)1yZEU#Es{!j4F_vnGkF&g0i13<{*Am#8mby2s7RGTSFrYbXV**MpJgvNjN zGw^!kaZRbG2L#WS`lM%IQ*}}8g_l9GKzG0KtgX~Z+EU8Z-vcu<>$x%~WewVvU~?(>gELevxDRqM<^lcR z6v|xHxtQ%s|EiA!*z`XNj*FFbzKU`pw&ibsEkN|zDv5!%72aEU*~V#KlcehGA2+3C zoMh!Dns$Bh>A%&5fdGs?#Hzf^mfpEhVor%1ZK!%tuGTNIU8{Ke_+awI&i|5A-djxE zd#m4`k9{OVbZzu}f86D6Xj%7~_)s>1s=h@l44p5A(1 zvMe# zd0<#z0|mDHuH2b5>I8p7U5s5dLse{wN{PEaGE~29MV)5~#s>i&z{{2+Jl$bj&gAYPN!!4Ok}p5>d@dAv)L{YD)>;O@?2BsnOWIXJd}Lxa~& zhPrc;LV$bwYOm451vS-YKhm+e{@%DFWOHMc|W$YFP#q$XS@6E-I1>{9`&fJ*51f7LZhLe zc(7QBJ9spzrk>w=zSWsGff~ZOK=)&b!BvxU+gJG`2OMCWXkAuaTJlvxO2NuF(MT=L zkB2QMQ`IQGgUcAwQR~YuG6Wn(VIF}gVM?4m0?OlzReb*iq|~eAcv%FGwvR!&1!a{`cyfJUd8ATOl*@uizU!_iD<=?}!RZIA!qW868kc(c{1U zCqiz2n0*33p@(6>A90z`*|9o^*F(SQF+@-O0~6H-C{Rl!6}B1wqwZIydl?!9zf}&| zaVc}HV%j1;sJZ8QZ#+?mHT0(Lt3=K``|jKwcfi3I<$y3^?|r;P<1>n0LqNg52Ln3V zmdc*3hvpX?<>bIArdJpGojv`nrH-nS086{p`JUq`LcCOh!9aQk$on{vu!tE2$5No+0R-Og7S!8p zOESyqLBRsm^ z->WQmQqjD_-IEX~J_BM(Kbs5-Ue$^OaVlTgd9{9oU~(`PoLwfegXplg;4X{-I8_*^ zhDZyVDxGROri^mKXy?MA{gco@=W)8$ouYvCj<}s=Bl_gHzemSOzV?JtgA2nG8BZ_6 zP!9sy23)ZX5X#icQZzx@Kq%`!MqCrs6slY2Wcph0hrXdJTu40ApY8xc3V(udVgyW#|O**=~n{|ZF}-fzZce}PE#j;5ReA;6;b8Wkh2y?B@b z2XlJ8TaqHHO7@s=O8z=~YG)+h_tLlSkR3%nkKdBKj!~{Z2XJFv{uz#jhz|Rn*>jwI z1!dP@oFYQZKOHtyxwfY_>r@3l8}NgdzTrii3I2Zi1Yd+Qf$(k;ki8P2${X~O(hV46 ztKNr%7nRt-#nAq~ir;#hgdd-P+_K(;ZeuI&zlJLAaC5$AF{j9~t?g2Lc{eQ4dssk6 z!!}eaN38Y6!tU+Awwf~ZHX8rxXHGnRnfg5>aP0Ud`+QOd6dLN>TRmg0L#t0nN*`su zfQHNOa1{yRm{%oQzK1th@H||YM}Oi^ueH=Yu|OEw><^SLte)95J1VmA*uK*+eriJe zzLuo#ONdNBuo>dNr?y=ye}qCaAZqE`xf#9tmII&yPg)LEEyf4l2Zgowr;Y`;q>j@I z$DK-xTCm~9KzWJhoAniSYI+9fpbXwtAdqQbDhzwLX5{XWVs?_&*{>auOy8EZ zEaS&zEAy?5H(hIv7Pu3iC`3_OT3x6D@B#Q_>R&%SzHF}Stg7Q0z2SpQA3NEWJ-HvWr03vo{w_vV6S~=Zw%4mxsZ1 z9d1VW1_K_bKS-uLHo{E1%__5^6J&nE;9uqF@wEQ9OW@v~MVYrSFHM2{S7aWa7(9*L zPxNws655u*yLDVI1^9LbpaUSIyFU_f{T+GU^6zTh63|5&Pdzo??=M_s`@+}*Q)r|6 zLVe&Gq*bW*-f}k`AKzd1G?NbwJ_`V53C~I>^8`Kh&odL42NK*>jW=#XnaIF<^?c%9 z(Z=(8&Orf)XR0Bc6*7?q0vz1+6u++mQK+K%Q(4p`!G*T41!^R6|LQj9@!Fy zMEIu0tCap>P4nPR%|FFA;Gu~J^rD&-7dDFbQi1_b0WAtV?-nf`J?5UGRK20@9~5|N zb^Iu`U#z6nh4>?Y2CKCz2b~{!En(`|X+&=2wc5LWYI`JP@dv$FRxOtqKKO+6ZB*P> zzOS-Ev;>P*VGt3zkJ_#dGY49knA|y~n*AaS1cZ!oU=+0;E%FQ*dxD^u3#}hY*Bb$x z1@6fZI!?)Sk7rJd6|8fitTgx`O54VS^JB-qcLX4-K!=EW9Z4E$T897L;GATzOgKtQ zz1m=M6cwo%GY*rHChYDI35P)==8^G%azsMBDNKnB+ga61tsCDLE+ayyBVG&9Wu3t| z#{zBwvjl%Z6=|#J8UFKlry*<%kY+^Vc5up3Ph4K|PO~G7drocZI?*rl`+NFxv@osF ztTzT4;zRldCdw62uBI9ygIM~hX^9o9M<4!q1kzVvcsOqJO_qEp|A!ZO zZ0R+!W4oRIkRZfrZ*@Xt%pytu%}))_W$mM$Va)IUSyhTAsCoUjeQ{y{KrJx${@E5j zk&yN@xDYce^sorHt}Y$ESRilttA>zU<=BoH@#OsHUplPWuXWRQuUeu+v&^a~r3jp& z^xUJM9w1p}rse2eq{qSJe1`V+a+gx@Oq&04p%Y|nW&;x0`*yAnU&yKc*_?VSZo}sL zq*D5H_(kw3amk)}3&h3@Q2zO{;$R1Db!6{=+PGI&Eh8l6{w}OA9L6P)62i#G%BfE& zkY5DMr06U^c(cEvyV+ln>rOT?6)nQEm;w zj4@6FxiC+d{b*8rLQ2*Bc&1@TK^7s*7*qc;TZcg}q@Vx{t@2NWp3B;5E;vf^!lW-^b)RgI^AlteCWW-2x8TkPz7_b;oqM5Ke|hV|LwL`HLa>I{{2) z&PtC0oIYMUSXX!$%ml^5PQ~A70Beb#KbdVM-D@>oWt4XmlqPt+dehab!E~dJuwhZu zSI=N%JmFM@kUPH%W2`+vNNQe{vbfzCo2X4DOmQ?GU9bn{&WJSfI-C3o$HTO&l@ zvY9qqdd`$(8lx9>Fnmm^UQ<~yP=jeL!nfS-8M=1t*ObNMcB}Js2^i#9UoX`0!JxwF zql2gn)X$SKd|Xzl>O36s*q`&7(CDX*A|m|F2%0!>v|>}a_(76mq+;?T9;0KVOGEjhWb zaH5toIl2##VvKk0^G?Js$uRX@aPjT zWK>ys{?<#qiC`k?%B1NfYXPmLpaL#_o^~@4=fhFbWQ5I!~I`Cl(Z5FIK!b^Tf z7tbCjlzFRYlOr&yed%=C#j!!nfjHC3lhhBDy+WZajUR}gu)dGLl!ba?wuOO&)&UgV zOe||)K9cNvaV{`c_*=gL1(}PkXn4If>z~rF(>ju_v^`cL@oEjZ4z%wRX zCoU!HT8&}a;Uw9QG`OXK;ND!KQOzg#0O(@(Zuz;F(j~ZJ{k+?y`NOLXMCutX;@q8h zJ%{NvwLq%b)s#fonwU`KsoCu=jf=AF;lxUc z`CJpw;J2PLM~%&OAWW{eo-UqDHJc5DDf6;bvkTMpWTgBM?m(ecX+YAeh&fT@zMHHz zeJcTaN!8}B`Fx0JC+JH*kD0_ z67YmAH~wN4`9*=T+wTLlVSK(`rQ>Fhztgo-fjd*m6Jde*?{(sGP_N%@ z)|3u?Y`QkOFm%l1W{$8y8h)3S(_>dR7%HGqoT|A!$hSV-kxUXWTWDtiMC}6mF$Ky( z%h{M#mjKBd=5RsQOwep%2WOdwxS=o24b#nH*DR&SXE7uU67`nvUg@ney0ju+rSa}_lR;Ix9Fy9~( zOq(;R3nUbqNr=~7B7H3e|iJc%cX6k85e4R+((&=OAukaC8W_18$q z)4mi)?tum4R+u4wq?Ex=b&GiEJ^d>IOBw+~>4q8%5@#^8Wig zVFQ&1jP&)m)NUA_rtO?k2N zR&KVgnn;67v+=**ZB14k>?_ZL3DtD<#u~Yqk6R8^TBlT$>anWps_Jgr>K#?~pJ=%P ztc5iBNTp<)Dh%R^Twdfpx5`jDK3-_Ol57JLOi8aAX{TMrdBP|aNA=fy502HohxlYE zx|2O<%t78ik>`A9W0zsC#7}pEOcSIYynmjP<=@#eWDmd#NbL6sOy z!nAk16WAGk?UYsp!4YN3mrn+GfvsjSR$>!QADIUu$Kr|^Vcw~F#5bojk%#NS33_2e zUutdR{A)Gqq5q>yOr}3*zqW^`aTlmIsWi*K@$4j)@dt|q zbEzA@+h4VdlnaZ^_P^TOZdw#QX5c94D_Q&!Ao(lc9GBKnDO}7MXaWd4+LOU~xcID< z13rmRruZU8Kess#gU-xTmlKhz0S6P#bbpjQ^1~ej8i1G&&6k$+a(TuG$nJwrz;CwH z-SUy~hxmm}Jva9k$qr{vW}Wxf@sMlq`vj0_Tu_SrDx%dj5V4Wk23)E8ky6i}j`n>_ zR>r@n)T;uAA}eq_BX`cu$F9dURn-56DG8EsQ?;imzVa&YyPms|-{^j&#=MZljZurb zSb)EB!X(WZlctF`e=XrXDX!sD2!pskKmOfL8Ryk;4{dHZ&o|U{l9UQ+vlAT0um5q8 zP6}u4Mi43A)AXJ@UO%F&kh?FF>=7jXtRZV;V$i8@f!sK~^C0=%R^*5>U_~-1!-@jB z2fb`L9!`;HFxq*SNS^+~Cx9hT-~e>$C(QniG&~rR+?+a>1XwSb6_7X$N4NK*iWJ<* zG-S>pts$&e3tVUW$Dp1?d9?as5V)~h9p)2#kj#RyQOR*LE9sZ0(WRFxP(3IuG(w1@ zRKhY^;F16+(msV=mhAo$eyID~-};P?O6!8*mBMVm<`i=4A5@8-n9w(=G*7>AoHi8m zV_I|Nx#d;8%$uf=_4T_;9KQf6AM7jdpL!nSt!eflF^Yhn933dWC$d0tFTE;7UNU)2 z?VrM*AhTLtyC5-o+#eO_OJmT8f5I;6Fg)7Pm1p#4>pA?0wBY>Wp6>eJ5*QI1qgIi5 z?`o1!8Zhl1&n}+6#!mh6tp%0M@M}I4q5j9|BncEbXXIAbFIEBRBo7K6uv#j_?zK!v z>X=oU3&Ztn4022x59~&2Ob4_zmPq?emjDLy2fLNM3f~KM-8bSR?0Dr zWz<%ue@TK~%bublsdkSW7%(!>Q-p2{E32qZQC>pYkXC0n04L)DUd1b0oWuM37Aw!a zvZ{}=`QOO^A?|h0TLIkHQ#6?Ff8@y_S}`e7o*W<|i#v~~K{8dx^p(ZC%|)6)1~}Ss zt;zb2b&5X4<#f-RpV!0P7zZhHp!7aLKs1(?^_a>N^7lqZ{ zTsVd9o_cQPFXxG)EUw)x^oCb&B`Ard8t|*Z&_`Ce#g+elL-lI7#5=8ZV&s!Sn|nHF z&Y#vnXzNV#dwQQONkA3c`)?4ThzMxBIa9B4xYgeb8LiBlE|&?D%Il9mTYy2CRcg)4 z7*P+mtR$q)O;H|CzY^UJ*mu1$z+pf<(b)46Ek5|}q=6}f=(w-o5koyNuwYH)C69A*41#KfZ zZI8n%*}rCF#P?TCghdC$OKF!>8(Z3urpWE!IqV|)Q3leOFejGTfj+y;7GCsSDEzSfXQ$l# zV&HAXi@}*XS}BXJ$+_pPI2<0EdA!ukj8{y%@~88mx}nauG?s(pqi|7Hql}YJQ+p7i z$H0j2s8Lq24mnB0ip)9pSI;DikeZJ z@EP+-K1;X=So`s$@yCK{L&d7AeIr9Qcb@$Muk2*_7Gm^B&4}F1DKbdmA6u)$0aOtw z&Kz*C1q`2!|Do7u=ADMTygfU*Am1-pw$0l^_kzlm5Ckzk!pNv9gSpLxgn~5s(D%(H z-z}7`NVc@{pNf}H6%?&NuX4Bd-M}4WLP8Fi0{RC48o8FaW#nZkAC37eF8mjnRwikD z7E*Ahw2H|0IL&*ye$YY)JHX(+pH}B)$;jp-)0Dh#r*)jMg!z2I8-xC5Bv|Ke|ZS+Xje7KmOq%&>b2fOPA_Ahic_a~~zk zfFuKLw%`T?5%Ldc6=D2z!aVe$YH1Ct1Y&U#hHvLy|7y--+7 z^{wic<5Av4E##ri}bjhp?C;3z`SUL-(n3ak8l_dYStaNt%e*X zzzC5IrJwvFWb0+KBpHh%eH{bof!ryP7J0jnn7x7fWF9b1bZMGJ6BG{`s;yRfvbI`7 zjR3eMiyeEaJGNBi9knQc3oU=jeo4|2`S~l=An{$0) zMkpzN1D=Y50nd6zV7?x|i6y`?GCg53!Uegn)16j9t@cjxhMvGO45ESVD^sZ++=DUq zesQqHkTsCS@{KRNlXq!s@58V*5hF|ZN>BL(UbAuZ5=LoR=_;J$K^Y{xXhjJ5tPOk% zoaB6&b(Rf`qa$nkFE7Z;=4fN746bxdiJ^hhsUC2xVCU_$f%~)kD?0={cMC~o7B--4 z12dI?7neuURi}m4^8j3f%kNf8yvNxU-CyappG71*Ho`NzU#E0I#_DI@#(s5cPyjRK zD+YZuj+mpl@Zn<%1p}V@5p1zSiy0kxwz<4xl-9g!)b-r!KQ{`;Eb6}GWpOj(A-1vZ z*J|lm`dxm3<$v#;ilndmSmwJH2eLaD<`m|2VC@yUu)Mr10GF=wdYl-osjITwd}h`| z8m6uO=I%k#Lu5jr*4VzBkjx(P96TBd_Z{Rk+bF-ZDT} zo7 zGH>X(zkdO}+OrKx;0{~|xsd#$3XA3G1DjnHdhmMDboJEJK+|cZxN_5xrTF=H98a+P zMA+1Z8ds2f$o!{;K+m(HORlRKb(-L?{(Z4OnAoj@9^4$Pl!=SA(~?P;TWE}uoEmwk ziyv%V=QX;rYS4%(tZ z9P5!utYFtgfXacngMFN?T_Arh;Xw3%rU>Y!^*!^yr7s^D{;TSoBu(#aC{Ak1+y{kw zb%q#89@^b*+HQDyA8!Z39J%6P|2sKa>{cF&MY1300wd($M;jlW}UHMV#HFL!10y?uKX}dnDQQn&ffgFt=+BApYyW^H{i*}`Hh9ViRXS` zrI>)5zRc?(-`Ik`zMM+f&{1nwA_}%(JK^Y};vRZgb%w5926P$<>@8;$au6FstAr>R zxjLT>xtg7kGB~xny!-6a;}h%a{`8>1LfMFL&{wJ*5#V^+2R%^GS!TxS z8d{yb{&;m+4T(Dd1H|vfbnDsR#joS5W+3m!`pgRW;dtN<`uIWfbDX&jjX0)v0CtJ;nVTr~cXP;4sq;`s0bHGR0gXfq z4y)Lo%P_zUln{1&;7RBdFMHaoH_{4U#;1vpF*w-bh5#nkC%&)Xi9ffx_&bX}Y~VY^ zMQ8Uh$*5zY4-#Pw{jP(8c z`{&P-63E<5HNNlYpa)RbL2*f!NV9Xu{APxRo_o&QeuK-dFK&3PF4LW7@M3w=-Jur4~x{t2^ z6(7RHG=adhGFr(J=N#uAzOVGlJxMNsmddPrbFA-8{DL zW3B%xryG7)RjuqKsWN7wIC#SGnEy}F&EfddR|(Yvkj%YiqMzs7#TW<*?q-5t&e!wd ztXXd;OiM{A)^R<}^ECCVY^mT(UqB` zyN#nOJ6&3f-uX7SNiM$)j}MpmdfzCg@;ePE*9oRv#UYi-ivOJY=&($VTW;Z1rK2or zmzA`@DPza1e&&QnYf7>Zt{i2mVdWwZYkE0acgp z;-&iYF=WiFhYZRIqX|!}-Le;H5yVy#H_|*CykvOkh;$(7d#x2ejhuF(%fy;{D4o`r zX%01_|7tEQ)i2|W>45t{@+=YmBzLBp#?Sxi)7$lFxM|K-1p#|r*~_;~`q+E5%Jg;| zY(+TNc3A9QO8h&V=9ozb?Dz+Lex){-<7>p|>W2;*l|1Z@VS4^Obm6wRhva&DG$(QIEB{vx2J;f_Qx z3v2NA1X{ZVQh)OT321CIh2KF3h2i#~#6Re(>DalKcV| z6T3oL8y)9T*#GYT0=B~N_943u_T`^HdWG&khv969lgHB^eEJ(CRndi9M<4ul)+JQO zOxOoc@N}9Mru7ZbN{HWw7iU~L+Pz(|m|-LHWp)6@QW?$vYxdb~>`@r3rPp{w1=qT9{V4q3Q-f$VRI)Nwz9{)^gA7&h*^j%C_7y%r`a zvHwZN^4SYwq~5nAs_ZAbO>%T+4;|>-I|>1z)D+xv#h68My~az}Hzwptq;CEq@&=i8ny&63>~k}<`ii% zkrZo{T4dT2aKsK-g%x%^`kGdtHxW>z+vs!U_x^&D#(n~q`Q2Hvyab!#{a|$8%NfLj$JR%uCR%XKr5o$#yw4`H*6w2$e4}C6mtpf6 z&;B_3vPh`?sWq#8b(qm{eZ|#9nuvsf(6{f>-pO>uXWk(}u+Ew_X{v_$$Jxai#hFS3 z9AOW#J`|r_*ts_JJVx{r%PCla&Q#pYmlVCX^BFiKTcxREJ1lLPOU`doXXTgY@XbX`Rb$>3#)EzZ=3$n(kJJ79;pwx^5E=xOP64atfa5e z1Cj?C^T;J`6T9^h4+nZL1=j%aDKf;hnDXfdMG&LwnbL^O9N!Nud*1`4*ix%XkS8pi zb(U>pnf>$o|8qi`*KgmfOp!!X1wnW|aw6UvxjebYQ(mcn|&QuajAEz;5%)97pbG17+ae6?1R9MUP zj4^wYf792=m--8LdRTk76I)zgAlMC4TE3s90cAf$%j&KZ(h;H(6!FZapN}MY;-GMm z-206~JZJkR(=&~}D)x#lGHOc+%37zRtTI$GG$4@3mXbD1tad)Q+O69C6$DI|FPcd` zVN^v>-j(Dygb(3Rc%uJ23Zqb;zDQo*zsc{`cBU;UY9Mdu)=PtzXasbrHC?C`w6v{9 zClq8{{}uM>-J6sP*ArT8O<*%ktevd=FXSq4+Di_3io3@VPUn?W-(Me>;DQ+FJniMr zps2=o7oDwVQzE$$J;)XzSVqF^Tc0xNnagiuTarkr3ueD=fk$@gI8Q|m^NjeH0`Km zKH7t;5j=EZSr;u4?fix44vxHW=diPF^+Zk^&!PoFbHexB3+|momVaj)X{>)6bC3t~ z2`*YOrh>nAW+wOTlRmm#&jbSFZ`Ft5g(u8j`lAA3TWTqXFIqAMh&9bj;Jp5DjpX?^cKzz8%?D9>f8q;CD+nE)0c_pFK ztuN%d^+#{P2u#M1T&44oS8mdr7av9&T1sKkF}`CP6rU5B`c-KHSpuSZb1dWaIH}k+$CADP2jJZ`)z=vX}LMMIWcI zdp44PuVo^>CS^CgfgMC(yA=Wz&BL9Gg_E^ErY0L{FCrW-hHRt!cAU*OUeZ5;H^J}B zrRXPaoBR&gThef!Jmf+0mEtnaq$Nu@=ihnYN^0D7!jh;>L)qXaL=@nwkgEO|BX0Vm z8A1`~d|faQms5@I6s3Buwq#_AIvx+o+b6bvSo;$Tp2uG!0NKv|lBp<|>#KCUTO;`p z4jSBdzUYyi&pIyAq4mO*(7)^F6vDv!e48wnvS%q$g*BL-!5LIDtR`MK2=MZ!o4eZSmyjs2Lgj|mAs5Ry23>_qmx+=Jy;UbII z%F*^wvh&#wcJ|VHM57g>m~fgj{fS^KI0jAfx_qM`GvYTu)ZZXLj1wRhV%>MHJzVqR zez?|r(v)_(pVzq13O3kd=`i`)bGNR5Og+ax+62ags(Ed@#gjD&C6I<3Cc2l0a^UmW zpNuCCeRehe0Ki_V1ok<#HM>Qd^CFC zgmyCnds&@+d|6_&AL4*O+BkAixwm!B$oE#-wgyPia(}ydky7%g%C#(bIy5iER%U8S z$NAp*24Zj^yO~XX#Hg)aSJ<8wt3FZhVa4h20X2cj9bOR=$=G|});@jzy^;1L6IZ`$ zd=h(BXMeKQL)J+A`SW~d>^E}bPZk`(U|e}ADkfXKym>}jp z5v;)m=_bGVxPYWhS6*2%NdMY5q`v9Nc#^C8_y~(3|023dZ^GaQH(8f@p3LI2KTPgE zhGfK;(vzmjyg5%IdODAeGRX|tqD`QC^8Z@83a}=>@BbnSeg(lsL_|fwB1Jk(I;0zh zN=S_wAqZ1cBm@PeLnNd@8b%CMLb|(SQ|S9m@|rx z;EP(!?(tfv2d3=|<(>K>`~<>%`H#e{oa}Y)D7P_st)!Q}i2?~nn*4inU!HcgwLC$I zFy$}oy?>*QOR?y?r859tK+wrU|6~?ut5f{7F3X|kt7*YNxqbTl zCo9%(by`{X(qLAR)RNL3ORih8o0LhB^t~ftt-0Gd>_$o72^%=udqNSV)9Z z`uPJ-vb8(2D-@%;OF=VvcE&2we!HYzEWol!bKtEvaF zPfy!;Aa$_xQn6Z#uuU5~Qs*?;e6we_+wtap$>VyH98l1q%Gv?#Z1=3GPRgdaSE?8q zwsVw-$QMjkWpzNQ-4uh#X%;;89!=QUTOoUHVf95ks&KRrwc$a@Om1%GK6RAH*N0Rf zsgc5lj!)-PeYtA|ny%btVMx6IHOhlzu}%xTux@fC{Ne3jMmVEEiS(B6r@}neuiCEK zsYg-b8$Z$c{qyb$sCi?$E)DJnh$39st*UQY+H-jJX@*XojtX&PGg4PE?&%B+15Na! zXP{@0DZir1xmkM(oZ7)8D|svbzJ$=#ydkXpYwmdfLfP0>Z@kE^L`?dqI`F0zIMn#U zs>aSjuuW|!RFj3w>W$6Wvu{I0ZNlUYPqAM(UOq@6AKCldlx%JirsCXq7zMlOvm_zS zWH#!#qAV37ESy$+B*=^Xu}JP*wDE)Y+ddY(w~H>F$a?bT?px!E(h%v+b%ukuoep6# zI)6`kdh%+|e!X?Fked#M4(oeD5R`FkX}mkCe5i*!l`jQ0N@wHu_1eENlas6b>vlfp zQE`w`^OF26Yl|&n4=d8E0Ec8TQPW?4a}hziE(KR`25(Y!HnLZCaTBW2a`gkOIFtw8 z)>cDo%~9yI=u_gPWXVjtG)kgCje&cr{lQ|$_Oi?Lqi2vOaQ0lIC9m9Sw5(9};`cKi zYM0qq>vkw~hlxM$HsM|qXT+4|HXmYW+K2x(H5w1)OcBR2Szfnr{{YYib;_B_Rc6vk zn|Gi1WR&H%@@1qf1yT#UAz@A_{!5?11A>tIu}W#O*KSo*y3&gm5RPE$-|}ns~{Kh;sBl17ujaK z7!)_GRJ{uJAoLoux|Q8r2Yl(HN_pC1UNwpmb;!71c>i~#fd4`oJr%NngJg;j?4}c% zQA~*yzLN9s`dILtFxPFj#iL6QYM>$^*q51}d{*l+8>&XiIFl3B;ekz;GYD}k*@)Y5 zNfALYo=1k!=OjwHf7yC0hpD=zCMH=^d=HNEjk}g66YLj3klFD$oPQM2sD~Z?Wk?8I zp5(c?ou)+_N7W$%`D=Z`BBs{qx?-P016$n8IV~!n%4d$c>s2S|X3EQ&^kvO~LwMf8 z?P9s5j+cS%j}reF@IKnW*$d+zGQVxcJ>j|6cdJfBF%Jj011bzc z2k0%F4lLnRxT?}4bU3M1tNHSKmT}n%>LR@X>icg^4hLKt;$}DM`W+JkAWI!wZ8c<8 zu^W>3)m+0N?FA1WDM-`pl5g0Gb3F)o2H` z#Um_Ou1(3!X+pmsmpy@17eaG9@8Y`;=)4Vr90Q>g^UTRZH%0?PgUk+}9=Q#{j4WiP zr^RIZiUC@BDtbQ&+mt_5B;u(S^ zIrJ!T;bx|0tHm#pb&3YN{A0Nb5QougBR(%=ig};tl@35)tMN!8Ed+uA!?G0*l^c}v zkz+@OXNz9p!U#h}!@Xik#D3UZ@Fxc0$e{P@9D935aO>G;#A!&;HReU)G7^0&%ve47zteED`paER0 zuDjUSvx8&UUD~jax^&Oq)`J`C%fNeE4e*`7LgSokCJ)jCi|qQ3&NV?;898Wp{jA|v z*}wU`!E2O)T#(3T4-fv`&nG482c%fP!Jr_U3k2iO9oKLTY(@1 zj^)lYO}jx+$Dcix0FC1%UEaT{gUru(aw6x&R>IxCBK=aBQ#KUZEO$RrveSQ_5-{LRcL=dmd(S_(v-D)T8itoX79Ilu{% z8xxX1&ZU>9D=D%h1;d%x*_pm~=x|6;JcN1#nZ%2JUeds6^u^K#7@9P=h+QwMeRi@$ zb-{p0wjtdtm%P`-WC7vy zCgTX_ESup#_$IsLAonFt*x`E1ILqQG<{Y?R_t%r1V93)TP@4UVAPiP(A6A-Z1SZl| z1}G4Z1WdE+LfTXB+VES-%Zai8*1fAgc9xo*y5nWmRmoE2a9^f`D+P)(_OtQuOGh^1 z&x_&9dPoqu@zZiy&2Ae{bdjy{c?6|bKlr)qr;X}h0_=P^La<0!#!RIUKz#C)@-n_( zo8xV49c09$KO+c>_9mL*ZT^csd&^yUFQtw9&8rK=2}MwzDaF>qOU@gwo1QpCcZzrNv;*5O1!hZ9VQSv{ovF_fkeeAK{4sKCRDxv6wQd@ z+PhkBn_A%F$JB7SF_uAVLFui^9h|Vv50;kHMoKJAFyx?b1C?kX-pA)>EuI{+epJ;F zHu}BxcAuW8E*K;~_T7&LI(yj;J23z*czeiW0UGy4e=Xm5vgwVEkJ)%a{So~&#@TE0 zqhwwGt{cSV)9BeCK(T~$`&L6FqV^Zcan7~WsGz{k#Bsx@tx`W&PW>moYT?@3|AGqH zHl?S7NAG~#q5iuVdGQZxjcUom((;|tOA|^>D5XWZ^|MWvl@@6i$>=^{$tjIdPg!5H z@;0|{c}7w4b_-pGVo+;aJ1hBDUq9>X2E)BM^z3P}<7PnE)R&6ePyb~(TdxkBgIirs z-`Y%Rr~J#pa0gh4bpENReE{JLn8@8WC3@Rs+tch$rna3$A0q-H1aTt1Ik=p{S2%B9 zuT()n5qJ^z@uOMZ1>03erjW!hWhZ$U6`r*+89SiV9zXuz`r$>q$Kxt0N%H?cxOy4K zqc?8vi?-hb%m)a)cjJ-AX04GcvaqU>8D$?oyxVWt!JGw`S#yu5bS4mQY$ahWO6b>RVV%TG6Z z@6XL{ct6YO|8Wib!M^HDm4QRsBj1IQwS?rPk+^!@>_q+$zJ#OHBG9LVr+dkFAbZ4)fWDoC1_hKSM}|0TSj7!$YZ-N z3a~gW?~u3(P51A*MuQL9h6~95bzDllspCA9u&HkMua+FO8 zzUK{W-8`m1%Ot;J@NlMazaU2kL$eS7Bd>C}Zlrwwm;T;(mEHW18u{90gkUcFN^L!D zV*0;6md&ImFtQ0oKI3qA_LQoNZOsnC-MR`%9{da$_x_kZPI2>>cXiD64<#6hfs0zt zr8*jJcJCJKO!Y+L%l@WMaI~bj!e}fyFpDkW2A{}{k%ckb2bf~$-B~2-7^6VbHut(x zbr)a}(afrSM*ntSlrGRp@T5S}T9*ttm2URy zImD;`=zzsw{TmO+5 z?())Zsj*r>01lP&FeRduXDnfun95~+C#hdq{Qsu3)a>_pCp+YvnH#6XJP|IT#X*H+ z{l_TKuzh1aYE08s;WDgS6(kw=Hp?*`*j9S zr5BUw4d!xJe`e7A_VXWRdeV8ASN^aD0%+aP=go&BG0Q|Ae_O%JFmCT#r}FKbOhpfl z{oP0rpy{+X$de1lb%hwyfuf{cODlrxZdP&Lvn;*fpysPR? z%vELY>)k6DAFCYTNNBi7cN9jFfnguRu)-HZK{)?pYYH|pv%V#i>&*;=4t-TE%6V3N zARzV*zumDhN1 znSLV=v!z1jR8*CJSJQYn%b1!f5RUCOpZDa3u_D97S?hl#R(o9j<&NW0U?I*rFTT;o zkr7u#cjdBzyps3!WP59=)m;C1c1S9B#xJ8Sg)`R!#lAZJwpIfg+|I<2P z{dteJb4^K~8pC-_*U^qnuphN&@JwErAZO!$QWG)X+?rnS!Hb}Dg3ZF_*XN7<(u>e6 z(6?|T>oC+-cAjk4=C9`v_4^0(yYk#DKOd}~7S?EJDm(Cbvn^5}U{4DQAvc|CDfVjL zZgVLl_ZXIDCKt9y9cV|R;bZd`=$+OuU#C4s(^#k?1;Reds{U(Vi}ln}y8LZWrcz#L2BhJ4&tabBz_uQcUT>LD0;=c$ceO>^2enbbA$Jo|Do3GlR! z#s`%j4hQ_={2dGVgzAAj50jp8`KGRYq^-T<_S!IjT(Bn(d^B^MvFWS3oFGn85Mds)qkO_Wy{Ht9uo4v^LR`17F|{B~mRt+{B}QFkyEbHu(*!YDiVO#IMC+ z0(oR5m~5nu#emqQ(w$!pX!YZRQ(C*W)*7a+oO5-OZf=_RGSxb9tTc zTde;SEY1BzPgK7lxhrvhulu%_2cRZd8YQ_1!^_2eZQ)FFr-`-6ACg=LQ|8}r)-c=m zdt!T=zN~OP3#JT*-BgjcZOUl7k-M`Tc-ACHn_SJuDm0t%!TrY@V^@qG_^y|hp&w)D zQS;yo$8L<}Z?0=tbGRgymkueDj}&{a?TGXF(;3ok3x8&-qd}Luk5Pg2)D^NmH`kTf zuGoq!=02dH(+vEGu36>RC+vfwY6(E=bvR4!SQ)*DCB=!g>{)WkPxeh36)hbyf#o4P z5B6MLy1b8W-+E&UUNrQ6&pL+=#$2f*5voZ}2SbDJT;?}(o~eA<73n-bWeP0Sg^VB+ zr7h85$CSi4sF$DMoLp;m;2KcMfWZApm#(2{^fN3WjVMrp8`33De2s>PTk+3s@-djo z5Saxog7}|umfDya3u!1Ob*D;^lgVyM*w!^2=j}>-{#GNiI_|a!m`-RwxVe^HIFo$$ zD#M(!trQLzYXE0;rl!z^*aWRi62i?DPzFTsWm7w1evoa8M=p2%+W!gL7k~!~JZVKM z#B^%6!mrYwvoi4?RsPxSF+(6v%h2*52`-DQg;H+`ST&9sw{R zTM=|SjA>rmDI4}IVF6m^7`ZNDkA&K*uGMF>ap27TqrE{7KuV&2@W$zSo@UjEbY6Y> z1t=VZqrW3PX|>G4v75WV01Z+)2kd0{-O<+&Stz`@+VA8)6bmR|2%P#kwqliUz~ zbgI}ZHc9fSo$t2>xM1(aXWix`N;xyQ#VFo(J2pk6m8p zR@4<8OCF_P_8`w$4i-l%Yi>6Cx3F-dyFniA8Fa(I#?hyPm|d&vQ-)ec3l!S{CR$j9 z)io~fekhX2?A2e4*vl7}I-qmEhPC;(;A@$k{WB#Y%eUdRGV=1W@mxyuVj|tRytRet z9+R8{Y0k2TQ1cmAl=ArKNN$OP{mY1%OUMvBAO>YTIT(zop7#71O%fd#IS8P-*~@S2 zf2nb4BXYUz|G5qOiWH$juxEYr8D~d{qnnDG`K_1_Crbe=L{RLJdQtUvIRl1>w-hxA zR<%qj1C->t5t61g$-JBsPIFQ(v|9cNdH6M7KCl%t;FrQ^o7w zC5-$VI7@#VV{3dFdZ!GF5&E$eITKO!4Wm8JtCbHPW6wT^&wung&Uj_F)H5csU!AAR zax@37Ce*tK#RkB!|A|In>U`JE+)E}>*en9i_}PpUW>z`=u5!hs&$b@e^Uj+n^I_C@ z$rNsRsCF|57(NEzBPt>i8ev2Y?Kj$^;wa;EIzTY+!jO$b#1WLXbImpX=3V7YET+b9 zz?pSt2?-cCU7VWQTNrNy&Dv=@bQ16Y^$d70hmX{q%s|&z zITxju^c-0KtUC|xzTIXeNDhT;cPp5my{FX0f}2LhYr1c6y% zGL318c7DRt_SI)Sx+t9&&|LLvUThAZjiX)|p|zmkMn$~iZ4r!=ot*5a{Iz=8We7^HApR7XlQex|= z1#-X|iD{e+o$GGc)fW@sBiy5hWB7iKehb-S8!Ps^SvtQDTJMtE{iwy};VkLO)?c zi+vpZai_Y~Pfyepz|3mVUmB#)`&_7Qdsm)yX(sIV&+Ox1?V(ezTNI!fXkU?xO^qQI zk17oGN>G{Kugb^Q_yvMwvn!c1WsJR;m z3X~5Dg#GUxA+cUpM^@LPPfd#jfK14b&+^{RZ4;;@l;3t#+W{mE=_3;uFO3r)OYB?< z9^z-X_W@1_!K(l?HM`=out&ND#W?vxAbM=-tuyh*qcHkPxnKE}018I1w<>I}%$K#j zy_B|7vT+=!nqV3wr>But7%sUj%c@_vKaR@8(K>tKopUxnS)(m1(z4I2fmyUGvwb!nC1D zfgBDnD8zM0YuRnQ6yWM|Rbm#*dju>84M!=D23K8YTuB`2V$Re~Vrf|xIfkGx7o(UP zPELQhE{rZ9g;?FLQy!p1JpTT^hxnfP!pqt();zKfxn-B%%5jk-A_X#xD|9Xlg<1^r zg}eU!1|CU!exMHVLPNg3OEHUI)3Q>aQ$aOies?EovY8uV{zoMR(y+f zV`w6p#jP+o>q?a+e=1PZ9R?M6N0Ri=esZt!;@gi44-Vta$)od33`2N4#^;8Ee$s20 z&UguNpFp^65B8d@>eIg?b}6Y_$L>DRr+4&HD1}yO_qXIXoc@W`v;Hwf*56Bq)Zs0> zR`}5$5mFK9VJSpCg>{RZyFEXtjB;#XC(BJk!VesM<;gB>bO*K^5kRS z=#YqW!GcyknxS>*a37{jB6|Kg8S|v{-@_ZmTbBfXrYwl>G2Ux9) z8*Y2KdPR{f2U`Fjkvw;9x|LVmp^p@|D^>#@$g`2hhuP0vze{8?BkkMj8e8P{)T=il zsMMWADu-8I&gE+M<13j@UTDGaBs`eR$JbCg_lqM6h??^qR&r9?QjuyfJ!dpvWLNlj z+{)c;#`pQp@QtUy33h;m!)q2@%Ty@)nQ6bUw{`knTOmk&nlCh=eSViE>14Pb0^qm% z!;O3vWbXrP*UfXPr==yMqSym~lvfQsy_{&Ua9H%D$Y1mg8Ch8fq7+f`TUywh+kJhc}u{hHjL1fyTZDTu)7a0-J||Ei=@x|6v!tEWW`& zX|>yx8!SLgRuDiTTij9%1-@B;P@7+x>7cj|(!g`)Pa zJUT3{{?HsajO0VGipbLyOw}hBgv(dq`flk4Nl{DYrFbIuuQMoVsyf>}ejgXK_CDpc zdZtfJ)(jhxg&`BPR1|MjQ;11&TJZl+QoK@;@j$BM0m97)H6*_)i?InAWyPAe%5S)6 zKbBMnE{Pcdm&}F02$q>Un2qmEwk8%m()Z+qbx@*3E;z=wrtgDAiiAp^mJ-HU-cRfz z-yz^avM%;6tR#KQ5GJrVM$Z)H78F4T^9fMeCRCI1e)0pCEu-D4#L6uR?*r*3vsNo@ zYOdQw7~K`)&=IBItI;xw=C?h;kJL>tO?MHPrprCP+YfK9{R?KUoZdxHws73ovqwMD zA3g3zSA*0`D%wmIikrPt7>1dPsRV+S@)KmnLyjQsAq|Vd|lu)Oj<9L<0g=K9y+3s4gel zII|$#*I`L)xt(Ct!M{}or<(8X;&oO3wznvPVu zv)A^@w&a$kpli|GjA+l65h1zp(8zlh#D>n<3@UE4)n6@I8Nww$X|5NnbIe%~KTT&y z%+_{z;y0Q%UHvvCx9+*TcOeuy<2*DL8W$C=^8P5MK~Pa3c1V>v{wp>Mt6c%P^wz{9 zyl9;qJnnsq{EPs7&)R|G1F^rw9x0~a5IF)gH9%FR!1aUkx1#OB`Ij8C?zrR)wYV8h zKqko>3AI_&{G+sfY|Su%Mj4vT9X5XjYYGr z>5O@fgyTgpIg(FyI`_S6;-w8U%`)qbKc7rsef`^>8b|e`vD3kYaaB@00(Cc+PG|Ac z3eytpnz`MY%}sloW+L!o&q&HjDs_e*!S0S+fqltDs$|MWk-pn&o3t}QG)P-Ng`Ph? zFFFu=*YAQ_0mYE?Y|`1L6Pe1HCt~>FMw&K%VM57B^awL_)6)6Ye4c@r8_;ra0G_J< zdcQuFq7O0Ny7GGR>H2V5S?6F@PM&^r|3hr;N*BXx688|DK9-p4`_tl$B&%!0I{%!t zg$0w^05yUy7>WH4K{Z5e4nP{b=E^V zMY>VOnR_#5=LY79gu%I)dB=Y(wO7y!miupfxNa>yc_EKs1rz@kxP;dbVoO()wOz8Q z<@LK@8bIe?54H4YC^@k-cXbl1&$lcynpKk{>OrHyxJwlVrWkjkg0(pDXQXJqkG|-| zfK}4Gcw|V(PtAd&P@Wqbfo9#1V2P4`rP*PA)2vc;P(_xMa&3ILBh(;Y& zv~D!f$2JZV!Z*EEo9vro^BDvcHN-N*}uAqolT^ zE=s=gn%}zH4KT*s%mnPhrbPsY^ApC2(2Eoc9~UeVTJzOtn;s?hk4{bMWu6p@YY|qX zrwzX)J1EqiUd)6b7A9Tv@D#zM+^NAQs()H+eQK|buzB*dCkea*IFco2a2%p%F?p&W zUuE%)$3IsN*VDzBRe* zE`(0TWU4wi*q&h*AY|^;(fRA-1mTu7*Cfm?@{P_B)4I&~*w~#2Jk-?bgB5?3NmJw8 zX|@jBf<=OBFE8>*QnObZe2Q~yZ>cc4KNdgFz~f}W%-omj-}<9Nn9sYS*=CrY`a;$E fz6>NRoO=@46WvP`AFZ|F)DW2`ijOlMqTc=wbFWpm diff --git a/pr-preview/pr-4027/img/logos/constellation_icon_white_bg.svg b/pr-preview/pr-4027/img/logos/constellation_icon_white_bg.svg deleted file mode 100644 index 9b917d449..000000000 --- a/pr-preview/pr-4027/img/logos/constellation_icon_white_bg.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/pr-preview/pr-4027/img/logos/constellation_oneline.svg b/pr-preview/pr-4027/img/logos/constellation_oneline.svg deleted file mode 100644 index 4e354958a..000000000 --- a/pr-preview/pr-4027/img/logos/constellation_oneline.svg +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - diff --git a/pr-preview/pr-4027/img/logos/constellation_white_bg.svg b/pr-preview/pr-4027/img/logos/constellation_white_bg.svg deleted file mode 100644 index 4bba8c2cf..000000000 --- a/pr-preview/pr-4027/img/logos/constellation_white_bg.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/pr-preview/pr-4027/img/shell-windowframe.svg b/pr-preview/pr-4027/img/shell-windowframe.svg deleted file mode 100644 index 65d844638..000000000 --- a/pr-preview/pr-4027/img/shell-windowframe.svg +++ /dev/null @@ -1,340 +0,0 @@ - - - - - - - - - - - - - - $ c $ co $ con $ cons $ const $ conste $ constel $ constell $ constella $ constellat $ constellati $ constellatio $ constellation $ constellation $ constellation c $ constellation co $ constellation con $ constellation conf $ constellation confi $ constellation config $ constellation config $ constellation config g $ constellation config ge $ constellation config gen $ constellation config gene $ constellation config gener $ constellation config genera $ constellation config generat $ constellation config generate $ constellation config generate $ constellation config generate g $ constellation config generate gc $ constellation config generate gcpConfig file written to constellation-conf.yamlPlease fill in your CSP-specific configuration before proceeding.State file written to constellation-state.yamlFor more information refer to the documentation:https://docs.edgeless.systems/constellation/getting-started/first-steps$ $ constellation i $ constellation ia $ constellation iam $ constellation iam $ constellation iam c $ constellation iam cr $ constellation iam cre $ constellation iam crea $ constellation iam creat $ constellation iam create $ constellation iam create $ constellation iam create g $ constellation iam create gc $ constellation iam create gcp $ constellation iam create gcp $ constellation iam create gcp - $ constellation iam create gcp -- $ constellation iam create gcp --u $ constellation iam create gcp --up $ constellation iam create gcp --upd $ constellation iam create gcp --upda $ constellation iam create gcp --updat $ constellation iam create gcp --update $ constellation iam create gcp --update- $ constellation iam create gcp --update-c $ constellation iam create gcp --update-co $ constellation iam create gcp --update-con $ constellation iam create gcp --update-conf $ constellation iam create gcp --update-confi $ constellation iam create gcp --update-config $ constellation iam create gcp --update-config $ constellation iam create gcp --update-config - $ constellation iam create gcp --update-config -- $ constellation iam create gcp --update-config --p $ constellation iam create gcp --update-config --pr $ constellation iam create gcp --update-config --pro $ constellation iam create gcp --update-config --proj $ constellation iam create gcp --update-config --proje $ constellation iam create gcp --update-config --projec $ constellation iam create gcp --update-config --project $ constellation iam create gcp --update-config --projectI $ constellation iam create gcp --update-config --projectID $ constellation iam create gcp --update-config --projectID $ constellation iam create gcp --update-config --projectID c $ constellation iam create gcp --update-config --projectID co $ constellation iam create gcp --update-config --projectID con $ constellation iam create gcp --update-config --projectID cons $ constellation iam create gcp --update-config --projectID const $ constellation iam create gcp --update-config --projectID conste $ constellation iam create gcp --update-config --projectID constel $ constellation iam create gcp --update-config --projectID constell $ constellation iam create gcp --update-config --projectID constella $ constellation iam create gcp --update-config --projectID constellat $ constellation iam create gcp --update-config --projectID constellati $ constellation iam create gcp --update-config --projectID constellatio $ constellation iam create gcp --update-config --projectID constellation $ constellation iam create gcp --update-config --projectID constellation $ constellation iam create gcp --update-config --projectID constellation - $ constellation iam create gcp --update-config --projectID constellation -- $ constellation iam create gcp --update-config --projectID constellation --s $ constellation iam create gcp --update-config --projectID constellation --se $ constellation iam create gcp --update-config --projectID constellation --ser $ constellation iam create gcp --update-config --projectID constellation --serv $ constellation iam create gcp --update-config --projectID constellation --servi $ constellation iam create gcp --update-config --projectID constellation --servic $ constellation iam create gcp --update-config --projectID constellation --service $ constellation iam create gcp --update-config --projectID constellation --serviceA $ constellation iam create gcp --update-config --projectID constellation --serviceAc $ constellation iam create gcp --update-config --projectID constellation --serviceAcc $ constellation iam create gcp --update-config --projectID constellation --serviceAcco $ constellation iam create gcp --update-config --projectID constellation --serviceAccou $ constellation iam create gcp --update-config --projectID constellation --serviceAccoun $ constellation iam create gcp --update-config --projectID constellation --serviceAccount $ constellation iam create gcp --update-config --projectID constellation --serviceAccountI $ constellation iam create gcp --update-config --projectID constellation --serviceAccountID $ constellation iam create gcp --update-config --projectID constellation --serviceAccountID $ constellation iam create gcp --update-config --projectID constellation --serviceAccountID c $ constellation iam create gcp --update-config --projectID constellation --serviceAccountID co $ constellation iam create gcp --update-config --projectID constellation --serviceAccountID con $ constellation iam create gcp --update-config --projectID constellation --serviceAccountID cons st ste stel stell stella stellat stellati stellatio stellation stellation- stellation-d stellation-de stellation-dem stellation-demo stellation-demo stellation-demo - stellation-demo -- stellation-demo --z stellation-demo --zo stellation-demo --zon stellation-demo --zone stellation-demo --zone stellation-demo --zone e stellation-demo --zone eu stellation-demo --zone eur stellation-demo --zone euro stellation-demo --zone europ stellation-demo --zone europe stellation-demo --zone europe- stellation-demo --zone europe-w stellation-demo --zone europe-we stellation-demo --zone europe-wes stellation-demo --zone europe-west stellation-demo --zone europe-west3 stellation-demo --zone europe-west3- stellation-demo --zone europe-west3-b stellation-demo --zone europe-west3-b stellation-demo --zone europe-west3-b - stellation-demo --zone europe-west3-b -yThe configuration file "constellation-conf.yaml" will be automatically updated with the IAM values and zone/region information.Your IAM configuration was created and filled into constellation-conf.yaml successfully.$ constellation a $ constellation ap $ constellation app $ constellation appl $ constellation apply $ constellation apply $ constellation apply - $ constellation apply -yUsing community license.For details, see https://docs.edgeless.systems/constellation/overview/licenseThe following Constellation cluster will be created: 3 control-plane nodes of type n2d-standard-4 will be created. 1 worker node of type n2d-standard-4 will be created.Cloud infrastructure created successfully.Your Constellation master secret was successfully written to "constellation-mastersecret.json"Your Constellation cluster was successfully initialized.Constellation cluster identifier 9a33e294b6f63d3593cdc85e0c4cba55f0e04800e2c9dd846e17da68c16364b9Kubernetes configuration constellation-admin.confYou can now connect to your cluster by executing:export KUBECONFIG="/constellation/constellation-admin.conf"$ e $ ex $ exp $ expo $ expor $ export $ export $ export K $ export KU $ export KUB $ export KUBE $ export KUBEC $ export KUBECO $ export KUBECON $ export KUBECONF $ export KUBECONFI $ export KUBECONFIG $ export KUBECONFIG= $ export KUBECONFIG=/ $ export KUBECONFIG=/c $ export KUBECONFIG=/co $ export KUBECONFIG=/con $ export KUBECONFIG=/cons $ export KUBECONFIG=/const $ export KUBECONFIG=/conste $ export KUBECONFIG=/constel $ export KUBECONFIG=/constell $ export KUBECONFIG=/constella $ export KUBECONFIG=/constellat $ export KUBECONFIG=/constellati $ export KUBECONFIG=/constellatio $ export KUBECONFIG=/constellation $ export KUBECONFIG=/constellation/ $ export KUBECONFIG=/constellation/c $ export KUBECONFIG=/constellation/co $ export KUBECONFIG=/constellation/con $ export KUBECONFIG=/constellation/cons $ export KUBECONFIG=/constellation/const $ export KUBECONFIG=/constellation/conste $ export KUBECONFIG=/constellation/constel $ export KUBECONFIG=/constellation/constell $ export KUBECONFIG=/constellation/constella $ export KUBECONFIG=/constellation/constellat $ export KUBECONFIG=/constellation/constellati $ export KUBECONFIG=/constellation/constellatio $ export KUBECONFIG=/constellation/constellation $ export KUBECONFIG=/constellation/constellation- $ export KUBECONFIG=/constellation/constellation-a $ export KUBECONFIG=/constellation/constellation-ad $ export KUBECONFIG=/constellation/constellation-adm $ export KUBECONFIG=/constellation/constellation-admi $ export KUBECONFIG=/constellation/constellation-admin $ export KUBECONFIG=/constellation/constellation-admin. $ export KUBECONFIG=/constellation/constellation-admin.c $ export KUBECONFIG=/constellation/constellation-admin.co $ export KUBECONFIG=/constellation/constellation-admin.con $ export KUBECONFIG=/constellation/constellation-admin.conf$ k $ ku $ kub $ kube $ kubec $ kubect $ kubectl $ kubectl $ kubectl g $ kubectl ge $ kubectl get $ kubectl get $ kubectl get n $ kubectl get no $ kubectl get nod $ kubectl get node $ kubectl get nodesNAME STATUS ROLES AGE VERSIONconstell-aad70a14-control-plane-65328c70-6kfn Ready control-plane 3m27s v1.27.8$ - \ No newline at end of file diff --git a/pr-preview/pr-4027/index.html b/pr-preview/pr-4027/index.html deleted file mode 100644 index faa8c04e3..000000000 --- a/pr-preview/pr-4027/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - -Introduction | Constellation - - - - - - - -
    Version: 2.24

    Introduction

    -
    Maintenance Notice

    Constellation is no longer actively maintained by Edgeless Systems.

    This project is no longer receiving updates or support from Edgeless Systems. The repository and documentation remain available for archival purposes and community use.

    -

    Welcome to the documentation of Constellation! Constellation is a Kubernetes engine that aims to provide the best possible data security.

    -

    Constellation concept

    -

    Constellation shields your entire Kubernetes cluster from the underlying cloud infrastructure. Everything inside is always encrypted, including at runtime in memory. For this, Constellation leverages a technology called confidential computing and more specifically Confidential VMs.

    -
    tip

    See the 📄whitepaper for more information on confidential computing.

    -

    Goals

    -

    From a security perspective, Constellation is designed to keep all data always encrypted and to prevent any access from the underlying (cloud) infrastructure. This includes access from datacenter employees, privileged cloud admins, and attackers coming through the infrastructure. Such attackers could be malicious co-tenants escalating their privileges or hackers who managed to compromise a cloud server.

    -

    From a DevOps perspective, Constellation is designed to work just like what you would expect from a modern Kubernetes engine.

    -

    Use cases

    -

    Constellation provides unique security features and benefits. The core use cases are:

    -
      -
    • Increasing the overall security of your clusters
    • -
    • Increasing the trustworthiness of your SaaS offerings
    • -
    • Moving sensitive workloads from on-prem to the cloud
    • -
    • Meeting regulatory requirements
    • -
    -

    Next steps

    -

    You can learn more about the concept of Confidential Kubernetes, features, security benefits, and performance of Constellation in the Basics section. To jump right into the action head to Getting started.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/architecture/attestation/index.html b/pr-preview/pr-4027/next/architecture/attestation/index.html deleted file mode 100644 index 7a5b209da..000000000 --- a/pr-preview/pr-4027/next/architecture/attestation/index.html +++ /dev/null @@ -1,229 +0,0 @@ - - - - - -Attestation | Constellation - - - - - - - -
    Version: Next

    Attestation

    -

    This page explains Constellation's attestation process and highlights the cornerstones of its trust model.

    -

    Terms

    -

    The following lists terms and concepts that help to understand the attestation concept of Constellation.

    -

    Trusted Platform Module (TPM)

    -

    A TPM chip is a dedicated tamper-resistant crypto-processor. -It can securely store artifacts such as passwords, certificates, encryption keys, or runtime measurements (more on this below). -When a TPM is implemented in software, it's typically called a virtual TPM (vTPM).

    -

    Runtime measurement

    -

    A runtime measurement is a cryptographic hash of the memory pages of a so called runtime component. Runtime components of interest typically include a system's bootloader or OS kernel.

    -

    Platform Configuration Register (PCR)

    -

    A Platform Configuration Register (PCR) is a memory location in the TPM that has some unique properties. -To store a new value in a PCR, the existing value is extended with a new value as follows:

    -
    PCR[N] = HASHalg( PCR[N] || ArgumentOfExtend )
    -

    The PCRs are typically used to store runtime measurements. -The new value of a PCR is always an extension of the existing value. -Thus, storing the measurements of multiple components into the same PCR irreversibly links them together.

    -

    Measured boot

    -

    Measured boot builds on the concept of chained runtime measurements. -Each component in the boot chain loads and measures the next component into the PCR before executing it. -By comparing the resulting PCR values against trusted reference values, the integrity of the entire boot chain and thereby the running system can be ensured.

    -

    Remote attestation (RA)

    -

    Remote attestation is the process of verifying certain properties of an application or platform, such as integrity and confidentiality, from a remote location. -In the case of a measured boot, the goal is to obtain a signed attestation statement on the PCR values of the boot measurements. -The statement can then be verified and compared to a set of trusted reference values. -This way, the integrity of the platform can be ensured before sharing secrets with it.

    -

    Confidential virtual machine (CVM)

    -

    Confidential computing (CC) is the protection of data in-use with hardware-based trusted execution environments (TEEs). -With CVMs, TEEs encapsulate entire virtual machines and isolate them against the hypervisor, other VMs, and direct memory access. -After loading the initial VM image into encrypted memory, the hypervisor calls for a secure processor to measure these initial memory pages. -The secure processor locks these pages and generates an attestation report on the initial page measurements. -CVM memory pages are encrypted with a key that resides inside the secure processor, which makes sure only the guest VM can access them. -The attestation report is signed by the secure processor and can be verified using remote attestation via the certificate authority of the hardware vendor. -Such an attestation statement guarantees the confidentiality and integrity of a CVM.

    -

    Attested TLS (aTLS)

    -

    In a CC environment, attested TLS (aTLS) can be used to establish secure connections between two parties using the remote attestation features of the CC components.

    -

    aTLS modifies the TLS handshake by embedding an attestation statement into the TLS certificate. -Instead of relying on a certificate authority, aTLS uses this attestation statement to establish trust in the certificate.

    -

    The protocol can be used by clients to verify a server certificate, by a server to verify a client certificate, or for mutual verification (mutual aTLS).

    -

    Overview

    -

    The challenge for Constellation is to lift a CVM's attestation statement to the Kubernetes software layer and make it end-to-end verifiable. -From there, Constellation needs to expand the attestation from a single CVM to the entire cluster.

    -

    The JoinService and VerificationService are where all runs together. -Internally, the JoinService uses remote attestation to securely join CVM nodes to the cluster. -Externally, the VerificationService provides an attestation statement for the cluster's CVMs and configuration.

    -

    The following explains the details of both steps.

    -

    Node attestation

    -

    The idea is that Constellation nodes should have verifiable integrity from the CVM hardware measurement up to the Kubernetes software layer. -The solution is a verifiable boot chain and an integrity-protected runtime environment.

    -

    Constellation uses measured boot within CVMs, measuring each component in the boot process before executing it. -Outside of CC, this is usually implemented via TPMs. -CVM technologies differ in how they implement runtime measurements, but the general concepts are similar to those of a TPM. -For simplicity, TPM terminology like PCR is used in the following.

    -

    When a Constellation node image boots inside a CVM, measured boot is used for all stages and components of the boot chain. -This process goes up to the root filesystem. -The root filesystem is mounted read-only with integrity protection. -For the details on the image and boot stages see the image architecture documentation. -Any changes to the image will inevitably also change the corresponding PCR values. -To create a node attestation statement, the Constellation image obtains a CVM attestation statement from the hardware. -This includes the runtime measurements and thereby binds the measured boot results to the CVM hardware measurement.

    -

    In addition to the image measurements, Constellation extends a PCR during the initialization phase that irrevocably marks the node as initialized. -The measurement is created using the clusterID, tying all future attestation statements to this ID. -Thereby, an attestation statement is unique for every cluster and a node can be identified unambiguously as being initialized.

    -

    To verify an attestation, the hardware's signature and a statement are verified first to establish trust in the contained runtime measurements. -If successful, the measurements are verified against the trusted values of the particular Constellation release version. -Finally, the measurement of the clusterID can be compared by calculating it with the master secret.

    -

    Runtime measurements

    -

    Constellation uses runtime measurements to implement the measured boot approach. -As stated above, the underlying hardware technology and guest firmware differ in their implementations of runtime measurements. -The following gives a detailed description of the available measurements in the different cloud environments.

    -

    The runtime measurements consist of two types of values:

    -
      -
    • -

      Measurements produced by the cloud infrastructure and firmware of the CVM: -These are measurements of closed-source firmware and other values controlled by the cloud provider. -While not being reproducible for the user, some of them can be compared against previously observed values. -Others may change frequently and aren't suitable for verification. -The signed image measurements include measurements that are known, previously observed values.

      -
    • -
    • -

      Measurements produced by the Constellation bootloader and boot chain: -The Constellation Bootloader takes over from the CVM firmware and measures the rest of the boot chain. -The Constellation Bootstrapper is the first user mode component that runs in a Constellation image. -It extends PCR registers with the IDs of the cluster marking a node as initialized.

      -
    • -
    -

    Constellation allows to specify in the config which measurements should be enforced during the attestation process. -Enforcing non-reproducible measurements controlled by the cloud provider means that changes in these values require manual updates to the cluster's config. -By default, Constellation only enforces measurements that are stable values produced by the infrastructure or by Constellation directly.

    -

    Constellation uses the vTPM (NitroTPM) feature of the AWS Nitro System on AWS for runtime measurements.

    The vTPM adheres to the TPM 2.0 specification. -The VMs are attested by obtaining signed PCR values over the VM's boot configuration from the TPM and comparing them to a known, good state (measured boot).

    The following table lists all PCR values of the vTPM and the measured components. -It also lists what components of the boot chain did the measurements and if the value is reproducible and verifiable. -The latter means that the value can be generated offline and compared to the one in the vTPM.

    PCRComponentsMeasured byReproducible and verifiable
    0FirmwareAWSNo
    1FirmwareAWSNo
    2FirmwareAWSNo
    3FirmwareAWSNo
    4Constellation Bootloader, Kernel, initramfs, Kernel command lineAWS, Constellation BootloaderYes
    5FirmwareAWSNo
    6FirmwareAWSNo
    7Secure Boot PolicyAWS, Constellation BootloaderNo
    8---
    9initramfs, Kernel command lineLinux KernelYes
    10User spaceLinux IMANo1
    11Unified Kernel Image componentsConstellation BootloaderYes
    12Reserved(User space, Constellation Bootloader)Yes
    13Reserved(Constellation Bootloader)Yes
    14Secure Boot StateConstellation BootloaderNo
    15ClusterIDConstellation BootstrapperYes
    16–23Unused--
    -

    CVM verification

    -

    To verify the integrity of the received attestation statement, a chain of trust from the CVM technology to the interface providing the statement has to be established. -For verification of the CVM technology, Constellation may expose additional options in its config file.

    -

    On AWS, AMD SEV-SNP is used to provide runtime encryption to the VMs. -An SEV-SNP attestation report is used to establish trust in the VM. -You may customize certain parameters for verification of the attestation statement using the Constellation config file.

      -
    • -

      TCB versions

      -

      You can set the minimum version numbers of components in the SEV-SNP TCB. -Use the latest versions to enforce that only machines with the most recent firmware updates are allowed to join the cluster. -Alternatively, you can set a lower minimum version to allow slightly out-of-date machines to still be able to join the cluster.

      -
    • -
    • -

      AMD Root Key Certificate

      -

      This certificate is the root of trust for verifying the SEV-SNP certificate chain.

      -
    • -
    • -

      AMD Signing Key Certificate

      -

      This is the intermediate certificate for verifying the SEV-SNP report's signature. -If it's not specified, the CLI fetches it from the AMD key distribution server.

      -
    • -
    -

    Cluster attestation

    -

    Cluster-facing, Constellation's JoinService verifies each node joining the cluster given the configured ground truth runtime measurements. -User-facing, the VerificationService provides an interface to verify a node using remote attestation. -By verifying the first node during the initialization and configuring the ground truth measurements that are subsequently enforced by the JoinService, the whole cluster is verified in a transitive way.

    -

    Cluster-facing attestation

    -

    The JoinService is provided with the runtime measurements of the whitelisted Constellation image version as the ground truth. -During the initialization and the cluster bootstrapping, each node connects to the JoinService using aTLS. -During the handshake, the node transmits an attestation statement including its runtime measurements. -The JoinService verifies that statement and compares the measurements against the ground truth. -For details of the initialization process check the microservice descriptions.

    -

    After the initialization, every node updates its runtime measurements with the clusterID value, marking it irreversibly as initialized. -When an initialized node tries to join another cluster, its measurements inevitably mismatch the measurements of an uninitialized node and it will be declined.

    -

    User-facing attestation

    -

    The VerificationService provides an endpoint for obtaining its hardware-based remote attestation statement, which includes the runtime measurements. -A user can verify this statement and compare the measurements against the configured ground truth and, thus, verify the identity and integrity of all Constellation components and the cluster configuration. Subsequently, the user knows that the entire cluster is in the expected state and is trustworthy.

    -

    Putting it all together

    -

    This section puts the aforementioned concepts together and illustrate how trust into a Constellation cluster is established and maintained.

    -

    CLI and node images

    -

    It all starts with the CLI executable. The CLI is signed by Edgeless Systems. To ensure non-repudiability for CLI releases, Edgeless Systems publishes corresponding signatures to the public ledger of the sigstore project. There's a step-by-step guide on how to verify CLI signatures based on sigstore.

    -

    The CLI contains the latest runtime measurements of the Constellation node image for all supported cloud platforms. In case a different version of the node image is to be used, the corresponding runtime measurements can be fetched using the CLI's fetch-measurements command. This command downloads the runtime measurements and the corresponding signature from cdn.confidential.cloud. See for example the following files corresponding to node image v2.16.3:

    - -

    The CLI contains the long-term public key of Edgeless Systems to verify the signature of downloaded runtime measurements.

    -

    Cluster creation

    -

    When a cluster is created, the CLI automatically verifies the runtime measurements of the first node using remote attestation. Based on this, the CLI and the first node set up a temporary TLS connection. This aTLS connection is used for two things:

    -
      -
    1. The CLI sends the master secret of the to-be-created cluster to the CLI. The master secret is generated by the first node.
    2. -
    3. The first node sends a kubeconfig file with Kubernetes credentials to the CLI.
    4. -
    -

    After this, the aTLS connection is closed and the first node bootstraps the Kubernetes cluster. All subsequent interactions between the CLI and the cluster go via the Kubernetes API server running inside the cluster. The CLI (and other tools like kubectl) use the credentials referenced by the kubeconfig file to authenticate themselves towards the Kubernetes API server and to establish a mTLS connection.

    -

    The CLI connects to the Kubernetes API to write the runtime measurements for the applicable node image to etcd. The JoinService uses these runtime measurements to verify all nodes that join the cluster subsequently.

    -

    Chain of trust

    -

    In summary, there's a chain of trust based on cryptographic signatures that goes from the user to the cluster via the CLI. This is illustrated in the following diagram.

    - -

    Upgrades

    -

    Whenever a cluster is upgraded to a new version of the node image, the CLI sends the corresponding runtime measurements via the Kubernetes API server. The new runtime measurements are stored in etcd within the cluster and replace any previous runtime measurements. The new runtime measurements are then used automatically by the JoinService for the verification of new nodes.

    -

    References

    - -

    Footnotes

    -
      -
    1. -

      Linux IMA produces runtime measurements of user-space binaries. -However, these measurements aren't deterministic and thus, PCR[10] can't be compared to a constant value. -Instead, a policy engine must be used to verify the TPM event log against a policy. 2 3 4

      -
    2. -
    -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/architecture/encrypted-storage/index.html b/pr-preview/pr-4027/next/architecture/encrypted-storage/index.html deleted file mode 100644 index 3251eb3ba..000000000 --- a/pr-preview/pr-4027/next/architecture/encrypted-storage/index.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - -Encrypted persistent storage | Constellation - - - - - - - -
    Version: Next

    Encrypted persistent storage

    -

    Confidential VMs provide runtime memory encryption to protect data in use. -In the context of Kubernetes, this is sufficient for the confidentiality and integrity of stateless services. -Consider a front-end web server, for example, that keeps all connection information cached in main memory. -No sensitive data is ever written to an insecure medium. -However, many real-world applications need some form of state or data-lake service that's connected to a persistent storage device and requires encryption at rest. -As described in Use persistent storage, cloud service providers (CSPs) use the container storage interface (CSI) to make their storage solutions available to Kubernetes workloads. -These CSI storage solutions often support some sort of encryption. -For example, Google Cloud encrypts data at rest by default, without any action required by the customer.

    -

    Cloud provider-managed encryption

    -

    CSP-managed storage solutions encrypt the data in the cloud backend before writing it physically to disk. -In the context of confidential computing and Constellation, the CSP and its managed services aren't trusted. -Hence, cloud provider-managed encryption protects your data from offline hardware access to physical storage devices. -It doesn't protect it from anyone with infrastructure-level access to the storage backend or a malicious insider in the cloud platform. -Even with "bring your own key" or similar concepts, the CSP performs the encryption process with access to the keys and plaintext data.

    -

    In the security model of Constellation, securing persistent storage and thereby data at rest requires that all cryptographic operations are performed inside a trusted execution environment. -Consequently, using CSP-managed encryption of persistent storage usually isn't an option.

    -

    Constellation-managed encryption

    -

    Constellation provides CSI drivers for storage solutions in all major clouds with built-in encryption support. -Block storage provisioned by the CSP is mapped using the dm-crypt, and optionally the dm-integrity, kernel modules, before it's formatted and accessed by the Kubernetes workloads. -All cryptographic operations happen inside the trusted environment of the confidential Constellation node.

    -

    Note that for integrity-protected disks, volume expansion isn't supported.

    -

    By default the driver uses data encryption keys (DEKs) issued by the Constellation KeyService. -The DEKs are in turn derived from the Constellation's key encryption key (KEK), which is directly derived from the master secret. -This is the recommended mode of operation, and also requires the least amount of setup by the cluster administrator.

    -

    Alternatively, the driver can be configured to use a key management system to store and access KEKs and DEKs.

    -

    Refer to keys and cryptography for more details on key management in Constellation.

    -

    Once deployed and configured, the CSI driver ensures transparent encryption and integrity of all persistent volumes provisioned via its storage class. -Data at rest is secured without any additional actions required by the developer.

    -

    Cryptographic algorithms

    -

    This section gives an overview of the libraries, cryptographic algorithms, and their configurations, used in Constellation's CSI drivers.

    -

    dm-crypt

    -

    To interact with the dm-crypt kernel module, Constellation uses libcryptsetup. -New devices are formatted as LUKS2 partitions with a sector size of 4096 bytes. -The used key derivation function is Argon2id with the recommended parameters for memory-constrained environments of 3 iterations and 64 MiB of memory, utilizing 4 parallel threads. -For encryption Constellation uses AES in XTS-Plain64. The key size is 512 bit.

    -

    dm-integrity

    -

    To interact with the dm-integrity kernel module, Constellation uses libcryptsetup. -When enabled, the used data integrity algorithm is HMAC with SHA256 as the hash function. -The tag size is 32 Bytes.

    -

    Encrypted S3 object storage

    -

    Constellation comes with a service that you can use to transparently retrofit client-side encryption to existing applications that use S3 (AWS or compatible) for storage. -To learn more, check out the s3proxy documentation.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/architecture/images/index.html b/pr-preview/pr-4027/next/architecture/images/index.html deleted file mode 100644 index 3ac427b1a..000000000 --- a/pr-preview/pr-4027/next/architecture/images/index.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - -Constellation images | Constellation - - - - - - - -
    Version: Next

    Constellation images

    -

    Constellation uses a minimal version of Fedora as the operating system running inside confidential VMs. This Linux distribution is optimized for containers and designed to be stateless. -The Constellation images provide measured boot and an immutable filesystem.

    -

    Measured boot

    - -

    Measured boot uses a Trusted Platform Module (TPM) to measure every part of the boot process. This allows for verification of the integrity of a running system at any point in time. To ensure correct measurements of every stage, each stage is responsible to measure the next stage before transitioning.

    -

    Firmware

    -

    With confidential VMs, the firmware is the root of trust and is measured automatically at boot. After initialization, the firmware will load and measure the bootloader before executing it.

    -

    Bootloader

    -

    The bootloader is the first modifiable part of the boot chain. The bootloader is tasked with loading the kernel, initramfs and setting the kernel command line. The Constellation bootloader measures these components before starting the kernel.

    -

    initramfs

    -

    The initramfs is a small filesystem loaded to prepare the actual root filesystem. The Constellation initramfs maps the block device containing the root filesystem with dm-verity. The initramfs then mounts the root filesystem from the mapped block device.

    -

    dm-verity provides integrity checking using a cryptographic hash tree. When a block is read, its integrity is checked by verifying the tree against a trusted root hash. The initramfs reads this root hash from the previously measured kernel command line. Thus, if any block of the root filesystem's device is modified on disk, trying to read the modified block will result in a kernel panic at runtime.

    -

    After mounting the root filesystem, the initramfs will switch over and start the init process of the integrity-protected root filesystem.

    -

    State disk

    -

    In addition to the read-only root filesystem, each Constellation node has a disk for storing state data. -This disk is mounted readable and writable by the initramfs and contains data that should persist across reboots. -Such data can contain sensitive information and, therefore, must be stored securely. -To that end, the state disk is protected by authenticated encryption. -See the section on keys and encryption for more information on the cryptographic primitives in use.

    -

    Kubernetes components

    -

    During initialization, the Bootstrapper downloads and verifies the Kubernetes components as configured by the user. -They're stored on the state partition and can be updated once new releases need to be installed.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/architecture/keys/index.html b/pr-preview/pr-4027/next/architecture/keys/index.html deleted file mode 100644 index 26c7b3555..000000000 --- a/pr-preview/pr-4027/next/architecture/keys/index.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - -Key management and cryptographic primitives | Constellation - - - - - - - -
    Version: Next

    Key management and cryptographic primitives

    -

    Constellation protects and isolates your cluster and workloads. -To that end, cryptography is the foundation that ensures the confidentiality and integrity of all components. -Evaluating the security and compliance of Constellation requires a precise understanding of the cryptographic primitives and keys used. -The following gives an overview of the architecture and explains the technical details.

    -

    Confidential VMs

    -

    Confidential VM (CVM) technology comes with hardware and software components for memory encryption, isolation, and remote attestation. -For details on the implementations and cryptographic soundness, refer to the hardware vendors' documentation and advisories.

    -

    Master secret

    -

    The master secret is the cryptographic material used for deriving the clusterID and the key encryption key (KEK) for storage encryption. -It's generated during the bootstrapping of a Constellation cluster. -It can either be managed by Constellation or an external key management system. -In case of recovery, the master secret allows to decrypt the state and recover a Constellation cluster.

    -

    Cluster identity

    -

    The identity of a Constellation cluster is represented by cryptographic measurements:

    -

    The base measurements represent the identity of a valid, uninitialized Constellation node. -They depend on the node image, but are otherwise the same for every Constellation cluster. -On node boot, they're determined using the CVM's attestation mechanism and measured boot up to the read-only root filesystem.

    -

    The clusterID represents the identity of a single initialized Constellation cluster. -It's derived from the master secret and a cryptographically random salt and unique for every Constellation cluster. -The Bootstrapper measures the clusterID into its own PCR before executing any code not measured as part of the base measurements. -See Node attestation for details.

    -

    The remote attestation statement of a Constellation cluster combines the base measurements and the clusterID for a verifiable, unspoofable, unique identity.

    -

    Network encryption

    -

    Constellation encrypts all cluster network communication using the container network interface (CNI). -See network encryption for more details.

    -

    The Cilium agent running on each node establishes a secure WireGuard tunnel between it and all other known nodes in the cluster. -Each node creates its own Curve25519 encryption key pair and distributes its public key via Kubernetes. -A node uses another node's public key to decrypt and encrypt traffic from and to Cilium-managed endpoints running on that node. -Connections are always encrypted peer-to-peer using ChaCha20 with Poly1305. -WireGuard implements forward secrecy with key rotation every 2 minutes.

    -

    Storage encryption

    -

    Constellation supports transparent encryption of persistent storage. -The Linux kernel's device mapper-based encryption features are used to encrypt the data on the block storage level. -Currently, the following primitives are used for block storage encryption:

    - -

    Adding primitives for integrity protection in the CVM attacker model are under active development and will be available in a future version of Constellation. -See encrypted storage for more details.

    -

    As a cluster administrator, when creating a cluster, you can use the Constellation installation program to select one of the following methods for key management:

    -
      -
    • Constellation-managed key management
    • -
    • User-managed key management
    • -
    -

    Constellation-managed key management

    -

    Key material and key derivation

    -

    During the creation of a Constellation cluster, the cluster's master secret is used to derive a KEK. -This means creating two clusters with the same master secret will yield the same KEK. -Any data encryption key (DEK) is derived from the KEK via HKDF. -Note that the master secret is recommended to be unique for every cluster and shouldn't be reused (except in case of recovering a cluster).

    -

    State and storage

    -

    The KEK is derived from the master secret during the initialization. -Subsequently, all other key material is derived from the KEK. -Given the same KEK, any DEK can be derived deterministically from a given identifier. -Hence, there is no need to store DEKs. They can be derived on demand. -After the KEK was derived, it's stored in memory only and never leaves the CVM context.

    -

    Availability

    -

    Constellation-managed key management has the same availability as the underlying Kubernetes cluster. -Therefore, the KEK is stored in the distributed Kubernetes etcd storage to allow for unexpected but non-fatal (control-plane) node failure. -The etcd storage is backed by the encrypted and integrity protected state disk of the nodes.

    -

    Recovery

    -

    Constellation clusters can be recovered in the event of a disaster, even when all node machines have been stopped and need to be rebooted. -For details on the process see the recovery workflow.

    -

    User-managed key management

    -

    User-managed key management is under active development and will be available soon. -In scenarios where constellation-managed key management isn't an option, this mode allows you to keep full control of your keys. -For example, compliance requirements may force you to keep your KEKs in an on-prem key management system (KMS).

    -

    During the creation of a Constellation cluster, you specify a KEK present in a remote KMS. -This follows the common scheme of "bring your own key" (BYOK). -Constellation will support several KMSs for managing the storage and access of your KEK. -Initially, it will support the following KMSs:

    - -

    Storing the keys in Cloud KMS of AWS, Azure, or GCP binds the key usage to the particular cloud identity access management (IAM). -In the future, Constellation will support remote attestation-based access policies for Cloud KMS once available. -Note that using a Cloud KMS limits the isolation and protection to the guarantees of the particular offering.

    -

    KMIP support allows you to use your KMIP-compatible on-prem KMS and keep full control over your keys. -This follows the common scheme of "hold your own key" (HYOK).

    -

    The KEK is used to encrypt per-data "data encryption keys" (DEKs). -DEKs are generated to encrypt your data before storing it on persistent storage. -After being encrypted by the KEK, the DEKs are stored on dedicated cloud storage for persistence. -Currently, Constellation supports the following cloud storage options:

    - -

    The DEKs are only present in plaintext form in the encrypted main memory of the CVMs. -Similarly, the cryptographic operations for encrypting data before writing it to persistent storage are performed in the context of the CVMs.

    -

    Recovery and migration

    -

    In the case of a disaster, the KEK can be used to decrypt the DEKs locally and subsequently use them to decrypt and retrieve the data. -In case of migration, configuring the same KEK will provide seamless migration of data. -Thus, only the DEK storage needs to be transferred to the new cluster alongside the encrypted data for seamless migration.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/architecture/microservices/index.html b/pr-preview/pr-4027/next/architecture/microservices/index.html deleted file mode 100644 index c5fed4cad..000000000 --- a/pr-preview/pr-4027/next/architecture/microservices/index.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - -Microservices | Constellation - - - - - - - -
    Version: Next

    Microservices

    -

    Constellation takes care of bootstrapping and initializing a Confidential Kubernetes cluster. -During the lifetime of the cluster, it handles day 2 operations such as key management, remote attestation, and updates. -These features are provided by several microservices:

    - -

    The relations between microservices are shown in the following diagram:

    - -

    Bootstrapper

    -

    The Bootstrapper is the first microservice launched after booting a Constellation node image. -It sets up that machine as a Kubernetes node and integrates that node into the Kubernetes cluster. -To this end, the Bootstrapper first downloads and verifies the Kubernetes components at the configured versions. -The Bootstrapper tries to find an existing cluster and if successful, communicates with the JoinService to join the node. -Otherwise, it waits for an initialization request to create a new Kubernetes cluster.

    -

    JoinService

    -

    The JoinService runs as DaemonSet on each control-plane node. -New nodes (at cluster start, or later through autoscaling) send a request to the service over attested TLS (aTLS). -The JoinService verifies the new node's certificate and attestation statement. -If attestation is successful, the new node is supplied with an encryption key from the KeyService for its state disk, and a Kubernetes bootstrap token.

    - -

    VerificationService

    -

    The VerificationService runs as DaemonSet on each node. -It provides user-facing functionality for remote attestation during the cluster's lifetime via an endpoint for verifying the cluster. -Read more about the hardware-based attestation feature of Constellation and how to verify a cluster on the client side.

    -

    KeyService

    -

    The KeyService runs as DaemonSet on each control-plane node. -It implements the key management for the storage encryption keys in Constellation. These keys are used for the state disk of each node and the transparently encrypted storage for Kubernetes. -Depending on wether the constellation-managed or user-managed mode is used, the KeyService holds the key encryption key (KEK) directly or calls an external key management service (KMS) for key derivation respectively.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/architecture/networking/index.html b/pr-preview/pr-4027/next/architecture/networking/index.html deleted file mode 100644 index 672d0144a..000000000 --- a/pr-preview/pr-4027/next/architecture/networking/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -Network encryption | Constellation - - - - - - - -
    Version: Next

    Network encryption

    -

    Constellation encrypts all pod communication using the container network interface (CNI). -To that end, Constellation deploys, configures, and operates the Cilium CNI plugin. -Cilium provides transparent encryption for all cluster traffic using either IPSec or WireGuard. -Currently, Constellation only supports WireGuard as the encryption engine. -You can read more about the cryptographic soundness of WireGuard in their white paper.

    -

    Cilium is actively working on implementing a feature called host-to-host encryption mode for WireGuard. -With host-to-host, all traffic between nodes will be tunneled via WireGuard (host-to-host, host-to-pod, pod-to-host, pod-to-pod). -Until the host-to-host feature is released, Constellation enables pod-to-pod encryption. -This mode encrypts all traffic between Kubernetes pods using WireGuard tunnels.

    -

    When using Cilium in the default setup but with encryption enabled, there is a known issue -that can cause pod-to-pod traffic to be unencrypted. -To mitigate this issue, Constellation adds a strict mode to Cilium's pod-to-pod encryption. -This mode changes the default behavior of traffic that's destined for an unknown endpoint to not be send out in plaintext, but instead being dropped. -The strict mode distinguishes between traffic that's send to a pod from traffic that's destined for a cluster-external endpoint by considering the pod's CIDR range.

    -

    Traffic originating from hosts isn't encrypted yet. -This mainly includes health checks from Kubernetes API server. -Also, traffic proxied over the API server via e.g. kubectl port-forward isn't encrypted.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/architecture/observability/index.html b/pr-preview/pr-4027/next/architecture/observability/index.html deleted file mode 100644 index d7a019668..000000000 --- a/pr-preview/pr-4027/next/architecture/observability/index.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - -Observability | Constellation - - - - - - - -
    Version: Next

    Observability

    -

    In Kubernetes, observability is the ability to gain insight into the behavior and performance of applications. -It helps identify and resolve issues more effectively, ensuring stability and performance of Kubernetes workloads, reducing downtime and outages, and improving efficiency. -The "three pillars of observability" are logs, metrics, and traces.

    -

    In the context of Confidential Computing, observability is a delicate subject and needs to be applied such that it doesn't leak any sensitive information. -The following gives an overview of where and how you can apply standard observability tools in Constellation.

    -

    Cloud resource monitoring

    -

    While inaccessible, Constellation's nodes are still visible as black box VMs to the hypervisor. -Resource consumption, such as memory and CPU utilization, can be monitored from the outside and observed via the cloud platforms directly. -Similarly, other resources, such as storage and network and their respective metrics, are visible via the cloud platform.

    -

    Metrics

    -

    Metrics are numeric representations of data measured over intervals of time. They're essential for understanding system health and gaining insights using telemetry signals.

    -

    By default, Constellation exposes the metrics for Kubernetes system components inside the cluster. -Similarly, the etcd metrics endpoints are exposed inside the cluster. -These metrics endpoints can be disabled.

    -

    You can collect these cluster-internal metrics via tools such as Prometheus or the Elastic Stack.

    -

    Constellation's CNI Cilium also supports metrics via Prometheus endpoints. -However, in Constellation, they're disabled by default and must be enabled first.

    -

    Logs

    -

    Logs represent discrete events that usually describe what's happening with your service. -The payload is an actual message emitted from your system along with a metadata section containing a timestamp, labels, and tracking identifiers.

    -

    System logs

    -

    Detailed system-level logs are accessible via /var/log and journald on the nodes directly. -They can be collected from there, for example, via Filebeat and Logstash, which are tools of the Elastic Stack.

    -

    In case of an error during the initialization, the CLI automatically collects the Bootstrapper logs and returns these as a file for troubleshooting. Here is an example of such an event:

    -
    Cluster initialization failed. This error is not recoverable.
    Terminate your cluster and try again.
    Fetched bootstrapper logs are stored in "constellation-cluster.log"
    -

    Kubernetes logs

    -

    Constellation supports the Kubernetes logging architecture. -By default, logs are written to the nodes' encrypted state disks. -These include the Pod and container logs and the system component logs.

    -

    Constellation services run as Pods inside the kube-system namespace and use the standard container logging mechanism. -The same applies for the Cilium Pods.

    -

    You can collect logs from within the cluster via tools such as Fluentd, Loki, or the Elastic Stack.

    -

    Traces

    -

    Modern systems are implemented as interconnected complex and distributed microservices. Understanding request flows and system communications is challenging, mainly because all systems in a chain need to be modified to propagate tracing information. Distributed tracing is a new approach to increasing observability and understanding performance bottlenecks. A trace represents consecutive events that reflect an end-to-end request path in a distributed system.

    -

    Constellation supports traces for Kubernetes system components. -By default, they're disabled and need to be enabled first.

    -

    Similarly, Cilium can be enabled to export traces.

    -

    You can collect these traces via tools such as Jaeger or Zipkin.

    -

    Integrations

    -

    Platforms and SaaS solutions such as Datadog, logz.io, Dynatrace, or New Relic facilitate the observability challenge for Kubernetes and provide all-in-one SaaS solutions. -They install agents into the cluster that collect metrics, logs, and tracing information and upload them into the data lake of the platform. -Technically, the agent-based approach is compatible with Constellation, and attaching these platforms is straightforward. -However, you need to evaluate if the exported data might violate Constellation's compliance and privacy guarantees by uploading them to a third-party platform.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/architecture/orchestration/index.html b/pr-preview/pr-4027/next/architecture/orchestration/index.html deleted file mode 100644 index e94dd946d..000000000 --- a/pr-preview/pr-4027/next/architecture/orchestration/index.html +++ /dev/null @@ -1,80 +0,0 @@ - - - - - -Orchestrating Constellation clusters | Constellation - - - - - - - -
    Version: Next

    Orchestrating Constellation clusters

    -

    You can use the CLI to create a cluster on the supported cloud platforms. -The CLI provisions the resources in your cloud environment and initiates the initialization of your cluster. -It uses a set of parameters and an optional configuration file to manage your cluster installation. -The CLI is also used for updating your cluster.

    -

    Workspaces

    -

    Each Constellation cluster has an associated workspace. -The workspace is where data such as the Constellation state and config files are stored. -Each workspace is associated with a single cluster and configuration. -The CLI stores state in the local filesystem making the current directory the active workspace. -Multiple clusters require multiple workspaces, hence, multiple directories. -Note that every operation on a cluster always has to be performed from the directory associated with its workspace.

    -

    You may copy files from the workspace to other locations, -but you shouldn't move or delete them while the cluster is still being used. -The Constellation CLI takes care of managing the workspace. -Only when a cluster was terminated, and you are sure the files aren't needed anymore, should you remove a workspace.

    -

    Cluster creation process

    -

    To allow for fine-grained configuration of your cluster and cloud environment, Constellation supports an extensive configuration file with strong defaults. Generating the configuration file is typically the first thing you do in the workspace.

    -

    Altogether, the following files are generated during the creation of a Constellation cluster and stored in the current workspace:

    -
      -
    • a configuration file
    • -
    • a state file
    • -
    • a Base64-encoded master secret
    • -
    • Terraform artifacts, stored in subdirectories
    • -
    • a Kubernetes kubeconfig file.
    • -
    -

    After the initialization of your cluster, the CLI will provide you with a Kubernetes kubeconfig file. -This file grants you access to your Kubernetes cluster and configures the kubectl tool. -In addition, the cluster's identifier is returned and stored in the state file.

    -

    Creation process details

    -
      -
    1. The CLI apply command first creates the confidential VM (CVM) resources in your cloud environment and configures the network
    2. -
    3. Each CVM boots the Constellation node image and measures every component in the boot chain
    4. -
    5. The first microservice launched in each node is the Bootstrapper
    6. -
    7. The Bootstrapper waits until it either receives an initialization request or discovers an initialized cluster
    8. -
    9. The CLI then connects to the Bootstrapper of a selected node, sends the configuration, and initiates the initialization of the cluster
    10. -
    11. The Bootstrapper of that node initializes the Kubernetes cluster and deploys the other Constellation microservices including the JoinService
    12. -
    13. Subsequently, the Bootstrappers of the other nodes discover the initialized cluster and send join requests to the JoinService
    14. -
    15. As part of the join request each node includes an attestation statement of its boot measurements as authentication
    16. -
    17. The JoinService verifies the attestation statements and joins the nodes to the Kubernetes cluster
    18. -
    19. This process is repeated for every node joining the cluster later (e.g., through autoscaling)
    20. -
    -

    Post-installation configuration

    -

    Post-installation the CLI provides a configuration for accessing the cluster using the Kubernetes API. -The kubeconfig file provides the credentials and configuration for connecting and authenticating to the API server. -Once configured, orchestrate the Kubernetes cluster via kubectl.

    -

    After the initialization, the CLI will present you with a couple of tokens:

    -
      -
    • The master secret (stored in the constellation-mastersecret.json file by default)
    • -
    • The clusterID of your cluster in Base64 encoding
    • -
    -

    You can read more about these values and their meaning in the guide on cluster identity.

    -

    The master secret must be kept secret and can be used to recover your cluster. -Instead of managing this secret manually, you can use your key management solution of choice with Constellation.

    -

    The clusterID uniquely identifies a cluster and can be used to verify your cluster.

    -

    Upgrades

    -

    Constellation images and microservices may need to be upgraded to new versions during the lifetime of a cluster. -Constellation implements a rolling update mechanism ensuring no downtime of the control or data plane. -You can upgrade a Constellation cluster with a single operation by using the CLI. -For step-by-step instructions on how to do this, refer to Upgrade your cluster.

    -

    Attestation of upgrades

    -

    With every new image, corresponding measurements are released. -During an update procedure, the CLI provides new measurements to the JoinService securely. -New measurements for an updated image are automatically pulled and verified by the CLI following the supply chain security concept of Constellation. -The attestation section describes in detail how these measurements are then used by the JoinService for the attestation of nodes.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/architecture/overview/index.html b/pr-preview/pr-4027/next/architecture/overview/index.html deleted file mode 100644 index b5f8554e2..000000000 --- a/pr-preview/pr-4027/next/architecture/overview/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - -Overview | Constellation - - - - - - - -
    Version: Next

    Overview

    -

    Constellation is a cloud-based confidential orchestration platform. -The foundation of Constellation is Kubernetes and therefore shares the same technology stack and architecture principles. -To learn more about Constellation and Kubernetes, see product overview.

    -

    About orchestration and updates

    -

    As a cluster administrator, you can use the Constellation CLI to install and deploy a cluster. -Updates are provided in accordance with the support policy.

    -

    About microservices and attestation

    -

    Constellation manages the nodes and network in your cluster. All nodes are bootstrapped by the Bootstrapper. They're verified and authenticated by the JoinService before being added to the cluster and the network. Finally, the entire cluster can be verified via the VerificationService using remote attestation.

    -

    About node images and verified boot

    -

    Constellation comes with operating system images for Kubernetes control-plane and worker nodes. -They're highly optimized for running containerized workloads and specifically prepared for running inside confidential VMs. -You can learn more about the images and how verified boot ensures their integrity during boot and beyond.

    -

    About key management and cryptographic primitives

    -

    Encryption of data at-rest, in-transit, and in-use is the fundamental building block for confidential computing and Constellation. Learn more about the keys and cryptographic primitives used in Constellation, encrypted persistent storage, and network encryption.

    -

    About observability

    -

    Observability in Kubernetes refers to the capability to troubleshoot issues using telemetry signals such as logs, metrics, and traces. -In the realm of Confidential Computing, it's crucial that observability aligns with confidentiality, necessitating careful implementation. -Learn more about the observability capabilities in Constellation.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/architecture/versions/index.html b/pr-preview/pr-4027/next/architecture/versions/index.html deleted file mode 100644 index ece5583dc..000000000 --- a/pr-preview/pr-4027/next/architecture/versions/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - -Versions and support policy | Constellation - - - - - - - -
    Version: Next

    Versions and support policy

    -

    All components of Constellation use a three-digit version number of the form v<MAJOR>.<MINOR>.<PATCH>. -The components are released in lock step, usually on the first Tuesday of every month. This release primarily introduces new features, but may also include security or performance improvements. The MINOR version will be incremented as part of this release.

    -

    Additional PATCH releases may be created on demand, to fix security issues or bugs before the next MINOR release window.

    -

    New releases are published on GitHub.

    -

    Kubernetes support policy

    -

    Constellation is aligned to the version support policy of Kubernetes, and therefore usually supports the most recent three minor versions. -When a new minor version of Kubernetes is released, support is added to the next Constellation release, and that version then supports four Kubernetes versions. -Subsequent Constellation releases drop support for the oldest (and deprecated) Kubernetes version.

    -

    The following Kubernetes versions are currently supported:

    -
      -
    • v1.30.14
    • -
    • v1.31.13
    • -
    • v1.32.9
    • -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/category/architecture/index.html b/pr-preview/pr-4027/next/category/architecture/index.html deleted file mode 100644 index a5a70f90f..000000000 --- a/pr-preview/pr-4027/next/category/architecture/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Architecture | Constellation - - - - - - - -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/category/basics/index.html b/pr-preview/pr-4027/next/category/basics/index.html deleted file mode 100644 index 78d73492e..000000000 --- a/pr-preview/pr-4027/next/category/basics/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Basics | Constellation - - - - - - - -
    Version: Next

    Basics

    📄️ Security benefits

    Constellation implements the Confidential Kubernetes concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be verified.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/category/getting-started/index.html b/pr-preview/pr-4027/next/category/getting-started/index.html deleted file mode 100644 index 0d17cdbc9..000000000 --- a/pr-preview/pr-4027/next/category/getting-started/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Getting started | Constellation - - - - - - - - - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/category/reference/index.html b/pr-preview/pr-4027/next/category/reference/index.html deleted file mode 100644 index 263080d34..000000000 --- a/pr-preview/pr-4027/next/category/reference/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Reference | Constellation - - - - - - - - - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/category/workflows/index.html b/pr-preview/pr-4027/next/category/workflows/index.html deleted file mode 100644 index 94399f4a3..000000000 --- a/pr-preview/pr-4027/next/category/workflows/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -Workflows | Constellation - - - - - - - -
    Version: Next

    Workflows

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/getting-started/examples/emojivoto/index.html b/pr-preview/pr-4027/next/getting-started/examples/emojivoto/index.html deleted file mode 100644 index 28fdc3a61..000000000 --- a/pr-preview/pr-4027/next/getting-started/examples/emojivoto/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - -Emojivoto | Constellation - - - - - - - -
    Version: Next

    Emojivoto

    -

    Emojivoto is a simple and fun application that's well suited to test the basic functionality of your cluster.

    -emojivoto - Web UI -
      -
    1. Deploy the application: -
      kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment
      -
    2. -
    3. Wait until it becomes available: -
      kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments
      -
    4. -
    5. Forward the web service to your machine: -
      kubectl -n emojivoto port-forward svc/web-svc 8080:80
      -
    6. -
    7. Visit http://localhost:8080
    8. -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/getting-started/examples/filestash-s3proxy/index.html b/pr-preview/pr-4027/next/getting-started/examples/filestash-s3proxy/index.html deleted file mode 100644 index 7b9994040..000000000 --- a/pr-preview/pr-4027/next/getting-started/examples/filestash-s3proxy/index.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - -Deploying Filestash | Constellation - - - - - - - -
    Version: Next

    Deploying Filestash

    -

    Filestash is a web frontend for different storage backends, including S3. -It's a useful application to showcase s3proxy in action.

    -
      -
    1. Deploy s3proxy as described in Deployment.
    2. -
    3. Create a deployment file for Filestash with one pod:
    4. -
    -
    cat << EOF > "deployment-filestash.yaml"
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: filestash
    spec:
    replicas: 1
    selector:
    matchLabels:
    app: filestash
    template:
    metadata:
    labels:
    app: filestash
    spec:
    hostAliases:
    - ip: $(kubectl get svc s3proxy-service -o=jsonpath='{.spec.clusterIP}')
    hostnames:
    - "s3.us-east-1.amazonaws.com"
    - "s3.us-east-2.amazonaws.com"
    - "s3.us-west-1.amazonaws.com"
    - "s3.us-west-2.amazonaws.com"
    - "s3.eu-north-1.amazonaws.com"
    - "s3.eu-south-1.amazonaws.com"
    - "s3.eu-south-2.amazonaws.com"
    - "s3.eu-west-1.amazonaws.com"
    - "s3.eu-west-2.amazonaws.com"
    - "s3.eu-west-3.amazonaws.com"
    - "s3.eu-central-1.amazonaws.com"
    - "s3.eu-central-2.amazonaws.com"
    - "s3.ap-northeast-1.amazonaws.com"
    - "s3.ap-northeast-2.amazonaws.com"
    - "s3.ap-northeast-3.amazonaws.com"
    - "s3.ap-east-1.amazonaws.com"
    - "s3.ap-southeast-1.amazonaws.com"
    - "s3.ap-southeast-2.amazonaws.com"
    - "s3.ap-southeast-3.amazonaws.com"
    - "s3.ap-southeast-4.amazonaws.com"
    - "s3.ap-south-1.amazonaws.com"
    - "s3.ap-south-2.amazonaws.com"
    - "s3.me-south-1.amazonaws.com"
    - "s3.me-central-1.amazonaws.com"
    - "s3.il-central-1.amazonaws.com"
    - "s3.af-south-1.amazonaws.com"
    - "s3.ca-central-1.amazonaws.com"
    - "s3.sa-east-1.amazonaws.com"
    containers:
    - name: filestash
    image: machines/filestash:latest
    ports:
    - containerPort: 8334
    volumeMounts:
    - name: ca-cert
    mountPath: /etc/ssl/certs/kube-ca.crt
    subPath: kube-ca.crt
    volumes:
    - name: ca-cert
    secret:
    secretName: s3proxy-tls
    items:
    - key: ca.crt
    path: kube-ca.crt
    EOF
    -

    The pod spec includes the hostAliases key, which adds an entry to the pod's /etc/hosts. -The entry forwards all requests for any of the currently defined AWS regions to the Kubernetes service s3proxy-service. -If you followed the s3proxy Deployment guide, this service points to a s3proxy pod.

    -

    The deployment specifies all regions explicitly to prevent accidental data leaks. -If one of your buckets were located in a region that's not part of the hostAliases key, traffic towards those buckets would not be redirected to s3proxy. -Similarly, if you want to exclude data for specific regions from going through s3proxy you can remove those regions from the deployment.

    -

    The spec also includes a volume mount for the TLS certificate and adds it to the pod's certificate trust store. -The volume is called ca-cert. -The key ca.crt of that volume is mounted to /etc/ssl/certs/kube-ca.crt, which is the default certificate trust store location for that container's OpenSSL library. -Not adding the CA certificate will result in TLS authentication errors.

    -
      -
    1. Apply the file: kubectl apply -f deployment-filestash.yaml
    2. -
    -

    Afterward, you can use a port forward to access the Filestash pod: -kubectl port-forward pod/$(kubectl get pod --selector='app=filestash' -o=jsonpath='{.items[*].metadata.name}') 8334:8334

    -
      -
    1. -

      After browsing to localhost:8443, Filestash will ask you to set an administrator password. -After setting it, you can directly leave the admin area by clicking the blue cloud symbol in the top left corner. -Subsequently, you can select S3 as storage backend and enter your credentials. -This will bring you to an overview of your buckets. -If you want to deploy Filestash in production, take a look at its documentation.

      -
    2. -
    3. -

      To see the logs of s3proxy intercepting requests made to S3, run: kubectl logs -f pod/$(kubectl get pod --selector='app=s3proxy' -o=jsonpath='{.items[*].metadata.name}') -Look out for log messages labeled intercepting. -There is one such log message for each message that's encrypted, decrypted, or blocked.

      -
    4. -
    5. -

      Once you have uploaded a file with Filestash, you should be able to view the file in Filestash. -However, if you go to the AWS S3 Web UI and download the file you just uploaded in Filestash, you won't be able to read it. -Another way to spot encrypted files without downloading them is to click on a file, scroll to the Metadata section, and look for the header named x-amz-meta-constellation-encryption. -This header holds the encrypted data encryption key of the object and is only present on objects that are encrypted by s3proxy.

      -
    6. -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/getting-started/examples/horizontal-scaling/index.html b/pr-preview/pr-4027/next/getting-started/examples/horizontal-scaling/index.html deleted file mode 100644 index 96b8b6511..000000000 --- a/pr-preview/pr-4027/next/getting-started/examples/horizontal-scaling/index.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - -Horizontal Pod Autoscaling | Constellation - - - - - - - -
    Version: Next

    Horizontal Pod Autoscaling

    -

    This example demonstrates Constellation's autoscaling capabilities. It's based on the Kubernetes HorizontalPodAutoscaler Walkthrough. During the following steps, Constellation will spawn new VMs on demand, verify them, add them to the cluster, and delete them again when the load has settled down.

    -

    Requirements

    -

    The cluster needs to be initialized with Kubernetes 1.23 or later. In addition, autoscaling must be enabled to enable Constellation to assign new nodes dynamically.

    -

    Just for this example specifically, the cluster should have as few worker nodes in the beginning as possible. Start with a small cluster with only one low-powered node for the control-plane node and one low-powered worker node.

    -
    info

    We tested the example using instances of types Standard_DC4as_v5 on Azure and n2d-standard-4 on GCP.

    -

    Setup

    -
      -
    1. -

      Install the Kubernetes Metrics Server:

      -
      kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
      -
    2. -
    3. -

      Deploy the HPA example server that's supposed to be scaled under load.

      -

      This manifest is similar to the one from the Kubernetes HPA walkthrough, but with increased CPU limits and requests to facilitate the triggering of node scaling events.

      -
      cat <<EOF | kubectl apply -f -
      apiVersion: apps/v1
      kind: Deployment
      metadata:
      name: php-apache
      spec:
      selector:
      matchLabels:
      run: php-apache
      replicas: 1
      template:
      metadata:
      labels:
      run: php-apache
      spec:
      containers:
      - name: php-apache
      image: registry.k8s.io/hpa-example
      ports:
      - containerPort: 80
      resources:
      limits:
      cpu: 900m
      requests:
      cpu: 600m
      ---
      apiVersion: v1
      kind: Service
      metadata:
      name: php-apache
      labels:
      run: php-apache
      spec:
      ports:
      - port: 80
      selector:
      run: php-apache
      EOF
      -
    4. -
    5. -

      Create a HorizontalPodAutoscaler.

      -

      Set an average CPU usage across all Pods of 20% to see one additional worker node being created later. Note that the CPU usage isn't related to the host CPU usage, but rather to the requested CPU capacities (20% of 600 milli-cores CPU across all Pods). See the original tutorial for more information on the HPA configuration.

      -
      kubectl autoscale deployment php-apache --cpu-percent=20 --min=1 --max=10
      -
    6. -
    7. -

      Create a Pod that generates load on the server:

      -
      kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while true; do wget -q -O- http://php-apache; done"
      -
    8. -
    9. -

      Wait a few minutes until new nodes are added to the cluster. You can monitor the state of the HorizontalPodAutoscaler, the list of nodes, and the behavior of the autoscaler.

      -
    10. -
    11. -

      To stop the load generator, press CTRL+C and run:

      -
      kubectl delete pod load-generator
      -
    12. -
    13. -

      The cluster-autoscaler checks every few minutes if nodes are underutilized. It will taint such candidates for removal and wait additional 10 minutes before the nodes are eventually removed and deallocated. The whole process can take about 20 minutes.

      -
    14. -
    -

    Monitoring

    -
    tip

    For better observability, run the listed commands in different tabs in your terminal.

    -

    You can watch the status of the HorizontalPodAutoscaler with the current CPU usage, the target CPU limit, and the number of replicas created with:

    -
    kubectl get hpa php-apache --watch
    -

    From time to time compare the list of nodes to check the behavior of the autoscaler:

    -
    kubectl get nodes
    -

    For deeper insights, see the logs of the autoscaler Pod, which contains more details about the scaling decision process:

    -
    kubectl logs -f deployment/constellation-cluster-autoscaler -n kube-system
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/getting-started/examples/index.html b/pr-preview/pr-4027/next/getting-started/examples/index.html deleted file mode 100644 index 9d79a41d4..000000000 --- a/pr-preview/pr-4027/next/getting-started/examples/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - -Examples | Constellation - - - - - - - -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/getting-started/examples/online-boutique/index.html b/pr-preview/pr-4027/next/getting-started/examples/online-boutique/index.html deleted file mode 100644 index f4b045d7b..000000000 --- a/pr-preview/pr-4027/next/getting-started/examples/online-boutique/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -Online Boutique | Constellation - - - - - - - -
    Version: Next

    Online Boutique

    -

    Online Boutique is an e-commerce demo application by Google consisting of 11 separate microservices. In this demo, Constellation automatically sets up a load balancer on your CSP, making it easy to expose services from your confidential cluster.

    -Online Boutique - Web UI -
      -
    1. Create a namespace: -
      kubectl create ns boutique
      -
    2. -
    3. Deploy the application: -
      kubectl apply -n boutique -f https://github.com/GoogleCloudPlatform/microservices-demo/raw/main/release/kubernetes-manifests.yaml
      -
    4. -
    5. Wait for all services to become available: -
      kubectl wait --for=condition=available --timeout=300s -n boutique --all deployments
      -
    6. -
    7. Get the frontend's external IP address: -
      $ kubectl get service frontend-external -n boutique | awk '{print $4}'
      EXTERNAL-IP
      <your-ip>
      -(<your-ip> is a placeholder for the IP assigned by your CSP.)
    8. -
    9. Enter the IP from the result in your browser to browse the online shop.
    10. -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/getting-started/first-steps-local/index.html b/pr-preview/pr-4027/next/getting-started/first-steps-local/index.html deleted file mode 100644 index 5ee80ec39..000000000 --- a/pr-preview/pr-4027/next/getting-started/first-steps-local/index.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - - -First steps with a local cluster | Constellation - - - - - - - -
    Version: Next

    First steps with a local cluster

    -

    A local cluster lets you deploy and test Constellation without a cloud subscription. -You have two options:

    -
      -
    • Use MiniConstellation to automatically deploy a two-node cluster.
    • -
    • For more fine-grained control, create the cluster using the QEMU provider.
    • -
    -

    Both options use virtualization to create a local cluster with control-plane nodes and worker nodes. They don't require hardware with Confidential VM (CVM) support. For attestation, they currently use a software-based vTPM provided by KVM/QEMU.

    -

    You need an x64 machine with a Linux OS. -You can use a VM, but it needs nested virtualization.

    -

    Prerequisites

    -
      -
    • Machine requirements: -
        -
      • An x86-64 CPU with at least 4 cores (6 cores are recommended)
      • -
      • At least 4 GB RAM (6 GB are recommended)
      • -
      • 20 GB of free disk space
      • -
      • Hardware virtualization enabled in the BIOS/UEFI (often referred to as Intel VT-x or AMD-V/SVM) / nested-virtualization support when using a VM
      • -
      -
    • -
    • Software requirements: - -
    • -
    -

    Software installation on Ubuntu

    -
    # install Docker
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    sudo apt update
    sudo apt install docker-ce
    # install other dependencies
    sudo apt install xsltproc
    sudo snap install kubectl --classic
    # install Constellation CLI
    curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-amd64
    sudo install constellation-linux-amd64 /usr/local/bin/constellation
    # do not drop forwarded packages
    sudo iptables -P FORWARD ACCEPT
    -

    Create a cluster

    -

    With the constellation mini command, you can deploy and test Constellation locally. This mode is called MiniConstellation. Conceptually, MiniConstellation is similar to MicroK8s, K3s, and minikube.

    caution

    MiniConstellation has specific soft- and hardware requirements such as a Linux OS running on an x86-64 CPU. Pay attention to all prerequisites when setting up.

    note

    Since MiniConstellation runs on your local system, cloud features such as load balancing, -attaching persistent storage, or autoscaling aren't available.

    The following creates your MiniConstellation cluster (may take up to 10 minutes to complete):

    constellation mini up

    This will configure your current directory as the workspace for this cluster. -All constellation commands concerning this cluster need to be issued from this directory.

    -

    Connect to the cluster

    -

    Your cluster initially consists of a single control-plane node:

    -
    $ kubectl get nodes
    NAME STATUS ROLES AGE VERSION
    control-plane-0 Ready control-plane 66s v1.24.6
    -

    Additional nodes will request to join the cluster shortly. Before each additional node is allowed to join the cluster, its state is verified using remote attestation by the JoinService. -If verification passes successfully, the new node receives keys and certificates to join the cluster.

    -

    You can follow this process by viewing the logs of the JoinService:

    -
    $ kubectl logs -n kube-system daemonsets/join-service -f
    {"level":"INFO","ts":"2022-10-14T09:32:20Z","caller":"cmd/main.go:48","msg":"Constellation Node Join Service","version":"2.1.0","cloudProvider":"qemu"}
    {"level":"INFO","ts":"2022-10-14T09:32:20Z","logger":"validator","caller":"watcher/validator.go:96","msg":"Updating expected measurements"}
    ...
    -

    Once all nodes have joined your cluster, it may take a couple of minutes for all resources to become available. -You can check on the state of your cluster by running the following:

    -
    $ kubectl get nodes
    NAME STATUS ROLES AGE VERSION
    control-plane-0 Ready control-plane 2m59s v1.24.6
    worker-0 Ready <none> 32s v1.24.6
    -

    Deploy a sample application

    -
      -
    1. Deploy the emojivoto app
    2. -
    -
    kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment
    -
      -
    1. Expose the frontend service locally
    2. -
    -
    kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments
    kubectl -n emojivoto port-forward svc/web-svc 8080:80 &
    curl http://localhost:8080
    kill %1
    -

    Terminate your cluster

    -

    Once you are done, you can clean up the created resources using the following command:

    constellation mini down

    This will destroy your cluster and clean up your workspace. -The VM image and cluster configuration file (constellation-conf.yaml) will be kept and may be reused to create new clusters.

    -

    Troubleshooting

    -

    Make sure to use the latest release and check out the known issues.

    -

    VMs have no internet access / CLI remains in "Initializing cluster" state

    -

    iptables rules may prevent your VMs from accessing the internet. -Make sure your rules aren't dropping forwarded packages.

    -

    List your rules:

    -
    sudo iptables -S
    -

    The output may look similar to the following:

    -
    -P INPUT ACCEPT
    -P FORWARD DROP
    -P OUTPUT ACCEPT
    -N DOCKER
    -N DOCKER-ISOLATION-STAGE-1
    -N DOCKER-ISOLATION-STAGE-2
    -N DOCKER-USER
    -

    If your FORWARD chain is set to DROP, you need to update your rules:

    -
    sudo iptables -P FORWARD ACCEPT
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/getting-started/first-steps/index.html b/pr-preview/pr-4027/next/getting-started/first-steps/index.html deleted file mode 100644 index 40d74172d..000000000 --- a/pr-preview/pr-4027/next/getting-started/first-steps/index.html +++ /dev/null @@ -1,90 +0,0 @@ - - - - - -First steps with Constellation | Constellation - - - - - - - -
    Version: Next

    First steps with Constellation

    -

    The following steps guide you through the process of creating a cluster and deploying a sample app. This example assumes that you have successfully installed and set up Constellation, -and have access to a cloud subscription.

    -
    tip

    If you don't have a cloud subscription, you can also set up a local Constellation cluster using virtualization for testing.

    -
    note

    If you encounter any problem with the following steps, make sure to use the latest release and check out the known issues.

    -

    Create a cluster

    -
      -
    1. -

      Create the configuration file and state file for your cloud provider. If you are following the steps of this guide, there is no need to edit the file.

      -
      constellation config generate aws
      -
    2. -
    3. -

      Create your IAM configuration.

      -
      constellation iam create aws --zone=us-east-2a --prefix=constellTest --update-config

      This command creates IAM configuration for the AWS zone us-east-2a using the prefix constellTest for all named resources being created. It also updates the configuration file constellation-conf.yaml in your current directory with the IAM values filled in.

      Depending on the attestation variant selected on config generation, different regions are available. -AMD SEV-SNP machines (requires the default attestation variant awsSEVSNP) are currently available in the following regions:

        -
      • eu-west-1
      • -
      • us-east-2
      • -

      You can find a list of regions that support AMD SEV-SNP in AWS's documentation.

      NitroTPM machines (requires the attestation variant awsNitroTPM) are available in all regions. -Constellation OS images are currently replicated to the following regions:

        -
      • eu-central-1
      • -
      • eu-west-1
      • -
      • eu-west-3
      • -
      • us-east-2
      • -
      • ap-south-1
      • -

      If you require the OS image to be available in another region, let us know.

      You can find a list of all regions in AWS's documentation.

      -
      tip

      To learn about all options you have for managing IAM resources and Constellation configuration, see the Configuration workflow.

      -
    4. -
    -
      -
    1. -

      Create the cluster. constellation apply uses options set in constellation-conf.yaml. -If you want to manually manage your cloud resources, for example by using Terraform, follow the corresponding instructions in the Create workflow.

      -
      tip

      On Azure, you may need to wait 15+ minutes at this point for role assignments to propagate.

      -
      constellation apply -y
      -

      This should look similar to the following:

      -
      $ constellation apply -y
      Checking for infrastructure changes
      The following Constellation cluster will be created:
      3 control-plane nodes of type n2d-standard-4 will be created.
      1 worker node of type n2d-standard-4 will be created.
      Creating
      Cloud infrastructure created successfully
      Your Constellation master secret was successfully written to ./constellation-mastersecret.json
      Connecting
      Initializing cluster
      Installing Kubernetes components
      Your Constellation cluster was successfully initialized.

      Constellation cluster identifier g6iMP5wRU1b7mpOz2WEISlIYSfdAhB0oNaOg6XEwKFY=
      Kubernetes configuration constellation-admin.conf

      You can now connect to your cluster by executing:
      export KUBECONFIG="$PWD/constellation-admin.conf"
      -

      The cluster's identifier will be different in your output. -Keep constellation-mastersecret.json somewhere safe. -This will allow you to recover your cluster in case of a disaster.

      -
      info

      Depending on your CSP and region, constellation apply may take 10+ minutes to complete.

      -
    2. -
    3. -

      Configure kubectl.

      -
      export KUBECONFIG="$PWD/constellation-admin.conf"
      -
    4. -
    -

    Deploy a sample application

    -
      -
    1. -

      Deploy the emojivoto app

      -
      kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment
      -
    2. -
    3. -

      Expose the frontend service locally

      -
      kubectl wait --for=condition=available --timeout=60s -n emojivoto --all deployments
      kubectl -n emojivoto port-forward svc/web-svc 8080:80 &
      curl http://localhost:8080
      kill %1
      -
    4. -
    -

    Terminate your cluster

    -

    Use the CLI to terminate your cluster. If you manually used Terraform to manage your cloud resources, follow the corresponding instructions in the Terminate workflow.

    -
    constellation terminate
    -

    This should give the following output:

    -
    $ constellation terminate
    You are about to terminate a Constellation cluster.
    All of its associated resources will be DESTROYED.
    This action is irreversible and ALL DATA WILL BE LOST.
    Do you want to continue? [y/n]:
    -

    Confirm with y to terminate the cluster:

    -
    Terminating ...
    Your Constellation cluster was terminated successfully.
    -

    Optionally, you can also delete your IAM resources.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/getting-started/install/index.html b/pr-preview/pr-4027/next/getting-started/install/index.html deleted file mode 100644 index b1169588f..000000000 --- a/pr-preview/pr-4027/next/getting-started/install/index.html +++ /dev/null @@ -1,239 +0,0 @@ - - - - - -Installation and setup | Constellation - - - - - - - -
    Version: Next

    Installation and setup

    -

    Constellation runs entirely in your cloud environment and can be controlled via a dedicated command-line interface (CLI) or a Terraform provider.

    -

    Prerequisites

    -

    Make sure the following requirements are met:

    -
      -
    • Your machine is running Linux, macOS, or Windows
    • -
    • You have admin rights on your machine
    • -
    • kubectl is installed
    • -
    • Your CSP is Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), or STACKIT
    • -
    -

    Install the Constellation CLI

    -
    tip

    If you prefer to use Terraform, you can alternatively use the Terraform provider to manage the cluster's lifecycle.

    -

    The CLI executable is available at GitHub. -Install it with the following commands:

    -
      -
    1. Download the CLI:
    2. -
    curl -LO https://github.com/edgelesssys/constellation/releases/latest/download/constellation-linux-amd64
      -
    1. -

      Verify the signature (optional)

      -
    2. -
    3. -

      Install the CLI to your PATH:

      -
    4. -
    sudo install constellation-linux-amd64 /usr/local/bin/constellation
    -
    tip

    The CLI supports autocompletion for various shells. To set it up, run constellation completion and follow the given steps.

    -

    Set up cloud credentials

    -

    Constellation makes authenticated calls to the CSP API. Therefore, you need to set up Constellation with the credentials for your CSP.

    -
    tip

    If you don't have a cloud subscription, you can also set up a local Constellation cluster using virtualization for testing.

    -

    Required permissions

    -

    To set up a Constellation cluster, you need to perform two tasks that require permissions: create the infrastructure and create roles for cluster nodes. Both of these actions can be performed by different users, e.g., an administrator to create roles and a DevOps engineer to create the infrastructure.

    To create the IAM configuration for Constellation, you need the following permissions:

    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Action": [
    "ec2:DescribeAccountAttributes",
    "iam:AddRoleToInstanceProfile",
    "iam:AttachRolePolicy",
    "iam:CreateInstanceProfile",
    "iam:CreatePolicy",
    "iam:CreateRole",
    "iam:DeleteInstanceProfile",
    "iam:DeletePolicy",
    "iam:DeletePolicyVersion",
    "iam:DeleteRole",
    "iam:DetachRolePolicy",
    "iam:GetInstanceProfile",
    "iam:GetPolicy",
    "iam:GetPolicyVersion",
    "iam:GetRole",
    "iam:ListAttachedRolePolicies",
    "iam:ListInstanceProfilesForRole",
    "iam:ListPolicyVersions",
    "iam:ListRolePolicies",
    "iam:PassRole",
    "iam:RemoveRoleFromInstanceProfile",
    "sts:GetCallerIdentity"
    ],
    "Resource": "*"
    }
    ]
    }

    The built-in AdministratorAccess policy is a superset of these permissions.

    To create a Constellation cluster, see the permissions of main.tf.

    The built-in PowerUserAccess policy is a superset of these permissions.

    Follow Amazon's guide on understanding and managing policies.

    -

    Authentication

    -

    You need to authenticate with your CSP. The following lists the required steps for testing and production environments.

    -
    note

    The steps for a testing environment are simpler. However, they may expose secrets to the CSP. If in doubt, follow the production steps.

    -

    Testing

    You can use the AWS CloudShell. Make sure you are authorized to use it.

    Production

    Use the latest version of the AWS CLI on a trusted machine:

    aws configure

    Options and first steps are described in the AWS CLI documentation.

    -

    Next steps

    -

    You are now ready to deploy your first confidential Kubernetes cluster and application.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/getting-started/marketplaces/index.html b/pr-preview/pr-4027/next/getting-started/marketplaces/index.html deleted file mode 100644 index 97d0df0e4..000000000 --- a/pr-preview/pr-4027/next/getting-started/marketplaces/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - -Using Constellation via Cloud Marketplaces | Constellation - - - - - - - -
    Version: Next

    Using Constellation via Cloud Marketplaces

    -

    Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please contact us.

    -

    This document explains how to run Constellation with the dynamically billed cloud marketplace images.

    -

    To use Constellation's marketplace images, ensure that you are subscribed to the marketplace offering through the web portal.

    Then, enable the use of marketplace images in your Constellation constellation-conf.yaml config file:

    yq eval -i ".provider.aws.useMarketplaceImage = true" constellation-conf.yaml
    -

    Ensure that the cluster uses an official release image version (i.e., .image=vX.Y.Z in the constellation-conf.yaml file).

    -

    From there, you can proceed with the cluster creation as usual.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/index.html b/pr-preview/pr-4027/next/index.html deleted file mode 100644 index 08f1c3149..000000000 --- a/pr-preview/pr-4027/next/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - -Introduction | Constellation - - - - - - - -
    Version: Next

    Introduction

    -
    Maintenance Notice

    Constellation is no longer actively maintained by Edgeless Systems.

    This project is no longer receiving updates or support from Edgeless Systems. The repository and documentation remain available for archival purposes and community use.

    -

    Welcome to the documentation of Constellation! Constellation is a Kubernetes engine that aims to provide the best possible data security.

    -

    Constellation concept

    -

    Constellation shields your entire Kubernetes cluster from the underlying cloud infrastructure. Everything inside is always encrypted, including at runtime in memory. For this, Constellation leverages a technology called confidential computing and more specifically Confidential VMs.

    -
    tip

    See the 📄whitepaper for more information on confidential computing.

    -

    Goals

    -

    From a security perspective, Constellation is designed to keep all data always encrypted and to prevent any access from the underlying (cloud) infrastructure. This includes access from datacenter employees, privileged cloud admins, and attackers coming through the infrastructure. Such attackers could be malicious co-tenants escalating their privileges or hackers who managed to compromise a cloud server.

    -

    From a DevOps perspective, Constellation is designed to work just like what you would expect from a modern Kubernetes engine.

    -

    Use cases

    -

    Constellation provides unique security features and benefits. The core use cases are:

    -
      -
    • Increasing the overall security of your clusters
    • -
    • Increasing the trustworthiness of your SaaS offerings
    • -
    • Moving sensitive workloads from on-prem to the cloud
    • -
    • Meeting regulatory requirements
    • -
    -

    Next steps

    -

    You can learn more about the concept of Confidential Kubernetes, features, security benefits, and performance of Constellation in the Basics section. To jump right into the action head to Getting started.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/overview/clouds/index.html b/pr-preview/pr-4027/next/overview/clouds/index.html deleted file mode 100644 index 5e3d77b85..000000000 --- a/pr-preview/pr-4027/next/overview/clouds/index.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - -Feature status of clouds | Constellation - - - - - - - -
    Version: Next

    Feature status of clouds

    -

    What works on which cloud? Currently, Confidential VMs (CVMs) are available in varying quality on the different clouds and software stacks.

    -

    For Constellation, the ideal environment provides the following:

    -
      -
    1. Ability to run arbitrary software and images inside CVMs
    2. -
    3. CVMs based on AMD SEV-SNP (available in EPYC CPUs since the Milan generation) or Intel TDX (available in Xeon CPUs since the Sapphire Rapids generation)
    4. -
    5. Ability for CVM guests to obtain raw hardware attestation statements
    6. -
    7. Reviewable, open-source firmware inside CVMs
    8. -
    9. Capability of the firmware to attest the integrity of the code it passes control to, e.g., with an embedded virtual TPM (vTPM)
    10. -
    -

    (1) is a functional must-have. (2)--(5) are required for remote attestation that fully keeps the infrastructure/cloud out. Constellation can work without them or with approximations, but won't protect against certain privileged attackers anymore.

    -

    The following table summarizes the state of features for different infrastructures.

    -
    FeatureAWSAzureGCPSTACKITOpenStack (Yoga)
    1. Custom imagesYesYesYesYesYes
    2. SEV-SNP or TDXYesYesYesNoDepends on kernel/HV
    3. Raw guest attestationYesYesYesNoDepends on kernel/HV
    4. Reviewable firmwareYesNo*NoNoDepends on kernel/HV
    5. Confidential measured bootNoYesNoNoDepends on kernel/HV
    -

    Amazon Web Services (AWS)

    -

    Amazon EC2 supports AMD SEV-SNP. -Regarding (3), AWS provides direct access to attestation statements. -However, regarding (5), attestation is partially based on the NitroTPM for measured boot, which is a vTPM managed by the Nitro hypervisor. -Hence, the hypervisor is currently part of Constellation's TCB. -Regarding (4), the firmware is open source and can be reproducibly built.

    -

    Microsoft Azure

    -

    With its CVM offering, Azure provides the best foundations for Constellation. -Regarding (3), Azure provides direct access to attestation statements. -The firmware runs in an isolated domain inside the CVM and exposes a vTPM (5), but it's closed source (4). -On SEV-SNP, Azure uses VM Privilege Level (VMPL) isolation for the separation of firmware and the rest of the VM; on TDX, they use TD partitioning. -This firmware is signed by Azure. -The signature is reflected in the attestation statements of CVMs. -Thus, the Azure closed-source firmware becomes part of Constellation's trusted computing base (TCB).

    -

    * Recently, Azure announced the open source paravisor OpenHCL. It's the foundation for fully open source and verifiable CVM firmware. Once Azure provides their CVM firmware with reproducible builds based on OpenHCL, (4) switches from No to Yes. Constellation will support OpenHCL based firmware on Azure in the future.

    -

    Google Cloud Platform (GCP)

    -

    The CVMs Generally Available in GCP are based on AMD SEV-ES or SEV-SNP. -Regarding (3), with their SEV-SNP offering Google provides direct access to attestation statements. -However, regarding (5), attestation is partially based on the Shielded VM vTPM for measured boot, which is a vTPM managed by Google's hypervisor. -Hence, the hypervisor is currently part of Constellation's TCB. -Regarding (4), the CVMs still include closed-source firmware.

    -

    TDX on Google is in public preview. -With it, Constellation would have a similar TCB and attestation flow as with the current SEV-SNP offering.

    -

    STACKIT

    -

    STACKIT Compute Engine supports AMD SEV-ES. A vTPM is used for measured boot, which is a vTPM managed by STACKIT's hypervisor. Hence, the hypervisor is currently part of Constellation's TCB.

    -

    OpenStack

    -

    OpenStack is an open-source cloud and infrastructure management software. It's used by many smaller CSPs and datacenters. In the latest Yoga version, OpenStack has basic support for CVMs. However, much depends on the employed kernel and hypervisor. Features (2)--(4) are likely to be a Yes with Linux kernel version 6.2. Thus, going forward, OpenStack on corresponding AMD or Intel hardware will be a viable underpinning for Constellation.

    -

    Conclusion

    -

    The different clouds and software like the Linux kernel and OpenStack are in the process of building out their support for state-of-the-art CVMs. Azure has already most features in place. For Constellation, the status quo means that the TCB has different shapes on different infrastructures. With broad SEV-SNP support coming to the Linux kernel, we soon expect a normalization of features across infrastructures.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/overview/confidential-kubernetes/index.html b/pr-preview/pr-4027/next/overview/confidential-kubernetes/index.html deleted file mode 100644 index 9e07bcb67..000000000 --- a/pr-preview/pr-4027/next/overview/confidential-kubernetes/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - -Confidential Kubernetes | Constellation - - - - - - - -
    Version: Next

    Confidential Kubernetes

    -

    We use the term Confidential Kubernetes to refer to the concept of using confidential-computing technology to shield entire Kubernetes clusters from the infrastructure. The three defining properties of this concept are:

    -
      -
    1. Workload shielding: the confidentiality and integrity of all workload-related data and code are enforced.
    2. -
    3. Control plane shielding: the confidentiality and integrity of the cluster's control plane, state, and workload configuration are enforced.
    4. -
    5. Attestation and verifiability: the two properties above can be verified remotely based on hardware-rooted cryptographic certificates.
    6. -
    -

    Each of the above properties is equally important. Only with all three in conjunction, an entire cluster can be shielded without gaps.

    -

    Constellation security features

    -

    Constellation implements the Confidential Kubernetes concept with the following security features.

    -
      -
    • Runtime encryption: Constellation runs all Kubernetes nodes inside Confidential VMs (CVMs). This gives runtime encryption for the entire cluster.
    • -
    • Network and storage encryption: Constellation augments this with transparent encryption of the network, persistent storage, and other managed storage like AWS S3. Thus, workloads and control plane are truly end-to-end encrypted: at rest, in transit, and at runtime.
    • -
    • Transparent key management: Constellation manages the corresponding cryptographic keys inside CVMs.
    • -
    • Node attestation and verification: Constellation verifies the integrity of each new CVM-based node using remote attestation. Only "good" nodes receive the cryptographic keys required to access the network and storage of a cluster.
    • -
    • Confidential computing-optimized images: A node is "good" if it's running a signed Constellation node image inside a CVM and is in the expected state. (Node images are hardware-measured during boot. The measurements are reflected in the attestation statements that are produced by nodes and verified by Constellation.)
    • -
    • "Whole cluster" attestation: Towards the DevOps engineer, Constellation provides a single hardware-rooted certificate from which all of the above can be verified.
    • -
    -

    With the above, Constellation wraps an entire cluster into one coherent and verifiable confidential context. The concept is depicted in the following.

    -

    Confidential Kubernetes

    -

    Comparison: Managed Kubernetes with CVMs

    -

    In comparison, managed Kubernetes with CVMs, as it's for example offered in AKS and GKE, only provides runtime encryption for certain worker nodes. Here, each worker node is a separate (and typically unverified) confidential context. This only provides limited security benefits as it only prevents direct access to a worker node's memory. The large majority of potential attacks through the infrastructure remain unaffected. This includes attacks through the control plane, access to external key management, and the corruption of worker node images. This leaves many problems unsolved. For instance, Node A has no means to verify if Node B is "good" and if it's OK to share data with it. Consequently, this approach leaves a large attack surface, as is depicted in the following.

    -

    Concept: Managed Kubernetes plus CVMs

    -

    The following table highlights the key differences in terms of features.

    -
    Managed Kubernetes with CVMsConfidential Kubernetes (Constellation✨)
    Runtime encryptionPartial (data plane only)Yes
    Node image verificationNoYes
    Full cluster attestationNoYes
    Transparent network encryptionNoYes
    Transparent storage encryptionNoYes
    Confidential key managementNoYes
    Cloud agnostic / multi-cloudNoYes
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/overview/license/index.html b/pr-preview/pr-4027/next/overview/license/index.html deleted file mode 100644 index b63a2b784..000000000 --- a/pr-preview/pr-4027/next/overview/license/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - -License | Constellation - - - - - - - -
    Version: Next

    License

    -

    Constellation is available under the Business Source License 1.1.

    -

    You may use it free of charge for non-production use ("Community License").

    -

    Enterprise License

    -

    Enterprise Licenses permit production use and come with support and additional features. Find out more at the product website.

    -

    Once you have received your Enterprise License file, place it in your Constellation workspace in a file named constellation.license.

    -

    CSP Marketplaces

    -

    Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please contact us.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/overview/performance/application/index.html b/pr-preview/pr-4027/next/overview/performance/application/index.html deleted file mode 100644 index c648cfe83..000000000 --- a/pr-preview/pr-4027/next/overview/performance/application/index.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - -Application benchmarks | Constellation - - - - - - - -
    Version: Next

    Application benchmarks

    -

    HashiCorp Vault

    -

    HashiCorp Vault is a distributed secrets management software that can be deployed to Kubernetes. -HashiCorp maintains a benchmarking tool for vault, vault-benchmark. -Vault-benchmark generates load on a Vault deployment and measures response times.

    -

    This article describes the results from running vault-benchmark on Constellation, AKS, and GKE. -You can find the setup for producing the data discussed in this article in the vault-benchmarks repository.

    -

    The Vault API used during benchmarking is the transits secret engine. -This allows services to send data to Vault for encryption, decryption, signing, and verification.

    -

    Results

    -

    On each run, vault-benchmark sends requests and measures the latencies. -The measured latencies are aggregated through various statistical features. -After running the benchmark n times, the arithmetic mean over a subset of the reported statistics is calculated. -The selected features are arithmetic mean, 99th percentile, minimum, and maximum.

    -

    Arithmetic mean gives a general sense of the latency on each target. -The 99th percentile shows performance in (most likely) erroneous states. -Minimum and maximum mark the range within which latency varies each run.

    -

    The benchmark was configured with 1300 workers and 10 seconds per run. -Those numbers were chosen empirically. -The latency was stabilizing at 10 seconds runtime, not changing with further increase. -Increasing the number of workers beyond 1300 leads to request failures, marking the limit Vault was able to handle in this setup. -All results are based on 100 runs.

    -

    The following data was generated while running five replicas, one primary, and four standby nodes. -All numbers are in seconds if not indicated otherwise.

    -
    ========== Results AKS ==========
    Mean: mean: 1.632200, variance: 0.002057
    P99: mean: 5.480679, variance: 2.263700
    Max: mean: 6.651001, variance: 2.808401
    Min: mean: 0.011415, variance: 0.000133
    ========== Results GKE ==========
    Mean: mean: 1.656435, variance: 0.003615
    P99: mean: 6.030807, variance: 3.955051
    Max: mean: 7.164843, variance: 3.300004
    Min: mean: 0.010233, variance: 0.000111
    ========== Results C11n ==========
    Mean: mean: 1.651549, variance: 0.001610
    P99: mean: 5.780422, variance: 3.016106
    Max: mean: 6.942997, variance: 3.075796
    Min: mean: 0.013774, variance: 0.000228
    ========== AKS vs C11n ==========
    Mean: +1.171577 % (AKS is faster)
    P99: +5.185495 % (AKS is faster)
    Max: +4.205618 % (AKS is faster)
    Min: +17.128781 % (AKS is faster)
    ========== GKE vs C11n ==========
    Mean: -0.295851 % (GKE is slower)
    P99: -4.331603 % (GKE is slower)
    Max: -3.195248 % (GKE is slower)
    Min: +25.710886 % (GKE is faster)
    -

    Interpretation: Latencies are all within ~5% of each other. -AKS performs slightly better than GKE and Constellation (C11n) in all cases except minimum latency. -Minimum latency is the lowest for GKE. -Compared to GKE, Constellation had slightly lower peak latencies (99th percentile and maximum), indicating that Constellation could have handled slightly more concurrent accesses than GKE. -Overall, performance is at comparable levels across all three distributions. -Based on these numbers, you can use a similarly sized Constellation cluster to run your existing Vault deployment.

    -

    Visualization

    -

    The following plots visualize the data presented above as box plots. -The whiskers denote the minimum and maximum. -The box stretches from the 25th to the 75th percentile, with the dividing bar marking the 50th percentile. -The circles outside the whiskers denote outliers.

    -
    Mean Latency

    Mean Latency

    -
    99th Percentile Latency

    99th Percentile Latency

    -
    Maximum Latency

    Maximum Latency

    -
    Minimum Latency

    Minimum Latency

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/overview/performance/compute/index.html b/pr-preview/pr-4027/next/overview/performance/compute/index.html deleted file mode 100644 index 49197ae63..000000000 --- a/pr-preview/pr-4027/next/overview/performance/compute/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - -Impact of runtime encryption on compute performance | Constellation - - - - - - - -
    Version: Next

    Impact of runtime encryption on compute performance

    -

    All nodes in a Constellation cluster are executed inside Confidential VMs (CVMs). Consequently, the performance of Constellation is inherently linked to the performance of these CVMs.

    -

    AMD and Azure benchmarking

    -

    AMD and Azure have collectively released a performance benchmark for CVMs that utilize 3rd Gen AMD EPYC processors (Milan) with SEV-SNP. This benchmark, which included a variety of mostly compute-intensive tests such as SPEC CPU 2017 and CoreMark, demonstrated that CVMs experience only minor performance degradation (ranging from 2% to 8%) when compared to standard VMs. Such results are indicative of the performance that can be expected from compute-intensive workloads running with Constellation on Azure.

    -

    AMD and Google benchmarking

    -

    Similarly, AMD and Google have jointly released a performance benchmark for CVMs employing 3rd Gen AMD EPYC processors (Milan) with SEV-SNP. With high-performance computing workloads such as WRF, NAMD, Ansys CFS, and Ansys LS_DYNA, they observed analogous findings, with only minor performance degradation (between 2% and 4%) compared to standard VMs. These outcomes are reflective of the performance that can be expected for compute-intensive workloads running with Constellation on GCP.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/overview/performance/index.html b/pr-preview/pr-4027/next/overview/performance/index.html deleted file mode 100644 index ac149f3fd..000000000 --- a/pr-preview/pr-4027/next/overview/performance/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - -Performance analysis of Constellation | Constellation - - - - - - - -
    Version: Next

    Performance analysis of Constellation

    -

    This section provides a comprehensive examination of the performance characteristics of Constellation.

    -

    Runtime encryption

    -

    Runtime encryption affects compute performance. Benchmarks by Azure and Google show that the performance degradation of Confidential VMs (CVMs) is small, ranging from 2% to 8% for compute-intensive workloads.

    -

    I/O performance benchmarks

    -

    We evaluated the I/O performance of Constellation, utilizing a collection of synthetic benchmarks targeting networking and storage. -We further compared this performance to native managed Kubernetes offerings from various cloud providers, to better understand how Constellation stands in relation to standard practices.

    -

    Application benchmarking

    -

    To gauge Constellation's applicability to well-known applications, we performed a benchmark of HashiCorp Vault running on Constellation. -The results were then compared to deployments on the managed Kubernetes offerings from different cloud providers, providing a tangible perspective on Constellation's performance in actual deployment scenarios.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/overview/performance/io/index.html b/pr-preview/pr-4027/next/overview/performance/io/index.html deleted file mode 100644 index 43fe74a55..000000000 --- a/pr-preview/pr-4027/next/overview/performance/io/index.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - -I/O performance benchmarks | Constellation - - - - - - - -
    Version: Next

    I/O performance benchmarks

    -

    To assess the overall performance of Constellation, this benchmark evaluates Constellation v2.6.0 in terms of storage I/O using fio and network performance using the Kubernetes Network Benchmark.

    -

    This benchmark tested Constellation on Azure and GCP and compared the results against the managed Kubernetes offerings AKS and GKE.

    -

    Configurations

    -

    Constellation

    -

    The benchmark was conducted with Constellation v2.6.0, Kubernetes v1.25.7, and Cilium v1.12. -It ran on the following infrastructure configurations.

    -

    Constellation on Azure:

    -
      -
    • Nodes: 3 (1 Control-plane, 2 Worker)
    • -
    • Machines: DC4as_v5: 3rd Generation AMD EPYC 7763v (Milan) processor with 4 Cores, 16 GiB memory
    • -
    • CVM: true
    • -
    • Region: West US
    • -
    • Zone: 2
    • -
    -

    Constellation on GCP:

    -
      -
    • Nodes: 3 (1 Control-plane, 2 Worker)
    • -
    • Machines: n2d-standard-4: 2nd Generation AMD EPYC (Rome) processor with 4 Cores, 16 GiB of memory
    • -
    • CVM: true
    • -
    • Zone: europe-west3-b
    • -
    -

    AKS

    -

    On AKS, the benchmark used Kubernetes v1.24.9 and nodes with version AKSUbuntu-1804gen2containerd-2023.02.15. -AKS ran with the kubenet CNI and the default CSI driver for Azure Disk.

    -

    The following infrastructure configurations was used:

    -
      -
    • Nodes: 2 (2 Worker)
    • -
    • Machines: D4as_v5: 3rd Generation AMD EPYC 7763v (Milan) processor with 4 Cores, 16 GiB memory
    • -
    • CVM: false
    • -
    • Region: West US
    • -
    • Zone: 2
    • -
    -

    GKE

    -

    On GKE, the benchmark used Kubernetes v1.24.9 and nodes with version 1.24.9-gke.3200. -GKE ran with the kubenet CNI and the default CSI driver for Compute Engine persistent disk.

    -

    The following infrastructure configurations was used:

    -
      -
    • Nodes: 2 (2 Worker)
    • -
    • Machines: n2d-standard-4 2nd Generation AMD EPYC (Rome) processor with 4 Cores, 16 GiB of memory
    • -
    • CVM: false
    • -
    • Zone: europe-west3-b
    • -
    -

    Results

    -

    Network

    -

    This section gives a thorough analysis of the network performance of Constellation, specifically focusing on measuring TCP and UDP bandwidth. -The benchmark measured the bandwidth of pod-to-pod and pod-to-service connections between two different nodes using iperf.

    -

    GKE and Constellation on GCP had a maximum network bandwidth of 10 Gbps. -AKS with Standard_D4as_v5 machines a maximum network bandwidth of 12.5 Gbps. -The Confidential VM equivalent Standard_DC4as_v5 currently has a network bandwidth of 1.25 Gbps. -Therefore, to make the test comparable, both AKS and Constellation on Azure were running with Standard_DC4as_v5 machines and 1.25 Gbps bandwidth.

    -

    Constellation on Azure and AKS used an MTU of 1500. -Constellation on GCP used an MTU of 8896. GKE used an MTU of 1450.

    -

    The difference in network bandwidth can largely be attributed to two factors.

    - -

    Pod-to-Pod

    -

    In this scenario, the client Pod connects directly to the server pod via its IP address.

    - -

    The results for "Pod-to-Pod" on Azure are as follows:

    -

    Network Pod2Pod Azure benchmark graph

    -

    The results for "Pod-to-Pod" on GCP are as follows:

    -

    Network Pod2Pod GCP benchmark graph

    -

    Pod-to-Service

    -

    In this scenario, the client Pod connects to the server Pod via a ClusterIP service. This is more relevant to real-world use cases.

    - -

    The results for "Pod-to-Pod" on Azure are as follows:

    -

    Network Pod2SVC Azure benchmark graph

    -

    The results for "Pod-to-Pod" on GCP are as follows:

    -

    Network Pod2SVC GCP benchmark graph

    -

    In our recent comparison of Constellation on GCP with GKE, Constellation has 58% less TCP bandwidth. However, UDP bandwidth was slightly better with Constellation, thanks to its higher MTU.

    -

    Similarly, when comparing Constellation on Azure with AKS using CVMs, Constellation achieved approximately 10% less TCP and 40% less UDP bandwidth.

    -

    Storage I/O

    -

    Azure and GCP offer persistent storage for their Kubernetes services AKS and GKE via the Container Storage Interface (CSI). CSI storage in Kubernetes is available via PersistentVolumes (PV) and consumed via PersistentVolumeClaims (PVC). -Upon requesting persistent storage through a PVC, GKE and AKS will provision a PV as defined by a default storage class. -Constellation provides persistent storage on Azure and GCP that's encrypted on the CSI layer. -Similarly, upon a PVC request, Constellation will provision a PV via a default storage class.

    -

    For Constellation on Azure and AKS, the benchmark ran with Azure Disk storage Standard SSD of 400 GiB size. -The DC4as machine type with four cores provides the following maximum performance:

    -
      -
    • 6400 (20000 burst) IOPS
    • -
    • 144 MB/s (600 MB/s burst) throughput
    • -
    -

    However, the performance is bound by the capabilities of the 512 GiB Standard SSD size (the size class of 400 GiB volumes):

    -
      -
    • 500 (600 burst) IOPS
    • -
    • 60 MB/s (150 MB/s burst) throughput
    • -
    -

    For Constellation on GCP and GKE, the benchmark ran with Compute Engine Persistent Disk Storage pd-balanced of 400 GiB size. -The N2D machine type with four cores and pd-balanced provides the following maximum performance:

    -
      -
    • 3,000 read IOPS
    • -
    • 15,000 write IOPS
    • -
    • 240 MB/s read throughput
    • -
    • 240 MB/s write throughput
    • -
    -

    However, the performance is bound by the capabilities of a Zonal balanced PD with 400 GiB size:

    -
      -
    • 2400 read IOPS
    • -
    • 2400 write IOPS
    • -
    • 112 MB/s read throughput
    • -
    • 112 MB/s write throughput
    • -
    -

    The fio benchmark consists of several tests. -The benchmark used Kubestr to run fio in Kubernetes. -The default test performs randomized access patterns that accurately depict worst-case I/O scenarios for most applications.

    -

    The following fio settings were used:

    -
      -
    • No Cloud caching
    • -
    • No OS caching
    • -
    • Single CPU
    • -
    • 60 seconds runtime
    • -
    • 10 seconds ramp-up time
    • -
    • 10 GiB file
    • -
    • IOPS: 4 KB blocks and 128 iodepth
    • -
    • Bandwidth: 1024 KB blocks and 128 iodepth
    • -
    -

    For more details, see the fio test configuration.

    -

    The results for IOPS on Azure are as follows:

    -

    I/O IOPS Azure benchmark graph

    -

    The results for IOPS on GCP are as follows:

    -

    I/O IOPS GCP benchmark graph

    -

    The results for bandwidth on Azure are as follows:

    -

    I/O bandwidth Azure benchmark graph

    -

    The results for bandwidth on GCP are as follows:

    -

    I/O bandwidth GCP benchmark graph

    -

    On GCP, the results exceed the maximum performance guarantees of the chosen disk type. There are two possible explanations for this. The first is that there may be cloud caching in place that isn't configurable. Alternatively, the underlying provisioned disk size may be larger than what was requested, resulting in higher performance boundaries.

    -

    When comparing Constellation on GCP with GKE, Constellation has similar bandwidth but about 10% less IOPS performance. On Azure, Constellation has similar IOPS performance compared to AKS, where both likely hit the maximum storage performance. However, Constellation has approximately 15% less read and write bandwidth.

    -

    Conclusion

    -

    Despite the added security benefits that Constellation provides, it only incurs a slight performance overhead when compared to managed Kubernetes offerings such as AKS and GKE. In most compute benchmarks, Constellation is on par with it's alternatives. -While it may be slightly slower in certain I/O scenarios due to network and storage encryption, there is ongoing work to reduce this overhead to single digits.

    -

    For instance, storage encryption only adds between 10% to 15% overhead in terms of bandwidth and IOPS. -Meanwhile, the biggest performance impact that Constellation currently faces is network encryption, which can incur up to 58% overhead on a 10 Gbps network. -However, the Cilium team has conducted benchmarks with Cilium using WireGuard encryption on a 100 Gbps network that yielded over 15 Gbps. -We're confident that Constellation will provide a similar level of performance with an upcoming release.

    -

    Overall, Constellation strikes a great balance between security and performance, and we're continuously working to improve its performance capabilities while maintaining its high level of security.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/overview/product/index.html b/pr-preview/pr-4027/next/overview/product/index.html deleted file mode 100644 index 508174d15..000000000 --- a/pr-preview/pr-4027/next/overview/product/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - -Product features | Constellation - - - - - - - -
    Version: Next

    Product features

    -

    Constellation is a Kubernetes engine that aims to provide the best possible data security in combination with enterprise-grade scalability and reliability features---and a smooth user experience.

    -

    From a security perspective, Constellation implements the Confidential Kubernetes concept and corresponding security features, which shield your entire cluster from the underlying infrastructure.

    -

    From an operational perspective, Constellation provides the following key features:

    -
      -
    • Native support for different clouds: Constellation works on Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), and STACKIT. Support for OpenStack-based environments is coming with a future release. Constellation securely interfaces with the cloud infrastructure to provide cluster autoscaling, dynamic persistent volumes, and service load balancing.
    • -
    • High availability: Constellation uses a multi-master architecture with a stacked etcd topology to ensure high availability.
    • -
    • Integrated Day-2 operations: Constellation lets you securely upgrade your cluster to a new release. It also lets you securely recover a failed cluster. Both with a single command.
    • -
    • Support for Terraform: Constellation includes a Terraform provider that lets you manage the full lifecycle of your cluster via Terraform.
    • -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/overview/security-benefits/index.html b/pr-preview/pr-4027/next/overview/security-benefits/index.html deleted file mode 100644 index 6217c6a92..000000000 --- a/pr-preview/pr-4027/next/overview/security-benefits/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - -Security benefits and threat model | Constellation - - - - - - - -
    Version: Next

    Security benefits and threat model

    -

    Constellation implements the Confidential Kubernetes concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be verified.

    -

    TCB comparison

    -

    Given this background, the following describes the concrete threat classes that Constellation addresses.

    -

    Insider access

    -

    Employees and third-party contractors of cloud service providers (CSPs) have access to different layers of the cloud infrastructure. -This opens up a large attack surface where workloads and data can be read, copied, or manipulated. With Constellation, Kubernetes deployments are shielded from the infrastructure and thus such accesses are prevented.

    -

    Infrastructure-based attacks

    -

    Malicious cloud users ("hackers") may break out of their tenancy and access other tenants' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. Analogously to the insider access scenario, Constellation also prevents access to a deployment's data in this scenario.

    -

    Supply chain attacks

    -

    Supply chain security is receiving lots of attention recently due to an increasing number of recorded attacks. For instance, a malicious actor could attempt to tamper Constellation node images (including Kubernetes and other software) before they're loaded in the confidential VMs of a cluster. Constellation uses remote attestation in conjunction with public transparency logs to prevent this.

    -

    In the future, Constellation will extend this feature to customer workloads. This will enable cluster owners to create auditable policies that precisely define which containers can run in a given deployment.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/reference/cli/index.html b/pr-preview/pr-4027/next/reference/cli/index.html deleted file mode 100644 index 969a7011f..000000000 --- a/pr-preview/pr-4027/next/reference/cli/index.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - -CLI reference | Constellation - - - - - - - -
    Version: Next

    CLI reference

    -

    Use the Constellation CLI to create and manage your clusters.

    -

    Usage:

    -
    constellation [command]
    -

    Commands:

    -
      -
    • config: Work with the Constellation configuration file -
        -
      • generate: Generate a default configuration and state file
      • -
      • fetch-measurements: Fetch measurements for configured cloud provider and image
      • -
      • instance-types: Print the supported instance types for all cloud providers
      • -
      • kubernetes-versions: Print the Kubernetes versions supported by this CLI
      • -
      • migrate: Migrate a configuration file to a new version
      • -
      -
    • -
    • create: Create instances on a cloud platform for your Constellation cluster
    • -
    • apply: Apply a configuration to a Constellation cluster
    • -
    • mini: Manage MiniConstellation clusters -
        -
      • up: Create and initialize a new MiniConstellation cluster
      • -
      • down: Destroy a MiniConstellation cluster
      • -
      -
    • -
    • status: Show status of a Constellation cluster
    • -
    • verify: Verify the confidential properties of a Constellation cluster
    • -
    • upgrade: Find and apply upgrades to your Constellation cluster -
        -
      • check: Check for possible upgrades
      • -
      • apply: Apply an upgrade to a Constellation cluster
      • -
      -
    • -
    • recover: Recover a completely stopped Constellation cluster
    • -
    • terminate: Terminate a Constellation cluster
    • -
    • iam: Work with the IAM configuration on your cloud provider -
        -
      • create: Create IAM configuration on a cloud platform for your Constellation cluster -
          -
        • aws: Create IAM configuration on AWS for your Constellation cluster
        • -
        • azure: Create IAM configuration on Microsoft Azure for your Constellation cluster
        • -
        • gcp: Create IAM configuration on GCP for your Constellation cluster
        • -
        -
      • -
      • destroy: Destroy an IAM configuration and delete local Terraform files
      • -
      • upgrade: Find and apply upgrades to your IAM profile -
          -
        • apply: Apply an upgrade to an IAM profile
        • -
        -
      • -
      -
    • -
    • version: Display version of this CLI
    • -
    • init: Initialize the Constellation cluster
    • -
    • ssh: Generate a certificate for emergency SSH access
    • -
    -

    constellation config

    -

    Work with the Constellation configuration file

    -

    Synopsis

    -

    Work with the Constellation configuration file.

    -

    Options

    -
      -h, --help   help for config
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation config generate

    -

    Generate a default configuration and state file

    -

    Synopsis

    -

    Generate a default configuration and state file for your selected cloud provider.

    -
    constellation config generate {aws|azure|gcp|openstack|qemu|stackit} [flags]
    -

    Options

    -
      -a, --attestation string   attestation variant to use {aws-sev-snp|aws-nitro-tpm|azure-sev-snp|azure-tdx|azure-trustedlaunch|gcp-sev-snp|gcp-sev-es|qemu-vtpm}. If not specified, the default for the cloud provider is used
    -h, --help help for generate
    -k, --kubernetes string Kubernetes version to use in format MAJOR.MINOR (default "v1.31")
    -t, --tags strings additional tags for created resources given a list of key=value
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation config fetch-measurements

    -

    Fetch measurements for configured cloud provider and image

    -

    Synopsis

    -

    Fetch measurements for configured cloud provider and image.

    -

    A config needs to be generated first.

    -
    constellation config fetch-measurements [flags]
    -

    Options

    -
      -h, --help                   help for fetch-measurements
    -s, --signature-url string alternative URL to fetch measurements' signature from
    -u, --url string alternative URL to fetch measurements from
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation config instance-types

    -

    Print the supported instance types for all cloud providers

    -

    Synopsis

    -

    Print the supported instance types for all cloud providers.

    -
    constellation config instance-types [flags]
    -

    Options

    -
      -h, --help   help for instance-types
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation config kubernetes-versions

    -

    Print the Kubernetes versions supported by this CLI

    -

    Synopsis

    -

    Print the Kubernetes versions supported by this CLI.

    -
    constellation config kubernetes-versions [flags]
    -

    Options

    -
      -h, --help   help for kubernetes-versions
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation config migrate

    -

    Migrate a configuration file to a new version

    -

    Synopsis

    -

    Migrate a configuration file to a new version.

    -
    constellation config migrate [flags]
    -

    Options

    -
      -h, --help   help for migrate
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation create

    -

    Create instances on a cloud platform for your Constellation cluster

    -

    Synopsis

    -

    Create instances on a cloud platform for your Constellation cluster.

    -
    constellation create [flags]
    -

    Options

    -
      -h, --help   help for create
    -y, --yes create the cluster without further confirmation
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation apply

    -

    Apply a configuration to a Constellation cluster

    -

    Synopsis

    -

    Apply a configuration to a Constellation cluster to initialize or upgrade the cluster.

    -
    constellation apply [flags]
    -

    Options

    -
          --conformance           enable conformance mode
    -h, --help help for apply
    --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config
    --skip-helm-wait install helm charts without waiting for deployments to be ready
    --skip-phases strings comma-separated list of upgrade phases to skip
    one or multiple of { infrastructure | init | attestationconfig | certsans | helm | image | k8s }
    -y, --yes run command without further confirmation
    WARNING: the command might delete or update existing resources without additional checks. Please read the docs.

    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation mini

    -

    Manage MiniConstellation clusters

    -

    Synopsis

    -

    Manage MiniConstellation clusters.

    -

    Options

    -
      -h, --help   help for mini
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation mini up

    -

    Create and initialize a new MiniConstellation cluster

    -

    Synopsis

    -

    Create and initialize a new MiniConstellation cluster.

    -

    A mini cluster consists of a single control-plane and worker node, hosted using QEMU/KVM.

    -
    constellation mini up [flags]
    -

    Options

    -
      -h, --help               help for up
    --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config (default true)
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation mini down

    -

    Destroy a MiniConstellation cluster

    -

    Synopsis

    -

    Destroy a MiniConstellation cluster.

    -
    constellation mini down [flags]
    -

    Options

    -
      -h, --help   help for down
    -y, --yes terminate the cluster without further confirmation
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation status

    -

    Show status of a Constellation cluster

    -

    Synopsis

    -

    Show the status of a constellation cluster.

    -

    Shows microservice, image, and Kubernetes versions installed in the cluster. Also shows status of current version upgrades.

    -
    constellation status [flags]
    -

    Options

    -
      -h, --help   help for status
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation verify

    -

    Verify the confidential properties of a Constellation cluster

    -

    Synopsis

    -

    Verify the confidential properties of a Constellation cluster. -If arguments aren't specified, values are read from constellation-state.yaml.

    -
    constellation verify [flags]
    -

    Options

    -
          --cluster-id string      expected cluster identifier
    -h, --help help for verify
    -e, --node-endpoint string endpoint of the node to verify, passed as HOST[:PORT]
    -o, --output string print the attestation document in the output format {json|raw}
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation upgrade

    -

    Find and apply upgrades to your Constellation cluster

    -

    Synopsis

    -

    Find and apply upgrades to your Constellation cluster.

    -

    Options

    -
      -h, --help   help for upgrade
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation upgrade check

    -

    Check for possible upgrades

    -

    Synopsis

    -

    Check which upgrades can be applied to your Constellation Cluster.

    -
    constellation upgrade check [flags]
    -

    Options

    -
      -h, --help            help for check
    --ref string the reference to use for querying new versions (default "-")
    --stream string the stream to use for querying new versions (default "stable")
    -u, --update-config update the specified config file with the suggested versions
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation upgrade apply

    -

    Apply an upgrade to a Constellation cluster

    -

    Synopsis

    -

    Apply an upgrade to a Constellation cluster by applying the chosen configuration.

    -
    constellation upgrade apply [flags]
    -

    Options

    -
          --conformance           enable conformance mode
    -h, --help help for apply
    --skip-helm-wait install helm charts without waiting for deployments to be ready
    --skip-phases strings comma-separated list of upgrade phases to skip
    one or multiple of { infrastructure | helm | image | k8s }
    -y, --yes run upgrades without further confirmation
    WARNING: might delete your resources in case you are using cert-manager in your cluster. Please read the docs.
    WARNING: might unintentionally overwrite measurements in the running cluster.
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation recover

    -

    Recover a completely stopped Constellation cluster

    -

    Synopsis

    -

    Recover a Constellation cluster by sending a recovery key to an instance in the boot stage.

    -

    This is only required if instances restart without other instances available for bootstrapping.

    -
    constellation recover [flags]
    -

    Options

    -
      -e, --endpoint string   endpoint of the instance, passed as HOST[:PORT]
    -h, --help help for recover
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation terminate

    -

    Terminate a Constellation cluster

    -

    Synopsis

    -

    Terminate a Constellation cluster.

    -

    The cluster can't be started again, and all persistent storage will be lost.

    -
    constellation terminate [flags]
    -

    Options

    -
      -h, --help   help for terminate
    -y, --yes terminate the cluster without further confirmation
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation iam

    -

    Work with the IAM configuration on your cloud provider

    -

    Synopsis

    -

    Work with the IAM configuration on your cloud provider.

    -

    Options

    -
      -h, --help   help for iam
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation iam create

    -

    Create IAM configuration on a cloud platform for your Constellation cluster

    -

    Synopsis

    -

    Create IAM configuration on a cloud platform for your Constellation cluster.

    -

    Options

    -
      -h, --help            help for create
    --update-config update the config file with the specific IAM information
    -y, --yes create the IAM configuration without further confirmation
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation iam create aws

    -

    Create IAM configuration on AWS for your Constellation cluster

    -

    Synopsis

    -

    Create IAM configuration on AWS for your Constellation cluster.

    -
    constellation iam create aws [flags]
    -

    Options

    -
      -h, --help            help for aws
    --prefix string name prefix for all resources (required)
    --zone string AWS availability zone the resources will be created in, e.g., us-east-2a (required)
    See the Constellation docs for a list of currently supported regions.
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    --update-config update the config file with the specific IAM information
    -C, --workspace string path to the Constellation workspace
    -y, --yes create the IAM configuration without further confirmation
    -

    constellation iam create azure

    -

    Create IAM configuration on Microsoft Azure for your Constellation cluster

    -

    Synopsis

    -

    Create IAM configuration on Microsoft Azure for your Constellation cluster.

    -
    constellation iam create azure [flags]
    -

    Options

    -
      -h, --help                      help for azure
    --region string region the resources will be created in, e.g., westus (required)
    --resourceGroup string name prefix of the two resource groups your cluster / IAM resources will be created in (required)
    --servicePrincipal string name of the service principal that will be created (required)
    --subscriptionID string subscription ID of the Azure account. Required if the 'ARM_SUBSCRIPTION_ID' environment variable is not set
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    --update-config update the config file with the specific IAM information
    -C, --workspace string path to the Constellation workspace
    -y, --yes create the IAM configuration without further confirmation
    -

    constellation iam create gcp

    -

    Create IAM configuration on GCP for your Constellation cluster

    -

    Synopsis

    -

    Create IAM configuration on GCP for your Constellation cluster.

    -
    constellation iam create gcp [flags]
    -

    Options

    -
      -h, --help               help for gcp
    --prefix string Prefix for the service account ID and VM ID that will be created (required)
    Must be letters, digits, or hyphens.
    --projectID string ID of the GCP project the configuration will be created in (required)
    Find it on the welcome screen of your project: https://console.cloud.google.com/welcome
    --zone string GCP zone the cluster will be deployed in (required)
    Find a list of available zones here: https://cloud.google.com/compute/docs/regions-zones#available
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    --update-config update the config file with the specific IAM information
    -C, --workspace string path to the Constellation workspace
    -y, --yes create the IAM configuration without further confirmation
    -

    constellation iam destroy

    -

    Destroy an IAM configuration and delete local Terraform files

    -

    Synopsis

    -

    Destroy an IAM configuration and delete local Terraform files.

    -
    constellation iam destroy [flags]
    -

    Options

    -
      -h, --help   help for destroy
    -y, --yes destroy the IAM configuration without asking for confirmation
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation iam upgrade

    -

    Find and apply upgrades to your IAM profile

    -

    Synopsis

    -

    Find and apply upgrades to your IAM profile.

    -

    Options

    -
      -h, --help   help for upgrade
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation iam upgrade apply

    -

    Apply an upgrade to an IAM profile

    -

    Synopsis

    -

    Apply an upgrade to an IAM profile.

    -
    constellation iam upgrade apply [flags]
    -

    Options

    -
      -h, --help   help for apply
    -y, --yes run upgrades without further confirmation
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation version

    -

    Display version of this CLI

    -

    Synopsis

    -

    Display version of this CLI.

    -
    constellation version [flags]
    -

    Options

    -
      -h, --help   help for version
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation init

    -

    Initialize the Constellation cluster

    -

    Synopsis

    -

    Initialize the Constellation cluster.

    -

    Start your confidential Kubernetes.

    -
    constellation init [flags]
    -

    Options

    -
          --conformance        enable conformance mode
    -h, --help help for init
    --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config
    --skip-helm-wait install helm charts without waiting for deployments to be ready
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation ssh

    -

    Generate a certificate for emergency SSH access

    -

    Synopsis

    -

    Generate a certificate for emergency SSH access to your SSH-enabled constellation cluster.

    -
    constellation ssh [flags]
    -

    Options

    -
      -h, --help         help for ssh
    --key string the path to an existing SSH public key
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/reference/migration/index.html b/pr-preview/pr-4027/next/reference/migration/index.html deleted file mode 100644 index 5b2333d72..000000000 --- a/pr-preview/pr-4027/next/reference/migration/index.html +++ /dev/null @@ -1,94 +0,0 @@ - - - - - -Migrations | Constellation - - - - - - - -
    Version: Next

    Migrations

    -

    This document describes breaking changes and migrations between Constellation releases. -Use constellation config migrate to automatically update an old config file to a new format.

    -

    Migrations to v2.23.0

    -

    GCP

    -

    GCP will require the additional permission compute.forwardingRules.list. Please update your IAM roles using constellation iam upgrade apply.

    -

    Migrations to v2.19.1

    -

    Azure

    -
      -
    • During the upgrade, security rules are migrated and the old ones need to be cleaned up manually by the user. The below script shows how to delete them through the Azure CLI:
    • -
    -
    #!/usr/bin/env bash
    name="<insert>" # the name provided in the config
    uid="<insert>" # the cluster id can be retrieved via `yq '.infrastructure.uid' constellation-state.yaml`
    resource_group="<insert>" # the RG can be retrieved via `yq '.provider.azure.resourceGroup' constellation-conf.yaml`

    rules=(
    "kubernetes"
    "bootstrapper"
    "verify"
    "recovery"
    "join"
    "debugd"
    "konnectivity"
    )

    for rule in "${rules[@]}"; do
    echo "Deleting rule: ${rule}"
    az network nsg rule delete \
    --resource-group "${resource_group}" \
    --nsg-name "${name}-${uid}" \
    --name "${rule}"
    done

    echo "All specified rules have been deleted."
    -

    Migrating from CLI versions before 2.21.1

    -

    AWS

    -
      -
    • AWS clusters that use LoadBalancer resources require more IAM permissions. Please upgrade your IAM roles using constellation iam upgrade apply. This will show necessary changes and apply them, if desired.
    • -
    -

    Migrating from CLI versions before 2.19.0

    -

    Azure

    -
      -
    • To allow seamless upgrades on Azure when Kubernetes services of type LoadBalancer are deployed, the target -load balancer in which the cloud-controller-manager creates load balancing rules was changed. Instead of using the load balancer -created and maintained by the CLI's Terraform code, the cloud-controller-manager now creates its own load balancer in Azure. -If your Constellation has services of type LoadBalancer, please remove them before the upgrade and re-apply them -afterward.
    • -
    -

    Migrating from CLI versions before 2.18.0

    -
      -
    • The provider.azure.appClientID and provider.azure.appClientSecret fields are no longer supported and should be removed.
    • -
    • To keep using an existing UAMI, add the Owner permission with the scope of your resourceGroup.
    • -
    • Otherwise, simply create new Constellation IAM credentials and use the created UAMI.
    • -
    • To migrate the authentication for an existing cluster on Azure to an UAMI with the necessary permissions: -
        -
      1. Remove the aadClientId and aadClientSecret from the azureconfig secret.
      2. -
      3. Set useManagedIdentityExtension to true and use the userAssignedIdentity from the Constellation config for the value of userAssignedIdentityID.
      4. -
      5. Restart the CSI driver, cloud controller manager, cluster autoscaler, and Constellation operator pods.
      6. -
      -
    • -
    -

    Migrating from CLI versions before 2.10

    -
      -
    • AWS cluster upgrades require additional IAM permissions for the newly introduced aws-load-balancer-controller. Please upgrade your IAM roles using iam upgrade apply. This will show necessary changes and apply them, if desired.
    • -
    • The global nodeGroups field was added.
    • -
    • The fields instanceType, stateDiskSizeGB, and stateDiskType for each cloud provider are now part of the configuration of individual node groups.
    • -
    • The constellation create command no longer uses the flags --control-plane-count and --worker-count. Instead, the initial node count is configured per node group in the nodeGroups field.
    • -
    -

    Migrating from CLI versions before 2.9

    -
      -
    • The provider.azure.appClientID and provider.azure.clientSecretValue fields were removed to enforce migration to managed identity authentication
    • -
    -

    Migrating from CLI versions before 2.8

    -
      -
    • The measurements field for each cloud service provider was replaced with a global attestation field.
    • -
    • The confidentialVM, idKeyDigest, and enforceIdKeyDigest fields for the Azure cloud service provider were removed in favor of using the global attestation field.
    • -
    • The optional global field attestationVariant was replaced by the now required attestation field.
    • -
    -

    Migrating from CLI versions before 2.3

    -
      -
    • -

      The sshUsers field was deprecated in v2.2 and has been removed from the configuration in v2.3. -As an alternative for SSH, check the workflow section Connect to nodes.

      -
    • -
    • -

      The image field for each cloud service provider has been replaced with a global image field. Use the following mapping to migrate your configuration:

      -
      Show all
      CSPold imagenew image
      AWSami-06b8cbf4837a0a57cv2.2.2
      AWSami-02e96dc04a9e438cdv2.2.2
      AWSami-028ead928a9034b2fv2.2.2
      AWSami-032ac10dd8d8266e3v2.2.1
      AWSami-032e0d57cc4395088v2.2.1
      AWSami-053c3e49e19b96bddv2.2.1
      AWSami-0e27ebcefc38f648bv2.2.0
      AWSami-098cd37f66523b7c3v2.2.0
      AWSami-04a87d302e2509aadv2.2.0
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.2v2.2.2
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.2v2.2.2
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.1v2.2.1
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.1v2.2.1
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.0v2.2.0
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.0v2.2.0
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.1.0v2.1.0
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.1.0v2.1.0
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.0.0v2.0.0
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.0.0v2.0.0
      GCPprojects/constellation-images/global/images/constellation-v2-2-2v2.2.2
      GCPprojects/constellation-images/global/images/constellation-v2-2-1v2.2.1
      GCPprojects/constellation-images/global/images/constellation-v2-2-0v2.2.0
      GCPprojects/constellation-images/global/images/constellation-v2-1-0v2.1.0
      GCPprojects/constellation-images/global/images/constellation-v2-0-0v2.0.0
      -
    • -
    • -

      The enforcedMeasurements field has been removed and merged with the measurements field.

      -
        -
      • -

        To migrate your config containing a new image (v2.3 or greater), remove the old measurements and enforcedMeasurements entries from your config and run constellation fetch-measurements

        -
      • -
      • -

        To migrate your config containing an image older than v2.3, remove the enforcedMeasurements entry and replace the entries in measurements as shown in the example below:

        -
        measurements:
        - 0: DzXCFGCNk8em5ornNZtKi+Wg6Z7qkQfs5CfE3qTkOc8=
        + 0:
        + expected: DzXCFGCNk8em5ornNZtKi+Wg6Z7qkQfs5CfE3qTkOc8=
        + warnOnly: true
        - 8: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
        + 8:
        + expected: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
        + warnOnly: false
        -enforcedMeasurements:
        - - 8
        -
      • -
      -
    • -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/reference/slsa/index.html b/pr-preview/pr-4027/next/reference/slsa/index.html deleted file mode 100644 index ad7fd11a7..000000000 --- a/pr-preview/pr-4027/next/reference/slsa/index.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - -Supply chain levels for software artifacts (SLSA) adoption | Constellation - - - - - - - -
    Version: Next

    Supply chain levels for software artifacts (SLSA) adoption

    -

    Supply chain Levels for Software Artifacts, or SLSA (salsa) is a framework for improving and grading a project's build system and engineering processes. SLSA focuses on security improvements for source code storage as well as build system definition, execution, and observation. SLSA is structured in four levels. This page describes the adoption of SLSA for Constellation.

    -
    info

    SLSA is still in alpha status. The presented levels and their requirements might change in the future. We will adopt any changes into our engineering processes, as they get defined.

    -

    Level 1 - Adopted

    -

    Build - Scripted

    -

    All build steps are automated via Bazel and GitHub Actions.

    -

    Provenance - Available

    -

    Provenance for the CLI is generated using the slsa-github-generator.

    -

    Level 2 - Adopted

    -

    Source - Version Controlled

    -

    Constellation is hosted on GitHub using git.

    -

    Build - Build Service

    -

    All builds are carried out by GitHub Actions.

    -

    Provenance - Authenticated

    -

    Provenance for the CLI is signed using the slsa-github-generator. Learn how to verify the CLI using the signed provenance, before using it for the first time.

    -

    Provenance - Service Generated

    -

    Provenance for the CLI is generated using the slsa-github-generator in GitHub Actions.

    -

    Level 3 - Adopted

    -

    Source - Verified History

    -

    The Edgeless Systems GitHub organization requires two-factor authentication for all members.

    -

    Source - Retained Indefinitely

    -

    Since we use GitHub to host the repository, an external person can't modify or delete the history. Before a pull request can be merged, an explicit approval from an Edgeless Systems team member is required.

    -

    The same holds true for changes proposed by team members. Each change to main needs to be proposed via a pull request and requires at least one approval.

    -

    The Edgeless Systems GitHub organization admins control these settings and are able to make changes to the repository's history should legal requirements necessitate it. These changes require two-party approval following the obliterate policy.

    -

    Build - Build as Code

    -

    All build files for Constellation are stored in the same repository.

    -

    Build - Ephemeral Environment

    -

    All GitHub Action workflows are executed on GitHub-hosted runners. These runners are only available during workflow.

    -

    We currently don't use self-hosted runners.

    -

    Build - Isolated

    -

    As outlined in the previous section, we use GitHub-hosted runners, which provide a new, isolated and ephemeral environment for each build.

    -

    Additionally, the SLSA GitHub generator itself is run in an isolated workflow with the artifact hash as defined inputs.

    -

    Provenance - Non-falsifiable

    -

    As outlined by SLSA GitHub generator it already fulfills the non-falsifiable requirements for SLSA Level 3. The generated provenance is signed using sigstore with an OIDC based proof of identity.

    -

    Level 4 - In Progress

    -

    We strive to adopt certain aspect of SLSA Level 4 that support our engineering process. At the same time, SLSA is still in alpha status and the biggest changes to SLSA are expected to be around Level 4.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/reference/terraform/index.html b/pr-preview/pr-4027/next/reference/terraform/index.html deleted file mode 100644 index ca53d3419..000000000 --- a/pr-preview/pr-4027/next/reference/terraform/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -Terraform usage | Constellation - - - - - - - -
    Version: Next

    Terraform usage

    -

    Terraform is an Infrastructure as Code (IaC) framework to manage cloud resources. This page explains how Constellation uses it internally and how advanced users may manually use it to have more control over the resource creation.

    -
    info

    Information on this page is intended for users who are familiar with Terraform. -It's not required for common usage of Constellation. -See the Terraform documentation if you want to learn more about it.

    -

    Terraform state files

    -

    Constellation keeps Terraform state files in subdirectories of the workspace together with the corresponding Terraform configuration files and metadata. -The subdirectories are created on the first Constellation CLI action that uses Terraform internally.

    -

    Currently, these subdirectories are:

    -
      -
    • constellation-terraform - Terraform state files for the resources of the Constellation cluster
    • -
    • constellation-iam-terraform - Terraform state files for IAM configuration
    • -
    -

    As with all commands, commands that work with these files (e.g., apply, terminate, iam) have to be executed from the root of the cluster's workspace directory. You usually don't need and shouldn't manipulate or delete the subdirectories manually.

    -

    Interacting with Terraform manually

    -

    Manual interaction with Terraform state created by Constellation (i.e., via the Terraform CLI) should only be performed by experienced users. It may lead to unrecoverable loss of cloud resources. For the majority of users and use cases, the interaction done by the Constellation CLI is sufficient.

    -

    Terraform debugging

    -

    To debug Terraform issues, the Constellation CLI offers the tf-log flag. You can set it to any of Terraform's log levels:

    -
      -
    • JSON (JSON-formatted logs at TRACE level)
    • -
    • TRACE
    • -
    • DEBUG
    • -
    • INFO
    • -
    • WARN
    • -
    • ERROR
    • -
    -

    The log output is written to the terraform.log file in the workspace directory. The output is appended to the file on each run.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/workflows/cert-manager/index.html b/pr-preview/pr-4027/next/workflows/cert-manager/index.html deleted file mode 100644 index 29c76dd6d..000000000 --- a/pr-preview/pr-4027/next/workflows/cert-manager/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - -Install cert-manager | Constellation - - - - - - - -
    Version: Next

    Install cert-manager

    -
    caution

    If you want to use cert-manager with Constellation, pay attention to the following to avoid potential pitfalls.

    -

    Constellation ships with cert-manager preinstalled. -The default installation is part of the kube-system namespace, as all other Constellation-managed microservices. -You are free to install more instances of cert-manager into other namespaces. -However, be aware that any new installation needs to use the same version as the one installed with Constellation or rely on the same CRD versions. -Also remember to set the installCRDs value to false when installing new cert-manager instances. -It will create problems if you have two installations of cert-manager depending on different versions of the installed CRDs. -CRDs are cluster-wide resources and cert-manager depends on specific versions of those CRDs for each release.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/workflows/config/index.html b/pr-preview/pr-4027/next/workflows/config/index.html deleted file mode 100644 index ee5822e37..000000000 --- a/pr-preview/pr-4027/next/workflows/config/index.html +++ /dev/null @@ -1,162 +0,0 @@ - - - - - -Configure your cluster | Constellation - - - - - - - -
    Version: Next

    Configure your cluster

    -
    info

    This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details.

    -
    Loading asciinema cast...
    -
    -

    Before you can create your cluster, you need to configure the identity and access management (IAM) for your cloud service provider (CSP) and choose machine types for the nodes.

    -

    Creating the configuration file

    -

    You can generate a configuration file for your CSP by using the following CLI command:

    -
    constellation config generate aws
    -

    This creates the file constellation-conf.yaml in the current directory.

    -

    Choosing a VM type

    -

    Constellation supports the following VM types:

    -

    By default, Constellation uses m6a.xlarge VMs (4 vCPUs, 16 GB RAM) to create your cluster. -Optionally, you can switch to a different VM type by modifying instanceType in the configuration file. -If you are using the default attestation variant awsSEVSNP, you can use the instance types described in AWS's AMD SEV-SNP docs. -Please mind the region restrictions mentioned in the Getting started section.

    If you are using the attestation variant awsNitroTPM, you can choose any of the nitroTPM-enabled instance types.

    The Constellation CLI can also print the supported instance types with: constellation config instance-types.

    -

    Fill the desired VM type into the instanceType fields in the constellation-conf.yml file.

    -

    Creating additional node groups

    -

    By default, Constellation creates the node groups control_plane_default and worker_default for control-plane nodes and workers, respectively. -If you require additional control-plane or worker groups with different instance types, zone placements, or disk sizes, you can add additional node groups to the constellation-conf.yml file. -Each node group can be scaled individually.

    -

    Consider the following example for AWS:

    -
    nodeGroups:
    control_plane_default:
    role: control-plane
    instanceType: c6a.xlarge
    stateDiskSizeGB: 30
    stateDiskType: gp3
    zone: eu-west-1c
    initialCount: 3
    worker_default:
    role: worker
    instanceType: c6a.xlarge
    stateDiskSizeGB: 30
    stateDiskType: gp3
    zone: eu-west-1c
    initialCount: 2
    high_cpu:
    role: worker
    instanceType: c6a.24xlarge
    stateDiskSizeGB: 128
    stateDiskType: gp3
    zone: eu-west-1c
    initialCount: 1
    -

    This configuration creates an additional node group high_cpu with a larger instance type and disk.

    -

    You can use the field zone to specify what availability zone nodes of the group are placed in. -On Azure, this field is empty by default and nodes are automatically spread across availability zones. -STACKIT currently offers SEV-enabled CPUs in the eu01-1, eu01-2, and eu01-3 zones. -Consult the documentation of your cloud provider for more information:

    - -

    Choosing a Kubernetes version

    -

    To learn which Kubernetes versions can be installed with your current CLI, you can run constellation config kubernetes-versions. -See also Constellation's Kubernetes support policy.

    -

    Creating an IAM configuration

    -

    You can create an IAM configuration for your cluster automatically using the constellation iam create command. -If you already have a Constellation configuration file, you can add the --update-config flag to the command. This writes the needed IAM fields into your configuration. Furthermore, the flag updates the zone/region of the configuration if it hasn't been set yet.

    -

    You must be authenticated with the AWS CLI in the shell session with a user that has the required permissions for IAM creation.

    constellation iam create aws --zone=us-east-2a --prefix=constellTest

    This command creates IAM configuration for the AWS zone us-east-2a using the prefix constellTest for all named resources being created.

    Constellation OS images are currently replicated to the following regions:

      -
    • eu-central-1
    • -
    • eu-west-1
    • -
    • eu-west-3
    • -
    • us-east-2
    • -
    • ap-south-1
    • -

    If you require the OS image to be available in another region, let us know.

    You can find a list of all regions in AWS's documentation.

    Paste the output into the corresponding fields of the constellation-conf.yaml file.

    -
    Alternatively, you can manually create the IAM configuration on your CSP.

    The following describes the configuration fields and how you obtain the required information or create the required resources.

      -
    • -

      region: The name of your chosen AWS data center region, e.g., us-east-2.

      -

      Constellation OS images are currently replicated to the following regions:

      -
        -
      • eu-central-1
      • -
      • eu-west-1
      • -
      • eu-west-3
      • -
      • us-east-2
      • -
      • ap-south-1
      • -
      -

      If you require the OS image to be available in another region, let us know.

      -

      You can find a list of all regions in AWS's documentation.

      -
    • -
    • -

      zone: The name of your chosen AWS data center availability zone, e.g., us-east-2a.

      -

      Learn more about availability zones in AWS's documentation.

      -
    • -
    • -

      iamProfileControlPlane: The name of an IAM instance profile attached to all control-plane nodes.

      -

      You can create the resource with Terraform. For that, use the provided Terraform script to generate the necessary profile. The profile name will be provided as Terraform output value: control_plane_instance_profile_name.

      -

      Alternatively, you can create the AWS profile with a tool of your choice. Use the JSON policy in main.tf in the resource aws_iam_policy.control_plane_policy.

      -
    • -
    • -

      iamProfileWorkerNodes: The name of an IAM instance profile attached to all worker nodes.

      -

      You can create the resource with Terraform. For that, use the provided Terraform script to generate the necessary profile. The profile name will be provided as Terraform output value: worker_nodes_instance_profile_name.

      -

      Alternatively, you can create the AWS profile with a tool of your choice. Use the JSON policy in main.tf in the resource aws_iam_policy.worker_node_policy.

      -
    • -
    -

    Now that you've configured your CSP, you can create your cluster.

    -

    Deleting an IAM configuration

    -

    You can keep a created IAM configuration and reuse it for new clusters. Alternatively, you can also delete it if you don't want to use it anymore.

    -

    Delete the IAM configuration by executing the following command in the same directory where you executed constellation iam create (the directory that contains constellation-iam-terraform as a subdirectory):

    -
    constellation iam destroy
    -
    caution

    For Azure, deleting the IAM configuration by executing constellation iam destroy will delete the whole resource group created by constellation iam create. -This also includes any additional resources in the resource group that weren't created by Constellation.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/workflows/create/index.html b/pr-preview/pr-4027/next/workflows/create/index.html deleted file mode 100644 index 365eda06c..000000000 --- a/pr-preview/pr-4027/next/workflows/create/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -Create your cluster | Constellation - - - - - - - -
    Version: Next

    Create your cluster

    -
    info

    This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details.

    -
    Loading asciinema cast...
    -
    -

    Creating your cluster happens through multiple phases. -The most significant ones are:

    -
      -
    1. Creating the necessary resources in your cloud environment
    2. -
    3. Bootstrapping the Constellation cluster and setting up a connection
    4. -
    5. Installing the necessary Kubernetes components
    6. -
    -

    constellation apply handles all this in a single command. -You can use the --skip-phases flag to skip specific phases of the process. -For example, if you created the infrastructure manually, you can skip the cloud resource creation phase.

    -

    See the architecture section for details on the inner workings of this process.

    -
    tip

    If you don't have a cloud subscription, you can also set up a local Constellation cluster using virtualization for testing.

    -

    Before you create the cluster, make sure to have a valid configuration file.

    -
    constellation apply

    apply stores the state of your cluster's cloud resources in a constellation-terraform directory in your workspace.

    -

    Finally, configure kubectl for your cluster:

    -
    export KUBECONFIG="$PWD/constellation-admin.conf"
    -

    🏁 That's it. You've successfully created a Constellation cluster.

    -

    Troubleshooting

    -

    In case apply fails, the CLI collects logs from the bootstrapping instance and stores them inside constellation-cluster.log.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/workflows/lb/index.html b/pr-preview/pr-4027/next/workflows/lb/index.html deleted file mode 100644 index 6d49a6e7a..000000000 --- a/pr-preview/pr-4027/next/workflows/lb/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - -Expose a service | Constellation - - - - - - - -
    Version: Next

    Expose a service

    -

    Constellation integrates the native load balancers of each CSP. Therefore, to expose a service simply create a service of type LoadBalancer.

    -

    Internet-facing LB service on AWS

    -

    To expose your application service externally you might want to use a Kubernetes Service of type LoadBalancer. On AWS, load-balancing is achieved through the AWS Load Balancer Controller as in the managed EKS.

    -

    Since recent versions, the controller deploy an internal LB by default requiring to set an annotation service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing to have an internet-facing LB. For more details, see the official docs.

    -

    For general information on LB with AWS see Network load balancing on Amazon EKS.

    -
    caution

    Before terminating the cluster, all LB backed services should be deleted, so that the controller can cleanup the related resources.

    -

    Ingress on AWS

    -

    The AWS Load Balancer Controller also provisions Ingress resources of class alb. -AWS Application Load Balancers (ALBs) can be configured with a target-type. -The target type ip requires using the EKS container network solution, which makes it incompatible with Constellation. -If a service can be exposed on a NodePort, the target type instance can be used.

    -

    See Application load balancing on Amazon EKS for more information.

    -
    caution

    Ingress handlers backed by AWS ALBs reside outside the Constellation cluster, so they shouldn't be handling sensitive traffic!

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/workflows/recovery/index.html b/pr-preview/pr-4027/next/workflows/recovery/index.html deleted file mode 100644 index 2004e3790..000000000 --- a/pr-preview/pr-4027/next/workflows/recovery/index.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - -Recover your cluster | Constellation - - - - - - - -
    Version: Next

    Recover your cluster

    -

    Recovery of a Constellation cluster means getting it back into a healthy state after too many concurrent node failures in the control plane. -Reasons for an unhealthy cluster can vary from a power outage, or planned reboot, to migration of nodes and regions. -Recovery events are rare, because Constellation is built for high availability and automatically and securely replaces failed nodes. When a node is replaced, Constellation's control plane first verifies the new node before it sends the node the cryptographic keys required to decrypt its state disk.

    -

    Constellation provides a recovery mechanism for cases where the control plane has failed and is unable to replace nodes. -The constellation recover command securely connects to all nodes in need of recovery using attested TLS and provides them with the keys to decrypt their state disks and continue booting.

    -

    Identify unhealthy clusters

    -

    The first step to recovery is identifying when a cluster becomes unhealthy. -Usually, this can be first observed when the Kubernetes API server becomes unresponsive.

    -

    You can check the health status of the nodes via the cloud service provider (CSP). -Constellation provides logging information on the boot process and status via serial console output. -In the following, you'll find detailed descriptions for identifying clusters stuck in recovery for each CSP.

    -

    First, open the AWS console to view all Auto Scaling Groups (ASGs) in the region of your cluster. Select the ASG of the control plane <cluster-name>-<UID>-control-plane and check that enough members are in a Running state.

    Second, check the boot logs of these Instances. In the ASG's Instance management view, select each desired instance. In the upper right corner, select Action > Monitor and troubleshoot > Get system log.

    In the serial console output, search for Waiting for decryption key. -Similar output to the following means your node was restarted and needs to decrypt the state disk:

    {"level":"INFO","ts":"2022-09-08T10:21:53Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"gcp"}
    {"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}
    {"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}
    {"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}

    The node will then try to connect to the JoinService and obtain the decryption key. -If this fails due to an unhealthy control plane, you will see log messages similar to the following:

    {"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["192.168.178.4:30090","192.168.178.2:30090"]}
    {"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.4:30090"}
    {"level":"WARN","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing dial tcp 192.168.178.4:30090: connect: connection refused\"","endpoint":"192.168.178.4:30090"}
    {"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.2:30090"}
    {"level":"WARN","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing dial tcp 192.168.178.2:30090: i/o timeout\"","endpoint":"192.168.178.2:30090"}
    {"level":"ERROR","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}

    This means that you have to recover the node manually.

    -

    Recover a cluster

    -

    Recovering a cluster requires the following parameters:

    -
      -
    • The constellation-state.yaml file in your working directory or the cluster's endpoint
    • -
    • The master secret of the cluster
    • -
    -

    A cluster can be recovered like this:

    -
    $ constellation recover
    Pushed recovery key.
    Pushed recovery key.
    Pushed recovery key.
    Recovered 3 control-plane nodes.
    -

    In the serial console output of the node you'll see a similar output to the following:

    -
    {"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer","caller":"recoveryserver/server.go:93","msg":"Received recover call"}
    {"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer","caller":"recoveryserver/server.go:125","msg":"Received state disk key and measurement secret, shutting down server"}
    {"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer.gRPC","caller":"zap/server_interceptors.go:61","msg":"finished streaming call with code OK","grpc.start_time":"2022-09-08T10:26:59Z","system":"grpc","span.kind":"server","grpc.service":"recoverproto.API","grpc.method":"Recover","peer.address":"192.0.2.3:41752","grpc.code":"OK","grpc.time_ms":15.701}
    {"level":"INFO","ts":"2022-09-08T10:27:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:87","msg":"RejoinClient stopped"}
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/workflows/reproducible-builds/index.html b/pr-preview/pr-4027/next/workflows/reproducible-builds/index.html deleted file mode 100644 index 73cb6011f..000000000 --- a/pr-preview/pr-4027/next/workflows/reproducible-builds/index.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - -Reproduce released artifacts | Constellation - - - - - - - -
    Version: Next

    Reproduce released artifacts

    -

    Constellation has first-class support for reproducible builds. -Reproducing the released artifacts is an alternative to signature verification that doesn't require trusting Edgeless Systems' release process. -The following sections describe how to rebuild an artifact and how Constellation ensures that the rebuild reproduces the artifacts bit-by-bit.

    -

    Build environment prerequisites

    -

    The build systems used by Constellation - Bazel and Nix - are designed for deterministic, reproducible builds. -These two dependencies should be the only prerequisites for a successful build. -However, it can't be ruled out completely that peculiarities of the host affect the build result. -Thus, we recommend the following host setup for best results:

    -
      -
    1. A Linux operating system not older than v5.4.
    2. -
    3. The GNU C library not older than v2.31 (avoid musl).
    4. -
    5. GNU coreutils not older than v8.30 (avoid busybox).
    6. -
    7. An ext4 filesystem for building.
    8. -
    9. AppArmor turned off.
    10. -
    -

    This is given, for example, on an Ubuntu 22.04 system, which is also used for reproducibility tests.

    -
    note

    To avoid any backwards-compatibility issues, the host software versions should also not be much newer than the Constellation release.

    -

    Run the build

    -

    The following instructions outline qualitatively how to reproduce a build. -Constellation implements these instructions in the Reproducible Builds workflow, which continuously tests for reproducibility. -The workflow is a good place to look up specific version numbers and build steps.

    -
      -
    1. -

      Check out the Constellation repository at the tag corresponding to the release.

      -
      git clone https://github.com/edgelesssys/constellation.git
      cd constellation
      git checkout v2.20.0
      -
    2. -
    3. -

      Install the Bazel release specified in .bazelversion.

      -
    4. -
    5. -

      Install Nix (any recent version should do).

      -
    6. -
    7. -

      Run the build with bazel build $target for one of the following targets of interest:

      -
      //cli:cli_enterprise_darwin_amd64
      //cli:cli_enterprise_darwin_arm64
      //cli:cli_enterprise_linux_amd64
      //cli:cli_enterprise_linux_arm64
      //cli:cli_enterprise_windows_amd64
      -
    8. -
    9. -

      Compare the build result with the downloaded release artifact.

      -
    10. -
    -

    Feedback

    -

    Reproduction failures often indicate a bug in the build system or in the build definitions. -Therefore, we're interested in any reproducibility issues you might encounter. -Start a bug report and describe the details of your build environment. -Make sure to include your result binary or a diffoscope report, if possible.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/workflows/s3proxy/index.html b/pr-preview/pr-4027/next/workflows/s3proxy/index.html deleted file mode 100644 index 7949d5c1b..000000000 --- a/pr-preview/pr-4027/next/workflows/s3proxy/index.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - -Install s3proxy | Constellation - - - - - - - -
    Version: Next

    Install s3proxy

    -

    Constellation includes a transparent client-side encryption proxy for AWS S3 and compatible stores. -s3proxy encrypts objects before sending them to S3 and automatically decrypts them on retrieval, without requiring changes to your application. -With s3proxy, you can use S3 for storage in a confidential way without having to trust the storage provider.

    -

    Limitations

    -

    Currently, s3proxy has the following limitations:

    -
      -
    • Only PutObject and GetObject requests are encrypted/decrypted by s3proxy. -By default, s3proxy will block requests that may expose unencrypted data to S3 (e.g. UploadPart). -The allow-multipart flag disables request blocking for evaluation purposes.
    • -
    • Using the Range header on GetObject is currently not supported and will result in an error.
    • -
    -

    These limitations will be removed with future iterations of s3proxy. -If you want to use s3proxy but these limitations stop you from doing so, consider opening an issue.

    -

    Deployment

    -

    You can add the s3proxy to your Constellation cluster as follows:

    -
      -
    1. Add the Edgeless Systems chart repository: -
      helm repo add edgeless https://helm.edgeless.systems/stable
      helm repo update
      -
    2. -
    3. Set ACCESS_KEY and ACCESS_SECRET to valid credentials you want s3proxy to use to interact with S3.
    4. -
    5. Deploy s3proxy: -
      helm install s3proxy edgeless/s3proxy --set awsAccessKeyID="$ACCESS_KEY" --set awsSecretAccessKey="$ACCESS_SECRET"
      -
    6. -
    -

    If you want to run a demo application, check out the Filestash with s3proxy example.

    -

    Technical details

    -

    Encryption

    -

    s3proxy relies on Google's Tink Cryptographic Library to implement cryptographic operations securely. -The used cryptographic primitives are NIST SP 800 38f for key wrapping and AES-GCM with 256 bit keys for data encryption.

    -

    s3proxy uses envelope encryption to encrypt objects. -This means s3proxy uses a key encryption key (KEK) issued by the KeyService to encrypt data encryption keys (DEKs). -Each S3 object is encrypted with its own DEK. -The encrypted DEK is then saved as metadata of the encrypted object. -This enables key rotation of the KEK without re-encrypting the data in S3. -The approach also allows access to objects from different locations, as long as each location has access to the KEK.

    -

    Traffic interception

    -

    To use s3proxy, you have to redirect your outbound S3 traffic to s3proxy. -This can either be done by modifying your client application or by changing the deployment of your application.

    -

    The necessary deployment modifications are to add DNS redirection and a trusted TLS certificate to the client's trust store. -DNS redirection can be defined for each pod, allowing you to use s3proxy for one application without changing other applications in the same cluster. -Adding a trusted TLS certificate is necessary as clients communicate with s3proxy via HTTPS. -To have your client application trust s3proxy's TLS certificate, the certificate has to be added to the client's certificate trust store. -The Filestash with s3proxy example shows how to do this.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/workflows/sbom/index.html b/pr-preview/pr-4027/next/workflows/sbom/index.html deleted file mode 100644 index 4ef577c65..000000000 --- a/pr-preview/pr-4027/next/workflows/sbom/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -Consume software bill of materials (SBOMs) | Constellation - - - - - - - -
    Version: Next

    Consume software bill of materials (SBOMs)

    -
    Loading asciinema cast...
    -
    -

    Constellation builds produce a software bill of materials (SBOM) for each generated artifact. -You can use SBOMs to make informed decisions about dependencies and vulnerabilities in a given application. Enterprises rely on SBOMs to maintain an inventory of used applications, which allows them to take data-driven approaches to managing risks related to vulnerabilities.

    -

    SBOMs for Constellation are generated using Syft, signed using Cosign, and stored with the produced artifact.

    -
    note

    The public key for Edgeless Systems' long-term code-signing key is:

    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT
    JmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==
    -----END PUBLIC KEY-----

    The public key is also available for download at https://edgeless.systems/es.pub and in the Twitter profile @EdgelessSystems.

    Make sure the key is available in a file named cosign.pub to execute the following examples.

    -

    Verify and download SBOMs

    -

    The following sections detail how to work with each type of artifact to verify and extract the SBOM.

    -

    Constellation CLI

    -

    The SBOM for Constellation CLI is made available on the GitHub release page. The SBOM (constellation.spdx.sbom) and corresponding signature (constellation.spdx.sbom.sig) are valid for each Constellation CLI for a given version, regardless of architecture and operating system.

    -
    curl -LO https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom
    curl -LO https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom.sig
    cosign verify-blob --key cosign.pub --signature constellation.spdx.sbom.sig constellation.spdx.sbom
    -

    Container Images

    -

    SBOMs for container images are attached to the image using Cosign and uploaded to the same registry.

    -

    As a consumer, use cosign to download and verify the SBOM:

    -
    # Verify and download the attestation statement
    cosign verify-attestation ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --type 'https://cyclonedx.org/bom' --key cosign.pub --output-file verification-service.att.json
    # Extract SBOM from attestation statement
    jq -r .payload verification-service.att.json | base64 -d > verification-service.cyclonedx.sbom
    -

    A successful verification should result in similar output:

    -
    $ cosign verify-attestation ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --type 'https://cyclonedx.org/bom' --key cosign.pub --output-file verification-service.sbom

    Verification for ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --
    The following checks were performed on each of these signatures:
    - The cosign claims were validated
    - The signatures were verified against the specified public key
    $ jq -r .payload verification-service.sbom | base64 -d > verification-service.cyclonedx.sbom
    -
    note

    This example considers only the verification-service. The same approach works for all containers in the Constellation container registry.

    -

    Vulnerability scanning

    -

    You can use a plethora of tools to consume SBOMs. This section provides suggestions for tools that are popular and known to produce reliable results, but any tool that consumes SPDX or CycloneDX files should work.

    -

    Syft is able to convert between the two formats in case you require a specific type.

    -

    Grype

    -

    Grype is a CLI tool that lends itself well for integration into CI/CD systems or local developer machines. It's also able to consume the signed attestation statement directly and does the verification in one go.

    -
    grype att:verification-service.sbom --key cosign.pub --add-cpes-if-none -q
    -

    Dependency Track

    -

    Dependency Track is one of the oldest and most mature solutions when it comes to managing software inventory and vulnerabilities. Once imported, it continuously scans SBOMs for new vulnerabilities. It supports the CycloneDX format and provides direct guidance on how to comply with U.S. Executive Order 14028.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/workflows/scale/index.html b/pr-preview/pr-4027/next/workflows/scale/index.html deleted file mode 100644 index ae66fb6fb..000000000 --- a/pr-preview/pr-4027/next/workflows/scale/index.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - -Scale your cluster | Constellation - - - - - - - -
    Version: Next

    Scale your cluster

    -

    Constellation provides all features of a Kubernetes cluster including scaling and autoscaling.

    -

    Worker node scaling

    -

    Autoscaling

    -

    Constellation comes with autoscaling disabled by default. To enable autoscaling, find the scaling group of -worker nodes:

    -
    kubectl get scalinggroups -o json | yq '.items | .[] | select(.spec.role == "Worker") | [{"name": .metadata.name, "nodeGoupName": .spec.nodeGroupName}]'
    -

    This will output a list of scaling groups with the corresponding cloud provider name (name) and the cloud provider agnostic name of the node group (nodeGroupName).

    -

    Then, patch the autoscaling field of the scaling group resource with the desired name to true:

    -
    # Replace <name> with the name of the scaling group you want to enable autoscaling for
    worker_group=<name>
    kubectl patch scalinggroups $worker_group --patch '{"spec":{"autoscaling": true}}' --type='merge'
    kubectl get scalinggroup $worker_group -o jsonpath='{.spec}' | yq -P
    -

    The cluster autoscaler now automatically provisions additional worker nodes so that all pods have a place to run. -You can configure the minimum and maximum number of worker nodes in the scaling group by patching the min or -max fields of the scaling group resource:

    -
    kubectl patch scalinggroups $worker_group --patch '{"spec":{"max": 5}}' --type='merge'
    kubectl get scalinggroup $worker_group -o jsonpath='{.spec}' | yq -P
    -

    The cluster autoscaler will now never provision more than 5 worker nodes.

    -

    If you want to see the autoscaling in action, try to add a deployment with a lot of replicas, like the -following Nginx deployment. The number of replicas needed to trigger the autoscaling depends on the size of -and count of your worker nodes. Wait for the rollout of the deployment to finish and compare the number of -worker nodes before and after the deployment:

    -
    kubectl create deployment nginx --image=nginx --replicas 150
    kubectl -n kube-system get nodes
    kubectl rollout status deployment nginx
    kubectl -n kube-system get nodes
    -

    Manual scaling

    -

    Alternatively, you can manually scale your cluster up or down:

    -
      -
    1. Go to Auto Scaling Groups and select the worker ASG to scale up.
    2. -
    3. Click Edit
    4. -
    5. Set the new (increased) Desired capacity and Update.
    6. -
    -

    Control-plane node scaling

    -

    Control-plane nodes can only be scaled manually and only scaled up!

    -

    To increase the number of control-plane nodes, follow these steps:

    -
      -
    1. Go to Auto Scaling Groups and select the control-plane ASG to scale up.
    2. -
    3. Click Edit
    4. -
    5. Set the new (increased) Desired capacity and Update.
    6. -
    -

    If you scale down the number of control-planes nodes, the removed nodes won't be able to exit the etcd cluster correctly. This will endanger the quorum that's required to run a stable Kubernetes control plane.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/workflows/storage/index.html b/pr-preview/pr-4027/next/workflows/storage/index.html deleted file mode 100644 index 1e9f5e36b..000000000 --- a/pr-preview/pr-4027/next/workflows/storage/index.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - -Use persistent storage | Constellation - - - - - - - -
    Version: Next

    Use persistent storage

    -

    Persistent storage in Kubernetes requires cloud-specific configuration. -For abstraction of container storage, Kubernetes offers volumes, -allowing users to mount storage solutions directly into containers. -The Container Storage Interface (CSI) is the standard interface for exposing arbitrary block and file storage systems into containers in Kubernetes. -Cloud service providers (CSPs) offer their own CSI-based solutions for cloud storage.

    -

    Confidential storage

    -

    Most cloud storage solutions support encryption, such as GCE Persistent Disks (PD). -Constellation supports the available CSI-based storage options for Kubernetes engines in AWS, Azure, GCP, and STACKIT. -However, their encryption takes place in the storage backend and is managed by the CSP. -Thus, using the default CSI drivers for these storage types means trusting the CSP with your persistent data.

    -

    To address this, Constellation provides CSI drivers for AWS EBS, Azure Disk, GCE PD, and OpenStack Cinder, offering encryption on the node level. They enable transparent encryption for persistent volumes without needing to trust the cloud backend. Plaintext data never leaves the confidential VM context, offering you confidential storage.

    -

    For more details see encrypted persistent storage.

    -

    CSI drivers

    -

    Constellation supports the following drivers, which offer node-level encryption and optional integrity protection.

    -

    Constellation CSI driver for AWS Elastic Block Store -Mount Elastic Block Store storage volumes into your Constellation cluster. -Follow the instructions on how to install the Constellation CSI driver or check out the repository for more information.

    -

    Note that in case the options above aren't a suitable solution for you, Constellation is compatible with all other CSI-based storage options. For example, you can use AWS EFS, Azure Files, or GCP Filestore with Constellation out of the box. Constellation is just not providing transparent encryption on the node level for these storage types yet.

    -

    Installation

    -

    The Constellation CLI automatically installs Constellation's CSI driver for the selected CSP in your cluster. -If you don't need a CSI driver or wish to deploy your own, you can disable the automatic installation by setting deployCSIDriver to false in your Constellation config file.

    -

    AWS comes with two storage classes by default.

      -
    • encrypted-rwo -
        -
      • Uses SSDs of gp3 type
      • -
      • ext-4 filesystem
      • -
      • Encryption of all data written to disk
      • -
      -
    • -
    • integrity-encrypted-rwo -
        -
      • Uses SSDs of gp3 type
      • -
      • ext-4 filesystem
      • -
      • Encryption of all data written to disk
      • -
      • Integrity protection of data written to disk
      • -
      -
    • -

    For more information on encryption algorithms and key sizes, refer to cryptographic algorithms.

    info

    The default storage class is set to encrypted-rwo for performance reasons. -If you want integrity-protected storage, set the storageClassName parameter of your persistent volume claim to integrity-encrypted-rwo.

    Alternatively, you can create your own storage class with integrity protection enabled by adding csi.storage.k8s.io/fstype: ext4-integrity to the class parameters. -Or use another filesystem by specifying another file system type with the suffix -integrity, e.g., csi.storage.k8s.io/fstype: xfs-integrity.

    Note that volume expansion isn't supported for integrity-protected disks.

    -
      -
    1. -

      Create a persistent volume

      -

      A persistent volume claim is a request for storage with certain properties. -It can refer to a storage class. -The following creates a persistent volume claim, requesting 20 GB of storage via the encrypted-rwo storage class:

      -
      cat <<EOF | kubectl apply -f -
      kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
      name: pvc-example
      namespace: default
      spec:
      accessModes:
      - ReadWriteOnce
      storageClassName: encrypted-rwo
      resources:
      requests:
      storage: 20Gi
      EOF
      -
    2. -
    3. -

      Create a Pod with persistent storage

      -

      You can assign a persistent volume claim to an application in need of persistent storage. -The mounted volume will persist restarts. -The following creates a pod that uses the previously created persistent volume claim:

      -
      cat <<EOF | kubectl apply -f -
      apiVersion: v1
      kind: Pod
      metadata:
      name: web-server
      namespace: default
      spec:
      containers:
      - name: web-server
      image: nginx
      volumeMounts:
      - mountPath: /var/lib/www/html
      name: mypvc
      volumes:
      - name: mypvc
      persistentVolumeClaim:
      claimName: pvc-example
      readOnly: false
      EOF
      -
    4. -
    -

    Change the default storage class

    -

    The default storage class is responsible for all persistent volume claims that don't explicitly request storageClassName. -Constellation creates a storage class with encryption enabled and sets this as the default class. -In case you wish to change it, follow the steps below:

    -
      -
    1. -

      List the storage classes in your cluster:

      -
      kubectl get storageclass
      -

      The output is similar to this:

      -
      NAME                      PROVISIONER                         RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
      encrypted-rwo (default) {your-csp}.csi.confidential.cloud Delete Immediate true 1d
      integrity-encrypted-rwo {your-csp}.csi.confidential.cloud Delete Immediate false 1d
      -

      The default storage class is marked by (default).

      -
    2. -
    3. -

      Mark old default storage class as non default

      -

      If you previously used another storage class as the default, you will have to remove that annotation:

      -
      kubectl patch storageclass encrypted-rwo -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
      -
    4. -
    5. -

      Mark new class as the default

      -
      kubectl patch storageclass integrity-encrypted-rwo -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
      -
    6. -
    7. -

      Verify that your chosen storage class is default:

      -
      kubectl get storageclass
      -

      The output is similar to this:

      -
      NAME                                PROVISIONER                         RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
      encrypted-rwo {your-csp}.csi.confidential.cloud Delete Immediate true 1d
      integrity-encrypted-rwo (default) {your-csp}.csi.confidential.cloud Delete Immediate false 1d
      -
    8. -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/workflows/terminate/index.html b/pr-preview/pr-4027/next/workflows/terminate/index.html deleted file mode 100644 index 6a13645af..000000000 --- a/pr-preview/pr-4027/next/workflows/terminate/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - -Terminate your cluster | Constellation - - - - - - - -
    Version: Next

    Terminate your cluster

    -
    info

    This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details.

    -
    Loading asciinema cast...
    -
    -

    You can terminate your cluster using the CLI. For this, you need the Terraform state directory named constellation-terraform in the current directory.

    -
    danger

    All ephemeral storage and state of your cluster will be lost. Make sure any data is safely stored in persistent storage. Constellation can recreate your cluster and the associated encryption keys, but won't backup your application data automatically.

    -

    Terminate the cluster by running:

    constellation terminate

    Or without confirmation (e.g., for automation purposes):

    constellation terminate --yes

    This deletes all resources created by Constellation in your cloud environment. -All local files created by the apply command are deleted as well, except for constellation-mastersecret.json and the configuration file.

    caution

    Termination can fail if additional resources have been created that depend on the ones managed by Constellation. In this case, you need to delete these additional -resources manually. Just run the terminate command again afterward to continue the termination process of the cluster.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/workflows/terraform-provider/index.html b/pr-preview/pr-4027/next/workflows/terraform-provider/index.html deleted file mode 100644 index 1adffdb31..000000000 --- a/pr-preview/pr-4027/next/workflows/terraform-provider/index.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - -Use the Terraform provider | Constellation - - - - - - - -
    Version: Next

    Use the Terraform provider

    -

    The Constellation Terraform provider allows to manage the full lifecycle of a Constellation cluster (namely creation, upgrades, and deletion) via Terraform. -The provider is available through the Terraform registry and is released in lock-step with Constellation releases.

    -

    Prerequisites

    -
      -
    • a Linux / Mac operating system (ARM64/AMD64)
    • -
    • a Terraform installation of version v1.4.4 or above
    • -
    -

    Quick setup

    -

    This example shows how to set up a Constellation cluster with the reference IAM and infrastructure setup. This setup is also used when creating a Constellation cluster through the Constellation CLI. You can either consume the IAM / infrastructure modules through a remote source (recommended) or local files. The latter requires downloading the infrastructure and IAM modules for the corresponding CSP from terraform-modules.zip on the Constellation release page and placing them in the Terraform workspace directory.

    -
      -
    1. Create a directory (workspace) for your Constellation cluster.
    2. -
    -
    mkdir constellation-workspace
    cd constellation-workspace
    -
      -
    1. Use one of the example configurations for using the Constellation Terraform provider or create a main.tf file and fill it with the resources you want to create. The Constellation Terraform provider documentation offers thorough documentation on the resources and their attributes.
    2. -
    3. Initialize and apply the Terraform configuration.
    4. -
    -

    Initialize the providers and apply the configuration.

    terraform init
    terraform apply

    Optionally, you can prefix the terraform apply command with TF_LOG=INFO to collect Terraform logs while applying the configuration. This may provide helpful output in debugging scenarios.

    -
      -
    1. Connect to the cluster.
    2. -
    -
    terraform output -raw kubeconfig > constellation-admin.conf
    export KUBECONFIG=$(realpath constellation-admin.conf)
    -

    Bringing your own infrastructure

    -

    Instead of using the example infrastructure used in the quick setup, you can also provide your own infrastructure. -If you need a starting point for a custom infrastructure setup, you can download the infrastructure / IAM Terraform modules for the respective CSP from the Constellation GitHub releases. You can modify and extend the modules per your requirements, while keeping the basic functionality intact. -The module contains:

    -
      -
    • {csp}: cloud resources the cluster runs on
    • -
    • iam/{csp}: IAM resources used within the cluster
    • -
    -

    When upgrading your cluster, make sure to check the Constellation release notes for potential breaking changes in the reference infrastructure / IAM modules that need to be considered.

    -

    Cluster upgrades

    - -

    The steps for applying the upgrade are as follows:

    -
      -
    1. Update the version constraint of the Constellation Terraform provider in the required_providers block in your Terraform configuration.
    2. -
    3. If you explicitly set any of the version attributes of the provider's resources and data sources (e.g. image_version or constellation_microservice_version), make sure to update them too. Refer to Constellation's version support policy for more information on how each Constellation version and its dependencies are supported.
    4. -
    5. Update the IAM / infrastructure configuration. - -
    6. -
    7. Upgrade the Terraform module and provider dependencies and apply the targeted configuration.
    8. -
    -
      terraform init -upgrade
    terraform apply
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/workflows/troubleshooting/index.html b/pr-preview/pr-4027/next/workflows/troubleshooting/index.html deleted file mode 100644 index 0947e81f5..000000000 --- a/pr-preview/pr-4027/next/workflows/troubleshooting/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - -Troubleshooting | Constellation - - - - - - - -
    Version: Next

    Troubleshooting

    -

    This section aids you in finding problems when working with Constellation.

    -

    Common issues

    -

    Issues with creating new clusters

    -

    When you create a new cluster, you should always use the latest release. -If something doesn't work, check out the known issues.

    -

    Azure: Resource Providers can't be registered

    -

    On Azure, you may receive the following error when running apply or terminate with limited IAM permissions:

    -
    Error: Error ensuring Resource Providers are registered.

    Terraform automatically attempts to register the Resource Providers it supports to
    ensure it's able to provision resources.

    If you don't have permission to register Resource Providers you may wish to use the
    "skip_provider_registration" flag in the Provider block to disable this functionality.

    [...]
    -

    To continue, please ensure that the required resource providers have been registered in your subscription by your administrator.

    -

    Afterward, set ARM_SKIP_PROVIDER_REGISTRATION=true as an environment variable and either run apply or terminate again. -For example:

    -
    ARM_SKIP_PROVIDER_REGISTRATION=true constellation apply
    -

    Or alternatively, for terminate:

    -
    ARM_SKIP_PROVIDER_REGISTRATION=true constellation terminate
    -

    Azure: Can't update attestation policy

    -

    On Azure, you may receive the following error when running apply from within an Azure environment, e.g., an Azure VM:

    -
    An error occurred: patching policies: updating attestation policy: unexpected status code: 403 Forbidden
    -

    The problem occurs because the Azure SDK we use internally attempts to authenticate towards the Azure API with the managed identity of your current environment instead of the Azure CLI token.

    -

    We decided not to deviate from this behavior and comply with the ordering of credentials.

    -

    A solution is to add the required permissions to the managed identity of your environment. For example, the managed identity of your Azure VM, instead of the account that you've authenticated with in the Azure CLI.

    -

    If your setup requires a change in the ordering of credentials, please open an issue and explain your desired behavior.

    -

    Nodes fail to join with error untrusted measurement value

    -

    This error indicates that a node's attestation statement contains measurements that don't match the trusted values expected by the JoinService. -This may for example happen if the cloud provider updates the VM's firmware such that it influences the runtime measurements in an unforeseen way. -A failed upgrade due to an erroneous attestation config can also cause this error. -You can change the expected measurements to resolve the failure.

    -
    caution

    Attestation and trusted measurements are crucial for the security of your cluster. -Be extra careful when manually changing these settings. -When in doubt, check if the encountered issue is known or contact support.

    -
    tip

    During an upgrade with modified attestation config, a backup of the current configuration is stored in the join-config config map in the kube-system namespace under the attestationConfig_backup key. To restore the old attestation config after a failed upgrade, replace the value of attestationConfig with the value from attestationConfig_backup:

    kubectl patch configmaps -n kube-system join-config -p "{\"data\":{\"attestationConfig\":\"$(kubectl get configmaps -n kube-system join-config -o "jsonpath={.data.attestationConfig_backup}")\"}}"
    -

    You can use the apply command to change measurements of a running cluster:

    -
      -
    1. Modify the measurements key in your local constellation-conf.yaml to the expected values.
    2. -
    3. Run constellation apply.
    4. -
    -

    Keep in mind that running apply also applies any version changes from your config to the cluster.

    -

    You can run these commands to learn about the versions currently configured in the cluster:

    -
      -
    • Kubernetes API server version: kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.kubernetesClusterVersion
    • -
    • image version: kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.imageVersion
    • -
    • microservices versions: helm list --filter 'constellation-services' -n kube-system
    • -
    -

    Upgrading Kubernetes resources fails

    -

    Constellation manages its Kubernetes resources using Helm. -When applying an upgrade, the charts that are about to be installed, and a values override file overrides.yaml, -are saved to disk in your current workspace under constellation-upgrade/upgrade-<timestamp>/helm-charts/. -If upgrading the charts using the Constellation CLI fails, you can review these charts and try to manually apply the upgrade.

    -
    caution

    Changing and manually applying the charts may destroy cluster resources and can lead to broken Constellation deployments. -Proceed with caution and when in doubt, -check if the encountered issue is known or contact support.

    -

    Diagnosing issues

    -

    Logs

    -

    To get started on diagnosing issues with Constellation, it's often helpful to collect logs from nodes, pods, or other resources in the cluster. Most logs are available through Kubernetes' standard -logging interfaces.

    -

    To debug issues occurring at boot time of the nodes, you can use the serial console interface of the CSP while the machine boots to get a read-only view of the boot logs.

    -

    Apart from that, Constellation also offers further observability integrations.

    -

    Node shell access

    -

    Debugging via a shell on a node is directly supported by Kubernetes.

    -
      -
    1. -

      Figure out which node to connect to:

      -
      kubectl get nodes
      # or to see more information, such as IPs:
      kubectl get nodes -o wide
      -
    2. -
    3. -

      Connect to the node:

      -
      kubectl debug node/constell-worker-xksa0-000000 -it --image=busybox
      -

      You will be presented with a prompt.

      -

      The nodes file system is mounted at /host.

      -
    4. -
    5. -

      Once finished, clean up the debug pod:

      -
      kubectl delete pod node-debugger-constell-worker-xksa0-000000-bjthj
      -
    6. -
    -

    Emergency SSH access

    -

    Emergency SSH access to nodes can be useful to diagnose issues or download important data even if the Kubernetes API isn't reachable anymore.

    -
      -
    1. -

      Enter the constellation-terraform directory in your Constellation workspace and enable emergency SSH access to the cluster:

      -
       cd constellation-terraform
      echo "emergency_ssh = true" >> ./terraform.tfvars
      terraform apply
      -
    2. -
    3. -

      Sign an existing SSH key with your master secret:

      -
      cd ../ # go back to your Constellation workspace
      constellation ssh --key your_public_key.pub
      -

      A certificate is written to constellation_cert.pub.

      -

      The certificate is valid for 24 hours and enables you to access your Constellation nodes using -certificate based authentication.

      -
    4. -
    5. -

      Now you can connect to any Constellation node using your certificate and your private key.

      -
      ssh -o CertificateFile=constellation_cert.pub -o UserKnownHostsFile=./known_hosts -i <your private key> root@<ip of constellation node>
      -

      Normally, you don't have access to the Constellation nodes since they reside in a private network. -To access those nodes anyways, you can use your Constellation load balancer as a proxy jump host. -For this, use something along the following SSH client configuration:

      -
      Host <LB public IP>
      ProxyJump none

      Host *
      IdentityFile <your private key>
      PreferredAuthentications publickey
      CertificateFile=constellation_cert.pub
      UserKnownHostsFile=./known_hosts
      User root
      ProxyJump <LB public IP>
      -

      With this configuration you can connect to a Constellation node using ssh -F <this config> <private node IP>. -You can obtain the private node IP and the public IP of the load balancer using your CSP's web UI. Note that if -you use the load balancers domain name, ssh host certificate verification doesn't work, so using the public IP is recommended.

      -
    6. -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/workflows/trusted-launch/index.html b/pr-preview/pr-4027/next/workflows/trusted-launch/index.html deleted file mode 100644 index e7de6e771..000000000 --- a/pr-preview/pr-4027/next/workflows/trusted-launch/index.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - -Use Azure trusted launch VMs | Constellation - - - - - - - -
    Version: Next

    Use Azure trusted launch VMs

    -

    Constellation also supports trusted launch VMs on Microsoft Azure. Trusted launch VMs don't offer the same level of security as Confidential VMs, but are available in more regions and in larger quantities. The main difference between trusted launch VMs and normal VMs is that the former offer vTPM-based remote attestation. When used with trusted launch VMs, Constellation relies on vTPM-based remote attestation to verify nodes.

    -
    caution

    Trusted launch VMs don't provide runtime encryption and don't keep the cloud service provider (CSP) out of your trusted computing base.

    -

    Constellation supports trusted launch VMs with instance types Standard_D*_v4 and Standard_E*_v4. Run constellation config instance-types for a list of all supported instance types.

    -

    VM images

    -

    Azure currently doesn't support community galleries for trusted launch VMs. Thus, you need to manually import the Constellation node image into your cloud subscription.

    -

    The latest image is available at https://cdn.confidential.cloud/constellation/images/azure/trusted-launch/v2.2.0/constellation.img. Simply adjust the version number to download a newer version.

    -

    After you've downloaded the image, create a resource group constellation-images in your Azure subscription and import the image. -You can use a script to do this:

    -
    wget https://raw.githubusercontent.com/edgelesssys/constellation/main/hack/importAzure.sh
    chmod +x importAzure.sh
    AZURE_IMAGE_VERSION=2.2.0 AZURE_RESOURCE_GROUP_NAME=constellation-images AZURE_IMAGE_FILE=./constellation.img ./importAzure.sh
    -

    The script creates the following resources:

    -
      -
    1. A new image gallery with the default name constellation-import
    2. -
    3. A new image definition with the default name constellation
    4. -
    5. The actual image with the provided version. In this case 2.2.0
    6. -
    -

    Once the import is completed, use the ID of the image version in your constellation-conf.yaml for the image field. Set confidentialVM to false.

    -

    Fetch the image measurements:

    -
    IMAGE_VERSION=2.2.0
    URL=https://public-edgeless-constellation.s3.us-east-2.amazonaws.com//communitygalleries/constellationcvm-b3782fa0-0df7-4f2f-963e-fc7fc42663df/images/constellation/versions/$IMAGE_VERSION/measurements.yaml
    constellation config fetch-measurements -u$URL -s$URL.sig
    -
    info

    The constellation apply command will issue a warning because manually imported images aren't recognized as production grade images:

    Configured image doesn't look like a released production image. Double check image before deploying to production.

    Please ignore this warning.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/workflows/upgrade/index.html b/pr-preview/pr-4027/next/workflows/upgrade/index.html deleted file mode 100644 index 16c158cc3..000000000 --- a/pr-preview/pr-4027/next/workflows/upgrade/index.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - - -Upgrade your cluster | Constellation - - - - - - - -
    Version: Next

    Upgrade your cluster

    -

    Constellation provides an easy way to upgrade all components of your cluster, without disrupting its availability. -Specifically, you can upgrade the Kubernetes version, the nodes' image, and the Constellation microservices. -You configure the desired versions in your local Constellation configuration and trigger upgrades with the apply command. -To learn about available versions you use the upgrade check command. -Which versions are available depends on the CLI version you are using.

    -

    Update the CLI

    -

    Each CLI comes with a set of supported microservice and Kubernetes versions. -Most importantly, a given CLI version can only upgrade a cluster of the previous minor version, but not older ones. -This means that you have to upgrade your CLI and cluster one minor version at a time.

    -

    For example, if you are currently on CLI version v2.6 and the latest version is v2.8, you should

    -
      -
    • upgrade the CLI to v2.7,
    • -
    • upgrade the cluster to v2.7,
    • -
    • and only then continue upgrading the CLI (and the cluster) to v2.8 after.
    • -
    -

    Also note that if your current Kubernetes version isn't supported by the next CLI version, use your current CLI to upgrade to a newer Kubernetes version first.

    -

    To learn which Kubernetes versions are supported by a particular CLI, run constellation config kubernetes-versions.

    -

    Migrate the configuration

    -

    The Constellation configuration file is located in the file constellation-conf.yaml in your workspace. -Refer to the migration reference to check if you need to update fields in your configuration file. -Use constellation config migrate to automatically update an old config file to a new format.

    -

    Check for upgrades

    -

    To learn which versions the current CLI can upgrade to and what's installed in your cluster, run:

    -
    # Show possible upgrades
    constellation upgrade check

    # Show possible upgrades and write them to config file
    constellation upgrade check --update-config
    -

    You can either enter the reported target versions into your config manually or run the above command with the --update-config flag. -When using this flag, the kubernetesVersion, image, microserviceVersion, and attestation fields are overwritten with the smallest available upgrade.

    -

    Apply the upgrade

    -

    Once you updated your config with the desired versions, you can trigger the upgrade with this command:

    -
    constellation apply
    -

    Microservice upgrades will be finished within a few minutes, depending on the cluster size. -If you are interested, you can monitor pods restarting in the kube-system namespace with your tool of choice.

    -

    Image and Kubernetes upgrades take longer. -For each node in your cluster, a new node has to be created and joined. -The process usually takes up to ten minutes per node.

    -

    When applying an upgrade, the Helm charts for the upgrade as well as backup files of Constellation-managed Custom Resource Definitions, Custom Resources, and Terraform state are created. -You can use the Terraform state backup to restore previous resources in case an upgrade misconfigured or erroneously deleted a resource. -You can use the Custom Resource (Definition) backup files to restore Custom Resources and Definitions manually (e.g., via kubectl apply) if the automatic migration of those resources fails. -You can use the Helm charts to manually apply upgrades to the Kubernetes resources, should an upgrade fail.

    -
    note

    For advanced users: the upgrade consists of several phases that can be individually skipped through the --skip-phases flag. -The phases are infrastracture for the cloud resource management through Terraform, helm for the chart management of the microservices, image for OS image upgrades, and k8s for Kubernetes version upgrades.

    -

    Check the status

    -

    Upgrades are asynchronous operations. -After you run apply, it will take a while until the upgrade has completed. -To understand if an upgrade is finished, you can run:

    -
    constellation status
    -

    This command displays the following information:

    -
      -
    • The installed services and their versions
    • -
    • The image and Kubernetes version the cluster is expecting on each node
    • -
    • How many nodes are up to date
    • -
    -

    Here's an example output:

    -
    Target versions:
    Image: v2.6.0
    Kubernetes: v1.25.8
    Service versions:
    Cilium: v1.12.1
    cert-manager: v1.10.0
    constellation-operators: v2.6.0
    constellation-services: v2.6.0
    Cluster status: Some node versions are out of date
    Image: 23/25
    Kubernetes: 25/25
    -

    This output indicates that the cluster is running Kubernetes version 1.25.8, and all nodes have the appropriate binaries installed. -23 out of 25 nodes have already upgraded to the targeted image version of 2.6.0, while two are still in progress.

    -

    Apply further upgrades

    -

    After the upgrade is finished, you can run constellation upgrade check again to see if there are more upgrades available. If so, repeat the process.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/workflows/verify-cli/index.html b/pr-preview/pr-4027/next/workflows/verify-cli/index.html deleted file mode 100644 index a95d1b10d..000000000 --- a/pr-preview/pr-4027/next/workflows/verify-cli/index.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - -Verify the CLI | Constellation - - - - - - - -
    Version: Next

    Verify the CLI

    -
    info

    This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details.

    -
    Loading asciinema cast...
    -
    -

    Edgeless Systems uses sigstore and SLSA to ensure supply-chain security for the Constellation CLI and node images ("artifacts"). sigstore consists of three components: Cosign, Rekor, and Fulcio. Edgeless Systems uses Cosign to sign artifacts. All signatures are uploaded to the public Rekor transparency log, which resides at https://rekor.sigstore.dev.

    -
    note

    The public key for Edgeless Systems' long-term code-signing key is:

    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT
    JmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==
    -----END PUBLIC KEY-----

    The public key is also available for download at https://edgeless.systems/es.pub and in the Twitter profile @EdgelessSystems.

    -

    The Rekor transparency log is a public append-only ledger that verifies and records signatures and associated metadata. The Rekor transparency log enables everyone to observe the sequence of (software) signatures issued by Edgeless Systems and many other parties. The transparency log allows for the public identification of dubious or malicious signatures.

    -

    You should always ensure that (1) your CLI executable was signed with the private key corresponding to the above public key and that (2) there is a corresponding entry in the Rekor transparency log. Both can be done as described in the following.

    -
    info

    You don't need to verify the Constellation node images. This is done automatically by your CLI and the rest of Constellation.

    -

    Verify the signature

    -
    info

    This guide assumes Linux on an amd64 processor. The exact steps for other platforms differ slightly.

    -

    First, install the Cosign CLI. Next, download and verify the signature that accompanies your CLI executable, for example:

    -
    $ cosign verify-blob --key https://edgeless.systems/es.pub --signature constellation-linux-amd64.sig constellation-linux-amd64

    Verified OK
    -

    The above performs an offline verification of the provided public key, signature, and executable. To also verify that a corresponding entry exists in the public Rekor transparency log, add the variable COSIGN_EXPERIMENTAL=1:

    -
    $ COSIGN_EXPERIMENTAL=1 cosign verify-blob --key https://edgeless.systems/es.pub --signature constellation-linux-amd64.sig constellation-linux-amd64

    tlog entry verified with uuid: afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13 index: 3477047
    Verified OK
    -

    🏁 You now know that your CLI executable was officially released and signed by Edgeless Systems.

    -

    Optional: Manually inspect the transparency log

    -

    To further inspect the public Rekor transparency log, install the Rekor CLI. A search for the CLI executable should give a single UUID. (Note that this UUID contains the UUID from the previous cosign command.)

    -
    $ rekor-cli search --artifact constellation-linux-amd64

    Found matching entries (listed by UUID):
    362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13
    -

    With this UUID you can get the full entry from the transparency log:

    -
    $ rekor-cli get --uuid=362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13

    LogID: c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d
    Index: 3477047
    IntegratedTime: 2022-09-12T22:28:16Z
    UUID: afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13
    Body: {
    "HashedRekordObj": {
    "data": {
    "hash": {
    "algorithm": "sha256",
    "value": "40e137b9b9b8204d672642fd1e181c6d5ccb50cfc5cc7fcbb06a8c2c78f44aff"
    }
    },
    "signature": {
    "content": "MEUCIQCSER3mGj+j5Pr2kOXTlCIHQC3gT30I7qkLr9Awt6eUUQIgcLUKRIlY50UN8JGwVeNgkBZyYD8HMxwC/LFRWoMn180=",
    "publicKey": {
    "content": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFZjhGMWhwbXdFK1lDRlh6akd0YVFjckw2WFpWVApKbUVlNWlTTHZHMVN5UVNBZXc3V2RNS0Y2bzl0OGUyVEZ1Q2t6bE9oaGx3czJPSFdiaUZabkZXQ0Z3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=="
    }
    }
    }
    }
    -

    The field publicKey should contain Edgeless Systems' public key in Base64 encoding.

    -

    You can get an exhaustive list of artifact signatures issued by Edgeless Systems via the following command:

    -
    rekor-cli search --public-key https://edgeless.systems/es.pub --pki-format x509
    -

    Edgeless Systems monitors this list to detect potential unauthorized use of its private key.

    -

    Verify the provenance

    -

    Provenance attests that a software artifact was produced by a specific repository and build system invocation. For more information on provenance visit slsa.dev and learn about the adoption of SLSA for Constellation.

    -

    Just as checking its signature proves that the CLI hasn't been manipulated, checking the provenance proves that the artifact was produced by the expected build process and hasn't been tampered with.

    -

    To verify the provenance, first install the slsa-verifier. Then make sure you have the provenance file (constellation.intoto.jsonl) and Constellation CLI downloaded. Both are available on the GitHub release page.

    -
    info

    The same provenance file is valid for all Constellation CLI executables of a given version independent of the target platform.

    -

    Use the verifier to perform the check:

    -
    $ slsa-verifier verify-artifact constellation-linux-amd64 \
    --provenance-path constellation.intoto.jsonl \
    --source-uri github.com/edgelesssys/constellation

    Verified signature against tlog entry index 7771317 at URL: https://rekor.sigstore.dev/api/v1/log/entries/24296fb24b8ad77af2c04c8b4ae0d5bc5...
    Verified build using builder https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v1.2.2 at commit 18e9924b416323c37b9cdfd6cc728de8a947424a
    PASSED: Verified SLSA provenance
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/next/workflows/verify-cluster/index.html b/pr-preview/pr-4027/next/workflows/verify-cluster/index.html deleted file mode 100644 index 3970c29a3..000000000 --- a/pr-preview/pr-4027/next/workflows/verify-cluster/index.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - -Verify your cluster | Constellation - - - - - - - -
    Version: Next

    Verify your cluster

    -

    Constellation's attestation feature allows you, or a third party, to verify the integrity and confidentiality of your Constellation cluster.

    -

    Fetch measurements

    -

    To verify the integrity of Constellation you need trusted measurements to verify against. For each node image released by Edgeless Systems, there are signed measurements, which you can download using the CLI:

    -
    constellation config fetch-measurements
    -

    This command performs the following steps:

    -
      -
    1. Download the signed measurements for the configured image. By default, this will use Edgeless Systems' public measurement registry.
    2. -
    3. Verify the signature of the measurements. This will use Edgeless Systems' public key.
    4. -
    5. Write measurements into configuration file.
    6. -
    -

    The configuration file then contains a list of measurements similar to the following:

    -
    # ...
    measurements:
    0:
    expected: "0f35c214608d93c7a6e68ae7359b4a8be5a0e99eea9107ece427c4dea4e439cf"
    warnOnly: false
    4:
    expected: "02c7a67c01ec70ffaf23d73a12f749ab150a8ac6dc529bda2fe1096a98bf42ea"
    warnOnly: false
    5:
    expected: "e6949026b72e5045706cd1318889b3874480f7a3f7c5c590912391a2d15e6975"
    warnOnly: true
    8:
    expected: "0000000000000000000000000000000000000000000000000000000000000000"
    warnOnly: false
    9:
    expected: "f0a6e8601b00e2fdc57195686cd4ef45eb43a556ac1209b8e25d993213d68384"
    warnOnly: false
    11:
    expected: "0000000000000000000000000000000000000000000000000000000000000000"
    warnOnly: false
    12:
    expected: "da99eb6cf7c7fbb692067c87fd5ca0b7117dc293578e4fea41f95d3d3d6af5e2"
    warnOnly: false
    13:
    expected: "0000000000000000000000000000000000000000000000000000000000000000"
    warnOnly: false
    14:
    expected: "d7c4cc7ff7933022f013e03bdee875b91720b5b86cf1753cad830f95e791926f"
    warnOnly: true
    15:
    expected: "0000000000000000000000000000000000000000000000000000000000000000"
    warnOnly: false
    # ...
    -

    Each entry specifies the expected value of the Constellation node, and whether the measurement should be enforced (warnOnly: false), or only a warning should be logged (warnOnly: true). -By default, the subset of the available measurements that can be locally reproduced and verified is enforced.

    -

    During attestation, the validating side (CLI or join service) compares each measurement reported by the issuing side (first node or joining node) individually. -For mismatching measurements that have set warnOnly to true only a warning is emitted. -For mismatching measurements that have set warnOnly to false an error is emitted and attestation fails. -If attestation fails for a new node, it isn't permitted to join the cluster.

    -

    The verify command

    -
    note

    The steps below are purely optional. They're automatically executed by constellation apply when you initialize your cluster. The constellation verify command mostly has an illustrative purpose.

    -

    The verify command obtains and verifies an attestation statement from a running Constellation cluster.

    -
    constellation verify [--cluster-id ...]
    -

    From the attestation statement, the command verifies the following properties:

    -
      -
    • The cluster is using the correct Confidential VM (CVM) type.
    • -
    • Inside the CVMs, the correct node images are running. The node images are identified through the measurements obtained in the previous step.
    • -
    • The unique ID of the cluster matches the one from your constellation-state.yaml file or passed in via --cluster-id.
    • -
    -

    Once the above properties are verified, you know that you are talking to the right Constellation cluster and it's in a good and trustworthy shape.

    -

    Custom arguments

    -

    The verify command also allows you to verify any Constellation deployment that you have network access to. For this you need the following:

    -
      -
    • The IP address of a running Constellation cluster's VerificationService. The VerificationService is exposed via a NodePort service using the external IP address of your cluster. Run kubectl get nodes -o wide and look for EXTERNAL-IP.
    • -
    • The cluster's clusterID. See cluster identity for more details.
    • -
    • A constellation-conf.yaml file with the expected measurements of the cluster in your working directory.
    • -
    -

    For example:

    -
    constellation verify -e 192.0.2.1 --cluster-id Q29uc3RlbGxhdGlvbkRvY3VtZW50YXRpb25TZWNyZXQ=
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/overview/clouds/index.html b/pr-preview/pr-4027/overview/clouds/index.html deleted file mode 100644 index b2b2f34f2..000000000 --- a/pr-preview/pr-4027/overview/clouds/index.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - -Feature status of clouds | Constellation - - - - - - - -
    Version: 2.24

    Feature status of clouds

    -

    What works on which cloud? Currently, Confidential VMs (CVMs) are available in varying quality on the different clouds and software stacks.

    -

    For Constellation, the ideal environment provides the following:

    -
      -
    1. Ability to run arbitrary software and images inside CVMs
    2. -
    3. CVMs based on AMD SEV-SNP (available in EPYC CPUs since the Milan generation) or Intel TDX (available in Xeon CPUs since the Sapphire Rapids generation)
    4. -
    5. Ability for CVM guests to obtain raw hardware attestation statements
    6. -
    7. Reviewable, open-source firmware inside CVMs
    8. -
    9. Capability of the firmware to attest the integrity of the code it passes control to, e.g., with an embedded virtual TPM (vTPM)
    10. -
    -

    (1) is a functional must-have. (2)--(5) are required for remote attestation that fully keeps the infrastructure/cloud out. Constellation can work without them or with approximations, but won't protect against certain privileged attackers anymore.

    -

    The following table summarizes the state of features for different infrastructures.

    -
    FeatureAWSAzureGCPSTACKITOpenStack (Yoga)
    1. Custom imagesYesYesYesYesYes
    2. SEV-SNP or TDXYesYesYesNoDepends on kernel/HV
    3. Raw guest attestationYesYesYesNoDepends on kernel/HV
    4. Reviewable firmwareYesNo*NoNoDepends on kernel/HV
    5. Confidential measured bootNoYesNoNoDepends on kernel/HV
    -

    Amazon Web Services (AWS)

    -

    Amazon EC2 supports AMD SEV-SNP. -Regarding (3), AWS provides direct access to attestation statements. -However, regarding (5), attestation is partially based on the NitroTPM for measured boot, which is a vTPM managed by the Nitro hypervisor. -Hence, the hypervisor is currently part of Constellation's TCB. -Regarding (4), the firmware is open source and can be reproducibly built.

    -

    Microsoft Azure

    -

    With its CVM offering, Azure provides the best foundations for Constellation. -Regarding (3), Azure provides direct access to attestation statements. -The firmware runs in an isolated domain inside the CVM and exposes a vTPM (5), but it's closed source (4). -On SEV-SNP, Azure uses VM Privilege Level (VMPL) isolation for the separation of firmware and the rest of the VM; on TDX, they use TD partitioning. -This firmware is signed by Azure. -The signature is reflected in the attestation statements of CVMs. -Thus, the Azure closed-source firmware becomes part of Constellation's trusted computing base (TCB).

    -

    * Recently, Azure announced the open source paravisor OpenHCL. It's the foundation for fully open source and verifiable CVM firmware. Once Azure provides their CVM firmware with reproducible builds based on OpenHCL, (4) switches from No to Yes. Constellation will support OpenHCL based firmware on Azure in the future.

    -

    Google Cloud Platform (GCP)

    -

    The CVMs Generally Available in GCP are based on AMD SEV-ES or SEV-SNP. -Regarding (3), with their SEV-SNP offering Google provides direct access to attestation statements. -However, regarding (5), attestation is partially based on the Shielded VM vTPM for measured boot, which is a vTPM managed by Google's hypervisor. -Hence, the hypervisor is currently part of Constellation's TCB. -Regarding (4), the CVMs still include closed-source firmware.

    -

    TDX on Google is in public preview. -With it, Constellation would have a similar TCB and attestation flow as with the current SEV-SNP offering.

    -

    STACKIT

    -

    STACKIT Compute Engine supports AMD SEV-ES. A vTPM is used for measured boot, which is a vTPM managed by STACKIT's hypervisor. Hence, the hypervisor is currently part of Constellation's TCB.

    -

    OpenStack

    -

    OpenStack is an open-source cloud and infrastructure management software. It's used by many smaller CSPs and datacenters. In the latest Yoga version, OpenStack has basic support for CVMs. However, much depends on the employed kernel and hypervisor. Features (2)--(4) are likely to be a Yes with Linux kernel version 6.2. Thus, going forward, OpenStack on corresponding AMD or Intel hardware will be a viable underpinning for Constellation.

    -

    Conclusion

    -

    The different clouds and software like the Linux kernel and OpenStack are in the process of building out their support for state-of-the-art CVMs. Azure has already most features in place. For Constellation, the status quo means that the TCB has different shapes on different infrastructures. With broad SEV-SNP support coming to the Linux kernel, we soon expect a normalization of features across infrastructures.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/overview/confidential-kubernetes/index.html b/pr-preview/pr-4027/overview/confidential-kubernetes/index.html deleted file mode 100644 index eec676824..000000000 --- a/pr-preview/pr-4027/overview/confidential-kubernetes/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - -Confidential Kubernetes | Constellation - - - - - - - -
    Version: 2.24

    Confidential Kubernetes

    -

    We use the term Confidential Kubernetes to refer to the concept of using confidential-computing technology to shield entire Kubernetes clusters from the infrastructure. The three defining properties of this concept are:

    -
      -
    1. Workload shielding: the confidentiality and integrity of all workload-related data and code are enforced.
    2. -
    3. Control plane shielding: the confidentiality and integrity of the cluster's control plane, state, and workload configuration are enforced.
    4. -
    5. Attestation and verifiability: the two properties above can be verified remotely based on hardware-rooted cryptographic certificates.
    6. -
    -

    Each of the above properties is equally important. Only with all three in conjunction, an entire cluster can be shielded without gaps.

    -

    Constellation security features

    -

    Constellation implements the Confidential Kubernetes concept with the following security features.

    -
      -
    • Runtime encryption: Constellation runs all Kubernetes nodes inside Confidential VMs (CVMs). This gives runtime encryption for the entire cluster.
    • -
    • Network and storage encryption: Constellation augments this with transparent encryption of the network, persistent storage, and other managed storage like AWS S3. Thus, workloads and control plane are truly end-to-end encrypted: at rest, in transit, and at runtime.
    • -
    • Transparent key management: Constellation manages the corresponding cryptographic keys inside CVMs.
    • -
    • Node attestation and verification: Constellation verifies the integrity of each new CVM-based node using remote attestation. Only "good" nodes receive the cryptographic keys required to access the network and storage of a cluster.
    • -
    • Confidential computing-optimized images: A node is "good" if it's running a signed Constellation node image inside a CVM and is in the expected state. (Node images are hardware-measured during boot. The measurements are reflected in the attestation statements that are produced by nodes and verified by Constellation.)
    • -
    • "Whole cluster" attestation: Towards the DevOps engineer, Constellation provides a single hardware-rooted certificate from which all of the above can be verified.
    • -
    -

    With the above, Constellation wraps an entire cluster into one coherent and verifiable confidential context. The concept is depicted in the following.

    -

    Confidential Kubernetes

    -

    Comparison: Managed Kubernetes with CVMs

    -

    In comparison, managed Kubernetes with CVMs, as it's for example offered in AKS and GKE, only provides runtime encryption for certain worker nodes. Here, each worker node is a separate (and typically unverified) confidential context. This only provides limited security benefits as it only prevents direct access to a worker node's memory. The large majority of potential attacks through the infrastructure remain unaffected. This includes attacks through the control plane, access to external key management, and the corruption of worker node images. This leaves many problems unsolved. For instance, Node A has no means to verify if Node B is "good" and if it's OK to share data with it. Consequently, this approach leaves a large attack surface, as is depicted in the following.

    -

    Concept: Managed Kubernetes plus CVMs

    -

    The following table highlights the key differences in terms of features.

    -
    Managed Kubernetes with CVMsConfidential Kubernetes (Constellation✨)
    Runtime encryptionPartial (data plane only)Yes
    Node image verificationNoYes
    Full cluster attestationNoYes
    Transparent network encryptionNoYes
    Transparent storage encryptionNoYes
    Confidential key managementNoYes
    Cloud agnostic / multi-cloudNoYes
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/overview/license/index.html b/pr-preview/pr-4027/overview/license/index.html deleted file mode 100644 index 995cced09..000000000 --- a/pr-preview/pr-4027/overview/license/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - -License | Constellation - - - - - - - -
    Version: 2.24

    License

    -

    Constellation is available under the Business Source License 1.1.

    -

    You may use it free of charge for non-production use ("Community License").

    -

    Enterprise License

    -

    Enterprise Licenses permit production use and come with support and additional features. Find out more at the product website.

    -

    Once you have received your Enterprise License file, place it in your Constellation workspace in a file named constellation.license.

    -

    CSP Marketplaces

    -

    Constellation is available through the Marketplaces of AWS, Azure, GCP, and STACKIT. This allows you to create self-managed Constellation clusters that are billed on a pay-per-use basis (hourly, per vCPU) with your CSP account. You can still get direct support by Edgeless Systems. For more information, please contact us.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/overview/performance/application/index.html b/pr-preview/pr-4027/overview/performance/application/index.html deleted file mode 100644 index bc578053d..000000000 --- a/pr-preview/pr-4027/overview/performance/application/index.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - -Application benchmarks | Constellation - - - - - - - -
    Version: 2.24

    Application benchmarks

    -

    HashiCorp Vault

    -

    HashiCorp Vault is a distributed secrets management software that can be deployed to Kubernetes. -HashiCorp maintains a benchmarking tool for vault, vault-benchmark. -Vault-benchmark generates load on a Vault deployment and measures response times.

    -

    This article describes the results from running vault-benchmark on Constellation, AKS, and GKE. -You can find the setup for producing the data discussed in this article in the vault-benchmarks repository.

    -

    The Vault API used during benchmarking is the transits secret engine. -This allows services to send data to Vault for encryption, decryption, signing, and verification.

    -

    Results

    -

    On each run, vault-benchmark sends requests and measures the latencies. -The measured latencies are aggregated through various statistical features. -After running the benchmark n times, the arithmetic mean over a subset of the reported statistics is calculated. -The selected features are arithmetic mean, 99th percentile, minimum, and maximum.

    -

    Arithmetic mean gives a general sense of the latency on each target. -The 99th percentile shows performance in (most likely) erroneous states. -Minimum and maximum mark the range within which latency varies each run.

    -

    The benchmark was configured with 1300 workers and 10 seconds per run. -Those numbers were chosen empirically. -The latency was stabilizing at 10 seconds runtime, not changing with further increase. -Increasing the number of workers beyond 1300 leads to request failures, marking the limit Vault was able to handle in this setup. -All results are based on 100 runs.

    -

    The following data was generated while running five replicas, one primary, and four standby nodes. -All numbers are in seconds if not indicated otherwise.

    -
    ========== Results AKS ==========
    Mean: mean: 1.632200, variance: 0.002057
    P99: mean: 5.480679, variance: 2.263700
    Max: mean: 6.651001, variance: 2.808401
    Min: mean: 0.011415, variance: 0.000133
    ========== Results GKE ==========
    Mean: mean: 1.656435, variance: 0.003615
    P99: mean: 6.030807, variance: 3.955051
    Max: mean: 7.164843, variance: 3.300004
    Min: mean: 0.010233, variance: 0.000111
    ========== Results C11n ==========
    Mean: mean: 1.651549, variance: 0.001610
    P99: mean: 5.780422, variance: 3.016106
    Max: mean: 6.942997, variance: 3.075796
    Min: mean: 0.013774, variance: 0.000228
    ========== AKS vs C11n ==========
    Mean: +1.171577 % (AKS is faster)
    P99: +5.185495 % (AKS is faster)
    Max: +4.205618 % (AKS is faster)
    Min: +17.128781 % (AKS is faster)
    ========== GKE vs C11n ==========
    Mean: -0.295851 % (GKE is slower)
    P99: -4.331603 % (GKE is slower)
    Max: -3.195248 % (GKE is slower)
    Min: +25.710886 % (GKE is faster)
    -

    Interpretation: Latencies are all within ~5% of each other. -AKS performs slightly better than GKE and Constellation (C11n) in all cases except minimum latency. -Minimum latency is the lowest for GKE. -Compared to GKE, Constellation had slightly lower peak latencies (99th percentile and maximum), indicating that Constellation could have handled slightly more concurrent accesses than GKE. -Overall, performance is at comparable levels across all three distributions. -Based on these numbers, you can use a similarly sized Constellation cluster to run your existing Vault deployment.

    -

    Visualization

    -

    The following plots visualize the data presented above as box plots. -The whiskers denote the minimum and maximum. -The box stretches from the 25th to the 75th percentile, with the dividing bar marking the 50th percentile. -The circles outside the whiskers denote outliers.

    -
    Mean Latency

    Mean Latency

    -
    99th Percentile Latency

    99th Percentile Latency

    -
    Maximum Latency

    Maximum Latency

    -
    Minimum Latency

    Minimum Latency

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/overview/performance/compute/index.html b/pr-preview/pr-4027/overview/performance/compute/index.html deleted file mode 100644 index 84f1415f9..000000000 --- a/pr-preview/pr-4027/overview/performance/compute/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - -Impact of runtime encryption on compute performance | Constellation - - - - - - - -
    Version: 2.24

    Impact of runtime encryption on compute performance

    -

    All nodes in a Constellation cluster are executed inside Confidential VMs (CVMs). Consequently, the performance of Constellation is inherently linked to the performance of these CVMs.

    -

    AMD and Azure benchmarking

    -

    AMD and Azure have collectively released a performance benchmark for CVMs that utilize 3rd Gen AMD EPYC processors (Milan) with SEV-SNP. This benchmark, which included a variety of mostly compute-intensive tests such as SPEC CPU 2017 and CoreMark, demonstrated that CVMs experience only minor performance degradation (ranging from 2% to 8%) when compared to standard VMs. Such results are indicative of the performance that can be expected from compute-intensive workloads running with Constellation on Azure.

    -

    AMD and Google benchmarking

    -

    Similarly, AMD and Google have jointly released a performance benchmark for CVMs employing 3rd Gen AMD EPYC processors (Milan) with SEV-SNP. With high-performance computing workloads such as WRF, NAMD, Ansys CFS, and Ansys LS_DYNA, they observed analogous findings, with only minor performance degradation (between 2% and 4%) compared to standard VMs. These outcomes are reflective of the performance that can be expected for compute-intensive workloads running with Constellation on GCP.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/overview/performance/index.html b/pr-preview/pr-4027/overview/performance/index.html deleted file mode 100644 index a1761f5ca..000000000 --- a/pr-preview/pr-4027/overview/performance/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - -Performance analysis of Constellation | Constellation - - - - - - - -
    Version: 2.24

    Performance analysis of Constellation

    -

    This section provides a comprehensive examination of the performance characteristics of Constellation.

    -

    Runtime encryption

    -

    Runtime encryption affects compute performance. Benchmarks by Azure and Google show that the performance degradation of Confidential VMs (CVMs) is small, ranging from 2% to 8% for compute-intensive workloads.

    -

    I/O performance benchmarks

    -

    We evaluated the I/O performance of Constellation, utilizing a collection of synthetic benchmarks targeting networking and storage. -We further compared this performance to native managed Kubernetes offerings from various cloud providers, to better understand how Constellation stands in relation to standard practices.

    -

    Application benchmarking

    -

    To gauge Constellation's applicability to well-known applications, we performed a benchmark of HashiCorp Vault running on Constellation. -The results were then compared to deployments on the managed Kubernetes offerings from different cloud providers, providing a tangible perspective on Constellation's performance in actual deployment scenarios.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/overview/performance/io/index.html b/pr-preview/pr-4027/overview/performance/io/index.html deleted file mode 100644 index 0baa9c0dc..000000000 --- a/pr-preview/pr-4027/overview/performance/io/index.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - -I/O performance benchmarks | Constellation - - - - - - - -
    Version: 2.24

    I/O performance benchmarks

    -

    To assess the overall performance of Constellation, this benchmark evaluates Constellation v2.6.0 in terms of storage I/O using fio and network performance using the Kubernetes Network Benchmark.

    -

    This benchmark tested Constellation on Azure and GCP and compared the results against the managed Kubernetes offerings AKS and GKE.

    -

    Configurations

    -

    Constellation

    -

    The benchmark was conducted with Constellation v2.6.0, Kubernetes v1.25.7, and Cilium v1.12. -It ran on the following infrastructure configurations.

    -

    Constellation on Azure:

    -
      -
    • Nodes: 3 (1 Control-plane, 2 Worker)
    • -
    • Machines: DC4as_v5: 3rd Generation AMD EPYC 7763v (Milan) processor with 4 Cores, 16 GiB memory
    • -
    • CVM: true
    • -
    • Region: West US
    • -
    • Zone: 2
    • -
    -

    Constellation on GCP:

    -
      -
    • Nodes: 3 (1 Control-plane, 2 Worker)
    • -
    • Machines: n2d-standard-4: 2nd Generation AMD EPYC (Rome) processor with 4 Cores, 16 GiB of memory
    • -
    • CVM: true
    • -
    • Zone: europe-west3-b
    • -
    -

    AKS

    -

    On AKS, the benchmark used Kubernetes v1.24.9 and nodes with version AKSUbuntu-1804gen2containerd-2023.02.15. -AKS ran with the kubenet CNI and the default CSI driver for Azure Disk.

    -

    The following infrastructure configurations was used:

    -
      -
    • Nodes: 2 (2 Worker)
    • -
    • Machines: D4as_v5: 3rd Generation AMD EPYC 7763v (Milan) processor with 4 Cores, 16 GiB memory
    • -
    • CVM: false
    • -
    • Region: West US
    • -
    • Zone: 2
    • -
    -

    GKE

    -

    On GKE, the benchmark used Kubernetes v1.24.9 and nodes with version 1.24.9-gke.3200. -GKE ran with the kubenet CNI and the default CSI driver for Compute Engine persistent disk.

    -

    The following infrastructure configurations was used:

    -
      -
    • Nodes: 2 (2 Worker)
    • -
    • Machines: n2d-standard-4 2nd Generation AMD EPYC (Rome) processor with 4 Cores, 16 GiB of memory
    • -
    • CVM: false
    • -
    • Zone: europe-west3-b
    • -
    -

    Results

    -

    Network

    -

    This section gives a thorough analysis of the network performance of Constellation, specifically focusing on measuring TCP and UDP bandwidth. -The benchmark measured the bandwidth of pod-to-pod and pod-to-service connections between two different nodes using iperf.

    -

    GKE and Constellation on GCP had a maximum network bandwidth of 10 Gbps. -AKS with Standard_D4as_v5 machines a maximum network bandwidth of 12.5 Gbps. -The Confidential VM equivalent Standard_DC4as_v5 currently has a network bandwidth of 1.25 Gbps. -Therefore, to make the test comparable, both AKS and Constellation on Azure were running with Standard_DC4as_v5 machines and 1.25 Gbps bandwidth.

    -

    Constellation on Azure and AKS used an MTU of 1500. -Constellation on GCP used an MTU of 8896. GKE used an MTU of 1450.

    -

    The difference in network bandwidth can largely be attributed to two factors.

    - -

    Pod-to-Pod

    -

    In this scenario, the client Pod connects directly to the server pod via its IP address.

    - -

    The results for "Pod-to-Pod" on Azure are as follows:

    -

    Network Pod2Pod Azure benchmark graph

    -

    The results for "Pod-to-Pod" on GCP are as follows:

    -

    Network Pod2Pod GCP benchmark graph

    -

    Pod-to-Service

    -

    In this scenario, the client Pod connects to the server Pod via a ClusterIP service. This is more relevant to real-world use cases.

    - -

    The results for "Pod-to-Pod" on Azure are as follows:

    -

    Network Pod2SVC Azure benchmark graph

    -

    The results for "Pod-to-Pod" on GCP are as follows:

    -

    Network Pod2SVC GCP benchmark graph

    -

    In our recent comparison of Constellation on GCP with GKE, Constellation has 58% less TCP bandwidth. However, UDP bandwidth was slightly better with Constellation, thanks to its higher MTU.

    -

    Similarly, when comparing Constellation on Azure with AKS using CVMs, Constellation achieved approximately 10% less TCP and 40% less UDP bandwidth.

    -

    Storage I/O

    -

    Azure and GCP offer persistent storage for their Kubernetes services AKS and GKE via the Container Storage Interface (CSI). CSI storage in Kubernetes is available via PersistentVolumes (PV) and consumed via PersistentVolumeClaims (PVC). -Upon requesting persistent storage through a PVC, GKE and AKS will provision a PV as defined by a default storage class. -Constellation provides persistent storage on Azure and GCP that's encrypted on the CSI layer. -Similarly, upon a PVC request, Constellation will provision a PV via a default storage class.

    -

    For Constellation on Azure and AKS, the benchmark ran with Azure Disk storage Standard SSD of 400 GiB size. -The DC4as machine type with four cores provides the following maximum performance:

    -
      -
    • 6400 (20000 burst) IOPS
    • -
    • 144 MB/s (600 MB/s burst) throughput
    • -
    -

    However, the performance is bound by the capabilities of the 512 GiB Standard SSD size (the size class of 400 GiB volumes):

    -
      -
    • 500 (600 burst) IOPS
    • -
    • 60 MB/s (150 MB/s burst) throughput
    • -
    -

    For Constellation on GCP and GKE, the benchmark ran with Compute Engine Persistent Disk Storage pd-balanced of 400 GiB size. -The N2D machine type with four cores and pd-balanced provides the following maximum performance:

    -
      -
    • 3,000 read IOPS
    • -
    • 15,000 write IOPS
    • -
    • 240 MB/s read throughput
    • -
    • 240 MB/s write throughput
    • -
    -

    However, the performance is bound by the capabilities of a Zonal balanced PD with 400 GiB size:

    -
      -
    • 2400 read IOPS
    • -
    • 2400 write IOPS
    • -
    • 112 MB/s read throughput
    • -
    • 112 MB/s write throughput
    • -
    -

    The fio benchmark consists of several tests. -The benchmark used Kubestr to run fio in Kubernetes. -The default test performs randomized access patterns that accurately depict worst-case I/O scenarios for most applications.

    -

    The following fio settings were used:

    -
      -
    • No Cloud caching
    • -
    • No OS caching
    • -
    • Single CPU
    • -
    • 60 seconds runtime
    • -
    • 10 seconds ramp-up time
    • -
    • 10 GiB file
    • -
    • IOPS: 4 KB blocks and 128 iodepth
    • -
    • Bandwidth: 1024 KB blocks and 128 iodepth
    • -
    -

    For more details, see the fio test configuration.

    -

    The results for IOPS on Azure are as follows:

    -

    I/O IOPS Azure benchmark graph

    -

    The results for IOPS on GCP are as follows:

    -

    I/O IOPS GCP benchmark graph

    -

    The results for bandwidth on Azure are as follows:

    -

    I/O bandwidth Azure benchmark graph

    -

    The results for bandwidth on GCP are as follows:

    -

    I/O bandwidth GCP benchmark graph

    -

    On GCP, the results exceed the maximum performance guarantees of the chosen disk type. There are two possible explanations for this. The first is that there may be cloud caching in place that isn't configurable. Alternatively, the underlying provisioned disk size may be larger than what was requested, resulting in higher performance boundaries.

    -

    When comparing Constellation on GCP with GKE, Constellation has similar bandwidth but about 10% less IOPS performance. On Azure, Constellation has similar IOPS performance compared to AKS, where both likely hit the maximum storage performance. However, Constellation has approximately 15% less read and write bandwidth.

    -

    Conclusion

    -

    Despite the added security benefits that Constellation provides, it only incurs a slight performance overhead when compared to managed Kubernetes offerings such as AKS and GKE. In most compute benchmarks, Constellation is on par with it's alternatives. -While it may be slightly slower in certain I/O scenarios due to network and storage encryption, there is ongoing work to reduce this overhead to single digits.

    -

    For instance, storage encryption only adds between 10% to 15% overhead in terms of bandwidth and IOPS. -Meanwhile, the biggest performance impact that Constellation currently faces is network encryption, which can incur up to 58% overhead on a 10 Gbps network. -However, the Cilium team has conducted benchmarks with Cilium using WireGuard encryption on a 100 Gbps network that yielded over 15 Gbps. -We're confident that Constellation will provide a similar level of performance with an upcoming release.

    -

    Overall, Constellation strikes a great balance between security and performance, and we're continuously working to improve its performance capabilities while maintaining its high level of security.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/overview/product/index.html b/pr-preview/pr-4027/overview/product/index.html deleted file mode 100644 index 1f67fb86d..000000000 --- a/pr-preview/pr-4027/overview/product/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - -Product features | Constellation - - - - - - - -
    Version: 2.24

    Product features

    -

    Constellation is a Kubernetes engine that aims to provide the best possible data security in combination with enterprise-grade scalability and reliability features---and a smooth user experience.

    -

    From a security perspective, Constellation implements the Confidential Kubernetes concept and corresponding security features, which shield your entire cluster from the underlying infrastructure.

    -

    From an operational perspective, Constellation provides the following key features:

    -
      -
    • Native support for different clouds: Constellation works on Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), and STACKIT. Support for OpenStack-based environments is coming with a future release. Constellation securely interfaces with the cloud infrastructure to provide cluster autoscaling, dynamic persistent volumes, and service load balancing.
    • -
    • High availability: Constellation uses a multi-master architecture with a stacked etcd topology to ensure high availability.
    • -
    • Integrated Day-2 operations: Constellation lets you securely upgrade your cluster to a new release. It also lets you securely recover a failed cluster. Both with a single command.
    • -
    • Support for Terraform: Constellation includes a Terraform provider that lets you manage the full lifecycle of your cluster via Terraform.
    • -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/overview/security-benefits/index.html b/pr-preview/pr-4027/overview/security-benefits/index.html deleted file mode 100644 index accf055cd..000000000 --- a/pr-preview/pr-4027/overview/security-benefits/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - -Security benefits and threat model | Constellation - - - - - - - -
    Version: 2.24

    Security benefits and threat model

    -

    Constellation implements the Confidential Kubernetes concept and shields entire Kubernetes deployments from the infrastructure. More concretely, Constellation decreases the size of the trusted computing base (TCB) of a Kubernetes deployment. The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. A smaller TCB results in a smaller attack surface. The following diagram shows how Constellation removes the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, and other components, from the TCB (red). Inside the confidential context (green), Kubernetes remains part of the TCB, but its integrity is attested and can be verified.

    -

    TCB comparison

    -

    Given this background, the following describes the concrete threat classes that Constellation addresses.

    -

    Insider access

    -

    Employees and third-party contractors of cloud service providers (CSPs) have access to different layers of the cloud infrastructure. -This opens up a large attack surface where workloads and data can be read, copied, or manipulated. With Constellation, Kubernetes deployments are shielded from the infrastructure and thus such accesses are prevented.

    -

    Infrastructure-based attacks

    -

    Malicious cloud users ("hackers") may break out of their tenancy and access other tenants' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. Analogously to the insider access scenario, Constellation also prevents access to a deployment's data in this scenario.

    -

    Supply chain attacks

    -

    Supply chain security is receiving lots of attention recently due to an increasing number of recorded attacks. For instance, a malicious actor could attempt to tamper Constellation node images (including Kubernetes and other software) before they're loaded in the confidential VMs of a cluster. Constellation uses remote attestation in conjunction with public transparency logs to prevent this.

    -

    In the future, Constellation will extend this feature to customer workloads. This will enable cluster owners to create auditable policies that precisely define which containers can run in a given deployment.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/reference/cli/index.html b/pr-preview/pr-4027/reference/cli/index.html deleted file mode 100644 index b22ea087d..000000000 --- a/pr-preview/pr-4027/reference/cli/index.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - -CLI reference | Constellation - - - - - - - -
    Version: 2.24

    CLI reference

    -

    Use the Constellation CLI to create and manage your clusters.

    -

    Usage:

    -
    constellation [command]
    -

    Commands:

    -
      -
    • config: Work with the Constellation configuration file -
        -
      • generate: Generate a default configuration and state file
      • -
      • fetch-measurements: Fetch measurements for configured cloud provider and image
      • -
      • instance-types: Print the supported instance types for all cloud providers
      • -
      • kubernetes-versions: Print the Kubernetes versions supported by this CLI
      • -
      • migrate: Migrate a configuration file to a new version
      • -
      -
    • -
    • create: Create instances on a cloud platform for your Constellation cluster
    • -
    • apply: Apply a configuration to a Constellation cluster
    • -
    • mini: Manage MiniConstellation clusters -
        -
      • up: Create and initialize a new MiniConstellation cluster
      • -
      • down: Destroy a MiniConstellation cluster
      • -
      -
    • -
    • status: Show status of a Constellation cluster
    • -
    • verify: Verify the confidential properties of a Constellation cluster
    • -
    • upgrade: Find and apply upgrades to your Constellation cluster -
        -
      • check: Check for possible upgrades
      • -
      • apply: Apply an upgrade to a Constellation cluster
      • -
      -
    • -
    • recover: Recover a completely stopped Constellation cluster
    • -
    • terminate: Terminate a Constellation cluster
    • -
    • iam: Work with the IAM configuration on your cloud provider -
        -
      • create: Create IAM configuration on a cloud platform for your Constellation cluster -
          -
        • aws: Create IAM configuration on AWS for your Constellation cluster
        • -
        • azure: Create IAM configuration on Microsoft Azure for your Constellation cluster
        • -
        • gcp: Create IAM configuration on GCP for your Constellation cluster
        • -
        -
      • -
      • destroy: Destroy an IAM configuration and delete local Terraform files
      • -
      • upgrade: Find and apply upgrades to your IAM profile -
          -
        • apply: Apply an upgrade to an IAM profile
        • -
        -
      • -
      -
    • -
    • version: Display version of this CLI
    • -
    • init: Initialize the Constellation cluster
    • -
    • ssh: Generate a certificate for emergency SSH access
    • -
    -

    constellation config

    -

    Work with the Constellation configuration file

    -

    Synopsis

    -

    Work with the Constellation configuration file.

    -

    Options

    -
      -h, --help   help for config
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation config generate

    -

    Generate a default configuration and state file

    -

    Synopsis

    -

    Generate a default configuration and state file for your selected cloud provider.

    -
    constellation config generate {aws|azure|gcp|openstack|qemu|stackit} [flags]
    -

    Options

    -
      -a, --attestation string   attestation variant to use {aws-sev-snp|aws-nitro-tpm|azure-sev-snp|azure-tdx|azure-trustedlaunch|gcp-sev-snp|gcp-sev-es|qemu-vtpm}. If not specified, the default for the cloud provider is used
    -h, --help help for generate
    -k, --kubernetes string Kubernetes version to use in format MAJOR.MINOR (default "v1.31")
    -t, --tags strings additional tags for created resources given a list of key=value
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation config fetch-measurements

    -

    Fetch measurements for configured cloud provider and image

    -

    Synopsis

    -

    Fetch measurements for configured cloud provider and image.

    -

    A config needs to be generated first.

    -
    constellation config fetch-measurements [flags]
    -

    Options

    -
      -h, --help                   help for fetch-measurements
    -s, --signature-url string alternative URL to fetch measurements' signature from
    -u, --url string alternative URL to fetch measurements from
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation config instance-types

    -

    Print the supported instance types for all cloud providers

    -

    Synopsis

    -

    Print the supported instance types for all cloud providers.

    -
    constellation config instance-types [flags]
    -

    Options

    -
      -h, --help   help for instance-types
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation config kubernetes-versions

    -

    Print the Kubernetes versions supported by this CLI

    -

    Synopsis

    -

    Print the Kubernetes versions supported by this CLI.

    -
    constellation config kubernetes-versions [flags]
    -

    Options

    -
      -h, --help   help for kubernetes-versions
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation config migrate

    -

    Migrate a configuration file to a new version

    -

    Synopsis

    -

    Migrate a configuration file to a new version.

    -
    constellation config migrate [flags]
    -

    Options

    -
      -h, --help   help for migrate
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation create

    -

    Create instances on a cloud platform for your Constellation cluster

    -

    Synopsis

    -

    Create instances on a cloud platform for your Constellation cluster.

    -
    constellation create [flags]
    -

    Options

    -
      -h, --help   help for create
    -y, --yes create the cluster without further confirmation
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation apply

    -

    Apply a configuration to a Constellation cluster

    -

    Synopsis

    -

    Apply a configuration to a Constellation cluster to initialize or upgrade the cluster.

    -
    constellation apply [flags]
    -

    Options

    -
          --conformance           enable conformance mode
    -h, --help help for apply
    --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config
    --skip-helm-wait install helm charts without waiting for deployments to be ready
    --skip-phases strings comma-separated list of upgrade phases to skip
    one or multiple of { infrastructure | init | attestationconfig | certsans | helm | image | k8s }
    -y, --yes run command without further confirmation
    WARNING: the command might delete or update existing resources without additional checks. Please read the docs.

    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation mini

    -

    Manage MiniConstellation clusters

    -

    Synopsis

    -

    Manage MiniConstellation clusters.

    -

    Options

    -
      -h, --help   help for mini
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation mini up

    -

    Create and initialize a new MiniConstellation cluster

    -

    Synopsis

    -

    Create and initialize a new MiniConstellation cluster.

    -

    A mini cluster consists of a single control-plane and worker node, hosted using QEMU/KVM.

    -
    constellation mini up [flags]
    -

    Options

    -
      -h, --help               help for up
    --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config (default true)
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation mini down

    -

    Destroy a MiniConstellation cluster

    -

    Synopsis

    -

    Destroy a MiniConstellation cluster.

    -
    constellation mini down [flags]
    -

    Options

    -
      -h, --help   help for down
    -y, --yes terminate the cluster without further confirmation
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation status

    -

    Show status of a Constellation cluster

    -

    Synopsis

    -

    Show the status of a constellation cluster.

    -

    Shows microservice, image, and Kubernetes versions installed in the cluster. Also shows status of current version upgrades.

    -
    constellation status [flags]
    -

    Options

    -
      -h, --help   help for status
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation verify

    -

    Verify the confidential properties of a Constellation cluster

    -

    Synopsis

    -

    Verify the confidential properties of a Constellation cluster. -If arguments aren't specified, values are read from constellation-state.yaml.

    -
    constellation verify [flags]
    -

    Options

    -
          --cluster-id string      expected cluster identifier
    -h, --help help for verify
    -e, --node-endpoint string endpoint of the node to verify, passed as HOST[:PORT]
    -o, --output string print the attestation document in the output format {json|raw}
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation upgrade

    -

    Find and apply upgrades to your Constellation cluster

    -

    Synopsis

    -

    Find and apply upgrades to your Constellation cluster.

    -

    Options

    -
      -h, --help   help for upgrade
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation upgrade check

    -

    Check for possible upgrades

    -

    Synopsis

    -

    Check which upgrades can be applied to your Constellation Cluster.

    -
    constellation upgrade check [flags]
    -

    Options

    -
      -h, --help            help for check
    --ref string the reference to use for querying new versions (default "-")
    --stream string the stream to use for querying new versions (default "stable")
    -u, --update-config update the specified config file with the suggested versions
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation upgrade apply

    -

    Apply an upgrade to a Constellation cluster

    -

    Synopsis

    -

    Apply an upgrade to a Constellation cluster by applying the chosen configuration.

    -
    constellation upgrade apply [flags]
    -

    Options

    -
          --conformance           enable conformance mode
    -h, --help help for apply
    --skip-helm-wait install helm charts without waiting for deployments to be ready
    --skip-phases strings comma-separated list of upgrade phases to skip
    one or multiple of { infrastructure | helm | image | k8s }
    -y, --yes run upgrades without further confirmation
    WARNING: might delete your resources in case you are using cert-manager in your cluster. Please read the docs.
    WARNING: might unintentionally overwrite measurements in the running cluster.
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation recover

    -

    Recover a completely stopped Constellation cluster

    -

    Synopsis

    -

    Recover a Constellation cluster by sending a recovery key to an instance in the boot stage.

    -

    This is only required if instances restart without other instances available for bootstrapping.

    -
    constellation recover [flags]
    -

    Options

    -
      -e, --endpoint string   endpoint of the instance, passed as HOST[:PORT]
    -h, --help help for recover
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation terminate

    -

    Terminate a Constellation cluster

    -

    Synopsis

    -

    Terminate a Constellation cluster.

    -

    The cluster can't be started again, and all persistent storage will be lost.

    -
    constellation terminate [flags]
    -

    Options

    -
      -h, --help   help for terminate
    -y, --yes terminate the cluster without further confirmation
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation iam

    -

    Work with the IAM configuration on your cloud provider

    -

    Synopsis

    -

    Work with the IAM configuration on your cloud provider.

    -

    Options

    -
      -h, --help   help for iam
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation iam create

    -

    Create IAM configuration on a cloud platform for your Constellation cluster

    -

    Synopsis

    -

    Create IAM configuration on a cloud platform for your Constellation cluster.

    -

    Options

    -
      -h, --help            help for create
    --update-config update the config file with the specific IAM information
    -y, --yes create the IAM configuration without further confirmation
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation iam create aws

    -

    Create IAM configuration on AWS for your Constellation cluster

    -

    Synopsis

    -

    Create IAM configuration on AWS for your Constellation cluster.

    -
    constellation iam create aws [flags]
    -

    Options

    -
      -h, --help            help for aws
    --prefix string name prefix for all resources (required)
    --zone string AWS availability zone the resources will be created in, e.g., us-east-2a (required)
    See the Constellation docs for a list of currently supported regions.
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    --update-config update the config file with the specific IAM information
    -C, --workspace string path to the Constellation workspace
    -y, --yes create the IAM configuration without further confirmation
    -

    constellation iam create azure

    -

    Create IAM configuration on Microsoft Azure for your Constellation cluster

    -

    Synopsis

    -

    Create IAM configuration on Microsoft Azure for your Constellation cluster.

    -
    constellation iam create azure [flags]
    -

    Options

    -
      -h, --help                      help for azure
    --region string region the resources will be created in, e.g., westus (required)
    --resourceGroup string name prefix of the two resource groups your cluster / IAM resources will be created in (required)
    --servicePrincipal string name of the service principal that will be created (required)
    --subscriptionID string subscription ID of the Azure account. Required if the 'ARM_SUBSCRIPTION_ID' environment variable is not set
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    --update-config update the config file with the specific IAM information
    -C, --workspace string path to the Constellation workspace
    -y, --yes create the IAM configuration without further confirmation
    -

    constellation iam create gcp

    -

    Create IAM configuration on GCP for your Constellation cluster

    -

    Synopsis

    -

    Create IAM configuration on GCP for your Constellation cluster.

    -
    constellation iam create gcp [flags]
    -

    Options

    -
      -h, --help               help for gcp
    --prefix string Prefix for the service account ID and VM ID that will be created (required)
    Must be letters, digits, or hyphens.
    --projectID string ID of the GCP project the configuration will be created in (required)
    Find it on the welcome screen of your project: https://console.cloud.google.com/welcome
    --zone string GCP zone the cluster will be deployed in (required)
    Find a list of available zones here: https://cloud.google.com/compute/docs/regions-zones#available
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    --update-config update the config file with the specific IAM information
    -C, --workspace string path to the Constellation workspace
    -y, --yes create the IAM configuration without further confirmation
    -

    constellation iam destroy

    -

    Destroy an IAM configuration and delete local Terraform files

    -

    Synopsis

    -

    Destroy an IAM configuration and delete local Terraform files.

    -
    constellation iam destroy [flags]
    -

    Options

    -
      -h, --help   help for destroy
    -y, --yes destroy the IAM configuration without asking for confirmation
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation iam upgrade

    -

    Find and apply upgrades to your IAM profile

    -

    Synopsis

    -

    Find and apply upgrades to your IAM profile.

    -

    Options

    -
      -h, --help   help for upgrade
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation iam upgrade apply

    -

    Apply an upgrade to an IAM profile

    -

    Synopsis

    -

    Apply an upgrade to an IAM profile.

    -
    constellation iam upgrade apply [flags]
    -

    Options

    -
      -h, --help   help for apply
    -y, --yes run upgrades without further confirmation
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation version

    -

    Display version of this CLI

    -

    Synopsis

    -

    Display version of this CLI.

    -
    constellation version [flags]
    -

    Options

    -
      -h, --help   help for version
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation init

    -

    Initialize the Constellation cluster

    -

    Synopsis

    -

    Initialize the Constellation cluster.

    -

    Start your confidential Kubernetes.

    -
    constellation init [flags]
    -

    Options

    -
          --conformance        enable conformance mode
    -h, --help help for init
    --merge-kubeconfig merge Constellation kubeconfig file with default kubeconfig file in $HOME/.kube/config
    --skip-helm-wait install helm charts without waiting for deployments to be ready
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    -

    constellation ssh

    -

    Generate a certificate for emergency SSH access

    -

    Synopsis

    -

    Generate a certificate for emergency SSH access to your SSH-enabled constellation cluster.

    -
    constellation ssh [flags]
    -

    Options

    -
      -h, --help         help for ssh
    --key string the path to an existing SSH public key
    -

    Options inherited from parent commands

    -
          --debug              enable debug logging
    --force disable version compatibility checks - might result in corrupted clusters
    --tf-log string Terraform log level (default "NONE")
    -C, --workspace string path to the Constellation workspace
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/reference/migration/index.html b/pr-preview/pr-4027/reference/migration/index.html deleted file mode 100644 index 284d03a99..000000000 --- a/pr-preview/pr-4027/reference/migration/index.html +++ /dev/null @@ -1,94 +0,0 @@ - - - - - -Migrations | Constellation - - - - - - - -
    Version: 2.24

    Migrations

    -

    This document describes breaking changes and migrations between Constellation releases. -Use constellation config migrate to automatically update an old config file to a new format.

    -

    Migrations to v2.23.0

    -

    GCP

    -

    GCP will require the additional permission compute.forwardingRules.list. Please update your IAM roles using constellation iam upgrade apply.

    -

    Migrations to v2.19.1

    -

    Azure

    -
      -
    • During the upgrade, security rules are migrated and the old ones need to be cleaned up manually by the user. The below script shows how to delete them through the Azure CLI:
    • -
    -
    #!/usr/bin/env bash
    name="<insert>" # the name provided in the config
    uid="<insert>" # the cluster id can be retrieved via `yq '.infrastructure.uid' constellation-state.yaml`
    resource_group="<insert>" # the RG can be retrieved via `yq '.provider.azure.resourceGroup' constellation-conf.yaml`

    rules=(
    "kubernetes"
    "bootstrapper"
    "verify"
    "recovery"
    "join"
    "debugd"
    "konnectivity"
    )

    for rule in "${rules[@]}"; do
    echo "Deleting rule: ${rule}"
    az network nsg rule delete \
    --resource-group "${resource_group}" \
    --nsg-name "${name}-${uid}" \
    --name "${rule}"
    done

    echo "All specified rules have been deleted."
    -

    Migrating from CLI versions before 2.21.1

    -

    AWS

    -
      -
    • AWS clusters that use LoadBalancer resources require more IAM permissions. Please upgrade your IAM roles using constellation iam upgrade apply. This will show necessary changes and apply them, if desired.
    • -
    -

    Migrating from CLI versions before 2.19.0

    -

    Azure

    -
      -
    • To allow seamless upgrades on Azure when Kubernetes services of type LoadBalancer are deployed, the target -load balancer in which the cloud-controller-manager creates load balancing rules was changed. Instead of using the load balancer -created and maintained by the CLI's Terraform code, the cloud-controller-manager now creates its own load balancer in Azure. -If your Constellation has services of type LoadBalancer, please remove them before the upgrade and re-apply them -afterward.
    • -
    -

    Migrating from CLI versions before 2.18.0

    -
      -
    • The provider.azure.appClientID and provider.azure.appClientSecret fields are no longer supported and should be removed.
    • -
    • To keep using an existing UAMI, add the Owner permission with the scope of your resourceGroup.
    • -
    • Otherwise, simply create new Constellation IAM credentials and use the created UAMI.
    • -
    • To migrate the authentication for an existing cluster on Azure to an UAMI with the necessary permissions: -
        -
      1. Remove the aadClientId and aadClientSecret from the azureconfig secret.
      2. -
      3. Set useManagedIdentityExtension to true and use the userAssignedIdentity from the Constellation config for the value of userAssignedIdentityID.
      4. -
      5. Restart the CSI driver, cloud controller manager, cluster autoscaler, and Constellation operator pods.
      6. -
      -
    • -
    -

    Migrating from CLI versions before 2.10

    -
      -
    • AWS cluster upgrades require additional IAM permissions for the newly introduced aws-load-balancer-controller. Please upgrade your IAM roles using iam upgrade apply. This will show necessary changes and apply them, if desired.
    • -
    • The global nodeGroups field was added.
    • -
    • The fields instanceType, stateDiskSizeGB, and stateDiskType for each cloud provider are now part of the configuration of individual node groups.
    • -
    • The constellation create command no longer uses the flags --control-plane-count and --worker-count. Instead, the initial node count is configured per node group in the nodeGroups field.
    • -
    -

    Migrating from CLI versions before 2.9

    -
      -
    • The provider.azure.appClientID and provider.azure.clientSecretValue fields were removed to enforce migration to managed identity authentication
    • -
    -

    Migrating from CLI versions before 2.8

    -
      -
    • The measurements field for each cloud service provider was replaced with a global attestation field.
    • -
    • The confidentialVM, idKeyDigest, and enforceIdKeyDigest fields for the Azure cloud service provider were removed in favor of using the global attestation field.
    • -
    • The optional global field attestationVariant was replaced by the now required attestation field.
    • -
    -

    Migrating from CLI versions before 2.3

    -
      -
    • -

      The sshUsers field was deprecated in v2.2 and has been removed from the configuration in v2.3. -As an alternative for SSH, check the workflow section Connect to nodes.

      -
    • -
    • -

      The image field for each cloud service provider has been replaced with a global image field. Use the following mapping to migrate your configuration:

      -
      Show all
      CSPold imagenew image
      AWSami-06b8cbf4837a0a57cv2.2.2
      AWSami-02e96dc04a9e438cdv2.2.2
      AWSami-028ead928a9034b2fv2.2.2
      AWSami-032ac10dd8d8266e3v2.2.1
      AWSami-032e0d57cc4395088v2.2.1
      AWSami-053c3e49e19b96bddv2.2.1
      AWSami-0e27ebcefc38f648bv2.2.0
      AWSami-098cd37f66523b7c3v2.2.0
      AWSami-04a87d302e2509aadv2.2.0
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.2v2.2.2
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.2v2.2.2
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.1v2.2.1
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.1v2.2.1
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.2.0v2.2.0
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.2.0v2.2.0
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.1.0v2.1.0
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.1.0v2.1.0
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2.0.0v2.0.0
      Azure/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_CVM/images/constellation/versions/2.0.0v2.0.0
      GCPprojects/constellation-images/global/images/constellation-v2-2-2v2.2.2
      GCPprojects/constellation-images/global/images/constellation-v2-2-1v2.2.1
      GCPprojects/constellation-images/global/images/constellation-v2-2-0v2.2.0
      GCPprojects/constellation-images/global/images/constellation-v2-1-0v2.1.0
      GCPprojects/constellation-images/global/images/constellation-v2-0-0v2.0.0
      -
    • -
    • -

      The enforcedMeasurements field has been removed and merged with the measurements field.

      -
        -
      • -

        To migrate your config containing a new image (v2.3 or greater), remove the old measurements and enforcedMeasurements entries from your config and run constellation fetch-measurements

        -
      • -
      • -

        To migrate your config containing an image older than v2.3, remove the enforcedMeasurements entry and replace the entries in measurements as shown in the example below:

        -
        measurements:
        - 0: DzXCFGCNk8em5ornNZtKi+Wg6Z7qkQfs5CfE3qTkOc8=
        + 0:
        + expected: DzXCFGCNk8em5ornNZtKi+Wg6Z7qkQfs5CfE3qTkOc8=
        + warnOnly: true
        - 8: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
        + 8:
        + expected: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
        + warnOnly: false
        -enforcedMeasurements:
        - - 8
        -
      • -
      -
    • -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/reference/slsa/index.html b/pr-preview/pr-4027/reference/slsa/index.html deleted file mode 100644 index d6e241c62..000000000 --- a/pr-preview/pr-4027/reference/slsa/index.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - -Supply chain levels for software artifacts (SLSA) adoption | Constellation - - - - - - - -
    Version: 2.24

    Supply chain levels for software artifacts (SLSA) adoption

    -

    Supply chain Levels for Software Artifacts, or SLSA (salsa) is a framework for improving and grading a project's build system and engineering processes. SLSA focuses on security improvements for source code storage as well as build system definition, execution, and observation. SLSA is structured in four levels. This page describes the adoption of SLSA for Constellation.

    -
    info

    SLSA is still in alpha status. The presented levels and their requirements might change in the future. We will adopt any changes into our engineering processes, as they get defined.

    -

    Level 1 - Adopted

    -

    Build - Scripted

    -

    All build steps are automated via Bazel and GitHub Actions.

    -

    Provenance - Available

    -

    Provenance for the CLI is generated using the slsa-github-generator.

    -

    Level 2 - Adopted

    -

    Source - Version Controlled

    -

    Constellation is hosted on GitHub using git.

    -

    Build - Build Service

    -

    All builds are carried out by GitHub Actions.

    -

    Provenance - Authenticated

    -

    Provenance for the CLI is signed using the slsa-github-generator. Learn how to verify the CLI using the signed provenance, before using it for the first time.

    -

    Provenance - Service Generated

    -

    Provenance for the CLI is generated using the slsa-github-generator in GitHub Actions.

    -

    Level 3 - Adopted

    -

    Source - Verified History

    -

    The Edgeless Systems GitHub organization requires two-factor authentication for all members.

    -

    Source - Retained Indefinitely

    -

    Since we use GitHub to host the repository, an external person can't modify or delete the history. Before a pull request can be merged, an explicit approval from an Edgeless Systems team member is required.

    -

    The same holds true for changes proposed by team members. Each change to main needs to be proposed via a pull request and requires at least one approval.

    -

    The Edgeless Systems GitHub organization admins control these settings and are able to make changes to the repository's history should legal requirements necessitate it. These changes require two-party approval following the obliterate policy.

    -

    Build - Build as Code

    -

    All build files for Constellation are stored in the same repository.

    -

    Build - Ephemeral Environment

    -

    All GitHub Action workflows are executed on GitHub-hosted runners. These runners are only available during workflow.

    -

    We currently don't use self-hosted runners.

    -

    Build - Isolated

    -

    As outlined in the previous section, we use GitHub-hosted runners, which provide a new, isolated and ephemeral environment for each build.

    -

    Additionally, the SLSA GitHub generator itself is run in an isolated workflow with the artifact hash as defined inputs.

    -

    Provenance - Non-falsifiable

    -

    As outlined by SLSA GitHub generator it already fulfills the non-falsifiable requirements for SLSA Level 3. The generated provenance is signed using sigstore with an OIDC based proof of identity.

    -

    Level 4 - In Progress

    -

    We strive to adopt certain aspect of SLSA Level 4 that support our engineering process. At the same time, SLSA is still in alpha status and the biggest changes to SLSA are expected to be around Level 4.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/reference/terraform/index.html b/pr-preview/pr-4027/reference/terraform/index.html deleted file mode 100644 index cc5b16aad..000000000 --- a/pr-preview/pr-4027/reference/terraform/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -Terraform usage | Constellation - - - - - - - -
    Version: 2.24

    Terraform usage

    -

    Terraform is an Infrastructure as Code (IaC) framework to manage cloud resources. This page explains how Constellation uses it internally and how advanced users may manually use it to have more control over the resource creation.

    -
    info

    Information on this page is intended for users who are familiar with Terraform. -It's not required for common usage of Constellation. -See the Terraform documentation if you want to learn more about it.

    -

    Terraform state files

    -

    Constellation keeps Terraform state files in subdirectories of the workspace together with the corresponding Terraform configuration files and metadata. -The subdirectories are created on the first Constellation CLI action that uses Terraform internally.

    -

    Currently, these subdirectories are:

    -
      -
    • constellation-terraform - Terraform state files for the resources of the Constellation cluster
    • -
    • constellation-iam-terraform - Terraform state files for IAM configuration
    • -
    -

    As with all commands, commands that work with these files (e.g., apply, terminate, iam) have to be executed from the root of the cluster's workspace directory. You usually don't need and shouldn't manipulate or delete the subdirectories manually.

    -

    Interacting with Terraform manually

    -

    Manual interaction with Terraform state created by Constellation (i.e., via the Terraform CLI) should only be performed by experienced users. It may lead to unrecoverable loss of cloud resources. For the majority of users and use cases, the interaction done by the Constellation CLI is sufficient.

    -

    Terraform debugging

    -

    To debug Terraform issues, the Constellation CLI offers the tf-log flag. You can set it to any of Terraform's log levels:

    -
      -
    • JSON (JSON-formatted logs at TRACE level)
    • -
    • TRACE
    • -
    • DEBUG
    • -
    • INFO
    • -
    • WARN
    • -
    • ERROR
    • -
    -

    The log output is written to the terraform.log file in the workspace directory. The output is appended to the file on each run.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/search-index-docs-default-2.22.json b/pr-preview/pr-4027/search-index-docs-default-2.22.json deleted file mode 100644 index c7cdd7898..000000000 --- a/pr-preview/pr-4027/search-index-docs-default-2.22.json +++ /dev/null @@ -1 +0,0 @@ -{"documents":[{"id":1,"pageTitle":"Introduction","sectionTitle":"Introduction","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/","type":"docs"},{"id":2,"pageTitle":"Introduction","sectionTitle":"Goals","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/#goals","type":"docs"},{"id":3,"pageTitle":"Introduction","sectionTitle":"Use cases","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/#use-cases","type":"docs"},{"id":4,"pageTitle":"Introduction","sectionTitle":"Next steps","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/#next-steps","type":"docs"},{"id":5,"pageTitle":"Attestation","sectionTitle":"Attestation","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation","type":"docs"},{"id":6,"pageTitle":"Attestation","sectionTitle":"Terms","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#terms","type":"docs"},{"id":7,"pageTitle":"Attestation","sectionTitle":"Trusted Platform Module (TPM)","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#trusted-platform-module-tpm","type":"docs"},{"id":8,"pageTitle":"Attestation","sectionTitle":"Runtime measurement","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#runtime-measurement","type":"docs"},{"id":9,"pageTitle":"Attestation","sectionTitle":"Platform Configuration Register (PCR)","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#platform-configuration-register-pcr","type":"docs"},{"id":10,"pageTitle":"Attestation","sectionTitle":"Measured boot","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#measured-boot","type":"docs"},{"id":11,"pageTitle":"Attestation","sectionTitle":"Remote attestation (RA)","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#remote-attestation-ra","type":"docs"},{"id":12,"pageTitle":"Attestation","sectionTitle":"Confidential virtual machine (CVM)","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#confidential-virtual-machine-cvm","type":"docs"},{"id":13,"pageTitle":"Attestation","sectionTitle":"Attested TLS (aTLS)","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#attested-tls-atls","type":"docs"},{"id":14,"pageTitle":"Attestation","sectionTitle":"Overview","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#overview","type":"docs"},{"id":15,"pageTitle":"Attestation","sectionTitle":"Node attestation","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#node-attestation","type":"docs"},{"id":16,"pageTitle":"Attestation","sectionTitle":"Runtime measurements","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#runtime-measurements","type":"docs"},{"id":17,"pageTitle":"Attestation","sectionTitle":"CVM verification","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#cvm-verification","type":"docs"},{"id":18,"pageTitle":"Attestation","sectionTitle":"Cluster attestation","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#cluster-attestation","type":"docs"},{"id":19,"pageTitle":"Attestation","sectionTitle":"Cluster-facing attestation","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#cluster-facing-attestation","type":"docs"},{"id":20,"pageTitle":"Attestation","sectionTitle":"User-facing attestation","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#user-facing-attestation","type":"docs"},{"id":21,"pageTitle":"Attestation","sectionTitle":"Putting it all together","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#putting-it-all-together","type":"docs"},{"id":22,"pageTitle":"Attestation","sectionTitle":"CLI and node images","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#cli-and-node-images","type":"docs"},{"id":23,"pageTitle":"Attestation","sectionTitle":"Cluster creation","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#cluster-creation","type":"docs"},{"id":24,"pageTitle":"Attestation","sectionTitle":"Chain of trust","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#chain-of-trust","type":"docs"},{"id":25,"pageTitle":"Attestation","sectionTitle":"Upgrades","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#upgrades","type":"docs"},{"id":26,"pageTitle":"Attestation","sectionTitle":"References","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#references","type":"docs"},{"id":27,"pageTitle":"Attestation","sectionTitle":"Footnotes","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/attestation#footnote-label","type":"docs"},{"id":28,"pageTitle":"Encrypted persistent storage","sectionTitle":"Encrypted persistent storage","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage","type":"docs"},{"id":29,"pageTitle":"Encrypted persistent storage","sectionTitle":"Cloud provider-managed encryption","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage#cloud-provider-managed-encryption","type":"docs"},{"id":30,"pageTitle":"Encrypted persistent storage","sectionTitle":"Constellation-managed encryption","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage#constellation-managed-encryption","type":"docs"},{"id":31,"pageTitle":"Encrypted persistent storage","sectionTitle":"Cryptographic algorithms","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage#cryptographic-algorithms","type":"docs"},{"id":32,"pageTitle":"Encrypted persistent storage","sectionTitle":"dm-crypt","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage#dm-crypt","type":"docs"},{"id":33,"pageTitle":"Encrypted persistent storage","sectionTitle":"dm-integrity","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage#dm-integrity","type":"docs"},{"id":34,"pageTitle":"Encrypted persistent storage","sectionTitle":"Encrypted S3 object storage","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storage#encrypted-s3-object-storage","type":"docs"},{"id":35,"pageTitle":"Constellation images","sectionTitle":"Constellation images","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/images","type":"docs"},{"id":36,"pageTitle":"Constellation images","sectionTitle":"Measured boot","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/images#measured-boot","type":"docs"},{"id":37,"pageTitle":"Constellation images","sectionTitle":"Firmware","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/images#firmware","type":"docs"},{"id":38,"pageTitle":"Constellation images","sectionTitle":"Bootloader","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/images#bootloader","type":"docs"},{"id":39,"pageTitle":"Constellation images","sectionTitle":"initramfs","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/images#initramfs","type":"docs"},{"id":40,"pageTitle":"Constellation images","sectionTitle":"State disk","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/images#state-disk","type":"docs"},{"id":41,"pageTitle":"Constellation images","sectionTitle":"Kubernetes components","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/images#kubernetes-components","type":"docs"},{"id":42,"pageTitle":"Key management and cryptographic primitives","sectionTitle":"Key management and cryptographic primitives","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/keys","type":"docs"},{"id":43,"pageTitle":"Key management and cryptographic primitives","sectionTitle":"Confidential VMs","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/keys#confidential-vms","type":"docs"},{"id":44,"pageTitle":"Key management and cryptographic primitives","sectionTitle":"Master secret","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/keys#master-secret","type":"docs"},{"id":45,"pageTitle":"Key management and cryptographic primitives","sectionTitle":"Cluster identity","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/keys#cluster-identity","type":"docs"},{"id":46,"pageTitle":"Key management and cryptographic primitives","sectionTitle":"Network encryption","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/keys#network-encryption","type":"docs"},{"id":47,"pageTitle":"Key management and cryptographic primitives","sectionTitle":"Storage encryption","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/keys#storage-encryption","type":"docs"},{"id":48,"pageTitle":"Key management and cryptographic primitives","sectionTitle":"Constellation-managed key management","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/keys#constellation-managed-key-management","type":"docs"},{"id":49,"pageTitle":"Key management and cryptographic primitives","sectionTitle":"User-managed key management","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/keys#user-managed-key-management","type":"docs"},{"id":50,"pageTitle":"Microservices","sectionTitle":"Microservices","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/microservices","type":"docs"},{"id":51,"pageTitle":"Microservices","sectionTitle":"Bootstrapper","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#bootstrapper","type":"docs"},{"id":52,"pageTitle":"Microservices","sectionTitle":"JoinService","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#joinservice","type":"docs"},{"id":53,"pageTitle":"Microservices","sectionTitle":"VerificationService","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#verificationservice","type":"docs"},{"id":54,"pageTitle":"Microservices","sectionTitle":"KeyService","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/microservices#keyservice","type":"docs"},{"id":55,"pageTitle":"Network encryption","sectionTitle":"Network encryption","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/networking","type":"docs"},{"id":56,"pageTitle":"Observability","sectionTitle":"Observability","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/observability","type":"docs"},{"id":57,"pageTitle":"Observability","sectionTitle":"Cloud resource monitoring","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/observability#cloud-resource-monitoring","type":"docs"},{"id":58,"pageTitle":"Observability","sectionTitle":"Metrics","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/observability#metrics","type":"docs"},{"id":59,"pageTitle":"Observability","sectionTitle":"Logs","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/observability#logs","type":"docs"},{"id":60,"pageTitle":"Observability","sectionTitle":"System logs","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/observability#system-logs","type":"docs"},{"id":61,"pageTitle":"Observability","sectionTitle":"Kubernetes logs","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/observability#kubernetes-logs","type":"docs"},{"id":62,"pageTitle":"Observability","sectionTitle":"Traces","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/observability#traces","type":"docs"},{"id":63,"pageTitle":"Observability","sectionTitle":"Integrations","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/observability#integrations","type":"docs"},{"id":64,"pageTitle":"Orchestrating Constellation clusters","sectionTitle":"Orchestrating Constellation clusters","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration","type":"docs"},{"id":65,"pageTitle":"Orchestrating Constellation clusters","sectionTitle":"Workspaces","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration#workspaces","type":"docs"},{"id":66,"pageTitle":"Orchestrating Constellation clusters","sectionTitle":"Cluster creation process","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration#cluster-creation-process","type":"docs"},{"id":67,"pageTitle":"Orchestrating Constellation clusters","sectionTitle":"Creation process details","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration#creation-process-details","type":"docs"},{"id":68,"pageTitle":"Orchestrating Constellation clusters","sectionTitle":"Post-installation configuration","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration#post-installation-configuration","type":"docs"},{"id":69,"pageTitle":"Orchestrating Constellation clusters","sectionTitle":"Upgrades","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration#upgrades","type":"docs"},{"id":70,"pageTitle":"Orchestrating Constellation clusters","sectionTitle":"Attestation of upgrades","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/orchestration#attestation-of-upgrades","type":"docs"},{"id":71,"pageTitle":"Overview","sectionTitle":"Overview","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/overview","type":"docs"},{"id":72,"pageTitle":"Overview","sectionTitle":"About orchestration and updates","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/overview#about-orchestration-and-updates","type":"docs"},{"id":73,"pageTitle":"Overview","sectionTitle":"About microservices and attestation","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/overview#about-microservices-and-attestation","type":"docs"},{"id":74,"pageTitle":"Overview","sectionTitle":"About node images and verified boot","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/overview#about-node-images-and-verified-boot","type":"docs"},{"id":75,"pageTitle":"Overview","sectionTitle":"About key management and cryptographic primitives","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/overview#about-key-management-and-cryptographic-primitives","type":"docs"},{"id":76,"pageTitle":"Overview","sectionTitle":"About observability","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/overview#about-observability","type":"docs"},{"id":77,"pageTitle":"Versions and support policy","sectionTitle":"Versions and support policy","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/versions","type":"docs"},{"id":78,"pageTitle":"Versions and support policy","sectionTitle":"Kubernetes support policy","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/architecture/versions#kubernetes-support-policy","type":"docs"},{"id":79,"pageTitle":"","sectionTitle":"📄️ Overview","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/architecture","type":"docs"},{"id":80,"pageTitle":"","sectionTitle":"📄️ Cluster orchestration","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/architecture","type":"docs"},{"id":81,"pageTitle":"","sectionTitle":"📄️ Versions and support","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/architecture","type":"docs"},{"id":82,"pageTitle":"","sectionTitle":"📄️ Microservices","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/architecture","type":"docs"},{"id":83,"pageTitle":"","sectionTitle":"📄️ Attestation","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/architecture","type":"docs"},{"id":84,"pageTitle":"","sectionTitle":"📄️ Images","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/architecture","type":"docs"},{"id":85,"pageTitle":"","sectionTitle":"📄️ Keys and cryptographic primitives","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/architecture","type":"docs"},{"id":86,"pageTitle":"","sectionTitle":"📄️ Encrypted persistent storage","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/architecture","type":"docs"},{"id":87,"pageTitle":"","sectionTitle":"📄️ Networking","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/architecture","type":"docs"},{"id":88,"pageTitle":"","sectionTitle":"📄️ Observability","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/architecture","type":"docs"},{"id":89,"pageTitle":"","sectionTitle":"📄️ Confidential Kubernetes","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/basics","type":"docs"},{"id":90,"pageTitle":"","sectionTitle":"📄️ Security benefits","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/basics","type":"docs"},{"id":91,"pageTitle":"","sectionTitle":"📄️ Product features","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/basics","type":"docs"},{"id":92,"pageTitle":"","sectionTitle":"📄️ Feature status of clouds","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/basics","type":"docs"},{"id":93,"pageTitle":"","sectionTitle":"🗃️ Performance","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/basics","type":"docs"},{"id":94,"pageTitle":"","sectionTitle":"📄️ License","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/basics","type":"docs"},{"id":95,"pageTitle":"","sectionTitle":"📄️ Installation","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/getting-started","type":"docs"},{"id":96,"pageTitle":"","sectionTitle":"📄️ First steps (cloud)","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/getting-started","type":"docs"},{"id":97,"pageTitle":"","sectionTitle":"📄️ First steps (local)","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/getting-started","type":"docs"},{"id":98,"pageTitle":"","sectionTitle":"📄️ Cloud Marketplaces","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/getting-started","type":"docs"},{"id":99,"pageTitle":"","sectionTitle":"🗃️ Examples","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/getting-started","type":"docs"},{"id":100,"pageTitle":"","sectionTitle":"📄️ CLI","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/reference","type":"docs"},{"id":101,"pageTitle":"","sectionTitle":"📄️ Configuration migrations","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/reference","type":"docs"},{"id":102,"pageTitle":"","sectionTitle":"📄️ Terraform usage","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/reference","type":"docs"},{"id":103,"pageTitle":"","sectionTitle":"📄️ SLSA adoption","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/reference","type":"docs"},{"id":104,"pageTitle":"","sectionTitle":"📄️ Verify the CLI","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/workflows","type":"docs"},{"id":105,"pageTitle":"","sectionTitle":"📄️ Configure your cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/workflows","type":"docs"},{"id":106,"pageTitle":"","sectionTitle":"📄️ Create your cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/workflows","type":"docs"},{"id":107,"pageTitle":"","sectionTitle":"📄️ Scale your cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/workflows","type":"docs"},{"id":108,"pageTitle":"","sectionTitle":"📄️ Upgrade your cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/workflows","type":"docs"},{"id":109,"pageTitle":"","sectionTitle":"📄️ Expose a service","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/workflows","type":"docs"},{"id":110,"pageTitle":"","sectionTitle":"📄️ Install cert-manager","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/workflows","type":"docs"},{"id":111,"pageTitle":"","sectionTitle":"📄️ Install s3proxy","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/workflows","type":"docs"},{"id":112,"pageTitle":"","sectionTitle":"📄️ Terminate your cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/workflows","type":"docs"},{"id":113,"pageTitle":"","sectionTitle":"📄️ Recover your cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/workflows","type":"docs"},{"id":114,"pageTitle":"","sectionTitle":"📄️ Verify your cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/workflows","type":"docs"},{"id":115,"pageTitle":"","sectionTitle":"📄️ Use persistent storage","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/workflows","type":"docs"},{"id":116,"pageTitle":"","sectionTitle":"📄️ Use the Terraform provider","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/workflows","type":"docs"},{"id":117,"pageTitle":"","sectionTitle":"📄️ Consume SBOMs","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/workflows","type":"docs"},{"id":118,"pageTitle":"","sectionTitle":"📄️ Reproduce release artifacts","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/workflows","type":"docs"},{"id":119,"pageTitle":"","sectionTitle":"📄️ Troubleshooting","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/category/workflows","type":"docs"},{"id":120,"pageTitle":"Examples","sectionTitle":"Examples","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples","type":"docs"},{"id":121,"pageTitle":"Emojivoto","sectionTitle":"Emojivoto","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/emojivoto","type":"docs"},{"id":122,"pageTitle":"Deploying Filestash","sectionTitle":"Deploying Filestash","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/filestash-s3proxy","type":"docs"},{"id":123,"pageTitle":"Horizontal Pod Autoscaling","sectionTitle":"Horizontal Pod Autoscaling","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scaling","type":"docs"},{"id":124,"pageTitle":"Horizontal Pod Autoscaling","sectionTitle":"Requirements","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scaling#requirements","type":"docs"},{"id":125,"pageTitle":"Horizontal Pod Autoscaling","sectionTitle":"Setup","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scaling#setup","type":"docs"},{"id":126,"pageTitle":"Horizontal Pod Autoscaling","sectionTitle":"Monitoring","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scaling#monitoring","type":"docs"},{"id":127,"pageTitle":"Online Boutique","sectionTitle":"Online Boutique","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/examples/online-boutique","type":"docs"},{"id":128,"pageTitle":"First steps with Constellation","sectionTitle":"First steps with Constellation","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps","type":"docs"},{"id":129,"pageTitle":"First steps with Constellation","sectionTitle":"Create a cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps#create-a-cluster","type":"docs"},{"id":130,"pageTitle":"First steps with Constellation","sectionTitle":"Deploy a sample application","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps#deploy-a-sample-application","type":"docs"},{"id":131,"pageTitle":"First steps with Constellation","sectionTitle":"Terminate your cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps#terminate-your-cluster","type":"docs"},{"id":132,"pageTitle":"First steps with a local cluster","sectionTitle":"First steps with a local cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local","type":"docs"},{"id":133,"pageTitle":"First steps with a local cluster","sectionTitle":"Prerequisites","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local#prerequisites","type":"docs"},{"id":134,"pageTitle":"First steps with a local cluster","sectionTitle":"Software installation on Ubuntu","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local#software-installation-on-ubuntu","type":"docs"},{"id":135,"pageTitle":"First steps with a local cluster","sectionTitle":"Create a cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local#create-a-cluster","type":"docs"},{"id":136,"pageTitle":"First steps with a local cluster","sectionTitle":"Connect to the cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local#connect-to-the-cluster","type":"docs"},{"id":137,"pageTitle":"First steps with a local cluster","sectionTitle":"Deploy a sample application","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local#deploy-a-sample-application","type":"docs"},{"id":138,"pageTitle":"First steps with a local cluster","sectionTitle":"Terminate your cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local#terminate-your-cluster","type":"docs"},{"id":139,"pageTitle":"First steps with a local cluster","sectionTitle":"Troubleshooting","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local#troubleshooting","type":"docs"},{"id":140,"pageTitle":"First steps with a local cluster","sectionTitle":"VMs have no internet access / CLI remains in \"Initializing cluster\" state","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-local#vms-have-no-internet-access--cli-remains-in-initializing-cluster-state","type":"docs"},{"id":141,"pageTitle":"Installation and setup","sectionTitle":"Installation and setup","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/install","type":"docs"},{"id":142,"pageTitle":"Installation and setup","sectionTitle":"Prerequisites","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/install#prerequisites","type":"docs"},{"id":143,"pageTitle":"Installation and setup","sectionTitle":"Install the Constellation CLI","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/install#install-the-constellation-cli","type":"docs"},{"id":144,"pageTitle":"Installation and setup","sectionTitle":"Set up cloud credentials","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/install#set-up-cloud-credentials","type":"docs"},{"id":145,"pageTitle":"Installation and setup","sectionTitle":"Required permissions","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/install#required-permissions","type":"docs"},{"id":146,"pageTitle":"Installation and setup","sectionTitle":"Authentication","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/install#authentication","type":"docs"},{"id":147,"pageTitle":"Installation and setup","sectionTitle":"Next steps","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/install#next-steps","type":"docs"},{"id":148,"pageTitle":"Using Constellation via Cloud Marketplaces","sectionTitle":"Using Constellation via Cloud Marketplaces","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/getting-started/marketplaces","type":"docs"},{"id":163,"pageTitle":"Feature status of clouds","sectionTitle":"Feature status of clouds","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/clouds","type":"docs"},{"id":164,"pageTitle":"Feature status of clouds","sectionTitle":"Amazon Web Services (AWS)","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/clouds#amazon-web-services-aws","type":"docs"},{"id":165,"pageTitle":"Feature status of clouds","sectionTitle":"Microsoft Azure","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/clouds#microsoft-azure","type":"docs"},{"id":166,"pageTitle":"Feature status of clouds","sectionTitle":"Google Cloud Platform (GCP)","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/clouds#google-cloud-platform-gcp","type":"docs"},{"id":167,"pageTitle":"Feature status of clouds","sectionTitle":"STACKIT","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/clouds#stackit","type":"docs"},{"id":168,"pageTitle":"Feature status of clouds","sectionTitle":"OpenStack","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/clouds#openstack","type":"docs"},{"id":169,"pageTitle":"Feature status of clouds","sectionTitle":"Conclusion","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/clouds#conclusion","type":"docs"},{"id":156,"pageTitle":"Confidential Kubernetes","sectionTitle":"Confidential Kubernetes","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/confidential-kubernetes","type":"docs"},{"id":157,"pageTitle":"Confidential Kubernetes","sectionTitle":"Constellation security features","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/confidential-kubernetes#constellation-security-features","type":"docs"},{"id":158,"pageTitle":"Confidential Kubernetes","sectionTitle":"Comparison: Managed Kubernetes with CVMs","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/confidential-kubernetes#comparison-managed-kubernetes-with-cvms","type":"docs"},{"id":149,"pageTitle":"License","sectionTitle":"License","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/license","type":"docs"},{"id":150,"pageTitle":"License","sectionTitle":"Source code","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/license#source-code","type":"docs"},{"id":151,"pageTitle":"License","sectionTitle":"Binaries","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/license#binaries","type":"docs"},{"id":152,"pageTitle":"License","sectionTitle":"Terraform provider","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/license#terraform-provider","type":"docs"},{"id":153,"pageTitle":"License","sectionTitle":"Community License","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/license#community-license","type":"docs"},{"id":154,"pageTitle":"License","sectionTitle":"Enterprise License","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/license#enterprise-license","type":"docs"},{"id":155,"pageTitle":"License","sectionTitle":"CSP Marketplaces","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/license#csp-marketplaces","type":"docs"},{"id":159,"pageTitle":"Performance analysis of Constellation","sectionTitle":"Performance analysis of Constellation","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/","type":"docs"},{"id":160,"pageTitle":"Performance analysis of Constellation","sectionTitle":"Runtime encryption","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/#runtime-encryption","type":"docs"},{"id":161,"pageTitle":"Performance analysis of Constellation","sectionTitle":"I/O performance benchmarks","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/#io-performance-benchmarks","type":"docs"},{"id":162,"pageTitle":"Performance analysis of Constellation","sectionTitle":"Application benchmarking","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/#application-benchmarking","type":"docs"},{"id":170,"pageTitle":"Application benchmarks","sectionTitle":"Application benchmarks","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/application","type":"docs"},{"id":171,"pageTitle":"Application benchmarks","sectionTitle":"HashiCorp Vault","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/application#hashicorp-vault","type":"docs"},{"id":172,"pageTitle":"Application benchmarks","sectionTitle":"Results","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/application#results","type":"docs"},{"id":173,"pageTitle":"Application benchmarks","sectionTitle":"Visualization","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/application#visualization","type":"docs"},{"id":174,"pageTitle":"Impact of runtime encryption on compute performance","sectionTitle":"Impact of runtime encryption on compute performance","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/compute","type":"docs"},{"id":175,"pageTitle":"Impact of runtime encryption on compute performance","sectionTitle":"AMD and Azure benchmarking","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/compute#amd-and-azure-benchmarking","type":"docs"},{"id":176,"pageTitle":"Impact of runtime encryption on compute performance","sectionTitle":"AMD and Google benchmarking","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/compute#amd-and-google-benchmarking","type":"docs"},{"id":177,"pageTitle":"I/O performance benchmarks","sectionTitle":"I/O performance benchmarks","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/io","type":"docs"},{"id":178,"pageTitle":"I/O performance benchmarks","sectionTitle":"Configurations","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/io#configurations","type":"docs"},{"id":179,"pageTitle":"I/O performance benchmarks","sectionTitle":"Constellation","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/io#constellation","type":"docs"},{"id":180,"pageTitle":"I/O performance benchmarks","sectionTitle":"AKS","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/io#aks","type":"docs"},{"id":181,"pageTitle":"I/O performance benchmarks","sectionTitle":"GKE","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/io#gke","type":"docs"},{"id":182,"pageTitle":"I/O performance benchmarks","sectionTitle":"Results","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/io#results","type":"docs"},{"id":183,"pageTitle":"I/O performance benchmarks","sectionTitle":"Network","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/io#network","type":"docs"},{"id":184,"pageTitle":"I/O performance benchmarks","sectionTitle":"Storage I/O","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/io#storage-io","type":"docs"},{"id":185,"pageTitle":"I/O performance benchmarks","sectionTitle":"Conclusion","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/performance/io#conclusion","type":"docs"},{"id":186,"pageTitle":"Product features","sectionTitle":"Product features","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/product","type":"docs"},{"id":187,"pageTitle":"Security benefits and threat model","sectionTitle":"Security benefits and threat model","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/security-benefits","type":"docs"},{"id":188,"pageTitle":"Security benefits and threat model","sectionTitle":"Insider access","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/security-benefits#insider-access","type":"docs"},{"id":189,"pageTitle":"Security benefits and threat model","sectionTitle":"Infrastructure-based attacks","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/security-benefits#infrastructure-based-attacks","type":"docs"},{"id":190,"pageTitle":"Security benefits and threat model","sectionTitle":"Supply chain attacks","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/overview/security-benefits#supply-chain-attacks","type":"docs"},{"id":191,"pageTitle":"CLI reference","sectionTitle":"CLI reference","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli","type":"docs"},{"id":192,"pageTitle":"CLI reference","sectionTitle":"constellation config","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-config","type":"docs"},{"id":193,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis","type":"docs"},{"id":194,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options","type":"docs"},{"id":195,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands","type":"docs"},{"id":196,"pageTitle":"CLI reference","sectionTitle":"constellation config generate","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-config-generate","type":"docs"},{"id":197,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-1","type":"docs"},{"id":198,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-1","type":"docs"},{"id":199,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-1","type":"docs"},{"id":200,"pageTitle":"CLI reference","sectionTitle":"constellation config fetch-measurements","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-config-fetch-measurements","type":"docs"},{"id":201,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-2","type":"docs"},{"id":202,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-2","type":"docs"},{"id":203,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-2","type":"docs"},{"id":204,"pageTitle":"CLI reference","sectionTitle":"constellation config instance-types","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-config-instance-types","type":"docs"},{"id":205,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-3","type":"docs"},{"id":206,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-3","type":"docs"},{"id":207,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-3","type":"docs"},{"id":208,"pageTitle":"CLI reference","sectionTitle":"constellation config kubernetes-versions","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-config-kubernetes-versions","type":"docs"},{"id":209,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-4","type":"docs"},{"id":210,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-4","type":"docs"},{"id":211,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-4","type":"docs"},{"id":212,"pageTitle":"CLI reference","sectionTitle":"constellation config migrate","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-config-migrate","type":"docs"},{"id":213,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-5","type":"docs"},{"id":214,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-5","type":"docs"},{"id":215,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-5","type":"docs"},{"id":216,"pageTitle":"CLI reference","sectionTitle":"constellation create","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-create","type":"docs"},{"id":217,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-6","type":"docs"},{"id":218,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-6","type":"docs"},{"id":219,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-6","type":"docs"},{"id":220,"pageTitle":"CLI reference","sectionTitle":"constellation apply","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-apply","type":"docs"},{"id":221,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-7","type":"docs"},{"id":222,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-7","type":"docs"},{"id":223,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-7","type":"docs"},{"id":224,"pageTitle":"CLI reference","sectionTitle":"constellation mini","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-mini","type":"docs"},{"id":225,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-8","type":"docs"},{"id":226,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-8","type":"docs"},{"id":227,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-8","type":"docs"},{"id":228,"pageTitle":"CLI reference","sectionTitle":"constellation mini up","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-mini-up","type":"docs"},{"id":229,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-9","type":"docs"},{"id":230,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-9","type":"docs"},{"id":231,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-9","type":"docs"},{"id":232,"pageTitle":"CLI reference","sectionTitle":"constellation mini down","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-mini-down","type":"docs"},{"id":233,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-10","type":"docs"},{"id":234,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-10","type":"docs"},{"id":235,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-10","type":"docs"},{"id":236,"pageTitle":"CLI reference","sectionTitle":"constellation status","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-status","type":"docs"},{"id":237,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-11","type":"docs"},{"id":238,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-11","type":"docs"},{"id":239,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-11","type":"docs"},{"id":240,"pageTitle":"CLI reference","sectionTitle":"constellation verify","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-verify","type":"docs"},{"id":241,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-12","type":"docs"},{"id":242,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-12","type":"docs"},{"id":243,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-12","type":"docs"},{"id":244,"pageTitle":"CLI reference","sectionTitle":"constellation upgrade","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-upgrade","type":"docs"},{"id":245,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-13","type":"docs"},{"id":246,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-13","type":"docs"},{"id":247,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-13","type":"docs"},{"id":248,"pageTitle":"CLI reference","sectionTitle":"constellation upgrade check","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-upgrade-check","type":"docs"},{"id":249,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-14","type":"docs"},{"id":250,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-14","type":"docs"},{"id":251,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-14","type":"docs"},{"id":252,"pageTitle":"CLI reference","sectionTitle":"constellation upgrade apply","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-upgrade-apply","type":"docs"},{"id":253,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-15","type":"docs"},{"id":254,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-15","type":"docs"},{"id":255,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-15","type":"docs"},{"id":256,"pageTitle":"CLI reference","sectionTitle":"constellation recover","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-recover","type":"docs"},{"id":257,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-16","type":"docs"},{"id":258,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-16","type":"docs"},{"id":259,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-16","type":"docs"},{"id":260,"pageTitle":"CLI reference","sectionTitle":"constellation terminate","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-terminate","type":"docs"},{"id":261,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-17","type":"docs"},{"id":262,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-17","type":"docs"},{"id":263,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-17","type":"docs"},{"id":264,"pageTitle":"CLI reference","sectionTitle":"constellation iam","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-iam","type":"docs"},{"id":265,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-18","type":"docs"},{"id":266,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-18","type":"docs"},{"id":267,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-18","type":"docs"},{"id":268,"pageTitle":"CLI reference","sectionTitle":"constellation iam create","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-iam-create","type":"docs"},{"id":269,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-19","type":"docs"},{"id":270,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-19","type":"docs"},{"id":271,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-19","type":"docs"},{"id":272,"pageTitle":"CLI reference","sectionTitle":"constellation iam create aws","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-iam-create-aws","type":"docs"},{"id":273,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-20","type":"docs"},{"id":274,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-20","type":"docs"},{"id":275,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-20","type":"docs"},{"id":276,"pageTitle":"CLI reference","sectionTitle":"constellation iam create azure","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-iam-create-azure","type":"docs"},{"id":277,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-21","type":"docs"},{"id":278,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-21","type":"docs"},{"id":279,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-21","type":"docs"},{"id":280,"pageTitle":"CLI reference","sectionTitle":"constellation iam create gcp","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-iam-create-gcp","type":"docs"},{"id":281,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-22","type":"docs"},{"id":282,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-22","type":"docs"},{"id":283,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-22","type":"docs"},{"id":284,"pageTitle":"CLI reference","sectionTitle":"constellation iam destroy","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-iam-destroy","type":"docs"},{"id":285,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-23","type":"docs"},{"id":286,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-23","type":"docs"},{"id":287,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-23","type":"docs"},{"id":288,"pageTitle":"CLI reference","sectionTitle":"constellation iam upgrade","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-iam-upgrade","type":"docs"},{"id":289,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-24","type":"docs"},{"id":290,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-24","type":"docs"},{"id":291,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-24","type":"docs"},{"id":292,"pageTitle":"CLI reference","sectionTitle":"constellation iam upgrade apply","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-iam-upgrade-apply","type":"docs"},{"id":293,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-25","type":"docs"},{"id":294,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-25","type":"docs"},{"id":295,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-25","type":"docs"},{"id":296,"pageTitle":"CLI reference","sectionTitle":"constellation version","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-version","type":"docs"},{"id":297,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-26","type":"docs"},{"id":298,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-26","type":"docs"},{"id":299,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-26","type":"docs"},{"id":300,"pageTitle":"CLI reference","sectionTitle":"constellation init","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-init","type":"docs"},{"id":301,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-27","type":"docs"},{"id":302,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-27","type":"docs"},{"id":303,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-27","type":"docs"},{"id":304,"pageTitle":"CLI reference","sectionTitle":"constellation ssh","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#constellation-ssh","type":"docs"},{"id":305,"pageTitle":"CLI reference","sectionTitle":"Synopsis","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#synopsis-28","type":"docs"},{"id":306,"pageTitle":"CLI reference","sectionTitle":"Options","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-28","type":"docs"},{"id":307,"pageTitle":"CLI reference","sectionTitle":"Options inherited from parent commands","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/cli#options-inherited-from-parent-commands-28","type":"docs"},{"id":308,"pageTitle":"Migrations","sectionTitle":"Migrations","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/migration","type":"docs"},{"id":309,"pageTitle":"Migrations","sectionTitle":"Migrations to v2.19.1","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/migration#migrations-to-v2191","type":"docs"},{"id":310,"pageTitle":"Migrations","sectionTitle":"Azure","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/migration#azure","type":"docs"},{"id":311,"pageTitle":"Migrations","sectionTitle":"Migrating from CLI versions before 2.21.1","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/migration#migrating-from-cli-versions-before-2211","type":"docs"},{"id":312,"pageTitle":"Migrations","sectionTitle":"AWS","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/migration#aws","type":"docs"},{"id":313,"pageTitle":"Migrations","sectionTitle":"Migrating from CLI versions before 2.19.0","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/migration#migrating-from-cli-versions-before-2190","type":"docs"},{"id":314,"pageTitle":"Migrations","sectionTitle":"Azure","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/migration#azure-1","type":"docs"},{"id":315,"pageTitle":"Migrations","sectionTitle":"Migrating from CLI versions before 2.18.0","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/migration#migrating-from-cli-versions-before-2180","type":"docs"},{"id":316,"pageTitle":"Migrations","sectionTitle":"Migrating from CLI versions before 2.10","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/migration#migrating-from-cli-versions-before-210","type":"docs"},{"id":317,"pageTitle":"Migrations","sectionTitle":"Migrating from CLI versions before 2.9","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/migration#migrating-from-cli-versions-before-29","type":"docs"},{"id":318,"pageTitle":"Migrations","sectionTitle":"Migrating from CLI versions before 2.8","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/migration#migrating-from-cli-versions-before-28","type":"docs"},{"id":319,"pageTitle":"Migrations","sectionTitle":"Migrating from CLI versions before 2.3","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/migration#migrating-from-cli-versions-before-23","type":"docs"},{"id":320,"pageTitle":"Supply chain levels for software artifacts (SLSA) adoption","sectionTitle":"Supply chain levels for software artifacts (SLSA) adoption","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/slsa","type":"docs"},{"id":321,"pageTitle":"Supply chain levels for software artifacts (SLSA) adoption","sectionTitle":"Level 1 - Adopted","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/slsa#level-1---adopted","type":"docs"},{"id":322,"pageTitle":"Supply chain levels for software artifacts (SLSA) adoption","sectionTitle":"Level 2 - Adopted","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/slsa#level-2---adopted","type":"docs"},{"id":323,"pageTitle":"Supply chain levels for software artifacts (SLSA) adoption","sectionTitle":"Level 3 - Adopted","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/slsa#level-3---adopted","type":"docs"},{"id":324,"pageTitle":"Supply chain levels for software artifacts (SLSA) adoption","sectionTitle":"Level 4 - In Progress","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/slsa#level-4---in-progress","type":"docs"},{"id":325,"pageTitle":"Terraform usage","sectionTitle":"Terraform usage","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/terraform","type":"docs"},{"id":326,"pageTitle":"Terraform usage","sectionTitle":"Terraform state files","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/terraform#terraform-state-files","type":"docs"},{"id":327,"pageTitle":"Terraform usage","sectionTitle":"Interacting with Terraform manually","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/terraform#interacting-with-terraform-manually","type":"docs"},{"id":328,"pageTitle":"Terraform usage","sectionTitle":"Terraform debugging","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/reference/terraform#terraform-debugging","type":"docs"},{"id":329,"pageTitle":"Install cert-manager","sectionTitle":"Install cert-manager","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/cert-manager","type":"docs"},{"id":330,"pageTitle":"Configure your cluster","sectionTitle":"Configure your cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/config","type":"docs"},{"id":331,"pageTitle":"Configure your cluster","sectionTitle":"Creating the configuration file","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/config#creating-the-configuration-file","type":"docs"},{"id":332,"pageTitle":"Configure your cluster","sectionTitle":"Choosing a VM type","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/config#choosing-a-vm-type","type":"docs"},{"id":333,"pageTitle":"Configure your cluster","sectionTitle":"Creating additional node groups","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/config#creating-additional-node-groups","type":"docs"},{"id":334,"pageTitle":"Configure your cluster","sectionTitle":"Choosing a Kubernetes version","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/config#choosing-a-kubernetes-version","type":"docs"},{"id":335,"pageTitle":"Configure your cluster","sectionTitle":"Creating an IAM configuration","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/config#creating-an-iam-configuration","type":"docs"},{"id":336,"pageTitle":"Configure your cluster","sectionTitle":"Deleting an IAM configuration","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/config#deleting-an-iam-configuration","type":"docs"},{"id":337,"pageTitle":"Create your cluster","sectionTitle":"Create your cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/create","type":"docs"},{"id":338,"pageTitle":"Create your cluster","sectionTitle":"Troubleshooting","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/create#troubleshooting","type":"docs"},{"id":339,"pageTitle":"Expose a service","sectionTitle":"Expose a service","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/lb","type":"docs"},{"id":340,"pageTitle":"Expose a service","sectionTitle":"Internet-facing LB service on AWS","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/lb#internet-facing-lb-service-on-aws","type":"docs"},{"id":341,"pageTitle":"Expose a service","sectionTitle":"Ingress on AWS","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/lb#ingress-on-aws","type":"docs"},{"id":342,"pageTitle":"Recover your cluster","sectionTitle":"Recover your cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/recovery","type":"docs"},{"id":343,"pageTitle":"Recover your cluster","sectionTitle":"Identify unhealthy clusters","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/recovery#identify-unhealthy-clusters","type":"docs"},{"id":344,"pageTitle":"Recover your cluster","sectionTitle":"Recover a cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/recovery#recover-a-cluster","type":"docs"},{"id":345,"pageTitle":"Reproduce released artifacts","sectionTitle":"Reproduce released artifacts","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/reproducible-builds","type":"docs"},{"id":346,"pageTitle":"Reproduce released artifacts","sectionTitle":"Build environment prerequisites","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/reproducible-builds#build-environment-prerequisites","type":"docs"},{"id":347,"pageTitle":"Reproduce released artifacts","sectionTitle":"Run the build","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/reproducible-builds#run-the-build","type":"docs"},{"id":348,"pageTitle":"Reproduce released artifacts","sectionTitle":"Feedback","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/reproducible-builds#feedback","type":"docs"},{"id":356,"pageTitle":"Install s3proxy","sectionTitle":"Install s3proxy","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/s3proxy","type":"docs"},{"id":357,"pageTitle":"Install s3proxy","sectionTitle":"Limitations","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/s3proxy#limitations","type":"docs"},{"id":358,"pageTitle":"Install s3proxy","sectionTitle":"Deployment","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/s3proxy#deployment","type":"docs"},{"id":359,"pageTitle":"Install s3proxy","sectionTitle":"Technical details","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/s3proxy#technical-details","type":"docs"},{"id":360,"pageTitle":"Install s3proxy","sectionTitle":"Encryption","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/s3proxy#encryption","type":"docs"},{"id":361,"pageTitle":"Install s3proxy","sectionTitle":"Traffic interception","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/s3proxy#traffic-interception","type":"docs"},{"id":349,"pageTitle":"Consume software bill of materials (SBOMs)","sectionTitle":"Consume software bill of materials (SBOMs)","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/sbom","type":"docs"},{"id":350,"pageTitle":"Consume software bill of materials (SBOMs)","sectionTitle":"Verify and download SBOMs","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/sbom#verify-and-download-sboms","type":"docs"},{"id":351,"pageTitle":"Consume software bill of materials (SBOMs)","sectionTitle":"Constellation CLI","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/sbom#constellation-cli","type":"docs"},{"id":352,"pageTitle":"Consume software bill of materials (SBOMs)","sectionTitle":"Container Images","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/sbom#container-images","type":"docs"},{"id":353,"pageTitle":"Consume software bill of materials (SBOMs)","sectionTitle":"Vulnerability scanning","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/sbom#vulnerability-scanning","type":"docs"},{"id":354,"pageTitle":"Consume software bill of materials (SBOMs)","sectionTitle":"Grype","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/sbom#grype","type":"docs"},{"id":355,"pageTitle":"Consume software bill of materials (SBOMs)","sectionTitle":"Dependency Track","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/sbom#dependency-track","type":"docs"},{"id":367,"pageTitle":"Scale your cluster","sectionTitle":"Scale your cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/scale","type":"docs"},{"id":368,"pageTitle":"Scale your cluster","sectionTitle":"Worker node scaling","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/scale#worker-node-scaling","type":"docs"},{"id":369,"pageTitle":"Scale your cluster","sectionTitle":"Autoscaling","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/scale#autoscaling","type":"docs"},{"id":370,"pageTitle":"Scale your cluster","sectionTitle":"Manual scaling","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/scale#manual-scaling","type":"docs"},{"id":371,"pageTitle":"Scale your cluster","sectionTitle":"Control-plane node scaling","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/scale#control-plane-node-scaling","type":"docs"},{"id":362,"pageTitle":"Use persistent storage","sectionTitle":"Use persistent storage","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/storage","type":"docs"},{"id":363,"pageTitle":"Use persistent storage","sectionTitle":"Confidential storage","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/storage#confidential-storage","type":"docs"},{"id":364,"pageTitle":"Use persistent storage","sectionTitle":"CSI drivers","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/storage#csi-drivers","type":"docs"},{"id":365,"pageTitle":"Use persistent storage","sectionTitle":"Installation","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/storage#installation","type":"docs"},{"id":366,"pageTitle":"Use persistent storage","sectionTitle":"Change the default storage class","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/storage#change-the-default-storage-class","type":"docs"},{"id":372,"pageTitle":"Terminate your cluster","sectionTitle":"Terminate your cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/terminate","type":"docs"},{"id":384,"pageTitle":"Use the Terraform provider","sectionTitle":"Use the Terraform provider","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/terraform-provider","type":"docs"},{"id":385,"pageTitle":"Use the Terraform provider","sectionTitle":"Prerequisites","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/terraform-provider#prerequisites","type":"docs"},{"id":386,"pageTitle":"Use the Terraform provider","sectionTitle":"Quick setup","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/terraform-provider#quick-setup","type":"docs"},{"id":387,"pageTitle":"Use the Terraform provider","sectionTitle":"Bringing your own infrastructure","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/terraform-provider#bringing-your-own-infrastructure","type":"docs"},{"id":388,"pageTitle":"Use the Terraform provider","sectionTitle":"Cluster upgrades","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/terraform-provider#cluster-upgrades","type":"docs"},{"id":373,"pageTitle":"Troubleshooting","sectionTitle":"Troubleshooting","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting","type":"docs"},{"id":374,"pageTitle":"Troubleshooting","sectionTitle":"Common issues","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting#common-issues","type":"docs"},{"id":375,"pageTitle":"Troubleshooting","sectionTitle":"Issues with creating new clusters","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting#issues-with-creating-new-clusters","type":"docs"},{"id":376,"pageTitle":"Troubleshooting","sectionTitle":"Azure: Resource Providers can't be registered","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting#azure-resource-providers-cant-be-registered","type":"docs"},{"id":377,"pageTitle":"Troubleshooting","sectionTitle":"Azure: Can't update attestation policy","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting#azure-cant-update-attestation-policy","type":"docs"},{"id":378,"pageTitle":"Troubleshooting","sectionTitle":"Nodes fail to join with error untrusted measurement value","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting#nodes-fail-to-join-with-error-untrusted-measurement-value","type":"docs"},{"id":379,"pageTitle":"Troubleshooting","sectionTitle":"Upgrading Kubernetes resources fails","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting#upgrading-kubernetes-resources-fails","type":"docs"},{"id":380,"pageTitle":"Troubleshooting","sectionTitle":"Diagnosing issues","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting#diagnosing-issues","type":"docs"},{"id":381,"pageTitle":"Troubleshooting","sectionTitle":"Logs","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting#logs","type":"docs"},{"id":382,"pageTitle":"Troubleshooting","sectionTitle":"Node shell access","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting#node-shell-access","type":"docs"},{"id":383,"pageTitle":"Troubleshooting","sectionTitle":"Emergency SSH access","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/troubleshooting#emergency-ssh-access","type":"docs"},{"id":389,"pageTitle":"Use Azure trusted launch VMs","sectionTitle":"Use Azure trusted launch VMs","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/trusted-launch","type":"docs"},{"id":390,"pageTitle":"Use Azure trusted launch VMs","sectionTitle":"VM images","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/trusted-launch#vm-images","type":"docs"},{"id":391,"pageTitle":"Upgrade your cluster","sectionTitle":"Upgrade your cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade","type":"docs"},{"id":392,"pageTitle":"Upgrade your cluster","sectionTitle":"Update the CLI","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade#update-the-cli","type":"docs"},{"id":393,"pageTitle":"Upgrade your cluster","sectionTitle":"Migrate the configuration","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade#migrate-the-configuration","type":"docs"},{"id":394,"pageTitle":"Upgrade your cluster","sectionTitle":"Check for upgrades","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade#check-for-upgrades","type":"docs"},{"id":395,"pageTitle":"Upgrade your cluster","sectionTitle":"Apply the upgrade","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade#apply-the-upgrade","type":"docs"},{"id":396,"pageTitle":"Upgrade your cluster","sectionTitle":"Check the status","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade#check-the-status","type":"docs"},{"id":397,"pageTitle":"Upgrade your cluster","sectionTitle":"Apply further upgrades","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/upgrade#apply-further-upgrades","type":"docs"},{"id":402,"pageTitle":"Verify the CLI","sectionTitle":"Verify the CLI","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli","type":"docs"},{"id":403,"pageTitle":"Verify the CLI","sectionTitle":"Verify the signature","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli#verify-the-signature","type":"docs"},{"id":404,"pageTitle":"Verify the CLI","sectionTitle":"Optional: Manually inspect the transparency log","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli#optional-manually-inspect-the-transparency-log","type":"docs"},{"id":405,"pageTitle":"Verify the CLI","sectionTitle":"Verify the provenance","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cli#verify-the-provenance","type":"docs"},{"id":398,"pageTitle":"Verify your cluster","sectionTitle":"Verify your cluster","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cluster","type":"docs"},{"id":399,"pageTitle":"Verify your cluster","sectionTitle":"Fetch measurements","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cluster#fetch-measurements","type":"docs"},{"id":400,"pageTitle":"Verify your cluster","sectionTitle":"The verify command","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cluster#the-verify-command","type":"docs"},{"id":401,"pageTitle":"Verify your cluster","sectionTitle":"Custom arguments","sectionRoute":"/constellation/pr-preview/pr-4027/2.22/workflows/verify-cluster#custom-arguments","type":"docs"}],"index":{"version":"2.3.9","fields":["title","content","tags"],"fieldVectors":[["title/1",[0,7.341]],["content/1",[1,5.55,2,3.43,3,0.376,4,1.866,5,3.143,6,4.514,7,1.38,8,4.267,9,3.89,10,2.344,11,2.635,12,3.974,13,3.326,14,0.55,15,4.827,16,1.418,17,2.72,18,6.539,19,2.691,20,4.514,21,1.964,22,2.53,23,2.72,24,3.278,25,6.539,26,3.974,27,4.161,28,2.814,29,4,30,2.904,31,2.878,32,2.282,33,4.384,34,3.022,35,6.539,36,2.948]],["tags/1",[]],["title/2",[37,6.671]],["content/2",[3,0.317,4,1.418,5,3.121,10,2.328,11,2.616,15,4.793,16,2.057,17,3.538,20,4.482,21,1.95,22,2.512,38,7.218,39,5.168,40,3.946,41,4.627,42,3.617,43,4.237,44,5.901,45,7.218,46,4.987,47,4.864,48,4.132,49,3.303,50,3.208,51,4.987,52,6.493,53,5.511,54,6.493,55,5.901,56,1.753,57,4.482,58,3.863,59,5.219,60,2.644,61,3.786,62,5.901]],["tags/2",[]],["title/3",[63,0.787,64,3.047]],["content/3",[3,0.281,7,1.593,11,3.773,14,0.635,16,1.637,63,0.992,64,3.841,65,5.212,66,2.837,67,4.692,68,5.38,69,6.672,70,6.069,71,6.408,72,6.861,73,3.899,74,6.861,75,5.798,76,3.841,77,6.861,78,6.861,79,6.861,80,2.544]],["tags/3",[]],["title/4",[81,4.135,82,2.734]],["content/4",[3,0.298,4,1.748,11,3.226,28,2.367,30,2.721,66,3.008,67,4.975,83,4.578,84,4.494,85,3.037,86,6.436,87,3.483,88,7.276,89,6.436,90,4.865,91,8.006,92,4.34,93,4.865]],["tags/4",[]],["title/5",[94,1.939]],["content/5",[94,2.292,95,3.462,96,4.628,97,3.23,98,3.392,99,5.394,100,5.523,101,3.358,102,5.164]],["tags/5",[]],["title/6",[103,4.198]],["content/6",[3,0.324,84,5.718,94,2.292,103,4.964,104,2.103,105,4.483,106,3.866,107,6.186]],["tags/6",[]],["title/7",[101,1.694,108,1.999,109,2.936,110,2.936]],["content/7",[11,2.97,21,2.214,23,3.066,27,4.69,30,2.505,50,3.642,110,6.749,111,7.37,112,5.087,113,6.255,114,7.37,115,7.37,116,5.087,117,3.1,118,3.244,119,6.255,120,4.385,121,2.549,122,2.618,123,5.44,124,3.866,125,3.406,126,3.033,127,5.66,128,4.69,129,4.69]],["tags/7",[]],["title/8",[23,2.492,122,2.128]],["content/8",[22,3.097,23,4.345,24,4.013,27,5.094,95,3.193,122,2.844,127,6.149,130,3.566,131,6.149,132,3.357,133,6.436,134,8.006,135,6.149,136,4.668,137,5.224]],["tags/8",[]],["title/9",[108,1.999,138,1.01,139,3.232,140,3.121]],["content/9",[20,4.36,23,2.628,24,3.166,63,0.83,65,4.36,104,1.53,108,2.883,110,4.235,117,3.935,122,2.967,127,4.851,132,2.185,138,1.457,139,4.663,140,7.378,141,4.501,142,3.758,143,3.549,144,5.431,145,5.19,146,4.851,147,8.351,148,1.871,149,6.316,150,6.316,151,5.74,152,3.838,153,4.663,154,3.758,155,5.077,156,5.74,157,4.663]],["tags/9",[]],["title/10",[122,2.128,158,3.003]],["content/10",[13,3.579,23,2.926,81,4.856,84,3.949,101,2.722,122,3.501,132,3.098,140,6.383,144,4.699,158,4.939,159,3.026,160,5.253,161,2.499,162,2.895,163,3.096,164,3.381,165,3.633,166,2.477,167,4.101,168,3.428,169,2.545,170,5.97,171,2.13,172,2.272,173,4.185]],["tags/10",[]],["title/11",[94,1.336,174,2.613,175,5.059]],["content/11",[28,2.004,37,6.159,50,3.349,64,3.448,94,2.309,98,2.648,101,2.622,108,3.991,122,3.107,140,4.83,141,4.83,142,4.032,144,4.588,158,4.384,163,2.983,165,3.501,168,3.303,169,3.164,173,4.032,174,4.517,176,2.432,177,4.83,178,2.915,179,4.423,180,3.737,181,4.588,182,2.648,183,3.501,184,5.752,185,3.737]],["tags/11",[]],["title/12",[28,1.295,128,2.786,186,2.262,187,1.822]],["content/12",[10,1.829,11,3.667,13,2.595,19,2.099,21,2.167,24,4.562,27,3.246,28,2.133,29,2.388,32,2.921,42,3.068,50,2.52,63,0.948,94,2.403,95,3.629,101,1.973,116,6.282,120,3.035,121,1.764,122,2.563,128,3.246,162,2.099,164,2.452,167,2.974,169,1.846,174,2.634,176,1.419,180,2.813,181,2.676,186,2.634,187,3.483,188,4.329,189,2.485,190,4.292,191,1.935,192,2.194,193,6.557,194,5.101,195,2.863,196,4.206,197,3.1,198,3.338,199,1.749,200,4.329,201,2.245,202,5.142,203,4.1,204,2.634,205,2.974,206,4.329,207,1.764,208,4.329,209,4.635,210,4.1]],["tags/12",[]],["title/13",[94,1.336,211,3.605,212,3.886]],["content/13",[11,2.494,58,4.902,63,1.298,66,2.326,94,2.608,101,2.395,120,6.119,132,2.141,174,3.197,176,2.292,181,4.323,188,6.994,192,2.662,208,5.253,211,6.601,212,7.585,213,5.872,214,3.413,215,3.609,216,3.54,217,3.149,218,4.15,219,5.625,220,5.625,221,4.15,222,4.754,223,6.19,224,4.192,225,8.24,226,3.683]],["tags/13",[]],["title/14",[227,3.914]],["content/14",[3,0.313,4,1.389,7,1.342,11,2.563,13,3.235,14,0.705,63,0.836,82,2.903,94,2.636,96,3.39,104,1.541,125,2.939,138,1.467,157,4.695,171,1.925,174,3.285,176,1.769,181,4.401,187,3.906,204,3.285,228,5.397,229,6.359,230,5.779,231,5.112,232,5.475,233,2.617,234,6.359,235,3.865,236,4.891,237,5.791,238,3.952,239,3.783,240,1.643,241,4.264,242,3.637,243,2.51,244,4.39]],["tags/14",[]],["title/15",[94,1.582,240,1.548]],["content/15",[2,1.764,3,0.318,4,0.734,14,0.283,19,1.384,22,1.301,23,3.077,26,2.043,34,1.554,63,0.972,65,2.321,84,1.888,94,2.123,98,2.065,101,2.044,104,0.815,110,4.375,122,3.633,124,2.772,125,1.554,132,1.828,140,4.651,144,2.772,146,2.583,158,4.634,160,2.817,161,1.195,163,1.48,164,1.616,165,1.737,166,1.184,167,1.961,169,2.361,170,4.484,176,2.236,179,2.194,181,4.217,185,1.854,187,3.55,188,2.854,189,2.575,190,3.883,192,1.446,198,2.603,199,2.926,201,1.48,207,1.163,213,2.396,231,2.703,240,2.077,243,1.327,245,3.363,246,2.326,247,2.09,248,2.09,249,2.703,250,2.254,251,1.595,252,2.001,253,2.482,254,3.363,255,3.363,256,4.247,257,3.056,258,3.448,259,3.647,260,2.321,261,1.463,262,2.396,263,2.575,264,3.056,265,1.854,266,1.17,267,3.056,268,1.854,269,1.711,270,2.583,271,3.363,272,2.482,273,3.765,274,3.363,275,2.321,276,2.09,277,2.09,278,3.363,279,2.194,280,3.363,281,1.923,282,1.228,283,1.43,284,2.583,285,2.854,286,1.228,287,0.838,288,2.854,289,3.056,290,2.001]],["tags/15",[]],["title/16",[23,2.492,122,2.128]],["content/16",[3,0.374,7,0.742,11,2.205,12,0.68,14,0.094,15,0.826,16,0.763,17,0.854,19,0.461,22,0.433,23,2.11,26,1.247,31,1.549,32,1.432,63,0.539,65,0.773,66,1.542,80,0.377,94,0.929,98,0.437,101,0.794,104,0.995,105,2.827,110,3.096,122,3.382,124,1.076,129,4.935,132,2.683,135,7.096,137,5.359,138,0.473,139,0.826,140,4.598,144,4.308,146,0.86,158,4.183,160,2.462,165,2.619,167,0.653,171,0.621,172,0.362,176,1.522,179,1.339,180,1.567,187,1.921,189,0.545,190,1.221,191,1.078,192,0.481,196,1.196,198,0.446,199,1.583,201,1.549,202,0.798,206,0.95,216,0.64,226,1.221,240,0.289,242,0.64,243,0.442,251,0.973,263,1,269,0.569,272,0.826,273,2.507,276,1.275,279,0.73,282,0.409,287,0.279,291,0.798,292,2.037,293,0.695,294,5.756,295,0.712,296,0.95,297,0.347,298,0.773,299,0.446,300,1.961,301,0.9,302,0.561,303,0.697,304,3.001,305,2.649,306,1.576,307,0.948,308,1.119,309,1.119,310,0.73,311,1.017,312,1.808,313,0.578,314,1.69,315,0.773,316,2.679,317,0.75,318,0.433,319,0.666,320,0.827,321,1.961,322,0.826,323,1.947,324,0.531,325,0.499,326,0.362,327,0.9,328,0.73,329,2.137,330,2.093,331,2.627,332,2.767,333,0.9,334,0.95,335,3.518,336,3.518,337,1.865,338,1.576,339,3.919,340,3.197,341,2.986,342,1.691,343,2.828,344,1.975,345,1.817,346,1.79,347,1.669,348,4.204,349,1.739,350,3.572,351,4.881,352,2.429,353,3.197,354,3.518,355,1.54,356,2.597,357,3.197,358,2.562,359,2.296,360,4.4,361,2.986,362,3.518,363,2.828,364,3.518,365,3.197,366,5.834,367,3.197,368,3.197,369,2.702,370,3.518,371,3.518,372,1.306,373,2.097,374,0.578,375,0.773,376,0.64,377,1.119,378,1.06,379,1.221,380,1.649]],["tags/16",[]],["title/17",[187,2.492,226,3.564]],["content/17",[3,0.208,7,1.439,14,0.573,19,0.868,21,1.674,23,2.604,26,2.189,30,0.717,32,2.679,58,2.143,63,1.203,94,2.027,101,2.97,105,1.86,120,5.341,121,2.655,122,0.749,126,1.482,129,2.292,132,1.63,138,0.487,144,1.106,160,2.971,165,1.089,167,1.23,169,0.763,171,0.638,176,2.026,177,3.359,180,1.986,181,3.284,182,2.664,186,3.522,187,1.498,191,0.8,196,1.23,202,4.461,207,0.729,213,4.461,226,3.724,239,4.057,258,4.45,268,1.986,281,2.06,287,2.188,294,4.197,297,0.654,303,0.717,318,2.818,319,3.316,320,2.522,321,3.254,325,2.099,329,1.193,330,1.224,331,1.466,332,2.235,355,1.143,381,1.456,382,1.042,383,0.963,384,1.065,385,1.862,386,5.591,387,6.019,388,4.803,389,3.359,390,3.479,391,4.144,392,5.033,393,2.473,394,3.16,395,3.359,396,2.864,397,4.283,398,3.62,399,2.555,400,4.283,401,2.804,402,3.601,403,3.601,404,0.867,405,2.238,406,2.022,407,3.601,408,1.695,409,3.273,410,1.62,411,2.109,412,1.79]],["tags/17",[]],["title/18",[14,0.504,94,1.582]],["content/18",[7,1.4,14,0.806,23,2.759,63,0.871,94,1.752,97,2.468,122,3.064,138,1.99,161,2.356,174,3.426,176,2.822,183,3.426,198,2.645,236,5.028,237,4.578,239,3.946,240,2.476,269,3.374,282,2.422,305,2.853,321,4.578,382,3.277,413,6.145,414,4.22,415,7.319,416,7.319,417,4.578,418,5.331,419,4.896]],["tags/18",[]],["title/19",[14,0.425,94,1.336,413,3.605]],["content/19",[3,0.211,7,1.195,14,0.652,22,2.19,23,3.682,63,0.744,94,1.495,98,2.212,122,3.66,144,2.97,155,4.551,161,2.011,165,2.924,167,3.3,176,1.575,181,4.07,198,3.978,199,1.941,212,4.348,214,3.122,219,5.145,236,5.16,239,3.368,240,2.577,243,2.235,264,5.145,269,3.947,272,4.179,273,4.034,287,1.411,296,4.805,325,2.522,415,6.584,416,6.584,420,5.661,421,3.068,422,5.661,423,1.844,424,2.721,425,3.908,426,4.034,427,5.145,428,5.145,429,5.661]],["tags/19",[]],["title/20",[94,1.336,305,2.176,413,3.605]],["content/20",[3,0.256,7,1.452,13,3.499,14,0.742,22,2.661,23,2.861,61,4.01,71,5.838,94,1.816,122,3.137,132,2.379,138,2.037,152,4.18,165,3.553,167,4.01,169,2.489,174,3.553,176,2.456,179,4.488,181,4.631,190,4.092,191,2.609,237,4.748,292,2.56,305,3.797,415,5.838,416,5.838,417,4.748,430,4.611,431,4.377,432,5.283]],["tags/20",[]],["title/21",[157,4.422,433,5.444]],["content/21",[3,0.318,14,0.717,84,4.783,87,3.707,101,3.297,157,6.29,213,6.072,433,7.744,434,8.521,435,7.232,436,6.544]],["tags/21",[]],["title/22",[199,1.735,240,1.307,404,1.217]],["content/22",[3,0.188,16,1.094,23,3.768,34,2.332,63,0.941,64,2.567,82,3.268,93,3.066,103,2.885,104,1.223,108,2.303,121,1.745,122,3.529,164,2.425,172,2.688,173,3.002,176,1.991,180,2.782,191,1.914,199,2.853,240,2.15,251,2.393,265,4.994,281,5.469,283,3.045,286,1.843,287,1.258,322,3.724,349,2.275,379,3.002,385,1.686,394,3.382,404,2.39,405,4.449,437,4.436,438,5.045,439,4.282,440,4.449,441,4.585,442,6.076,443,3.595,444,4.585,445,1.362,446,4.585,447,3.948,448,5.045,449,2.122,450,5.045,451,4.056]],["tags/22",[]],["title/23",[14,0.504,452,2.734]],["content/23",[4,2.014,14,0.809,19,1.891,23,3.285,58,3.983,63,1.14,94,1.214,122,2.806,171,1.391,174,2.373,176,1.862,178,1.977,182,1.796,185,3.691,191,1.743,199,1.576,201,2.023,207,1.589,211,3.275,212,5.141,213,3.275,214,5.085,215,2.679,216,2.628,236,2.679,239,2.734,240,2.567,246,2.023,266,1.482,282,3.368,290,3.983,301,3.694,385,2.236,404,2.45,417,4.621,421,2.491,453,2.373,454,4.595,455,4.176,456,4.368,457,4.771,458,4.488,459,3.275,460,3.081,461,4.907,462,2.793,463,2.304,464,4.595,465,2.628,466,4.595,467,3.694,468,4.595,469,3.275,470,3.392]],["tags/23",[]],["title/24",[101,2.318,160,3.193]],["content/24",[14,0.691,101,3.18,104,1.992,130,3.661,160,4.382,191,3.118,207,2.843,257,7.469,281,4.7,305,3.535,404,1.978,435,6.975,444,7.469,471,8.219,472,5.51]],["tags/24",[]],["title/25",[473,2.352]],["content/25",[4,1.513,14,0.746,23,4.291,58,4.123,63,0.91,117,2.914,122,3.665,143,3.913,199,2.376,207,2.397,226,4.123,236,4.04,240,2.292,248,4.306,265,3.821,287,1.727,404,1.667,453,3.579,456,4.522,461,4.306,470,5.115,473,2.22,474,6.929,475,5.115,476,5.115]],["tags/25",[]],["title/26",[168,3.577]],["content/26",[5,3.433,23,2.972,63,0.939,110,4.789,122,3.213,144,3.747,148,1.428,152,4.341,165,3.689,167,4.165,176,1.987,221,4.789,300,4.931,305,3.072,310,4.661,345,3.689,346,3.634,347,3.388,355,4.902,358,3.344,360,5.742,361,6.062,477,6.491,478,4.931,479,5.742,480,6.491,481,5.09,482,6.491,483,4.931,484,2.515]],["tags/26",[]],["title/27",[477,6.671]],["content/27",[5,3.46,23,2.995,63,0.946,110,4.826,122,3.229,144,3.776,148,1.439,152,4.374,165,3.718,167,4.197,176,2.002,221,4.826,300,4.969,305,3.096,310,4.697,345,3.718,346,3.662,347,3.414,355,4.926,358,3.37,360,5.786,361,6.109,478,4.969,479,5.786,480,6.542,481,5.13,482,6.542,483,4.969,484,2.535]],["tags/27",[]],["title/28",[21,1.52,485,1.901,486,1.607]],["content/28",[4,1.557,7,1.505,10,3.239,16,1.547,21,2.713,23,2.087,24,3.575,28,2.109,32,1.751,36,2.262,40,3.049,58,2.985,63,1.09,75,3.854,76,2.553,80,2.403,90,3.049,169,1.816,178,2.158,189,2.445,204,2.592,214,3.933,232,3.275,233,2.065,247,4.432,283,2.134,292,1.867,297,1.556,315,4.923,326,1.621,372,3.193,376,2.87,382,2.48,389,3.576,445,1.355,449,2.999,485,2.679,486,3.032,487,4.56,488,3.118,489,2.748,490,3.704,491,5.018,492,3.193,493,4.56,494,4.034,495,3.576,496,5.018,497,5.018,498,2.592,499,4.56,500,4.56,501,2.985,502,4.56,503,3.854,504,2.767,505,1.922,506,4.432,507,5.018,508,3.193,509,1.941]],["tags/28",[]],["title/29",[7,0.924,16,0.95,21,1.315,56,1.182]],["content/29",[3,0.267,7,1.065,10,3.247,11,2.885,16,1.805,17,2.099,19,2.946,21,2.72,28,1.492,29,2.362,42,3.539,51,3.875,56,2.445,63,0.663,80,1.7,84,2.832,85,2.716,98,1.971,101,2.77,102,3.002,108,2.303,121,2.476,130,2.247,163,2.221,164,2.425,170,4.282,189,3.488,190,3.002,192,2.17,247,3.135,250,3.382,252,3.002,310,3.292,315,3.483,341,4.282,375,3.483,376,2.885,378,2.606,384,1.492,469,3.595,485,2.69,486,3.038,489,1.671,503,3.875,505,3.469,510,6.076,511,4.942,512,3.724,513,5.045,514,1.86,515,4.056,516,4.056,517,4.056,518,2.458,519,4.282,520,3.066]],["tags/29",[]],["title/30",[3,0.189,21,1.52,56,1.366]],["content/30",[3,0.312,4,0.934,7,0.903,10,2.277,11,1.724,14,0.36,16,0.928,19,1.76,21,2.517,28,1.265,30,1.454,42,2.701,56,1.714,63,0.995,76,2.176,80,2.14,90,2.599,97,1.592,101,1.655,109,2.868,117,1.799,121,3.245,126,1.76,130,1.905,137,2.791,138,1.465,163,1.883,168,2.084,169,2.741,172,1.382,173,2.545,185,2.359,189,2.084,192,1.84,207,1.48,240,1.105,243,1.688,247,2.658,268,2.359,290,2.545,315,2.953,317,2.868,326,1.382,328,2.791,374,2.209,378,2.209,384,1.265,396,2.599,445,1.714,485,1.607,486,2.406,505,1.639,506,3.946,509,1.655,518,3.094,520,2.599,521,5.619,522,3.63,523,3.438,524,2.658,525,4.688,526,3.438,527,4.526,528,3.438,529,2.722,530,3.438,531,4.258,532,3.887,533,6.088,534,2.084,535,3.158,536,3.887,537,4.688,538,4.688,539,2.084,540,4.277,541,2.545,542,3.158,543,3.887,544,2.494,545,1.592,546,1.952,547,2.144,548,3.438]],["tags/30",[]],["title/31",[130,2.668,549,4.601]],["content/31",[63,1.12,87,3.707,97,3.171,130,3.795,138,1.966,227,4.543,295,5.422,506,5.295,521,5.713,549,6.544,550,6.849]],["tags/31",[]],["title/32",[527,4.269,528,4.815]],["content/32",[3,0.316,21,1.937,24,4.244,63,1.242,109,4.323,121,2.928,137,4.208,143,2.446,192,2.773,346,3.28,347,3.058,380,5.183,390,4.76,459,4.595,503,4.952,527,4.595,528,5.183,529,4.103,537,4.76,539,3.142,551,5.86,552,6.448,553,6.448,554,4.936,555,6.448,556,5.86,557,4.323,558,6.448,559,6.448,560,5.86,561,5.472,562,6.448,563,4.952,564,6.448,565,6.448,566,5.86,567,6.448,568,6.448,569,5.86,570,5.472]],["tags/32",[]],["title/33",[169,2.168,527,4.269]],["content/33",[3,0.291,10,2.798,63,1.256,109,5.232,131,5.994,137,5.093,169,3.458,459,5.561,527,5.561,549,5.994,551,7.092,554,4.55,556,7.092,557,5.232,571,2.877,572,7.804,573,7.092,574,6.623,575,7.092]],["tags/33",[]],["title/34",[21,1.315,486,1.391,576,2.134,577,3.52]],["content/34",[2,4.06,3,0.288,21,2.324,30,2.63,48,4.924,63,1.249,83,4.426,145,4.809,178,3.329,224,3.937,329,2.564,399,4.195,423,2.521,486,2.459,489,2.564,546,3.532,576,3.771,578,7.739,579,4.126,580,2.853,581,3.824]],["tags/34",[]],["title/35",[3,0.223,199,2.054]],["content/35",[3,0.351,7,1.606,19,3.133,28,2.251,32,2.656,39,4.626,63,1,122,2.704,158,3.816,171,2.304,172,2.459,199,2.61,259,5.254,283,3.237,287,1.897,358,3.563,406,4.273,488,4.73,518,3.709,582,4.73,583,4.844,584,4.626,585,7.612]],["tags/35",[]],["title/36",[122,2.128,158,3.003]],["content/36",[63,0.953,81,5.008,98,2.835,101,2.807,108,3.311,109,4.864,110,4.864,122,3.727,158,4.578,161,2.578,163,3.193,169,2.625,171,2.196,172,2.343,173,4.316,226,4.316,256,8.034,318,2.807,419,5.355,586,3.932,587,5.832,588,4.734,589,6.593,590,5.572]],["tags/36",[]],["title/37",[294,4.922]],["content/37",[28,2.43,32,2.868,101,3.18,122,3.503,135,6.312,158,4.12,162,3.382,163,3.618,164,3.95,198,3.278,258,5.363,294,6.611,453,4.245]],["tags/37",[]],["title/38",[135,5.638]],["content/38",[3,0.288,93,4.703,122,2.75,132,2.677,135,7.903,137,6.715,158,3.879,160,4.126,162,3.185,163,3.406,182,3.024,218,5.188,282,2.826,348,5.944,349,2.459,350,5.05,586,4.195,591,7.033]],["tags/38",[]],["title/39",[348,5.638]],["content/39",[3,0.193,7,1.095,23,2.158,63,0.681,93,3.152,98,2.027,101,2.006,122,1.843,130,2.31,131,6.488,137,4.764,152,3.152,162,2.134,166,1.826,167,3.024,169,3.057,176,1.442,189,2.527,218,4.894,258,6.861,259,6.919,260,5.039,261,3.675,283,2.206,306,3.983,314,3.085,348,7.421,349,1.648,350,3.384,378,2.679,423,2.378,425,3.58,503,6.488,524,6.005,526,5.868,527,5.202,592,4.402,593,4.713,594,4.169,595,7.3,596,7.3,597,5.186,598,5.186,599,4.402,600,3.58]],["tags/39",[]],["title/40",[292,2.229,378,3.094]],["content/40",[3,0.245,10,3.424,11,2.653,21,2.578,30,2.238,34,3.044,36,3.87,50,3.254,63,0.865,75,5.058,87,2.865,117,3.61,121,2.278,130,2.933,161,2.34,189,3.209,232,4.297,240,1.702,258,4.297,259,4.546,260,4.546,261,2.865,268,3.631,283,3.65,292,3.194,348,5.058,378,4.932,465,3.766,485,2.474,601,6.585,602,6.585,603,5.589,604,3.301,605,3.631]],["tags/40",[]],["title/41",[4,1.308,132,2.072]],["content/41",[4,1.733,117,3.338,132,2.746,138,1.831,143,3.011,176,2.208,198,3.165,233,3.267,269,4.038,286,2.899,292,2.954,305,3.414,316,5.18,325,3.536,380,6.381,447,4.377,544,4.628,606,5.322,607,2.629]],["tags/41",[]],["title/42",[56,1.182,121,1.515,130,1.95,605,2.415]],["content/42",[3,0.34,11,2.923,14,0.61,28,2.145,63,0.953,76,3.691,80,2.445,96,3.868,104,1.758,107,5.17,121,2.509,130,3.231,132,2.509,169,2.625,173,4.316,189,3.535,195,4.073,227,3.868,232,4.734,243,2.864,262,5.17,295,4.616,543,6.593,605,4.001,608,6.157,609,5.355,610,6.157,611,6.593,612,6.157]],["tags/42",[]],["title/43",[28,1.771,32,2.09]],["content/43",[2,4.06,21,2.324,24,3.879,26,4.703,28,2.288,32,2.701,48,4.924,94,2.044,124,4.06,125,3.577,130,3.447,132,2.677,168,3.771,174,3.997,187,3.219,190,5.656,195,4.344,209,7.033,243,3.055,613,7.033,614,7.739]],["tags/43",[]],["title/44",[185,3.303,290,3.564]],["content/44",[3,0.366,14,0.75,21,2.677,56,2.406,63,0.917,64,3.552,121,3.396,126,2.873,130,3.11,172,2.255,185,4.915,201,3.073,241,4.681,269,3.552,273,4.975,290,5.303,292,2.598,318,2.701,421,3.784,486,2.218,537,5.154,538,5.154,615,5.612,616,3.5,617,4.819,618,3.11]],["tags/44",[]],["title/45",[14,0.504,431,3.812]],["content/45",[3,0.374,14,0.814,34,2.41,63,0.685,65,5.059,94,2.238,122,3.665,126,2.146,130,3.264,140,3.717,154,3.103,158,3.674,163,2.296,164,2.507,174,2.694,176,1.451,181,2.736,185,2.876,191,3.214,198,2.08,199,1.788,230,4.74,235,3.169,240,2.375,243,2.059,246,2.296,258,3.403,259,3.6,261,2.269,273,6.038,290,3.103,316,3.403,428,4.74,431,5.848,537,3.85,586,2.827,606,3.497,619,7.191,620,3.6,621,2.928,622,4.192,623,5.215,624,4.192,625,4.74,626,5.215,627,2.614,628,3.6,629,5.215]],["tags/45",[]],["title/46",[21,1.799,630,2.701]],["content/46",[3,0.206,4,1.207,11,2.227,14,0.642,20,3.815,21,2.97,30,1.878,34,2.554,56,1.492,63,1.148,121,3.26,124,2.899,161,2.711,171,2.31,207,1.911,213,3.938,214,3.047,215,3.222,240,2.555,243,2.181,266,1.223,283,2.35,312,3.516,345,2.854,382,2.731,406,3.102,426,3.938,430,3.705,440,4.742,617,3.815,630,3.94,631,2.995,632,3.222,633,5.116,634,5.022,635,6.133,636,5.022,637,5.526,638,5.526,639,4.442,640,4.079,641,7.63,642,5.526,643,5.526,644,3.705,645,5.526,646,5.022,647,4.079]],["tags/46",[]],["title/47",[21,1.799,486,1.903]],["content/47",[3,0.35,10,1.97,14,0.639,21,2.964,30,1.867,34,2.539,47,3.141,56,2.664,63,1.145,66,2.064,102,3.268,104,1.841,121,3.013,169,2.75,187,2.285,189,2.677,191,2.084,243,2.168,266,1.216,275,3.792,287,1.369,297,1.703,305,2.363,342,2.64,358,2.572,445,1.483,485,2.064,486,2.987,503,4.219,514,2.025,524,4.722,527,5.415,528,4.416,542,4.055,546,2.507,548,4.416,605,4.19,607,1.82,648,5.493,649,5.493,650,2.285,651,3.683,652,3.683,653,4.416,654,5.493,655,3.414,656,5.493]],["tags/47",[]],["title/48",[3,0.163,56,1.744,121,1.515]],["content/48",[3,0.273,4,1.332,10,1.453,14,0.773,15,2.992,21,1.832,24,2.032,34,1.873,56,1.647,63,0.533,64,2.062,65,2.798,98,1.584,117,3.085,121,3.027,126,1.668,154,4.855,169,1.467,185,4.5,186,2.093,187,1.686,189,1.975,198,1.616,207,1.402,216,2.318,233,2.51,240,1.895,242,2.318,243,1.6,266,0.897,269,3.103,277,2.519,290,4.855,292,2.27,297,1.891,303,1.378,318,1.568,322,2.992,323,1.922,374,2.093,376,2.318,378,2.093,406,2.275,414,3.882,417,2.798,452,1.85,470,4.503,479,3.258,483,2.798,486,2.33,512,2.992,515,3.258,533,5.896,537,7.248,538,7.248,539,1.975,603,3.44,604,2.032,615,4.903,616,3.058,618,2.717,657,3.684,658,4.053,659,3.258,660,3.44,661,3.44,662,3.44,663,3.44,664,3.258,665,3.684,666,4.053,667,1.686,668,2.126,669,2.126,670,3.258,671,2.992,672,2.992]],["tags/48",[]],["title/49",[56,1.744,121,1.515,305,1.883]],["content/49",[3,0.278,7,0.61,10,3.014,14,0.394,16,1.823,21,2.524,24,1.449,40,3.587,42,2.511,56,2.269,63,0.98,64,2.383,73,1.493,77,4.256,80,0.974,85,1.097,94,0.763,104,1.645,112,1.996,117,2.483,121,3.287,130,1.288,138,0.667,143,1.097,152,1.757,154,1.72,163,2.061,172,0.934,174,2.419,187,1.948,189,1.409,191,1.097,195,1.623,198,1.153,201,1.273,210,2.324,233,1.19,267,2.627,269,1.471,275,1.996,279,1.887,285,3.975,297,1.452,303,1.592,305,1.243,314,1.72,317,1.938,318,1.812,319,1.72,329,1.955,330,2.006,331,2.404,355,1.567,374,1.493,376,1.653,384,1.385,417,1.996,431,1.84,445,2.013,449,1.216,452,1.32,469,2.06,485,2.218,486,2.781,494,2.324,501,1.72,516,2.324,517,2.324,518,1.409,520,1.757,533,6.416,538,6.205,544,1.686,548,2.324,576,1.409,580,1.726,610,2.454,616,1.449,617,3.233,650,1.203,652,1.938,653,2.324,670,2.324,673,2.627,674,2.06,675,2.282,676,1.336,677,8.219,678,2.282,679,3.975,680,4.256,681,2.891,682,2.134,683,4.683,684,2.22,685,5.903,686,1.84,687,1.086,688,1.84,689,2.324,690,2.891,691,1.757,692,2.454,693,1.938,694,3.177,695,1.409,696,2.324,697,4.256,698,2.891,699,2.891]],["tags/49",[]],["title/50",[424,3.529]],["content/50",[3,0.344,4,1.343,7,1.731,14,0.828,28,1.818,50,3.038,56,2.215,66,2.31,94,2.167,104,1.49,121,2.838,143,2.333,145,3.821,174,4.237,198,3.272,215,3.585,236,3.585,237,4.244,238,3.821,239,3.658,240,2.12,269,3.128,313,3.176,316,4.012,325,2.739,345,3.176,421,4.447,424,3.943,472,4.122,518,2.996,535,4.539,557,4.122,682,4.539,700,3.658,701,5.219,702,4.943,703,5.588,704,4.539,705,5.588]],["tags/50",[]],["title/51",[316,4.791]],["content/51",[3,0.244,4,2.203,14,0.8,132,2.262,138,1.509,143,2.481,145,4.063,158,3.278,169,2.366,176,1.819,182,2.555,186,3.377,198,2.608,199,2.242,232,4.267,236,3.812,239,3.89,240,2.607,246,2.878,266,1.448,282,3.12,284,5.022,287,1.63,316,6.21,373,4.827,424,3.143,425,4.514,447,3.606,622,5.256,631,3.544,706,2.845,707,3.974,708,3.974]],["tags/51",[]],["title/52",[236,4.28]],["content/52",[4,1.459,14,0.562,21,2.006,49,3.398,93,4.059,94,2.539,120,3.974,121,2.311,143,3.648,161,2.373,171,2.022,176,1.858,181,3.504,211,4.76,212,5.13,236,5.051,240,2.484,284,5.13,292,2.486,303,2.27,314,3.974,378,3.45,421,3.621,456,4.359,489,2.213,535,4.931,639,5.37,667,2.779,708,4.059,709,5.669,710,5.37,711,3.211,712,4.251,713,4.931]],["tags/52",[]],["title/53",[237,5.068]],["content/53",[3,0.273,7,1.543,14,0.772,30,2.485,66,2.747,94,2.424,161,2.598,171,2.214,174,3.777,176,2.553,190,4.35,191,2.774,207,2.529,224,3.72,237,5.047,240,1.889,242,4.181,261,3.181,269,3.72,305,3.145,413,5.211,430,4.902,557,4.902,579,3.898,701,6.206,709,6.206]],["tags/53",[]],["title/54",[535,5.419]],["content/54",[3,0.313,4,1.389,21,2.82,27,4.047,56,2.695,63,1.102,121,3.759,124,3.336,161,2.981,171,1.925,240,2.168,241,4.264,292,2.367,303,2.162,305,2.735,317,4.264,328,4.15,378,3.285,486,2.665,489,2.107,535,6.193,537,4.695,538,4.695,546,2.903,621,3.57,667,2.646,677,5.779,689,5.112,709,5.397,714,6.359,715,4.695]],["tags/54",[]],["title/55",[21,1.799,630,2.701]],["content/55",[3,0.307,4,1.198,5,1.696,7,0.745,14,0.461,21,2.963,22,1.365,27,2.246,30,1.199,58,3.264,60,1.437,63,0.998,66,2.061,124,1.851,130,1.572,138,0.814,207,1.898,215,3.925,221,2.366,232,2.303,240,0.912,241,2.366,261,1.535,263,1.72,279,2.303,283,1.501,286,1.289,312,2.246,314,2.1,317,5.514,326,1.772,372,4.283,382,1.744,399,1.913,423,1.149,430,3.678,445,0.953,456,3.58,461,3.41,463,1.769,490,2.605,517,2.837,518,1.72,520,3.334,534,2.673,541,2.1,545,1.313,546,1.611,571,2.023,613,3.207,630,1.591,631,1.913,632,3.199,633,5.09,635,6.999,636,4.986,640,7.124,644,2.366,650,1.468,653,2.837,716,5.039,717,3.529,718,3.529,719,3.529,720,3.529,721,5.745,722,2.71,723,3.207,724,3.207,725,3.529,726,2.057,727,5.487,728,3.529,729,2.057,730,5.487,731,3.529,732,2.837,733,3.529,734,3.207,735,3.529,736,2.71,737,2.995,738,3.207,739,2.995,740,1.913,741,2.057,742,2.515]],["tags/55",[]],["title/56",[307,3.393]],["content/56",[3,0.232,4,1.807,28,1.842,29,2.917,30,2.118,36,2.809,50,3.079,75,4.786,76,3.17,85,3.14,104,1.51,106,2.776,173,3.707,178,2.68,227,3.322,233,2.564,277,3.872,295,3.965,307,4.577,375,4.301,376,3.563,462,3.787,484,2.194,534,3.036,729,3.633,743,3.872,744,3.787,745,3.707,746,5.663,747,5.663,748,5.663,749,5.663,750,5.663,751,5.663,752,4.301,753,6.231,754,3.17,755,6.231,756,4.441,757,4.6,758,6.231,759,6.231,760,3.051,761,5.663,762,3.707]],["tags/56",[]],["title/57",[16,1.097,763,1.957,764,3.605]],["content/57",[16,1.952,24,3.553,32,2.474,50,4.447,97,2.638,108,4.108,196,4.133,207,3.113,240,1.832,249,5.698,307,3.276,328,4.626,401,4.217,486,2.252,563,5.444,630,3.196,693,4.752,715,5.233,756,5.051,763,3.482,764,5.051,765,7.088,766,9,767,7.088,768,6.016,769,6.442,770,4.752]],["tags/57",[]],["title/58",[756,5.232]],["content/58",[3,0.295,4,1.275,10,2.094,14,0.756,19,3.261,50,2.885,63,0.767,97,2.173,107,4.161,122,2.075,132,2.02,172,2.559,207,2.741,238,3.629,282,2.133,314,3.474,326,2.559,383,3.616,430,6.03,445,1.576,462,3.548,470,4.31,571,2.153,588,3.81,606,5.312,632,3.404,633,3.915,693,3.915,739,4.956,744,3.548,745,3.474,756,7.41,771,5.839,772,5.839,773,5.839,774,5.307,775,5.307,776,5.307,777,3.447,778,3.81,779,7.923,780,4.694,781,3.629]],["tags/58",[]],["title/59",[484,2.585]],["content/59",[87,3.367,172,2.5,250,5.188,277,4.809,283,3.291,483,5.342,484,2.725,489,2.564,504,4.268,530,6.221,594,6.221,619,6.568,782,7.739,783,7.033,784,7.033,785,6.568,786,7.033,787,7.033,788,5.342,789,7.739,790,6.568,791,6.568]],["tags/59",[]],["title/60",[172,1.935,484,2.109]],["content/60",[3,0.235,14,0.702,42,2.686,50,3.121,64,3.213,117,2.657,172,2.04,198,3.33,207,2.889,240,1.632,243,2.493,269,3.213,316,5.45,328,4.122,385,2.11,404,1.52,405,3.925,425,4.36,449,3.513,453,3.262,462,3.838,483,4.36,484,3.294,514,2.328,778,5.45,780,5.077,781,3.925,792,6.316,793,6.316,794,6.316,795,6.316,796,5.45,797,5.74,798,3.213,799,5.361,800,3.925,801,6.316,802,2.717,803,4.663,804,5.74]],["tags/60",[]],["title/61",[4,1.308,484,2.109]],["content/61",[3,0.314,4,1.398,14,0.538,19,2.635,21,1.923,22,2.477,50,3.164,63,0.841,132,2.215,154,3.81,171,1.938,172,2.722,207,2.215,240,1.655,248,3.979,262,4.563,283,3.584,292,2.383,326,2.068,378,3.307,445,1.729,462,3.891,484,3.759,489,2.121,495,4.563,624,5.147,633,4.293,716,4.59,760,2.361,762,3.81,778,4.179,780,5.147,781,3.979,805,4.42,806,4.727,807,6.403,808,6.403]],["tags/61",[]],["title/62",[757,5.419]],["content/62",[3,0.212,4,1.244,36,2.568,50,2.815,62,5.176,69,4.059,85,2.161,107,5.552,124,2.988,132,1.97,143,2.161,160,3.036,172,3.229,207,1.97,218,3.819,228,4.834,232,5.084,233,3.206,282,2.08,291,4.059,307,2.632,326,1.84,406,4.984,424,2.738,445,1.538,462,3.461,483,3.932,571,2.872,606,3.819,619,4.834,631,3.087,633,3.819,693,3.819,708,4.734,738,5.176,757,7.619,777,2.478,778,3.717,809,5.696,810,5.696,811,5.176,812,5.176,813,5.696,814,5.696,815,4.578,816,2.45,817,4.205,818,5.696,819,5.696]],["tags/62",[]],["title/63",[169,2.656]],["content/63",[3,0.232,4,1.361,7,1.315,10,2.968,14,0.524,36,2.809,50,3.079,72,7.522,97,2.319,108,4.52,143,2.364,191,2.364,210,5.009,217,3.17,228,5.289,233,2.564,247,5.144,291,4.441,307,2.88,342,2.995,484,2.194,502,5.663,580,2.297,607,2.064,609,4.6,610,5.289,612,5.289,634,7.522,756,4.441,757,4.6,778,4.066,817,4.6,820,6.231,821,6.231,822,6.231,823,6.231,824,5.663,825,6.653,826,5.009,827,6.231,828,6.231,829,6.231,830,3.322]],["tags/63",[]],["title/64",[3,0.189,14,0.425,831,2.95]],["content/64",[14,0.887,16,2,56,1.99,63,1.323,108,3.364,138,1.701,182,2.88,192,3.17,198,3.678,266,1.632,325,3.283,384,2.179,385,2.462,390,5.44,404,2.422,445,1.99,525,5.44,607,2.441,763,2.851]],["tags/64",[]],["title/65",[832,2.928]],["content/65",[3,0.325,10,1.97,14,0.858,20,3.792,50,2.715,56,1.483,63,0.722,74,4.992,80,1.851,85,2.084,117,3.196,138,1.267,141,3.915,153,6.431,161,2.7,204,2.837,205,3.203,233,2.261,235,3.338,259,3.792,279,3.585,292,2.828,310,3.585,313,2.837,320,2.213,374,2.837,385,2.911,401,3.268,404,1.828,512,4.055,518,2.677,650,2.285,653,4.416,659,4.416,695,2.677,700,3.268,802,2.363,832,4.318,833,6.209,834,5.294,835,4.992,836,2.336,837,4.416,838,3.029]],["tags/65",[]],["title/66",[14,0.425,98,1.977,452,2.309]],["content/66",[3,0.286,4,1.914,7,1.173,14,0.795,16,1.206,42,2.364,104,1.347,117,3.687,118,2.447,127,4.27,138,2.287,151,5.052,185,3.066,192,2.391,198,2.217,201,3.372,242,3.179,268,3.066,269,2.828,277,3.455,282,2.03,290,3.307,292,2.851,318,2.151,326,1.796,385,3.626,404,1.338,445,1.501,452,2.537,455,5.052,457,5.46,462,3.378,463,2.787,650,2.313,797,5.052,832,3.055,839,5.052,840,5.052,841,5.559,842,5.559,843,4.469,844,4.718,845,1.501,846,4.718,847,5.559]],["tags/66",[]],["title/67",[98,1.977,243,1.997,452,2.309]],["content/67",[3,0.257,4,1.505,14,0.821,16,1.038,22,2.667,28,1.415,32,1.67,49,2.434,94,1.82,98,1.87,122,2.449,132,1.655,138,1.59,158,4.05,160,2.551,161,2.871,176,1.331,181,3.616,187,2.868,192,2.058,198,3.892,199,1.641,214,2.639,236,4.711,239,5.26,240,2.66,266,1.059,282,2.517,316,6.115,349,1.52,373,3.532,381,3.303,404,1.659,417,3.303,424,3.313,456,4.498,465,2.736,545,1.781,586,2.594,630,2.157,655,2.974,707,2.908,708,4.91,710,3.846,711,2.3,722,3.675,741,2.79,760,1.764,763,1.851,848,6.893,849,4.349]],["tags/67",[]],["title/68",[138,1.167,607,1.676,850,4.598]],["content/68",[3,0.281,4,1.646,7,1.591,14,0.877,30,1.845,42,2.309,56,2.035,58,3.23,63,1.229,65,3.748,117,2.283,121,1.878,138,1.998,144,2.848,176,1.51,185,5.158,198,2.165,207,1.878,214,2.994,221,3.64,247,3.374,261,2.362,273,5.371,277,3.374,290,4.484,323,2.575,324,2.575,326,1.754,379,3.23,385,2.518,404,1.814,431,3.455,457,3.869,458,3.64,461,4.684,463,2.722,465,3.105,544,3.165,607,1.798,618,2.418,678,2.645,713,4.008,831,3.165,843,4.364,844,4.608,850,4.934,851,4.934,852,4.364,853,4.934,854,4.364]],["tags/68",[]],["title/69",[473,2.352]],["content/69",[3,0.369,10,2.541,14,0.832,63,0.931,82,4.108,124,3.719,143,2.689,168,3.454,173,4.217,199,2.43,233,2.917,235,4.308,269,3.606,287,1.767,303,2.409,325,3.157,404,1.706,424,3.407,473,3.168,518,3.454,624,5.698,667,2.949,701,6.016,750,6.442,855,7.088,856,5.444]],["tags/69",[]],["title/70",[94,1.582,473,1.919]],["content/70",[3,0.256,7,1.452,11,3.557,63,0.904,84,3.861,87,2.993,94,2.331,104,1.667,122,3.655,143,3.699,160,3.667,176,1.913,199,3.027,236,5.147,240,1.777,243,2.715,265,3.793,269,3.499,286,2.512,325,3.932,404,2.124,453,3.553,504,3.793,712,4.377,857,6.878,858,6.251]],["tags/70",[]],["title/71",[227,3.914]],["content/71",[3,0.382,4,2.065,16,1.664,26,4.664,28,2.269,30,2.609,34,3.547,83,4.389,108,3.503,154,4.566,184,6.514,191,2.912,227,4.092,262,5.469,604,3.847,608,6.514,781,4.769,831,4.475,859,7.675,860,4.664]],["tags/71",[]],["title/72",[325,2.668,831,3.493]],["content/72",[3,0.312,7,1.766,14,0.838,63,1.099,325,3.727,355,4.535,404,2.013,445,2.259,542,6.177,545,3.114,607,2.772,861,8.367]],["tags/72",[]],["title/73",[94,1.582,424,2.879]],["content/73",[3,0.279,13,3.81,14,0.853,56,2.022,63,0.984,94,1.978,163,3.296,174,3.868,176,2.591,207,2.59,236,4.366,237,5.17,240,2.407,279,4.887,288,6.356,316,4.887,421,4.059,465,4.283,606,5.021,630,4.2,651,5.021]],["tags/73",[]],["title/74",[158,2.195,176,1.218,199,1.501,240,1.131]],["content/74",[3,0.266,4,1.56,19,2.94,28,2.112,30,2.428,31,3.144,32,2.493,48,4.545,76,3.634,83,4.085,158,4.533,169,2.585,171,2.738,172,2.307,173,4.25,176,1.987,199,3.101,240,1.846,269,3.634,303,2.428,518,3.481,584,4.341,593,6.491,606,4.789,667,2.972,862,3.808,863,7.143,864,7.143,865,6.491]],["tags/74",[]],["title/75",[56,1.182,121,1.515,130,1.95,605,2.415]],["content/75",[3,0.353,10,2.752,21,3.079,28,2.269,29,3.593,30,2.609,63,1.243,83,4.389,121,2.655,130,3.419,159,3.301,315,5.298,419,5.665,485,2.884,486,2.438,524,4.769,605,4.232,630,3.46,866,7.675]],["tags/75",[]],["title/76",[307,3.393]],["content/76",[3,0.273,4,1.597,28,2.714,29,3.423,30,2.485,50,3.613,63,0.961,83,4.181,124,3.836,126,3.009,168,3.563,307,4.636,484,2.575,534,3.563,700,4.35,756,5.211,757,5.398,775,6.645,776,6.645,798,3.72,867,6.775,868,7.312,869,6.645,870,6.206,871,6.645]],["tags/76",[]],["title/77",[287,1.261,355,2.742,445,1.366]],["content/77",[3,0.235,11,3.365,22,2.444,63,0.83,66,2.373,81,4.36,82,2.883,85,2.396,132,2.889,143,3.168,163,2.78,200,5.361,250,4.235,266,1.398,268,3.483,282,2.307,286,3.885,287,2.082,393,3.314,439,5.361,501,3.758,534,3.078,586,3.424,662,5.361,752,4.36,754,3.213,872,3.838,873,6.316,874,6.316,875,6.316,876,6.316,877,5.077,878,6.414,879,6.316,880,4.501,881,6.316,882,5.74,883,5.077,884,4.122]],["tags/77",[]],["title/78",[4,1.105,355,2.742,445,1.366]],["content/78",[3,0.354,4,2.281,81,4.482,104,1.573,143,2.463,250,4.353,286,3.464,287,2.722,355,3.519,395,4.627,417,4.482,445,2.894,604,3.255,650,2.701,651,4.353,732,5.219,754,3.303,870,5.511,878,6.532,885,4.482,886,5.901,887,5.901,888,6.493,889,6.493,890,6.493]],["tags/78",[]],["title/79",[148,1.198,227,3.193]],["content/79",[3,0.353,4,1.416,7,0.928,10,1.577,14,0.714,16,1.406,19,1.81,21,2.313,23,1.83,24,2.205,28,2.512,32,2.263,39,2.673,63,1.19,76,2.238,85,1.669,94,1.712,95,1.754,96,2.345,97,1.637,98,1.719,99,2.734,100,2.799,101,1.702,102,2.617,108,2.959,121,1.522,130,1.96,132,1.522,148,2.088,171,1.332,172,1.421,178,1.892,189,3.159,191,1.669,195,2.47,198,1.754,199,1.508,227,2.345,266,0.974,283,2.757,287,1.919,307,2.997,313,2.272,358,2.059,382,2.174,393,2.308,404,1.058,406,2.47,421,2.385,424,2.115,445,1.75,485,1.653,486,1.398,488,2.734,501,2.617,518,2.144,582,2.734,583,2.799,584,2.673,605,2.426,630,2.923,631,2.385,632,2.565,700,2.617,716,2.144,729,2.565,743,2.734,744,2.673,745,2.617,754,2.238,831,3.78,872,2.673,891,2.871]],["tags/79",[]],["title/80",[14,0.425,148,1.011,831,2.95]],["content/80",[3,0.353,4,1.416,7,0.928,10,1.577,14,0.714,16,1.406,19,1.81,21,2.313,23,1.83,24,2.205,28,2.512,32,2.263,39,2.673,63,1.19,76,2.238,85,1.669,94,1.712,95,1.754,96,2.345,97,1.637,98,1.719,99,2.734,100,2.799,101,1.702,102,2.617,108,2.959,121,1.522,130,1.96,132,1.522,148,2.088,171,1.332,172,1.421,178,1.892,189,3.159,191,1.669,195,2.47,198,1.754,199,1.508,227,2.345,266,0.974,283,2.757,287,1.919,307,2.997,313,2.272,358,2.059,382,2.174,393,2.308,404,1.058,406,2.47,421,2.385,424,2.115,445,1.75,485,1.653,486,1.398,488,2.734,501,2.617,518,2.144,582,2.734,583,2.799,584,2.673,605,2.426,630,2.923,631,2.385,632,2.565,700,2.617,716,2.144,729,2.565,743,2.734,744,2.673,745,2.617,754,2.238,831,3.78,872,2.673,891,2.871]],["tags/80",[]],["title/81",[148,1.011,287,1.261,445,1.366]],["content/81",[3,0.353,4,1.416,7,0.928,10,1.577,14,0.714,16,1.406,19,1.81,21,2.313,23,1.83,24,2.205,28,2.512,32,2.263,39,2.673,63,1.19,76,2.238,85,1.669,94,1.712,95,1.754,96,2.345,97,1.637,98,1.719,99,2.734,100,2.799,101,1.702,102,2.617,108,2.959,121,1.522,130,1.96,132,1.522,148,2.088,171,1.332,172,1.421,178,1.892,189,3.159,191,1.669,195,2.47,198,1.754,199,1.508,227,2.345,266,0.974,283,2.757,287,1.919,307,2.997,313,2.272,358,2.059,382,2.174,393,2.308,404,1.058,406,2.47,421,2.385,424,2.115,445,1.75,485,1.653,486,1.398,488,2.734,501,2.617,518,2.144,582,2.734,583,2.799,584,2.673,605,2.426,630,2.923,631,2.385,632,2.565,700,2.617,716,2.144,729,2.565,743,2.734,744,2.673,745,2.617,754,2.238,831,3.78,872,2.673,891,2.871]],["tags/81",[]],["title/82",[148,1.198,424,2.879]],["content/82",[3,0.353,4,1.416,7,0.928,10,1.577,14,0.714,16,1.406,19,1.81,21,2.313,23,1.83,24,2.205,28,2.512,32,2.263,39,2.673,63,1.19,76,2.238,85,1.669,94,1.712,95,1.754,96,2.345,97,1.637,98,1.719,99,2.734,100,2.799,101,1.702,102,2.617,108,2.959,121,1.522,130,1.96,132,1.522,148,2.088,171,1.332,172,1.421,178,1.892,189,3.159,191,1.669,195,2.47,198,1.754,199,1.508,227,2.345,266,0.974,283,2.757,287,1.919,307,2.997,313,2.272,358,2.059,382,2.174,393,2.308,404,1.058,406,2.47,421,2.385,424,2.115,445,1.75,485,1.653,486,1.398,488,2.734,501,2.617,518,2.144,582,2.734,583,2.799,584,2.673,605,2.426,630,2.923,631,2.385,632,2.565,700,2.617,716,2.144,729,2.565,743,2.734,744,2.673,745,2.617,754,2.238,831,3.78,872,2.673,891,2.871]],["tags/82",[]],["title/83",[94,1.582,148,1.198]],["content/83",[3,0.353,4,1.416,7,0.928,10,1.577,14,0.714,16,1.406,19,1.81,21,2.313,23,1.83,24,2.205,28,2.512,32,2.263,39,2.673,63,1.19,76,2.238,85,1.669,94,1.712,95,1.754,96,2.345,97,1.637,98,1.719,99,2.734,100,2.799,101,1.702,102,2.617,108,2.959,121,1.522,130,1.96,132,1.522,148,2.088,171,1.332,172,1.421,178,1.892,189,3.159,191,1.669,195,2.47,198,1.754,199,1.508,227,2.345,266,0.974,283,2.757,287,1.919,307,2.997,313,2.272,358,2.059,382,2.174,393,2.308,404,1.058,406,2.47,421,2.385,424,2.115,445,1.75,485,1.653,486,1.398,488,2.734,501,2.617,518,2.144,582,2.734,583,2.799,584,2.673,605,2.426,630,2.923,631,2.385,632,2.565,700,2.617,716,2.144,729,2.565,743,2.734,744,2.673,745,2.617,754,2.238,831,3.78,872,2.673,891,2.871]],["tags/83",[]],["title/84",[148,1.198,199,2.054]],["content/84",[3,0.353,4,1.416,7,0.928,10,1.577,14,0.714,16,1.406,19,1.81,21,2.313,23,1.83,24,2.205,28,2.512,32,2.263,39,2.673,63,1.19,76,2.238,85,1.669,94,1.712,95,1.754,96,2.345,97,1.637,98,1.719,99,2.734,100,2.799,101,1.702,102,2.617,108,2.959,121,1.522,130,1.96,132,1.522,148,2.088,171,1.332,172,1.421,178,1.892,189,3.159,191,1.669,195,2.47,198,1.754,199,1.508,227,2.345,266,0.974,283,2.757,287,1.919,307,2.997,313,2.272,358,2.059,382,2.174,393,2.308,404,1.058,406,2.47,421,2.385,424,2.115,445,1.75,485,1.653,486,1.398,488,2.734,501,2.617,518,2.144,582,2.734,583,2.799,584,2.673,605,2.426,630,2.923,631,2.385,632,2.565,700,2.617,716,2.144,729,2.565,743,2.734,744,2.673,745,2.617,754,2.238,831,3.78,872,2.673,891,2.871]],["tags/84",[]],["title/85",[121,1.515,130,1.95,148,0.875,605,2.415]],["content/85",[3,0.353,4,1.416,7,0.928,10,1.577,14,0.714,16,1.406,19,1.81,21,2.313,23,1.83,24,2.205,28,2.512,32,2.263,39,2.673,63,1.19,76,2.238,85,1.669,94,1.712,95,1.754,96,2.345,97,1.637,98,1.719,99,2.734,100,2.799,101,1.702,102,2.617,108,2.959,121,1.522,130,1.96,132,1.522,148,2.088,171,1.332,172,1.421,178,1.892,189,3.159,191,1.669,195,2.47,198,1.754,199,1.508,227,2.345,266,0.974,283,2.757,287,1.919,307,2.997,313,2.272,358,2.059,382,2.174,393,2.308,404,1.058,406,2.47,421,2.385,424,2.115,445,1.75,485,1.653,486,1.398,488,2.734,501,2.617,518,2.144,582,2.734,583,2.799,584,2.673,605,2.426,630,2.923,631,2.385,632,2.565,700,2.617,716,2.144,729,2.565,743,2.734,744,2.673,745,2.617,754,2.238,831,3.78,872,2.673,891,2.871]],["tags/85",[]],["title/86",[21,1.315,148,0.875,485,1.645,486,1.391]],["content/86",[3,0.353,4,1.416,7,0.928,10,1.577,14,0.714,16,1.406,19,1.81,21,2.313,23,1.83,24,2.205,28,2.512,32,2.263,39,2.673,63,1.19,76,2.238,85,1.669,94,1.712,95,1.754,96,2.345,97,1.637,98,1.719,99,2.734,100,2.799,101,1.702,102,2.617,108,2.959,121,1.522,130,1.96,132,1.522,148,2.088,171,1.332,172,1.421,178,1.892,189,3.159,191,1.669,195,2.47,198,1.754,199,1.508,227,2.345,266,0.974,283,2.757,287,1.919,307,2.997,313,2.272,358,2.059,382,2.174,393,2.308,404,1.058,406,2.47,421,2.385,424,2.115,445,1.75,485,1.653,486,1.398,488,2.734,501,2.617,518,2.144,582,2.734,583,2.799,584,2.673,605,2.426,630,2.923,631,2.385,632,2.565,700,2.617,716,2.144,729,2.565,743,2.734,744,2.673,745,2.617,754,2.238,831,3.78,872,2.673,891,2.871]],["tags/86",[]],["title/87",[148,1.198,630,2.701]],["content/87",[3,0.353,4,1.416,7,0.928,10,1.577,14,0.714,16,1.406,19,1.81,21,2.313,23,1.83,24,2.205,28,2.512,32,2.263,39,2.673,63,1.19,76,2.238,85,1.669,94,1.712,95,1.754,96,2.345,97,1.637,98,1.719,99,2.734,100,2.799,101,1.702,102,2.617,108,2.959,121,1.522,130,1.96,132,1.522,148,2.088,171,1.332,172,1.421,178,1.892,189,3.159,191,1.669,195,2.47,198,1.754,199,1.508,227,2.345,266,0.974,283,2.757,287,1.919,307,2.997,313,2.272,358,2.059,382,2.174,393,2.308,404,1.058,406,2.47,421,2.385,424,2.115,445,1.75,485,1.653,486,1.398,488,2.734,501,2.617,518,2.144,582,2.734,583,2.799,584,2.673,605,2.426,630,2.923,631,2.385,632,2.565,700,2.617,716,2.144,729,2.565,743,2.734,744,2.673,745,2.617,754,2.238,831,3.78,872,2.673,891,2.871]],["tags/87",[]],["title/88",[148,1.198,307,2.769]],["content/88",[3,0.353,4,1.416,7,0.928,10,1.577,14,0.714,16,1.406,19,1.81,21,2.313,23,1.83,24,2.205,28,2.512,32,2.263,39,2.673,63,1.19,76,2.238,85,1.669,94,1.712,95,1.754,96,2.345,97,1.637,98,1.719,99,2.734,100,2.799,101,1.702,102,2.617,108,2.959,121,1.522,130,1.96,132,1.522,148,2.088,171,1.332,172,1.421,178,1.892,189,3.159,191,1.669,195,2.47,198,1.754,199,1.508,227,2.345,266,0.974,283,2.757,287,1.919,307,2.997,313,2.272,358,2.059,382,2.174,393,2.308,404,1.058,406,2.47,421,2.385,424,2.115,445,1.75,485,1.653,486,1.398,488,2.734,501,2.617,518,2.144,582,2.734,583,2.799,584,2.673,605,2.426,630,2.923,631,2.385,632,2.565,700,2.617,716,2.144,729,2.565,743,2.734,744,2.673,745,2.617,754,2.238,831,3.78,872,2.673,891,2.871]],["tags/88",[]],["title/89",[4,1.105,28,1.496,148,1.011]],["content/89",[3,0.302,4,2.135,5,1.923,6,2.762,7,0.844,8,2.611,9,2.38,10,1.434,11,2.434,12,3.671,13,3.073,14,0.336,16,1.758,17,3.027,19,1.647,22,1.548,26,2.431,28,2.705,29,3.407,30,1.36,32,1.396,43,2.611,47,2.288,57,2.762,60,1.629,63,0.794,66,2.734,67,2.486,84,4.085,85,1.518,94,1.057,101,2.337,103,2.288,104,0.969,124,2.099,125,1.849,132,1.384,136,2.333,142,2.38,148,1.899,166,1.409,168,1.949,169,1.448,176,1.113,187,1.664,191,1.518,192,1.721,196,2.333,251,1.898,297,1.24,302,2.006,305,1.721,346,2.035,376,2.288,391,5.288,472,2.682,511,2.762,545,2.248,554,2.333,586,2.169,627,2.006,628,2.762,650,1.664,721,3.454,754,2.035,781,2.486,838,2.206,860,2.431,892,2.431,893,2.851,894,2.851,895,2.851,896,2.851,897,4.17,898,2.682,899,2.066,900,2.851,901,2.851,902,2.611,903,2.486,904,2.431,905,2.851,906,2.762,907,2.851,908,2.762,909,2.035,910,2.682,911,2.851,912,2.431,913,2.38]],["tags/89",[]],["title/90",[11,2.039,67,3.144,148,1.011]],["content/90",[3,0.302,4,2.135,5,1.923,6,2.762,7,0.844,8,2.611,9,2.38,10,1.434,11,2.434,12,3.671,13,3.073,14,0.336,16,1.758,17,3.027,19,1.647,22,1.548,26,2.431,28,2.705,29,3.407,30,1.36,32,1.396,43,2.611,47,2.288,57,2.762,60,1.629,63,0.794,66,2.734,67,2.486,84,4.085,85,1.518,94,1.057,101,2.337,103,2.288,104,0.969,124,2.099,125,1.849,132,1.384,136,2.333,142,2.38,148,1.899,166,1.409,168,1.949,169,1.448,176,1.113,187,1.664,191,1.518,192,1.721,196,2.333,251,1.898,297,1.24,302,2.006,305,1.721,346,2.035,376,2.288,391,5.288,472,2.682,511,2.762,545,2.248,554,2.333,586,2.169,627,2.006,628,2.762,650,1.664,721,3.454,754,2.035,781,2.486,838,2.206,860,2.431,892,2.431,893,2.851,894,2.851,895,2.851,896,2.851,897,4.17,898,2.682,899,2.066,900,2.851,901,2.851,902,2.611,903,2.486,904,2.431,905,2.851,906,2.762,907,2.851,908,2.762,909,2.035,910,2.682,911,2.851,912,2.431,913,2.38]],["tags/90",[]],["title/91",[66,1.901,148,1.011,860,3.075]],["content/91",[3,0.302,4,2.135,5,1.923,6,2.762,7,0.844,8,2.611,9,2.38,10,1.434,11,2.434,12,3.671,13,3.073,14,0.336,16,1.758,17,3.027,19,1.647,22,1.548,26,2.431,28,2.705,29,3.407,30,1.36,32,1.396,43,2.611,47,2.288,57,2.762,60,1.629,63,0.794,66,2.734,67,2.486,84,4.085,85,1.518,94,1.057,101,2.337,103,2.288,104,0.969,124,2.099,125,1.849,132,1.384,136,2.333,142,2.38,148,1.899,166,1.409,168,1.949,169,1.448,176,1.113,187,1.664,191,1.518,192,1.721,196,2.333,251,1.898,297,1.24,302,2.006,305,1.721,346,2.035,376,2.288,391,5.288,472,2.682,511,2.762,545,2.248,554,2.333,586,2.169,627,2.006,628,2.762,650,1.664,721,3.454,754,2.035,781,2.486,838,2.206,860,2.431,892,2.431,893,2.851,894,2.851,895,2.851,896,2.851,897,4.17,898,2.682,899,2.066,900,2.851,901,2.851,902,2.611,903,2.486,904,2.431,905,2.851,906,2.762,907,2.851,908,2.762,909,2.035,910,2.682,911,2.851,912,2.431,913,2.38]],["tags/91",[]],["title/92",[16,0.95,66,1.645,148,0.875,909,2.228]],["content/92",[3,0.302,4,2.135,5,1.923,6,2.762,7,0.844,8,2.611,9,2.38,10,1.434,11,2.434,12,3.671,13,3.073,14,0.336,16,1.758,17,3.027,19,1.647,22,1.548,26,2.431,28,2.705,29,3.407,30,1.36,32,1.396,43,2.611,47,2.288,57,2.762,60,1.629,63,0.794,66,2.734,67,2.486,84,4.085,85,1.518,94,1.057,101,2.337,103,2.288,104,0.969,124,2.099,125,1.849,132,1.384,136,2.333,142,2.38,148,1.899,166,1.409,168,1.949,169,1.448,176,1.113,187,1.664,191,1.518,192,1.721,196,2.333,251,1.898,297,1.24,302,2.006,305,1.721,346,2.035,376,2.288,391,5.288,472,2.682,511,2.762,545,2.248,554,2.333,586,2.169,627,2.006,628,2.762,650,1.664,721,3.454,754,2.035,781,2.486,838,2.206,860,2.431,892,2.431,893,2.851,894,2.851,895,2.851,896,2.851,897,4.17,898,2.682,899,2.066,900,2.851,901,2.851,902,2.611,903,2.486,904,2.431,905,2.851,906,2.762,907,2.851,908,2.762,909,2.035,910,2.682,911,2.851,912,2.431,913,2.38]],["tags/92",[]],["title/93",[85,2.272,148,1.198]],["content/93",[3,0.302,4,2.135,5,1.923,6,2.762,7,0.844,8,2.611,9,2.38,10,1.434,11,2.434,12,3.671,13,3.073,14,0.336,16,1.758,17,3.027,19,1.647,22,1.548,26,2.431,28,2.705,29,3.407,30,1.36,32,1.396,43,2.611,47,2.288,57,2.762,60,1.629,63,0.794,66,2.734,67,2.486,84,4.085,85,1.518,94,1.057,101,2.337,103,2.288,104,0.969,124,2.099,125,1.849,132,1.384,136,2.333,142,2.38,148,1.899,166,1.409,168,1.949,169,1.448,176,1.113,187,1.664,191,1.518,192,1.721,196,2.333,251,1.898,297,1.24,302,2.006,305,1.721,346,2.035,376,2.288,391,5.288,472,2.682,511,2.762,545,2.248,554,2.333,586,2.169,627,2.006,628,2.762,650,1.664,721,3.454,754,2.035,781,2.486,838,2.206,860,2.431,892,2.431,893,2.851,894,2.851,895,2.851,896,2.851,897,4.17,898,2.682,899,2.066,900,2.851,901,2.851,902,2.611,903,2.486,904,2.431,905,2.851,906,2.762,907,2.851,908,2.762,909,2.035,910,2.682,911,2.851,912,2.431,913,2.38]],["tags/93",[]],["title/94",[148,1.198,913,3.564]],["content/94",[3,0.302,4,2.135,5,1.923,6,2.762,7,0.844,8,2.611,9,2.38,10,1.434,11,2.434,12,3.671,13,3.073,14,0.336,16,1.758,17,3.027,19,1.647,22,1.548,26,2.431,28,2.705,29,3.407,30,1.36,32,1.396,43,2.611,47,2.288,57,2.762,60,1.629,63,0.794,66,2.734,67,2.486,84,4.085,85,1.518,94,1.057,101,2.337,103,2.288,104,0.969,124,2.099,125,1.849,132,1.384,136,2.333,142,2.38,148,1.899,166,1.409,168,1.949,169,1.448,176,1.113,187,1.664,191,1.518,192,1.721,196,2.333,251,1.898,297,1.24,302,2.006,305,1.721,346,2.035,376,2.288,391,5.288,472,2.682,511,2.762,545,2.248,554,2.333,586,2.169,627,2.006,628,2.762,650,1.664,721,3.454,754,2.035,781,2.486,838,2.206,860,2.431,892,2.431,893,2.851,894,2.851,895,2.851,896,2.851,897,4.17,898,2.682,899,2.066,900,2.851,901,2.851,902,2.611,903,2.486,904,2.431,905,2.851,906,2.762,907,2.851,908,2.762,909,2.035,910,2.682,911,2.851,912,2.431,913,2.38]],["tags/94",[]],["title/95",[148,1.198,607,1.984]],["content/95",[3,0.354,7,1.042,13,2.512,14,0.691,16,1.945,30,1.678,36,2.226,49,3.587,56,1.333,63,0.649,82,3.753,98,1.929,104,1.196,112,3.409,148,1.896,171,1.495,172,1.595,182,1.929,192,2.124,197,3.001,207,1.708,246,2.173,266,1.561,282,2.575,297,1.531,303,1.678,318,1.91,329,1.636,330,1.678,331,2.011,332,2.342,347,2.342,349,1.569,350,3.222,379,2.938,382,2.44,401,2.938,404,1.188,437,2.632,445,1.333,449,2.965,505,1.892,509,1.91,545,2.624,607,2.335,691,4.284,695,3.435,845,1.333,912,3.001,914,3.409,915,3.222,916,3.519,917,3.069,918,3.519,919,2.59,920,2.879,921,4.601,922,3.31,923,3.31,924,2.44,925,3.519,926,3.519,927,3.31,928,2.938,929,2.824,930,3.31]],["tags/95",[]],["title/96",[16,0.95,82,1.999,148,0.875,282,1.599]],["content/96",[3,0.354,7,1.042,13,2.512,14,0.691,16,1.945,30,1.678,36,2.226,49,3.587,56,1.333,63,0.649,82,3.753,98,1.929,104,1.196,112,3.409,148,1.896,171,1.495,172,1.595,182,1.929,192,2.124,197,3.001,207,1.708,246,2.173,266,1.561,282,2.575,297,1.531,303,1.678,318,1.91,329,1.636,330,1.678,331,2.011,332,2.342,347,2.342,349,1.569,350,3.222,379,2.938,382,2.44,401,2.938,404,1.188,437,2.632,445,1.333,449,2.965,505,1.892,509,1.91,545,2.624,607,2.335,691,4.284,695,3.435,845,1.333,912,3.001,914,3.409,915,3.222,916,3.519,917,3.069,918,3.519,919,2.59,920,2.879,921,4.601,922,3.31,923,3.31,924,2.44,925,3.519,926,3.519,927,3.31,928,2.938,929,2.824,930,3.31]],["tags/96",[]],["title/97",[82,1.999,148,0.875,282,1.599,695,2.134]],["content/97",[3,0.354,7,1.042,13,2.512,14,0.691,16,1.945,30,1.678,36,2.226,49,3.587,56,1.333,63,0.649,82,3.753,98,1.929,104,1.196,112,3.409,148,1.896,171,1.495,172,1.595,182,1.929,192,2.124,197,3.001,207,1.708,246,2.173,266,1.561,282,2.575,297,1.531,303,1.678,318,1.91,329,1.636,330,1.678,331,2.011,332,2.342,347,2.342,349,1.569,350,3.222,379,2.938,382,2.44,401,2.938,404,1.188,437,2.632,445,1.333,449,2.965,505,1.892,509,1.91,545,2.624,607,2.335,691,4.284,695,3.435,845,1.333,912,3.001,914,3.409,915,3.222,916,3.519,917,3.069,918,3.519,919,2.59,920,2.879,921,4.601,922,3.31,923,3.31,924,2.44,925,3.519,926,3.519,927,3.31,928,2.938,929,2.824,930,3.31]],["tags/97",[]],["title/98",[16,1.097,148,1.011,921,3.302]],["content/98",[3,0.354,7,1.042,13,2.512,14,0.691,16,1.945,30,1.678,36,2.226,49,3.587,56,1.333,63,0.649,82,3.753,98,1.929,104,1.196,112,3.409,148,1.896,171,1.495,172,1.595,182,1.929,192,2.124,197,3.001,207,1.708,246,2.173,266,1.561,282,2.575,297,1.531,303,1.678,318,1.91,329,1.636,330,1.678,331,2.011,332,2.342,347,2.342,349,1.569,350,3.222,379,2.938,382,2.44,401,2.938,404,1.188,437,2.632,445,1.333,449,2.965,505,1.892,509,1.91,545,2.624,607,2.335,691,4.284,695,3.435,845,1.333,912,3.001,914,3.409,915,3.222,916,3.519,917,3.069,918,3.519,919,2.59,920,2.879,921,4.601,922,3.31,923,3.31,924,2.44,925,3.519,926,3.519,927,3.31,928,2.938,929,2.824,930,3.31]],["tags/98",[]],["title/99",[148,1.198,449,2.519]],["content/99",[3,0.354,7,1.042,13,2.512,14,0.691,16,1.945,30,1.678,36,2.226,49,3.587,56,1.333,63,0.649,82,3.753,98,1.929,104,1.196,112,3.409,148,1.896,171,1.495,172,1.595,182,1.929,192,2.124,197,3.001,207,1.708,246,2.173,266,1.561,282,2.575,297,1.531,303,1.678,318,1.91,329,1.636,330,1.678,331,2.011,332,2.342,347,2.342,349,1.569,350,3.222,379,2.938,382,2.44,401,2.938,404,1.188,437,2.632,445,1.333,449,2.965,505,1.892,509,1.91,545,2.624,607,2.335,691,4.284,695,3.435,845,1.333,912,3.001,914,3.409,915,3.222,916,3.519,917,3.069,918,3.519,919,2.59,920,2.879,921,4.601,922,3.31,923,3.31,924,2.44,925,3.519,926,3.519,927,3.31,928,2.938,929,2.824,930,3.31]],["tags/99",[]],["title/100",[148,1.198,404,1.441]],["content/100",[2,2.676,3,0.339,5,2.452,11,2.055,14,0.429,16,1.106,17,2.122,30,1.734,56,1.948,63,1.1,95,2.877,96,2.719,98,1.993,118,2.245,125,2.357,138,1.177,148,1.819,159,3.103,160,2.719,164,2.452,172,2.33,215,2.974,238,3.17,263,2.485,266,1.129,286,1.863,302,2.557,303,1.734,305,2.194,307,2.357,314,3.035,324,2.419,404,1.736,452,2.328,486,1.621,504,3.979,514,2.66,627,3.617,686,3.246,694,3.377,712,3.246,752,4.98,763,2.791,845,1.948,885,3.521,904,3.1,931,3.635,932,3.917,933,5.326,934,3.521,935,5.836,936,4.484,937,3.917,938,3.917,939,3.765,940,3.329,941,3.521,942,3.917]],["tags/100",[]],["title/101",[138,1.167,148,1.011,694,2.368]],["content/101",[2,2.676,3,0.339,5,2.452,11,2.055,14,0.429,16,1.106,17,2.122,30,1.734,56,1.948,63,1.1,95,2.877,96,2.719,98,1.993,118,2.245,125,2.357,138,1.177,148,1.819,159,3.103,160,2.719,164,2.452,172,2.33,215,2.974,238,3.17,263,2.485,266,1.129,286,1.863,302,2.557,303,1.734,305,2.194,307,2.357,314,3.035,324,2.419,404,1.736,452,2.328,486,1.621,504,3.979,514,2.66,627,3.617,686,3.246,694,3.377,712,3.246,752,4.98,763,2.791,845,1.948,885,3.521,904,3.1,931,3.635,932,3.917,933,5.326,934,3.521,935,5.836,936,4.484,937,3.917,938,3.917,939,3.765,940,3.329,941,3.521,942,3.917]],["tags/101",[]],["title/102",[148,1.011,686,3.219,845,1.366]],["content/102",[2,2.676,3,0.339,5,2.452,11,2.055,14,0.429,16,1.106,17,2.122,30,1.734,56,1.948,63,1.1,95,2.877,96,2.719,98,1.993,118,2.245,125,2.357,138,1.177,148,1.819,159,3.103,160,2.719,164,2.452,172,2.33,215,2.974,238,3.17,263,2.485,266,1.129,286,1.863,302,2.557,303,1.734,305,2.194,307,2.357,314,3.035,324,2.419,404,1.736,452,2.328,486,1.621,504,3.979,514,2.66,627,3.617,686,3.246,694,3.377,712,3.246,752,4.98,763,2.791,845,1.948,885,3.521,904,3.1,931,3.635,932,3.917,933,5.326,934,3.521,935,5.836,936,4.484,937,3.917,938,3.917,939,3.765,940,3.329,941,3.521,942,3.917]],["tags/102",[]],["title/103",[148,1.011,935,3.075,936,3.144]],["content/103",[2,2.676,3,0.339,5,2.452,11,2.055,14,0.429,16,1.106,17,2.122,30,1.734,56,1.948,63,1.1,95,2.877,96,2.719,98,1.993,118,2.245,125,2.357,138,1.177,148,1.819,159,3.103,160,2.719,164,2.452,172,2.33,215,2.974,238,3.17,263,2.485,266,1.129,286,1.863,302,2.557,303,1.734,305,2.194,307,2.357,314,3.035,324,2.419,404,1.736,452,2.328,486,1.621,504,3.979,514,2.66,627,3.617,686,3.246,694,3.377,712,3.246,752,4.98,763,2.791,845,1.948,885,3.521,904,3.1,931,3.635,932,3.917,933,5.326,934,3.521,935,5.836,936,4.484,937,3.917,938,3.917,939,3.765,940,3.329,941,3.521,942,3.917]],["tags/103",[]],["title/104",[148,1.011,176,1.407,404,1.217]],["content/104",[3,0.36,4,1.071,7,1.481,14,0.828,16,0.664,21,0.92,22,1.898,28,0.906,31,1.348,56,1.657,60,1.247,63,0.806,66,1.843,80,1.032,87,1.333,92,1.66,94,0.809,95,2.799,97,1.14,104,0.742,117,1.288,118,1.348,126,2.888,132,1.059,138,1.132,148,2.072,159,1.317,161,1.088,162,1.261,169,1.775,176,1.707,183,1.582,207,1.059,217,1.558,224,1.558,240,0.791,243,2.77,261,3.053,266,1.086,282,1.119,286,1.119,292,1.14,297,0.95,299,1.221,303,1.041,304,2.391,318,1.898,323,1.453,329,1.015,383,2.239,404,0.737,445,0.827,452,1.398,473,1.966,485,1.843,486,1.559,489,2.033,498,1.582,505,1.173,509,1.185,539,3.42,546,1.398,547,1.535,576,1.492,579,1.633,580,1.129,581,1.514,604,1.535,607,1.625,616,1.535,618,1.364,667,1.274,668,1.607,669,1.607,675,3.742,678,3.42,706,1.333,711,1.472,740,1.66,798,1.558,802,1.317,830,1.633,836,1.303,845,1.657,924,1.514,943,3.682,944,3.741,945,3.741,946,2.297,947,1.689,948,1.719,949,1.66,950,1.472,951,1.633,952,1.607,953,2.534,954,1.398,955,1.66,956,1.689,957,1.607,958,1.719,959,1.719,960,1.689,961,1.633,962,1.317,963,1.558,964,1.514,965,1.719,966,1.607]],["tags/104",[]],["title/105",[14,0.425,138,1.167,148,1.011]],["content/105",[3,0.36,4,1.071,7,1.481,14,0.828,16,0.664,21,0.92,22,1.898,28,0.906,31,1.348,56,1.657,60,1.247,63,0.806,66,1.843,80,1.032,87,1.333,92,1.66,94,0.809,95,2.799,97,1.14,104,0.742,117,1.288,118,1.348,126,2.888,132,1.059,138,1.132,148,2.072,159,1.317,161,1.088,162,1.261,169,1.775,176,1.707,183,1.582,207,1.059,217,1.558,224,1.558,240,0.791,243,2.77,261,3.053,266,1.086,282,1.119,286,1.119,292,1.14,297,0.95,299,1.221,303,1.041,304,2.391,318,1.898,323,1.453,329,1.015,383,2.239,404,0.737,445,0.827,452,1.398,473,1.966,485,1.843,486,1.559,489,2.033,498,1.582,505,1.173,509,1.185,539,3.42,546,1.398,547,1.535,576,1.492,579,1.633,580,1.129,581,1.514,604,1.535,607,1.625,616,1.535,618,1.364,667,1.274,668,1.607,669,1.607,675,3.742,678,3.42,706,1.333,711,1.472,740,1.66,798,1.558,802,1.317,830,1.633,836,1.303,845,1.657,924,1.514,943,3.682,944,3.741,945,3.741,946,2.297,947,1.689,948,1.719,949,1.66,950,1.472,951,1.633,952,1.607,953,2.534,954,1.398,955,1.66,956,1.689,957,1.607,958,1.719,959,1.719,960,1.689,961,1.633,962,1.317,963,1.558,964,1.514,965,1.719,966,1.607]],["tags/105",[]],["title/106",[14,0.425,148,1.011,266,1.12]],["content/106",[3,0.36,4,1.071,7,1.481,14,0.828,16,0.664,21,0.92,22,1.898,28,0.906,31,1.348,56,1.657,60,1.247,63,0.806,66,1.843,80,1.032,87,1.333,92,1.66,94,0.809,95,2.799,97,1.14,104,0.742,117,1.288,118,1.348,126,2.888,132,1.059,138,1.132,148,2.072,159,1.317,161,1.088,162,1.261,169,1.775,176,1.707,183,1.582,207,1.059,217,1.558,224,1.558,240,0.791,243,2.77,261,3.053,266,1.086,282,1.119,286,1.119,292,1.14,297,0.95,299,1.221,303,1.041,304,2.391,318,1.898,323,1.453,329,1.015,383,2.239,404,0.737,445,0.827,452,1.398,473,1.966,485,1.843,486,1.559,489,2.033,498,1.582,505,1.173,509,1.185,539,3.42,546,1.398,547,1.535,576,1.492,579,1.633,580,1.129,581,1.514,604,1.535,607,1.625,616,1.535,618,1.364,667,1.274,668,1.607,669,1.607,675,3.742,678,3.42,706,1.333,711,1.472,740,1.66,798,1.558,802,1.317,830,1.633,836,1.303,845,1.657,924,1.514,943,3.682,944,3.741,945,3.741,946,2.297,947,1.689,948,1.719,949,1.66,950,1.472,951,1.633,952,1.607,953,2.534,954,1.398,955,1.66,956,1.689,957,1.607,958,1.719,959,1.719,960,1.689,961,1.633,962,1.317,963,1.558,964,1.514,965,1.719,966,1.607]],["tags/106",[]],["title/107",[14,0.425,148,1.011,946,2.368]],["content/107",[3,0.36,4,1.071,7,1.481,14,0.828,16,0.664,21,0.92,22,1.898,28,0.906,31,1.348,56,1.657,60,1.247,63,0.806,66,1.843,80,1.032,87,1.333,92,1.66,94,0.809,95,2.799,97,1.14,104,0.742,117,1.288,118,1.348,126,2.888,132,1.059,138,1.132,148,2.072,159,1.317,161,1.088,162,1.261,169,1.775,176,1.707,183,1.582,207,1.059,217,1.558,224,1.558,240,0.791,243,2.77,261,3.053,266,1.086,282,1.119,286,1.119,292,1.14,297,0.95,299,1.221,303,1.041,304,2.391,318,1.898,323,1.453,329,1.015,383,2.239,404,0.737,445,0.827,452,1.398,473,1.966,485,1.843,486,1.559,489,2.033,498,1.582,505,1.173,509,1.185,539,3.42,546,1.398,547,1.535,576,1.492,579,1.633,580,1.129,581,1.514,604,1.535,607,1.625,616,1.535,618,1.364,667,1.274,668,1.607,669,1.607,675,3.742,678,3.42,706,1.333,711,1.472,740,1.66,798,1.558,802,1.317,830,1.633,836,1.303,845,1.657,924,1.514,943,3.682,944,3.741,945,3.741,946,2.297,947,1.689,948,1.719,949,1.66,950,1.472,951,1.633,952,1.607,953,2.534,954,1.398,955,1.66,956,1.689,957,1.607,958,1.719,959,1.719,960,1.689,961,1.633,962,1.317,963,1.558,964,1.514,965,1.719,966,1.607]],["tags/107",[]],["title/108",[14,0.425,148,1.011,473,1.621]],["content/108",[3,0.36,4,1.071,7,1.481,14,0.828,16,0.664,21,0.92,22,1.898,28,0.906,31,1.348,56,1.657,60,1.247,63,0.806,66,1.843,80,1.032,87,1.333,92,1.66,94,0.809,95,2.799,97,1.14,104,0.742,117,1.288,118,1.348,126,2.888,132,1.059,138,1.132,148,2.072,159,1.317,161,1.088,162,1.261,169,1.775,176,1.707,183,1.582,207,1.059,217,1.558,224,1.558,240,0.791,243,2.77,261,3.053,266,1.086,282,1.119,286,1.119,292,1.14,297,0.95,299,1.221,303,1.041,304,2.391,318,1.898,323,1.453,329,1.015,383,2.239,404,0.737,445,0.827,452,1.398,473,1.966,485,1.843,486,1.559,489,2.033,498,1.582,505,1.173,509,1.185,539,3.42,546,1.398,547,1.535,576,1.492,579,1.633,580,1.129,581,1.514,604,1.535,607,1.625,616,1.535,618,1.364,667,1.274,668,1.607,669,1.607,675,3.742,678,3.42,706,1.333,711,1.472,740,1.66,798,1.558,802,1.317,830,1.633,836,1.303,845,1.657,924,1.514,943,3.682,944,3.741,945,3.741,946,2.297,947,1.689,948,1.719,949,1.66,950,1.472,951,1.633,952,1.607,953,2.534,954,1.398,955,1.66,956,1.689,957,1.607,958,1.719,959,1.719,960,1.689,961,1.633,962,1.317,963,1.558,964,1.514,965,1.719,966,1.607]],["tags/108",[]],["title/109",[148,1.011,383,2.309,489,1.676]],["content/109",[3,0.36,4,1.071,7,1.481,14,0.828,16,0.664,21,0.92,22,1.898,28,0.906,31,1.348,56,1.657,60,1.247,63,0.806,66,1.843,80,1.032,87,1.333,92,1.66,94,0.809,95,2.799,97,1.14,104,0.742,117,1.288,118,1.348,126,2.888,132,1.059,138,1.132,148,2.072,159,1.317,161,1.088,162,1.261,169,1.775,176,1.707,183,1.582,207,1.059,217,1.558,224,1.558,240,0.791,243,2.77,261,3.053,266,1.086,282,1.119,286,1.119,292,1.14,297,0.95,299,1.221,303,1.041,304,2.391,318,1.898,323,1.453,329,1.015,383,2.239,404,0.737,445,0.827,452,1.398,473,1.966,485,1.843,486,1.559,489,2.033,498,1.582,505,1.173,509,1.185,539,3.42,546,1.398,547,1.535,576,1.492,579,1.633,580,1.129,581,1.514,604,1.535,607,1.625,616,1.535,618,1.364,667,1.274,668,1.607,669,1.607,675,3.742,678,3.42,706,1.333,711,1.472,740,1.66,798,1.558,802,1.317,830,1.633,836,1.303,845,1.657,924,1.514,943,3.682,944,3.741,945,3.741,946,2.297,947,1.689,948,1.719,949,1.66,950,1.472,951,1.633,952,1.607,953,2.534,954,1.398,955,1.66,956,1.689,957,1.607,958,1.719,959,1.719,960,1.689,961,1.633,962,1.317,963,1.558,964,1.514,965,1.719,966,1.607]],["tags/109",[]],["title/110",[56,1.182,148,0.875,607,1.45,953,2.262]],["content/110",[3,0.36,4,1.071,7,1.481,14,0.828,16,0.664,21,0.92,22,1.898,28,0.906,31,1.348,56,1.657,60,1.247,63,0.806,66,1.843,80,1.032,87,1.333,92,1.66,94,0.809,95,2.799,97,1.14,104,0.742,117,1.288,118,1.348,126,2.888,132,1.059,138,1.132,148,2.072,159,1.317,161,1.088,162,1.261,169,1.775,176,1.707,183,1.582,207,1.059,217,1.558,224,1.558,240,0.791,243,2.77,261,3.053,266,1.086,282,1.119,286,1.119,292,1.14,297,0.95,299,1.221,303,1.041,304,2.391,318,1.898,323,1.453,329,1.015,383,2.239,404,0.737,445,0.827,452,1.398,473,1.966,485,1.843,486,1.559,489,2.033,498,1.582,505,1.173,509,1.185,539,3.42,546,1.398,547,1.535,576,1.492,579,1.633,580,1.129,581,1.514,604,1.535,607,1.625,616,1.535,618,1.364,667,1.274,668,1.607,669,1.607,675,3.742,678,3.42,706,1.333,711,1.472,740,1.66,798,1.558,802,1.317,830,1.633,836,1.303,845,1.657,924,1.514,943,3.682,944,3.741,945,3.741,946,2.297,947,1.689,948,1.719,949,1.66,950,1.472,951,1.633,952,1.607,953,2.534,954,1.398,955,1.66,956,1.689,957,1.607,958,1.719,959,1.719,960,1.689,961,1.633,962,1.317,963,1.558,964,1.514,965,1.719,966,1.607]],["tags/110",[]],["title/111",[148,1.011,581,2.5,607,1.676]],["content/111",[3,0.36,4,1.071,7,1.481,14,0.828,16,0.664,21,0.92,22,1.898,28,0.906,31,1.348,56,1.657,60,1.247,63,0.806,66,1.843,80,1.032,87,1.333,92,1.66,94,0.809,95,2.799,97,1.14,104,0.742,117,1.288,118,1.348,126,2.888,132,1.059,138,1.132,148,2.072,159,1.317,161,1.088,162,1.261,169,1.775,176,1.707,183,1.582,207,1.059,217,1.558,224,1.558,240,0.791,243,2.77,261,3.053,266,1.086,282,1.119,286,1.119,292,1.14,297,0.95,299,1.221,303,1.041,304,2.391,318,1.898,323,1.453,329,1.015,383,2.239,404,0.737,445,0.827,452,1.398,473,1.966,485,1.843,486,1.559,489,2.033,498,1.582,505,1.173,509,1.185,539,3.42,546,1.398,547,1.535,576,1.492,579,1.633,580,1.129,581,1.514,604,1.535,607,1.625,616,1.535,618,1.364,667,1.274,668,1.607,669,1.607,675,3.742,678,3.42,706,1.333,711,1.472,740,1.66,798,1.558,802,1.317,830,1.633,836,1.303,845,1.657,924,1.514,943,3.682,944,3.741,945,3.741,946,2.297,947,1.689,948,1.719,949,1.66,950,1.472,951,1.633,952,1.607,953,2.534,954,1.398,955,1.66,956,1.689,957,1.607,958,1.719,959,1.719,960,1.689,961,1.633,962,1.317,963,1.558,964,1.514,965,1.719,966,1.607]],["tags/111",[]],["title/112",[14,0.425,148,1.011,802,2.176]],["content/112",[3,0.36,4,1.071,7,1.481,14,0.828,16,0.664,21,0.92,22,1.898,28,0.906,31,1.348,56,1.657,60,1.247,63,0.806,66,1.843,80,1.032,87,1.333,92,1.66,94,0.809,95,2.799,97,1.14,104,0.742,117,1.288,118,1.348,126,2.888,132,1.059,138,1.132,148,2.072,159,1.317,161,1.088,162,1.261,169,1.775,176,1.707,183,1.582,207,1.059,217,1.558,224,1.558,240,0.791,243,2.77,261,3.053,266,1.086,282,1.119,286,1.119,292,1.14,297,0.95,299,1.221,303,1.041,304,2.391,318,1.898,323,1.453,329,1.015,383,2.239,404,0.737,445,0.827,452,1.398,473,1.966,485,1.843,486,1.559,489,2.033,498,1.582,505,1.173,509,1.185,539,3.42,546,1.398,547,1.535,576,1.492,579,1.633,580,1.129,581,1.514,604,1.535,607,1.625,616,1.535,618,1.364,667,1.274,668,1.607,669,1.607,675,3.742,678,3.42,706,1.333,711,1.472,740,1.66,798,1.558,802,1.317,830,1.633,836,1.303,845,1.657,924,1.514,943,3.682,944,3.741,945,3.741,946,2.297,947,1.689,948,1.719,949,1.66,950,1.472,951,1.633,952,1.607,953,2.534,954,1.398,955,1.66,956,1.689,957,1.607,958,1.719,959,1.719,960,1.689,961,1.633,962,1.317,963,1.558,964,1.514,965,1.719,966,1.607]],["tags/112",[]],["title/113",[14,0.425,148,1.011,618,2.254]],["content/113",[3,0.36,4,1.071,7,1.481,14,0.828,16,0.664,21,0.92,22,1.898,28,0.906,31,1.348,56,1.657,60,1.247,63,0.806,66,1.843,80,1.032,87,1.333,92,1.66,94,0.809,95,2.799,97,1.14,104,0.742,117,1.288,118,1.348,126,2.888,132,1.059,138,1.132,148,2.072,159,1.317,161,1.088,162,1.261,169,1.775,176,1.707,183,1.582,207,1.059,217,1.558,224,1.558,240,0.791,243,2.77,261,3.053,266,1.086,282,1.119,286,1.119,292,1.14,297,0.95,299,1.221,303,1.041,304,2.391,318,1.898,323,1.453,329,1.015,383,2.239,404,0.737,445,0.827,452,1.398,473,1.966,485,1.843,486,1.559,489,2.033,498,1.582,505,1.173,509,1.185,539,3.42,546,1.398,547,1.535,576,1.492,579,1.633,580,1.129,581,1.514,604,1.535,607,1.625,616,1.535,618,1.364,667,1.274,668,1.607,669,1.607,675,3.742,678,3.42,706,1.333,711,1.472,740,1.66,798,1.558,802,1.317,830,1.633,836,1.303,845,1.657,924,1.514,943,3.682,944,3.741,945,3.741,946,2.297,947,1.689,948,1.719,949,1.66,950,1.472,951,1.633,952,1.607,953,2.534,954,1.398,955,1.66,956,1.689,957,1.607,958,1.719,959,1.719,960,1.689,961,1.633,962,1.317,963,1.558,964,1.514,965,1.719,966,1.607]],["tags/113",[]],["title/114",[14,0.425,148,1.011,176,1.407]],["content/114",[3,0.36,4,1.071,7,1.481,14,0.828,16,0.664,21,0.92,22,1.898,28,0.906,31,1.348,56,1.657,60,1.247,63,0.806,66,1.843,80,1.032,87,1.333,92,1.66,94,0.809,95,2.799,97,1.14,104,0.742,117,1.288,118,1.348,126,2.888,132,1.059,138,1.132,148,2.072,159,1.317,161,1.088,162,1.261,169,1.775,176,1.707,183,1.582,207,1.059,217,1.558,224,1.558,240,0.791,243,2.77,261,3.053,266,1.086,282,1.119,286,1.119,292,1.14,297,0.95,299,1.221,303,1.041,304,2.391,318,1.898,323,1.453,329,1.015,383,2.239,404,0.737,445,0.827,452,1.398,473,1.966,485,1.843,486,1.559,489,2.033,498,1.582,505,1.173,509,1.185,539,3.42,546,1.398,547,1.535,576,1.492,579,1.633,580,1.129,581,1.514,604,1.535,607,1.625,616,1.535,618,1.364,667,1.274,668,1.607,669,1.607,675,3.742,678,3.42,706,1.333,711,1.472,740,1.66,798,1.558,802,1.317,830,1.633,836,1.303,845,1.657,924,1.514,943,3.682,944,3.741,945,3.741,946,2.297,947,1.689,948,1.719,949,1.66,950,1.472,951,1.633,952,1.607,953,2.534,954,1.398,955,1.66,956,1.689,957,1.607,958,1.719,959,1.719,960,1.689,961,1.633,962,1.317,963,1.558,964,1.514,965,1.719,966,1.607]],["tags/114",[]],["title/115",[63,0.575,148,0.875,485,1.645,486,1.391]],["content/115",[3,0.36,4,1.071,7,1.481,14,0.828,16,0.664,21,0.92,22,1.898,28,0.906,31,1.348,56,1.657,60,1.247,63,0.806,66,1.843,80,1.032,87,1.333,92,1.66,94,0.809,95,2.799,97,1.14,104,0.742,117,1.288,118,1.348,126,2.888,132,1.059,138,1.132,148,2.072,159,1.317,161,1.088,162,1.261,169,1.775,176,1.707,183,1.582,207,1.059,217,1.558,224,1.558,240,0.791,243,2.77,261,3.053,266,1.086,282,1.119,286,1.119,292,1.14,297,0.95,299,1.221,303,1.041,304,2.391,318,1.898,323,1.453,329,1.015,383,2.239,404,0.737,445,0.827,452,1.398,473,1.966,485,1.843,486,1.559,489,2.033,498,1.582,505,1.173,509,1.185,539,3.42,546,1.398,547,1.535,576,1.492,579,1.633,580,1.129,581,1.514,604,1.535,607,1.625,616,1.535,618,1.364,667,1.274,668,1.607,669,1.607,675,3.742,678,3.42,706,1.333,711,1.472,740,1.66,798,1.558,802,1.317,830,1.633,836,1.303,845,1.657,924,1.514,943,3.682,944,3.741,945,3.741,946,2.297,947,1.689,948,1.719,949,1.66,950,1.472,951,1.633,952,1.607,953,2.534,954,1.398,955,1.66,956,1.689,957,1.607,958,1.719,959,1.719,960,1.689,961,1.633,962,1.317,963,1.558,964,1.514,965,1.719,966,1.607]],["tags/115",[]],["title/116",[7,0.924,63,0.575,148,0.875,845,1.182]],["content/116",[3,0.36,4,1.071,7,1.481,14,0.828,16,0.664,21,0.92,22,1.898,28,0.906,31,1.348,56,1.657,60,1.247,63,0.806,66,1.843,80,1.032,87,1.333,92,1.66,94,0.809,95,2.799,97,1.14,104,0.742,117,1.288,118,1.348,126,2.888,132,1.059,138,1.132,148,2.072,159,1.317,161,1.088,162,1.261,169,1.775,176,1.707,183,1.582,207,1.059,217,1.558,224,1.558,240,0.791,243,2.77,261,3.053,266,1.086,282,1.119,286,1.119,292,1.14,297,0.95,299,1.221,303,1.041,304,2.391,318,1.898,323,1.453,329,1.015,383,2.239,404,0.737,445,0.827,452,1.398,473,1.966,485,1.843,486,1.559,489,2.033,498,1.582,505,1.173,509,1.185,539,3.42,546,1.398,547,1.535,576,1.492,579,1.633,580,1.129,581,1.514,604,1.535,607,1.625,616,1.535,618,1.364,667,1.274,668,1.607,669,1.607,675,3.742,678,3.42,706,1.333,711,1.472,740,1.66,798,1.558,802,1.317,830,1.633,836,1.303,845,1.657,924,1.514,943,3.682,944,3.741,945,3.741,946,2.297,947,1.689,948,1.719,949,1.66,950,1.472,951,1.633,952,1.607,953,2.534,954,1.398,955,1.66,956,1.689,957,1.607,958,1.719,959,1.719,960,1.689,961,1.633,962,1.317,963,1.558,964,1.514,965,1.719,966,1.607]],["tags/116",[]],["title/117",[148,1.011,963,2.574,964,2.5]],["content/117",[3,0.36,4,1.071,7,1.481,14,0.828,16,0.664,21,0.92,22,1.898,28,0.906,31,1.348,56,1.657,60,1.247,63,0.806,66,1.843,80,1.032,87,1.333,92,1.66,94,0.809,95,2.799,97,1.14,104,0.742,117,1.288,118,1.348,126,2.888,132,1.059,138,1.132,148,2.072,159,1.317,161,1.088,162,1.261,169,1.775,176,1.707,183,1.582,207,1.059,217,1.558,224,1.558,240,0.791,243,2.77,261,3.053,266,1.086,282,1.119,286,1.119,292,1.14,297,0.95,299,1.221,303,1.041,304,2.391,318,1.898,323,1.453,329,1.015,383,2.239,404,0.737,445,0.827,452,1.398,473,1.966,485,1.843,486,1.559,489,2.033,498,1.582,505,1.173,509,1.185,539,3.42,546,1.398,547,1.535,576,1.492,579,1.633,580,1.129,581,1.514,604,1.535,607,1.625,616,1.535,618,1.364,667,1.274,668,1.607,669,1.607,675,3.742,678,3.42,706,1.333,711,1.472,740,1.66,798,1.558,802,1.317,830,1.633,836,1.303,845,1.657,924,1.514,943,3.682,944,3.741,945,3.741,946,2.297,947,1.689,948,1.719,949,1.66,950,1.472,951,1.633,952,1.607,953,2.534,954,1.398,955,1.66,956,1.689,957,1.607,958,1.719,959,1.719,960,1.689,961,1.633,962,1.317,963,1.558,964,1.514,965,1.719,966,1.607]],["tags/117",[]],["title/118",[118,1.927,148,0.875,286,1.599,304,2.134]],["content/118",[3,0.36,4,1.071,7,1.481,14,0.828,16,0.664,21,0.92,22,1.898,28,0.906,31,1.348,56,1.657,60,1.247,63,0.806,66,1.843,80,1.032,87,1.333,92,1.66,94,0.809,95,2.799,97,1.14,104,0.742,117,1.288,118,1.348,126,2.888,132,1.059,138,1.132,148,2.072,159,1.317,161,1.088,162,1.261,169,1.775,176,1.707,183,1.582,207,1.059,217,1.558,224,1.558,240,0.791,243,2.77,261,3.053,266,1.086,282,1.119,286,1.119,292,1.14,297,0.95,299,1.221,303,1.041,304,2.391,318,1.898,323,1.453,329,1.015,383,2.239,404,0.737,445,0.827,452,1.398,473,1.966,485,1.843,486,1.559,489,2.033,498,1.582,505,1.173,509,1.185,539,3.42,546,1.398,547,1.535,576,1.492,579,1.633,580,1.129,581,1.514,604,1.535,607,1.625,616,1.535,618,1.364,667,1.274,668,1.607,669,1.607,675,3.742,678,3.42,706,1.333,711,1.472,740,1.66,798,1.558,802,1.317,830,1.633,836,1.303,845,1.657,924,1.514,943,3.682,944,3.741,945,3.741,946,2.297,947,1.689,948,1.719,949,1.66,950,1.472,951,1.633,952,1.607,953,2.534,954,1.398,955,1.66,956,1.689,957,1.607,958,1.719,959,1.719,960,1.689,961,1.633,962,1.317,963,1.558,964,1.514,965,1.719,966,1.607]],["tags/118",[]],["title/119",[148,1.198,798,3.047]],["content/119",[3,0.36,4,1.071,7,1.481,14,0.828,16,0.664,21,0.92,22,1.898,28,0.906,31,1.348,56,1.657,60,1.247,63,0.806,66,1.843,80,1.032,87,1.333,92,1.66,94,0.809,95,2.799,97,1.14,104,0.742,117,1.288,118,1.348,126,2.888,132,1.059,138,1.132,148,2.072,159,1.317,161,1.088,162,1.261,169,1.775,176,1.707,183,1.582,207,1.059,217,1.558,224,1.558,240,0.791,243,2.77,261,3.053,266,1.086,282,1.119,286,1.119,292,1.14,297,0.95,299,1.221,303,1.041,304,2.391,318,1.898,323,1.453,329,1.015,383,2.239,404,0.737,445,0.827,452,1.398,473,1.966,485,1.843,486,1.559,489,2.033,498,1.582,505,1.173,509,1.185,539,3.42,546,1.398,547,1.535,576,1.492,579,1.633,580,1.129,581,1.514,604,1.535,607,1.625,616,1.535,618,1.364,667,1.274,668,1.607,669,1.607,675,3.742,678,3.42,706,1.333,711,1.472,740,1.66,798,1.558,802,1.317,830,1.633,836,1.303,845,1.657,924,1.514,943,3.682,944,3.741,945,3.741,946,2.297,947,1.689,948,1.719,949,1.66,950,1.472,951,1.633,952,1.607,953,2.534,954,1.398,955,1.66,956,1.689,957,1.607,958,1.719,959,1.719,960,1.689,961,1.633,962,1.317,963,1.558,964,1.514,965,1.719,966,1.607]],["tags/119",[]],["title/120",[449,3.088]],["content/120",[14,0.578,93,4.18,97,2.56,104,1.667,178,4.194,266,1.523,282,2.512,298,4.748,342,3.306,363,5.529,404,1.655,424,3.306,449,3.713,492,4.377,508,4.377,545,2.56,607,2.278,711,4.243,716,3.352,867,5.077,967,6.878,968,4.748,969,5.283,970,6.251,971,6.251,972,5.838,973,5.838,974,5.283,975,6.251,976,5.838,977,4.902,978,6.251,979,5.838]],["tags/120",[]],["title/121",[969,5.638]],["content/121",[14,0.558,86,5.331,178,3.709,186,3.426,297,2.056,372,4.22,463,4.803,489,2.197,492,4.22,545,3.209,557,4.447,644,5.781,707,5.24,722,5.094,742,4.726,760,2.445,919,3.479,940,4.328,969,7.359,970,6.027,971,6.027,980,6.632,981,5.331,982,5.629,983,4.896,984,5.331,985,5.629,986,5.627,987,5.629,988,5.331,989,5.629,990,6.027,991,5.629]],["tags/121",[]],["title/122",[545,2.229,992,4.815]],["content/122",[2,0.954,3,0.068,4,0.397,10,1.511,16,0.395,21,1.886,22,1.63,27,1.158,31,0.801,34,0.841,41,1.297,42,0.774,46,1.397,49,0.926,50,0.899,63,0.417,87,0.792,90,1.106,101,1.227,104,0.441,117,1.334,119,1.544,120,3.001,121,1.978,126,0.749,141,2.26,148,0.634,161,0.646,166,0.641,171,0.551,178,0.783,182,1.239,183,0.94,185,1.003,199,0.624,211,3.003,227,0.97,251,0.863,253,2.341,260,2.189,261,0.792,266,0.403,283,0.774,313,0.94,319,1.082,326,0.588,328,1.187,329,1.05,342,2.025,344,1.021,372,2.018,379,1.082,385,2.256,399,0.986,408,1.463,417,1.256,426,1.297,447,1.748,458,1.22,460,2.126,463,2.528,465,1.04,467,1.463,484,1.776,486,1.007,489,1.671,492,2.018,504,1.003,509,0.704,510,2.691,516,1.463,524,1.131,531,3.381,542,1.343,544,1.061,545,2.907,550,1.463,576,2.458,577,2.549,581,3.993,586,0.986,587,1.463,617,1.256,640,1.343,644,2.825,650,0.757,651,1.22,655,1.131,664,1.463,678,0.887,689,1.463,693,1.22,708,1.927,716,3.06,726,1.849,734,2.881,742,3.003,760,1.169,761,1.653,785,3.576,788,2.909,790,2.691,796,1.187,805,2.189,816,0.783,825,2.549,838,1.003,860,1.106,892,1.106,912,1.106,915,2.069,953,2.176,954,1.447,962,2.46,988,1.463,992,6.688,993,1.463,994,1.819,995,1.544,996,2.691,997,3.171,998,1.544,999,1.653,1000,1.544,1001,4.054,1002,1.397,1003,1.653,1004,1.653,1005,1.653,1006,4.214,1007,1.256,1008,1.819,1009,1.819,1010,5.043,1011,3.873,1012,9.055,1013,7.157,1014,4.222,1015,7.157,1016,1.819,1017,5.33,1018,4.214,1019,4.854,1020,7.812,1021,4.214,1022,5.043,1023,1.819,1024,3.171,1025,1.819,1026,1.819,1027,1.819,1028,1.819,1029,1.819,1030,1.653,1031,1.819,1032,1.653,1033,5.043,1034,1.653,1035,3.171,1036,6.28,1037,1.819,1038,1.819,1039,2.26,1040,1.819,1041,3.639,1042,1.819,1043,4.214,1044,1.653,1045,1.819,1046,1.819,1047,1.819,1048,2.26,1049,1.397,1050,3.171,1051,1.819,1052,3.171,1053,1.819,1054,1.653,1055,1.819,1056,1.544,1057,1.819,1058,2.435,1059,1.819,1060,1.819,1061,1.819,1062,1.653,1063,1.653,1064,1.397,1065,2.825,1066,2.881,1067,1.544,1068,1.819,1069,1.397,1070,1.653,1071,1.463,1072,1.819,1073,1.819,1074,2.881,1075,1.544,1076,1.819,1077,1.819]],["tags/122",[]],["title/123",[711,2.432,716,2.465,978,4.598]],["content/123",[3,0.279,4,1.635,14,0.63,32,2.613,82,3.418,97,2.787,104,1.815,126,3.082,143,2.841,162,3.082,176,2.083,191,2.841,269,3.81,449,3.15,662,6.356,711,3.6,726,4.366,803,5.528,836,3.185,867,5.528,979,6.356,1078,6.356,1079,6.806,1080,7.489,1081,7.489,1082,5.021]],["tags/123",[]],["title/124",[80,2.474]],["content/124",[3,0.234,4,1.37,9,3.732,14,0.784,31,2.761,63,0.824,93,3.812,143,2.38,198,2.502,233,2.582,240,2.669,268,3.459,299,2.502,303,2.132,330,2.132,331,2.555,342,3.996,347,2.975,449,3.497,571,3.065,592,5.324,667,2.61,710,5.043,711,3.015,762,3.732,862,4.432,919,3.291,1083,6.273,1084,4.471,1085,4.818,1086,5.324,1087,5.324,1088,8.314,1089,7.556,1090,3.658,1091,3.191,1092,5.324,1093,4.471]],["tags/124",[]],["title/125",[541,4.367]],["content/125",[4,1.023,14,0.394,30,0.983,34,2.165,36,1.303,50,1.429,58,3.512,68,2.06,69,2.06,98,1.13,105,1.493,138,0.667,143,1.097,148,0.578,162,3.069,163,1.273,171,2.416,182,1.13,199,0.991,201,2.987,240,2.063,252,1.72,266,1.307,268,2.583,279,1.887,283,1.23,292,1.076,313,1.493,342,2.251,344,1.623,359,1.887,372,1.84,374,1.493,418,2.324,423,0.942,449,1.97,463,3.738,483,1.996,489,0.958,520,1.757,545,2.197,607,0.958,647,5.01,651,1.938,652,1.938,671,2.134,686,3.756,688,2.98,704,2.134,707,2.846,708,3.587,710,2.324,716,3.307,721,1.653,722,2.22,729,1.686,737,2.454,742,4.207,756,2.06,760,1.726,763,1.119,764,2.06,770,6.063,788,4.075,790,3.975,824,2.627,836,1.23,838,2.583,862,1.541,946,2.192,962,2.539,995,2.454,996,3.975,998,3.975,999,2.627,1000,3.975,1001,4.745,1002,2.22,1003,4.256,1004,2.627,1005,2.627,1030,2.627,1048,3.338,1078,3.975,1079,2.627,1086,3.975,1094,2.891,1095,2.891,1096,2.891,1097,5.365,1098,2.891,1099,2.891,1100,2.324,1101,7.955,1102,8.219,1103,2.891,1104,4.683,1105,2.891,1106,2.891,1107,2.454,1108,2.891,1109,5.01,1110,2.454,1111,2.627,1112,2.891,1113,2.891,1114,4.745,1115,2.891,1116,2.891,1117,2.891,1118,2.891,1119,2.627,1120,2.891,1121,2.891,1122,2.891,1123,1.32,1124,1.797,1125,2.627,1126,2.627,1127,1.996,1128,2.891,1129,2.134,1130,2.891,1131,2.891,1132,2.891,1133,2.891,1134,2.891,1135,2.891,1136,2.891]],["tags/125",[]],["title/126",[764,5.232]],["content/126",[14,0.504,30,2.036,33,4.016,34,2.768,98,2.341,105,4.164,165,3.094,171,1.813,172,1.935,240,2.083,243,2.364,251,2.841,266,1.326,283,2.547,307,2.768,349,1.903,393,3.142,423,1.951,463,4.567,484,2.838,588,5.26,650,2.492,686,3.812,688,3.812,716,2.919,729,3.492,745,3.564,770,5.404,802,2.576,805,4.135,909,3.047,946,2.804,986,3.909,1002,4.6,1048,4.269,1078,5.084,1097,5.444,1101,5.444,1102,5.444,1114,7.324,1137,4.815,1138,5.444,1139,8.061,1140,3.812,1141,5.99,1142,5.444,1143,5.99]],["tags/126",[]],["title/127",[972,5.084,973,5.084]],["content/127",[3,0.192,14,0.434,28,1.525,148,1.454,162,2.123,166,1.816,178,3.128,182,2.015,204,2.664,241,5.646,246,2.27,266,1.61,297,1.599,298,3.56,347,2.446,363,4.146,383,2.354,424,2.479,453,2.664,463,4.585,489,2.79,505,2.786,508,3.282,545,2.706,707,4.419,760,1.901,806,3.807,947,2.844,950,2.479,972,6.171,973,8.184,974,3.961,975,4.687,976,6.171,977,3.675,983,3.807,984,4.146,986,5.496,993,4.146,1007,6.907,1048,3.675,1054,4.687,1064,3.961,1084,3.675,1144,5.157,1145,5.157,1146,5.157,1147,5.157,1148,5.157,1149,5.157,1150,3.807,1151,5.157,1152,3.56,1153,5.157,1154,5.157,1155,5.157]],["tags/127",[]],["title/128",[3,0.189,82,2.309,282,1.848]],["content/128",[3,0.316,14,0.712,16,1.836,33,4.323,42,2.742,49,3.28,63,1.112,82,3.864,98,2.52,104,2.051,128,4.103,182,3.308,204,3.33,205,3.759,246,3.726,266,1.427,286,2.355,312,4.103,374,3.33,379,3.836,394,4.323,399,3.495,423,2.1,449,2.712,534,3.142,545,2.4,607,2.136,695,3.142,914,4.451,915,4.208,916,4.595,917,4.007,919,3.383,920,4.936,966,3.383,1156,3.759,1157,5.183]],["tags/128",[]],["title/129",[14,0.504,266,1.326]],["content/129",[2,2.407,3,0.373,4,0.616,7,0.336,14,0.562,16,0.823,17,1.173,33,1.89,34,0.736,40,0.967,42,0.677,56,0.761,63,0.689,64,0.81,73,0.822,80,1.546,82,1.287,83,0.91,94,1.002,104,1.521,105,2.37,126,0.655,132,0.55,136,2.675,138,1.82,143,1.439,144,1.991,148,0.318,164,0.765,168,0.776,182,0.622,185,0.878,186,1.96,187,1.173,198,1.124,199,1.573,201,2.554,204,0.822,205,0.928,214,1.554,233,1.16,240,0.728,242,0.91,243,0.628,251,1.337,252,0.947,263,0.776,265,0.878,266,2.013,269,0.81,276,2.851,277,1.752,279,1.039,290,0.947,292,0.592,297,1.799,299,1.513,303,0.541,305,0.685,313,0.822,318,0.616,320,2.694,324,0.755,325,2.584,326,0.514,329,1.738,330,2.133,331,2.363,332,3.491,333,1.279,344,2.945,345,1.456,346,1.434,347,1.337,349,1.206,359,1.039,369,1.222,372,1.794,374,0.822,379,0.947,384,0.834,385,2.097,386,1.644,387,1.794,388,1.582,423,0.518,426,2.009,432,2.165,443,3.739,445,0.761,449,0.669,463,0.798,489,0.934,495,1.134,505,0.61,529,1.013,587,1.279,607,0.934,618,0.709,621,1.582,647,2.081,650,2.414,652,1.067,655,0.989,667,0.662,670,1.279,672,2.081,682,1.175,687,2.87,706,1.996,707,0.967,713,1.175,760,1.691,762,1.677,763,1.775,812,1.446,817,2.081,833,1.134,834,2.306,845,0.43,852,2.266,856,1.222,862,0.848,899,0.822,917,2.358,919,1.479,928,1.677,954,0.726,962,0.685,1011,3.524,1014,2.801,1017,1.351,1019,1.351,1041,5.292,1065,1.067,1084,1.134,1090,0.928,1093,3.27,1158,1.175,1159,1.446,1160,2.392,1161,1.446,1162,1.946,1163,1.175,1164,2.562,1165,3.692,1166,3.688,1167,3.22,1168,1.446,1169,3.894,1170,2.392,1171,1.446,1172,2.562,1173,1.446,1174,1.351,1175,1.446,1176,3.448,1177,1.446,1178,1.446,1179,1.446,1180,1.446,1181,2.392,1182,0.967,1183,1.351,1184,1.446,1185,1.446,1186,1.446,1187,1.446,1188,1.446,1189,1.446,1190,1.279,1191,1.446,1192,2.562,1193,1.446,1194,2.266,1195,1.446,1196,1.446,1197,1.279,1198,2.392,1199,1.446,1200,1.175,1201,1.351,1202,1.351,1203,1.592,1204,2.819,1205,1.446,1206,1.446,1207,2.165,1208,1.013,1209,1.039,1210,1.013,1211,1.446,1212,1.592,1213,3.794,1214,1.592,1215,1.099,1216,1.644,1217,1.446,1218,2.914,1219,1.013,1220,2.392,1221,0.91,1222,1.446,1223,1.351,1224,1.099]],["tags/129",[]],["title/130",[178,2.176,545,1.883,914,3.492]],["content/130",[148,1.439,344,4.041,383,3.285,463,4.992,489,2.384,545,3.382,644,4.826,695,3.508,707,4.374,742,5.13,760,2.654,915,4.697,969,7.649,981,5.786,982,6.109,984,5.786,985,6.109,986,5.93,987,6.109,988,5.786,989,6.109,991,6.109,993,5.786,1225,5.528,1226,6.542]],["tags/130",[]],["title/131",[14,0.504,802,2.577]],["content/131",[3,0.37,10,2.249,14,0.835,16,1.361,56,1.694,63,1.092,90,3.812,104,2.015,148,1.662,155,5.043,265,3.459,295,3.992,324,2.975,384,1.855,404,1.509,672,4.631,687,2.357,763,3.608,802,4.73,833,4.471,836,2.668,845,1.694,856,4.818,917,3.899,954,2.863,1216,3.658,1221,3.588,1227,3.899,1228,5.043,1229,4.094,1230,5.701,1231,3.732]],["tags/131",[]],["title/132",[14,0.368,82,1.999,282,1.599,695,2.134]],["content/132",[3,0.214,7,1.651,14,0.805,16,1.243,28,1.694,30,1.948,32,2.73,63,1.316,80,1.931,94,1.513,125,2.649,128,4.978,129,3.647,136,3.341,186,2.96,187,2.384,190,3.41,191,2.174,216,4.474,233,3.22,240,2.302,244,3.956,266,1.732,303,2.659,358,2.683,384,2.313,445,1.547,453,2.96,509,2.217,545,2.911,650,2.384,667,2.384,695,3.812,839,5.208,840,5.208,862,3.055,918,4.084,919,3.006,920,3.341,1156,3.341,1232,3.74,1233,4.864,1234,5.731,1235,5.731,1236,5.208]],["tags/132",[]],["title/133",[1237,5.419]],["content/133",[32,2.118,42,2.581,63,0.797,68,5.795,80,2.74,109,4.068,125,2.805,128,5.174,136,3.538,137,3.96,148,1.213,168,2.957,186,3.134,190,3.61,240,1.568,307,2.805,347,3.857,353,7.39,358,2.841,360,4.878,378,3.134,384,1.794,388,3.407,445,1.638,539,4.469,561,5.15,571,2.237,770,4.068,1075,5.15,1109,5.15,1236,5.515,1238,5.515,1239,7.784,1240,5.515,1241,4.661,1242,6.068,1243,4.878,1244,6.068,1245,6.068,1246,6.068,1247,5.15,1248,5.515,1249,6.068,1250,5.15,1251,5.515,1252,6.068]],["tags/133",[]],["title/134",[125,2.338,607,1.676,1247,4.294]],["content/134",[3,0.283,148,2.092,180,3.029,193,4.992,325,2.447,327,4.416,358,3.557,404,1.322,410,4.219,463,2.754,607,3.466,621,3.084,644,5.095,732,4.416,1127,3.792,1225,5.836,1250,6.449,1251,4.992,1253,5.493,1254,5.493,1255,9.051,1256,5.493,1257,5.493,1258,5.493,1259,4.662,1260,5.493,1261,5.493,1262,5.493,1263,5.493,1264,5.493,1265,5.493,1266,5.493,1267,5.493,1268,8.712,1269,5.493,1270,5.493,1271,5.493,1272,4.662,1273,4.992,1274,5.836,1275,4.992,1276,4.992,1277,4.992,1278,4.219]],["tags/134",[]],["title/135",[14,0.504,266,1.326]],["content/135",[3,0.393,4,0.918,7,0.888,14,0.812,16,1.36,17,1.75,27,2.676,31,1.851,32,0.885,40,1.541,50,3.099,63,0.553,64,1.29,66,1.58,80,1.417,104,1.306,132,0.877,136,2.452,138,1.604,148,0.507,153,1.872,161,0.901,162,1.731,164,2.021,171,1.898,172,1.358,182,2.45,185,1.398,190,2.502,198,1.677,201,1.116,214,2.319,233,2.218,240,1.62,242,1.45,246,3.061,251,1.203,252,1.508,263,1.235,266,2.019,277,2.614,282,0.926,290,1.508,297,1.304,299,1.677,303,0.862,310,2.744,313,2.172,317,1.7,318,0.981,320,1.022,344,1.423,345,2.172,346,1.29,349,1.712,358,1.969,359,2.744,374,2.172,384,0.75,385,1.405,423,0.826,459,1.807,463,1.271,485,1.58,486,1.336,495,1.807,534,1.235,541,1.508,545,0.944,561,3.569,607,0.84,618,1.129,621,1.423,647,3.105,650,1.75,667,1.055,670,2.038,695,3.388,711,2.021,760,2.312,770,2.82,817,3.105,826,3.381,832,1.677,834,3.275,852,3.381,862,1.352,917,3.349,919,1.33,924,2.078,927,2.82,950,2.021,955,2.28,983,1.872,1065,1.7,1090,1.478,1165,2.676,1208,2.676,1216,2.452,1217,2.304,1218,4.139,1219,2.676,1220,3.569,1221,2.405,1222,2.304,1223,2.152,1224,2.903,1232,4.893,1233,6.741,1237,3.105,1238,3.822,1279,2.82,1280,2.535,1281,2.535,1282,2.535,1283,2.535,1284,4.206,1285,2.535,1286,2.304]],["tags/135",[]],["title/136",[14,0.504,214,3.303]],["content/136",[14,0.794,61,2.541,63,0.573,94,1.151,98,1.703,104,1.56,120,2.593,121,1.507,122,1.548,143,1.653,148,1.691,161,1.548,163,1.918,171,1.319,172,1.408,174,2.251,176,1.212,198,1.738,226,2.593,235,2.648,236,3.754,239,5.369,240,2.592,268,3.551,287,1.605,292,2.396,297,1.351,298,3.008,303,3.067,313,2.251,318,1.686,343,6.155,359,4.202,381,3.008,423,1.419,463,3.839,484,2.267,489,1.444,544,2.541,575,3.96,647,3.217,667,3.754,708,2.648,763,1.686,805,3.008,851,3.96,862,2.323,909,3.276,917,2.708,962,2.769,968,5.286,983,3.217,986,2.844,1048,3.106,1069,3.347,1215,4.445,1287,5.851,1288,4.358,1289,7.657,1290,4.358,1291,3.106,1292,4.358,1293,5.465,1294,4.358,1295,4.358,1296,4.358,1297,4.358,1298,1.965]],["tags/136",[]],["title/137",[178,2.176,545,1.883,914,3.492]],["content/137",[148,1.439,344,4.041,383,3.285,463,4.992,489,2.384,545,3.382,644,4.826,695,3.508,707,4.374,742,5.13,760,2.654,915,4.697,969,7.649,981,5.786,982,6.109,984,5.786,985,6.109,986,5.93,987,6.109,988,5.786,989,6.109,991,6.109,993,5.786,1225,5.528,1226,6.542]],["tags/137",[]],["title/138",[14,0.504,802,2.577]],["content/138",[3,0.38,10,1.789,14,0.891,32,2.479,63,0.933,90,3.033,104,2.004,138,1.639,143,2.695,148,1.42,155,4.012,199,2.436,246,3.967,266,1.995,295,3.176,349,2.257,385,2.373,544,4.142,660,6.03,763,3.2,802,4.258,832,2.833,833,3.557,853,6.456,917,3.102,954,2.278,1082,3.346,1129,5.244,1165,4.521,1216,2.91,1221,2.854,1227,5.14,1228,4.012,1229,3.257,1230,4.536,1231,2.969,1232,3.257,1233,4.236,1279,3.346,1299,7.649]],["tags/138",[]],["title/139",[798,3.735]],["content/139",[63,1.141,204,4.483,205,5.061,286,3.17,312,5.523,394,5.82,399,4.705,423,2.827,534,4.23]],["tags/139",[]],["title/140",[14,0.22,32,0.914,42,1.113,148,0.523,198,1.044,292,0.974,404,0.63,902,1.708,1300,2.105]],["content/140",[32,2.077,41,4.241,42,2.531,104,1.442,105,3.074,160,3.173,182,2.326,195,4.506,204,3.074,205,3.47,233,2.449,252,3.541,256,6.452,305,2.56,310,3.884,325,2.651,344,3.341,345,3.074,410,6.975,644,6.517,732,7.3,986,6.343,1065,3.99,1221,4.59,1250,8.25,1255,6.812,1276,5.409,1277,8.253,1278,7.466,1300,4.784,1301,7.814,1302,5.409,1303,5.051]],["tags/140",[]],["title/141",[541,3.564,607,1.984]],["content/141",[3,0.309,7,1.75,13,4.219,16,1.798,112,5.724,171,2.51,192,3.567,207,2.868,303,2.818,349,2.635,350,5.411,382,4.098,404,1.995,845,2.239]],["tags/141",[]],["title/142",[1237,5.419]],["content/142",[16,1.611,46,5.706,80,2.503,89,5.972,104,1.8,108,3.391,171,2.249,186,4.788,204,3.837,205,4.331,329,2.461,330,2.525,331,3.025,332,3.523,358,3.478,463,3.724,489,2.461,492,4.727,505,2.846,508,4.727,607,2.461,883,5.972,1304,7.429,1305,6.305,1306,5.484,1307,5.294]],["tags/142",[]],["title/143",[3,0.189,404,1.217,607,1.676]],["content/143",[3,0.303,7,0.728,27,2.195,33,3.614,56,0.931,63,0.708,82,1.575,104,1.306,143,1.309,164,1.658,171,1.044,172,1.114,176,2.263,182,2.107,192,1.484,242,1.973,246,1.519,281,4.653,283,1.467,297,1.07,349,1.096,358,4.038,384,2.406,396,2.097,404,2.475,414,2.195,445,0.931,447,4.487,460,2.313,478,2.382,607,3.247,652,2.313,726,2.012,816,4.011,845,1.455,883,5.333,884,2.251,915,2.251,934,3.721,954,1.575,961,1.839,1058,5.76,1064,2.65,1138,3.136,1158,2.547,1224,2.382,1225,5.76,1243,2.773,1255,6.366,1272,6.366,1273,7.395,1274,6.624,1275,6.816,1286,3.136,1305,4.575,1308,3.45,1309,8.137,1310,3.45,1311,3.45,1312,7.5,1313,3.45,1314,3.45,1315,3.45,1316,3.45,1317,3.136,1318,3.45,1319,5.391,1320,3.45,1321,2.195,1322,4.575,1323,4.14,1324,3.45,1325,3.45,1326,2.928,1327,2.65]],["tags/143",[]],["title/144",[16,0.95,182,1.711,246,1.927,458,2.936]],["content/144",[3,0.379,14,0.635,16,1.637,27,4.804,33,5.062,63,0.992,128,4.804,182,3.659,204,3.899,233,3.107,246,4.121,458,5.062,461,4.692,465,4.318,505,3.587,604,3.785,695,3.679,919,3.961,920,4.402,1156,4.402]],["tags/144",[]],["title/145",[80,2.019,1328,4.135]],["content/145",[2,1.122,3,0.311,5,1.751,7,0.769,14,0.531,17,1.516,29,1.001,34,0.988,42,0.909,56,0.577,59,1.719,63,0.281,80,1.605,85,1.382,90,2.214,104,1.952,107,3.393,138,1.298,139,4.152,143,0.811,145,1.329,148,1.611,157,2.69,163,0.941,181,1.122,182,1.424,192,0.92,216,1.223,233,3.179,240,0.552,244,1.476,246,0.941,251,1.014,266,2.035,287,0.533,293,1.329,305,1.567,318,0.827,326,1.177,329,0.708,330,0.727,331,0.871,332,3.258,342,1.028,344,2.046,355,2.581,359,1.395,379,2.833,425,1.476,443,1.524,453,1.104,461,2.264,489,1.577,501,2.168,523,5.522,542,1.578,571,0.788,591,1.943,687,2.113,713,1.578,741,1.247,747,1.943,763,1.842,920,1.247,928,2.833,952,1.122,1065,1.433,1084,3.393,1124,1.329,1200,1.578,1202,3.093,1209,1.395,1215,5.762,1323,1.642,1328,6.347,1329,2.138,1330,2.138,1331,2.138,1332,2.138,1333,2.138,1334,2.138,1335,2.138,1336,2.138,1337,2.138,1338,2.138,1339,2.138,1340,2.138,1341,2.138,1342,2.138,1343,2.138,1344,2.138,1345,2.138,1346,2.138,1347,2.138,1348,2.138,1349,2.138,1350,2.138,1351,2.138,1352,2.138,1353,2.138,1354,6.869,1355,1.815,1356,2.138,1357,2.138,1358,2.138,1359,2.138,1360,2.138,1361,2.138,1362,2.138,1363,2.138,1364,3.644,1365,2.138,1366,2.138,1367,3.644,1368,2.138,1369,1.719,1370,2.138,1371,2.138,1372,2.138,1373,2.138,1374,2.138,1375,2.138,1376,2.138,1377,2.138,1378,2.138,1379,2.138,1380,1.943,1381,2.138,1382,2.138,1383,1.943,1384,2.799,1385,2.138,1386,2.138,1387,2.138,1388,2.138,1389,2.138,1390,2.138,1391,2.138,1392,2.138,1393,2.138,1394,2.138,1395,2.138,1396,2.138,1397,3.644,1398,3.644,1399,2.138,1400,2.138,1401,2.138,1402,2.138,1403,2.138,1404,2.138,1405,2.138,1406,2.138,1407,2.138,1408,2.138,1409,2.138,1410,2.138,1411,2.138,1412,2.138,1413,2.138,1414,2.138,1415,2.138,1416,2.138,1417,2.138,1418,2.138,1419,2.138,1420,2.138,1421,2.138,1422,2.138,1423,2.138,1424,2.138,1425,2.138,1426,2.138,1427,2.138,1428,2.138,1429,2.138,1430,2.138,1431,2.138,1432,2.138,1433,2.138,1434,2.138,1435,2.138,1436,2.138,1437,2.138,1438,2.138,1439,2.138,1440,2.138,1441,2.138,1442,2.138,1443,2.138,1444,2.138,1445,2.138,1446,2.138,1447,2.138,1448,2.138,1449,2.138,1450,2.138,1451,2.138,1452,2.138,1453,2.138,1454,2.138,1455,2.138,1456,2.138,1457,2.138,1458,2.138,1459,2.138,1460,1.943]],["tags/145",[]],["title/146",[465,4.198]],["content/146",[2,3.509,3,0.105,16,1.259,17,1.91,42,2.469,63,1.139,80,0.95,82,3.053,101,2.246,104,2.016,105,1.457,119,2.394,138,1.339,162,1.161,164,1.356,168,1.374,178,1.213,179,1.841,182,1.794,185,1.555,186,2.998,192,1.974,204,2.998,205,3.384,208,4.926,233,2.389,246,2.021,266,1.63,276,3.607,282,1.03,287,1.144,305,1.974,324,1.338,326,0.911,329,2.439,330,1.973,331,1.149,332,3.946,342,1.356,346,1.435,358,1.32,372,1.795,374,1.457,379,2.731,383,1.287,384,1.716,385,1.939,394,3.078,404,1.771,410,2.166,443,4.137,449,1.186,453,1.457,458,4.936,461,3.607,465,3.319,484,0.993,489,2.216,504,2.531,505,1.759,508,2.921,652,3.078,713,4.285,833,2.01,860,4.474,883,3.69,899,1.457,919,3.862,928,4.38,951,1.504,1056,2.394,1084,2.01,1190,2.267,1200,2.082,1202,2.394,1206,4.172,1207,2.166,1208,1.795,1209,3.788,1210,1.795,1211,2.563,1215,1.947,1291,2.01,1305,2.394,1321,1.795,1327,3.526,1460,2.563,1461,2.821,1462,2.394,1463,2.821,1464,2.267,1465,2.563,1466,2.821,1467,2.563,1468,4.591,1469,4.591,1470,2.821,1471,2.821,1472,2.821,1473,2.821,1474,2.821,1475,2.821,1476,2.821,1477,2.821,1478,2.821,1479,2.821,1480,4.591,1481,2.821,1482,2.821,1483,2.821,1484,2.821,1485,4.591,1486,2.821,1487,2.821,1488,2.821,1489,2.821,1490,2.821,1491,2.821,1492,2.821,1493,2.821]],["tags/146",[]],["title/147",[81,4.135,82,2.734]],["content/147",[4,1.913,14,0.737,28,2.591,178,3.769,282,3.2,545,3.261,968,6.049,1219,5.576]],["tags/147",[]],["title/148",[3,0.144,16,0.837,63,0.507,207,1.335,921,2.519]],["content/148",[2,1.751,3,0.397,14,0.546,16,0.724,20,2.305,30,1.786,32,1.165,36,2.368,42,1.42,49,3.304,56,0.901,63,1.246,73,2.713,96,1.78,97,1.242,103,3.715,148,1.299,171,1.011,172,1.697,173,3.864,197,2.029,199,3.451,233,1.374,250,2.238,266,0.739,286,1.219,287,0.832,297,1.035,318,1.292,320,2.617,329,1.74,330,2.208,331,2.139,332,3.494,385,2.461,401,1.986,404,0.803,410,4.989,437,2.801,439,2.833,445,0.901,452,1.524,492,3.343,505,1.279,544,1.946,571,2.395,655,2.075,691,3.193,706,1.452,744,2.029,920,1.946,921,6.662,922,2.238,923,3.522,924,1.65,925,2.379,926,2.379,927,2.238,928,3.126,929,3.004,930,3.522,1085,2.564,1124,4.037,1165,5.664,1207,4.989,1464,2.684,1494,3.338,1495,5.513,1496,6.496,1497,3.338,1498,2.684,1499,4.774,1500,3.338,1501,2.833,1502,3.338,1503,3.338,1504,3.338,1505,2.833,1506,2.833,1507,3.338,1508,3.034]],["tags/148",[]],["title/163",[16,1.097,66,1.901,909,2.574]],["content/163",[3,0.218,7,0.809,16,1.269,17,1.596,19,2.408,28,1.73,32,1.338,40,2.331,45,3.255,47,2.193,60,2.382,66,2.198,80,1.292,94,2.095,104,1.417,110,2.571,122,1.363,125,2.704,128,2.441,129,2.441,158,1.923,167,2.236,169,1.388,171,1.161,174,1.981,177,2.733,179,2.503,181,2.012,187,3.554,189,1.869,190,2.282,191,1.455,192,1.65,199,2.006,201,2.575,206,4.965,220,3.486,251,2.775,292,1.427,294,4.754,297,2.199,302,1.923,303,1.304,329,1.27,330,1.304,331,1.562,332,1.819,339,3.255,344,3.284,345,3.021,346,1.951,347,1.819,351,5.911,352,4.038,386,3.411,387,3.722,388,2.153,389,2.733,399,2.079,509,1.484,557,2.571,621,4.454,627,1.923,650,1.596,741,2.236,743,3.635,770,3.922,781,2.383,837,3.083,867,2.831,910,2.571,911,2.733,1071,3.083,1209,2.503,1243,3.083,1291,2.733,1321,2.441,1509,3.835,1510,3.486,1511,2.831,1512,2.946,1513,4.965,1514,3.835,1515,3.835,1516,3.835,1517,5.316,1518,5.316,1519,3.486,1520,3.835,1521,3.255,1522,3.835,1523,3.486,1524,7.933]],["tags/163",[]],["title/164",[329,1.45,489,1.45,492,2.786,1306,3.232]],["content/164",[7,1.43,42,2.882,56,1.83,94,2.309,97,2.522,122,2.408,129,4.313,158,3.398,181,3.556,191,2.571,196,5.099,197,4.119,294,4.544,302,3.398,304,3.303,329,2.245,333,5.448,334,5.752,346,3.448,347,3.215,352,4.679,386,3.952,387,4.313,388,3.805,391,4.119,445,1.83,512,5.003,523,5.448,586,3.674,650,2.82,1306,5.003,1321,4.313,1525,6.778,1526,8.217,1527,5.752]],["tags/164",[]],["title/165",[330,2.036,1307,4.269]],["content/165",[3,0.253,7,1.686,8,3.059,19,1.929,29,2.195,32,2.37,42,1.994,45,3.979,63,0.892,73,2.421,94,1.794,97,1.745,101,1.814,126,2.795,129,2.983,148,0.937,152,2.849,159,2.016,171,1.419,176,1.304,180,2.585,181,3.563,187,3.867,191,3.03,195,3.813,197,2.849,275,3.236,281,2.681,294,6.702,301,5.46,302,4.39,304,2.284,315,3.236,330,3.48,346,2.385,347,3.221,351,2.632,352,3.236,380,3.769,383,2.14,386,2.733,387,2.983,391,2.849,395,3.341,445,1.266,514,1.728,544,2.733,586,2.541,599,3.979,608,5.765,815,3.769,977,3.341,983,3.461,1321,4.322,1513,3.979,1519,4.261,1526,3.979,1528,4.261,1529,4.688,1530,4.688,1531,4.688,1532,4.688,1533,7.987]],["tags/165",[]],["title/166",[16,0.95,108,1.999,331,1.783,508,2.786]],["content/166",[3,0.216,7,1.225,12,3.526,22,2.245,32,2.025,42,2.468,56,1.567,73,4.075,94,2.367,97,2.159,122,2.062,129,5.02,158,2.909,181,3.044,187,3.282,191,2.993,196,4.6,197,3.526,201,2.554,252,3.452,294,3.89,297,1.799,301,4.664,302,2.909,331,2.363,346,2.952,347,2.752,352,4.005,386,5.609,387,5.704,388,3.257,391,4.795,401,3.452,412,4.925,440,3.606,508,5.02,512,4.283,586,3.145,650,3.282,811,5.273,1200,4.283,1513,4.925,1526,7.608,1527,4.925,1534,5.803]],["tags/166",[]],["title/167",[332,3.482]],["content/167",[5,3.751,29,3.653,56,2.107,63,1.025,97,2.904,122,2.773,129,6.081,158,3.912,196,5.571,332,3.701,386,4.55,388,4.381,391,4.742,412,6.623,445,2.107,512,5.761,586,4.23,650,3.247,1535,7.804]],["tags/167",[]],["title/168",[1209,4.791]],["content/168",[3,0.244,16,1.418,17,2.72,43,4.267,56,1.765,63,0.859,66,2.457,86,5.256,125,3.022,126,2.691,137,5.575,152,3.974,187,2.72,190,3.89,196,3.812,265,3.606,287,2.13,302,3.278,345,3.377,347,3.101,351,3.671,358,3.061,388,3.671,394,4.384,445,1.765,460,4.384,498,3.377,505,2.505,621,3.671,644,4.384,897,4.514,1209,6.21,1243,5.256,1321,4.161,1523,5.942,1536,5.942,1537,5.942,1538,6.539,1539,6.539,1540,6.539]],["tags/168",[]],["title/169",[1541,6.671]],["content/169",[3,0.254,16,1.481,17,3.655,48,4.345,61,3.981,66,3.301,98,2.668,125,3.156,137,5.734,159,2.937,187,2.84,251,4.608,292,2.541,323,3.238,330,2.321,358,4.113,386,3.981,387,4.345,391,4.149,399,3.701,445,2.372,673,6.205,909,3.473,1209,4.455,1210,4.345,1384,5.244,1542,6.827,1543,6.827,1544,6.205,1545,6.827,1546,5.795]],["tags/169",[]],["title/156",[4,1.308,28,1.771]],["content/156",[4,1.708,10,2.055,12,5.816,13,3.98,14,0.658,17,2.384,26,3.483,28,2.83,29,2.683,63,1.028,76,4.531,84,4.392,94,1.513,103,3.277,120,3.41,130,2.553,138,1.322,142,5.299,161,2.036,168,2.793,169,2.831,174,2.96,176,2.176,190,3.41,191,2.174,216,3.277,242,3.277,258,3.74,292,2.133,293,4.862,303,2.659,321,5.4,509,2.217,627,2.873,667,3.255,704,4.23,754,3.98,892,3.483,1547,5.731,1548,4.607,1549,5.208,1550,5.731]],["tags/156",[]],["title/157",[3,0.189,11,2.039,66,1.901]],["content/157",[3,0.371,4,1.298,5,1.882,7,0.827,11,1.578,13,3.024,14,0.674,19,2.956,21,2.589,23,2.988,28,2.371,29,1.833,32,1.367,42,1.666,56,1.939,59,3.148,61,2.283,63,0.515,66,1.471,76,1.992,80,1.32,84,3.336,94,2.118,104,1.44,120,2.33,121,2.485,122,2.112,124,2.055,126,1.612,130,2.647,143,1.486,152,2.38,158,1.963,161,1.391,169,1.417,171,1.799,174,2.023,176,2.23,180,2.16,181,2.055,187,3.336,190,3.536,191,1.486,199,2.463,226,2.33,232,3.879,235,2.38,240,2.51,258,2.556,265,2.16,269,1.992,292,1.457,293,3.694,295,2.492,300,2.703,303,1.331,315,2.703,329,1.297,338,4.565,342,1.882,376,2.24,381,2.703,418,3.148,419,2.891,467,3.148,485,1.471,486,2.548,546,2.713,576,1.908,584,2.38,630,3.238,667,1.629,815,3.148,1551,3.916,1552,3.916,1553,3.559,1554,3.916,1555,3.324]],["tags/157",[]],["title/158",[4,0.956,56,1.182,187,1.822,1556,3.716]],["content/158",[3,0.157,4,1.636,7,1.322,10,2.246,11,1.692,14,0.353,16,1.359,17,1.747,21,2.495,22,1.625,23,2.606,24,2.105,28,2.215,41,2.993,42,2.664,47,4.285,49,3.187,56,2.243,66,1.578,67,2.61,73,2.169,94,1.109,99,2.61,103,2.402,104,1.518,121,2.592,126,2.578,127,3.226,148,0.84,161,1.492,176,1.168,177,2.993,184,3.565,187,2.606,197,2.552,199,2.148,226,2.499,240,2.408,241,2.816,251,1.992,291,2.993,303,1.428,323,1.992,338,3.226,339,3.565,351,5.42,376,2.402,449,1.766,486,1.334,498,2.169,519,3.565,522,3.565,546,2.859,630,1.894,639,3.376,664,5.036,667,2.606,675,2.047,688,2.673,799,3.565,862,4.428,898,2.816,902,2.741,957,2.203,966,2.203,977,2.993,1091,2.137,1527,3.565,1555,3.565,1556,3.565,1557,2.816,1558,2.816,1559,4.2,1560,5.317,1561,4.2,1562,1.941,1563,4.2,1564,3.565,1565,3.817,1566,3.817,1567,3.817]],["tags/158",[]],["title/149",[913,4.367]],["content/149",[]],["tags/149",[]],["title/150",[302,3.003,627,3.003]],["content/150",[97,3.142,201,3.717,297,2.618,302,4.233,440,5.247,627,4.233,652,5.661,884,5.51,913,5.023,1568,7.673,1569,8.443,1570,8.443]],["tags/150",[]],["title/151",[478,5.068]],["content/151",[3,0.351,7,1.351,14,0.538,22,2.477,36,2.887,63,1.107,97,2.383,172,2.722,180,3.531,198,2.554,199,2.196,240,1.655,242,3.662,248,5.237,297,1.985,321,4.42,375,4.42,404,2.028,437,4.493,478,5.817,590,4.918,631,3.471,688,4.075,715,4.727,903,3.979,913,5.955,968,4.42,1241,4.918,1571,5.819,1572,7.152,1573,5.819,1574,4.918,1575,5.819,1576,5.819,1577,5.435]],["tags/151",[]],["title/152",[7,1.264,845,1.617]],["content/152",[3,0.268,7,1.918,63,0.946,97,2.679,172,2.935,242,4.117,248,5.648,297,2.232,321,4.969,375,4.969,437,4.845,590,5.528,631,3.902,688,4.581,715,5.314,845,1.943,903,4.473,913,5.925,1241,5.528,1571,6.542,1572,7.713,1573,6.542,1576,6.542,1577,6.109]],["tags/152",[]],["title/153",[631,3.247,913,3.564]],["content/153",[3,0.339,7,1.918,63,1.309,73,3.718,172,2.935,217,3.662,238,4.473,266,1.594,295,4.581,322,5.314,437,4.845,445,1.943,478,6.273,489,3.01,609,5.314,721,4.117,769,6.542,830,3.838,1241,5.528,1578,5.786,1579,9.088,1580,7.198]],["tags/153",[]],["title/154",[903,3.723,913,3.564]],["content/154",[3,0.281,30,2.566,48,4.804,66,2.837,268,4.163,293,4.692,381,5.212,385,3.128,399,4.092,445,2.038,544,4.402,688,4.804,706,3.285,832,3.011,860,4.588,903,5.819,913,5.57,962,3.247,1156,4.402,1210,4.804,1581,7.55,1582,7.55]],["tags/154",[]],["title/155",[505,2.295,921,3.909]],["content/155",[3,0.335,14,0.596,30,2.409,36,3.196,49,3.606,56,1.914,63,0.931,172,2.29,197,4.308,266,1.569,297,2.198,318,2.742,329,2.348,330,2.409,331,2.886,332,3.362,401,4.217,437,3.779,445,1.914,505,2.715,691,5.469,921,4.626,922,4.752,923,4.752,924,3.503,925,5.051,926,5.051,927,4.752,928,4.217,929,4.054,930,4.752]],["tags/155",[]],["title/159",[3,0.189,85,1.919,1583,4.598]],["content/159",[3,0.33,7,1.867,85,3.356,87,3.849,1584,8.846,1585,8.846,1586,8.846]],["tags/159",[]],["title/160",[21,1.799,23,2.492]],["content/160",[21,2.344,23,3.247,28,2.307,29,4.473,32,2.723,76,3.97,85,3.625,187,3.247,330,2.653,345,4.031,356,5.761,508,4.966,592,6.623,736,5.994,899,4.031,1587,7.092,1588,4.16,1589,6.623,1590,6.623]],["tags/160",[]],["title/161",[85,1.919,1588,2.697,1591,3.392]],["content/161",[3,0.344,4,1.609,7,1.555,16,1.598,56,1.99,73,3.807,85,3.499,107,5.252,165,3.807,486,2.342,563,5.66,609,5.44,630,3.323,704,5.44,762,4.385,778,4.809,949,3.995,1137,5.924,1140,4.69,1326,6.255,1588,3.929,1591,4.941,1592,7.37,1593,4.297,1594,7.37,1595,7.37]],["tags/161",[]],["title/162",[178,2.577,1588,3.193]],["content/162",[3,0.273,4,1.597,7,1.937,16,1.586,38,6.206,56,1.974,73,3.777,85,3.482,97,3.415,165,3.777,166,2.575,171,2.214,178,3.947,251,3.468,312,4.653,545,3.415,594,5.878,674,5.211,684,5.616,940,4.771,1588,3.898,1596,7.312,1597,6.206,1598,7.312]],["tags/162",[]],["title/170",[178,2.577,1588,3.193]],["content/170",[]],["tags/170",[]],["title/171",[684,4.601,1597,5.084]],["content/171",[3,0.22,4,1.291,5,2.842,10,2.865,21,1.776,56,1.597,63,0.777,122,2.101,125,2.733,162,2.434,166,2.082,171,1.79,180,3.261,185,4.407,201,2.603,226,3.518,269,3.008,300,4.082,318,2.288,406,3.32,419,4.365,436,4.542,456,3.859,461,3.675,462,3.594,489,1.959,504,3.261,541,3.518,545,2.974,588,3.859,590,4.542,617,4.082,684,8.446,706,2.573,1557,3.965,1558,3.965,1588,5.564,1597,6.783,1599,7.992,1600,5.913,1601,4.214]],["tags/171",[]],["title/172",[166,2.585]],["content/172",[3,0.227,10,0.866,14,0.203,23,1.005,30,0.821,42,1.028,49,1.229,63,0.318,64,1.229,66,1.518,69,2.88,70,1.943,85,1.975,104,0.586,122,1.436,138,0.558,145,1.502,148,2.007,161,2.162,165,2.087,166,2.143,171,2.353,191,1.533,201,1.779,202,1.722,240,0.624,248,2.511,253,1.784,263,1.178,272,2.983,289,2.196,292,0.899,295,1.538,314,1.438,323,4.85,342,1.162,352,1.668,359,2.637,392,4.492,393,3.193,397,2.196,398,3.999,406,1.357,456,1.577,514,0.891,541,1.438,545,0.899,554,1.409,588,1.577,622,1.943,655,1.502,661,2.051,668,1.268,684,3.999,688,1.538,691,1.469,693,1.62,702,3.248,708,2.456,736,1.856,748,2.196,754,1.229,862,2.154,865,2.196,885,1.668,899,1.248,910,1.62,960,1.333,986,1.577,1002,1.856,1137,1.943,1140,1.538,1326,2.051,1557,5.21,1558,5.859,1588,2.776,1593,1.409,1602,7.694,1603,2.417,1604,4.041,1605,5.207,1606,2.196,1607,4.732,1608,4.732,1609,3.999,1610,2.417,1611,2.051,1612,4.041,1613,4.419,1614,1.856,1615,2.417,1616,2.051,1617,2.196,1618,2.417,1619,2.417,1620,2.417,1621,3.103,1622,2.417,1623,9.185,1624,2.417,1625,6.771,1626,2.417,1627,2.417,1628,6.154,1629,2.417,1630,2.417,1631,6.154,1632,2.417,1633,2.417,1634,2.417,1635,2.417,1636,2.417,1637,2.417,1638,2.417,1639,2.417,1640,2.417,1641,2.417,1642,6.086,1643,2.417,1644,2.417,1645,2.417,1646,2.417,1647,2.417,1648,2.417,1649,2.417,1650,2.417,1651,4.041,1652,2.417,1653,6.771,1654,2.417,1655,2.417,1656,2.417,1657,2.417,1658,4.732,1659,2.417,1660,2.417,1661,2.417,1662,2.417,1663,2.417,1664,2.417]],["tags/172",[]],["title/173",[1665,6.671]],["content/173",[10,2.485,104,1.679,249,5.57,272,5.115,293,4.306,323,3.287,392,6.548,678,3.377,768,7.529,1602,9.374,1607,6.297,1608,8.892,1609,6.813,1665,6.297,1666,8.87,1667,8.87,1668,8.87,1669,6.929,1670,6.929,1671,6.929,1672,6.929,1673,6.929,1674,6.929,1675,6.929,1676,6.929]],["tags/173",[]],["title/174",[21,1.159,23,1.606,29,1.807,85,1.464,1677,3.508]],["content/174",[3,0.368,14,0.691,19,3.382,28,2.43,32,2.868,85,3.741,156,7.469,164,3.95,187,4.102,240,2.124,519,6.975,1678,8.219]],["tags/174",[]],["title/175",[330,1.72,388,2.84,1588,2.697]],["content/175",[3,0.232,22,2.411,29,3.875,32,2.175,50,4.09,61,3.633,76,3.17,85,3.526,116,4.301,165,3.218,166,2.194,171,1.886,187,3.443,286,2.276,330,2.813,345,3.218,356,4.6,386,3.633,387,3.965,388,4.646,563,4.786,736,4.786,762,3.707,770,4.178,778,4.066,878,4.786,908,4.301,919,3.269,979,5.289,1001,5.009,1511,4.6,1512,4.786,1588,4.413,1589,5.289,1590,7.025,1621,4.786,1679,5.009,1680,5.663,1681,6.231,1682,5.663,1683,6.231,1684,6.231]],["tags/175",[]],["title/176",[388,2.84,508,3.219,1588,2.697]],["content/176",[3,0.234,29,3.892,32,2.189,50,3.1,61,3.658,76,4.23,85,3.767,116,4.331,165,3.24,171,1.899,187,2.61,215,3.658,286,2.291,307,2.899,331,2.555,345,3.24,347,2.975,386,3.658,387,3.992,388,4.667,508,3.992,693,4.206,706,2.729,762,3.732,815,5.043,878,4.818,1511,4.631,1512,4.818,1537,5.701,1588,3.344,1589,5.324,1590,5.324,1679,5.043,1680,5.701,1685,6.273,1686,5.043,1687,6.273,1688,6.273,1689,8.314,1690,6.273,1691,6.273,1692,5.701,1693,6.273]],["tags/176",[]],["title/177",[85,1.919,1588,2.697,1591,3.392]],["content/177",[3,0.37,4,1.975,56,1.928,63,1.188,70,5.742,73,3.689,85,3.431,103,4.085,165,3.689,166,2.515,167,4.165,330,2.428,331,2.909,486,2.269,609,5.273,630,4.077,919,3.747,1557,4.789,1558,4.789,1588,5.29,1591,4.789,1694,7.143,1695,6.062,1696,6.491]],["tags/177",[]],["title/178",[138,1.694]],["content/178",[]],["tags/178",[]],["title/179",[3,0.274]],["content/179",[3,0.325,4,1.2,17,2.285,24,3.809,68,5.415,104,1.331,116,5.246,138,1.267,186,3.925,187,3.161,201,3.345,240,1.963,303,2.583,330,1.867,331,2.237,344,4.266,345,4.5,346,3.866,347,4.132,388,4.266,633,3.683,667,3.161,762,3.268,862,4.051,1014,4.055,1041,3.496,1093,3.915,1124,4.722,1162,5.246,1194,4.416,1197,4.416,1511,5.609,1512,4.219,1564,4.662,1588,2.929,1679,4.416,1695,4.662,1697,4.992,1698,5.493,1699,5.493,1700,4.416,1701,5.493,1702,4.992,1703,6.108,1704,6.108,1705,4.992,1706,4.992]],["tags/179",[]],["title/180",[1557,4.922]],["content/180",[4,1.398,17,2.664,24,3.21,63,1.107,68,4.563,104,1.552,116,4.42,138,1.477,186,3.307,187,2.664,201,2.819,240,2.178,287,1.596,326,2.068,330,2.176,345,4.865,347,3.037,378,3.307,388,3.595,506,3.979,521,4.293,632,3.733,862,3.414,1014,4.727,1041,4.075,1162,4.42,1511,4.727,1512,4.918,1557,5.65,1588,3.414,1679,5.147,1700,5.147,1702,5.819,1703,5.147,1704,5.147,1707,5.819,1708,6.403,1709,6.403,1710,6.403,1711,5.819,1712,6.403,1713,4.42]],["tags/180",[]],["title/181",[1558,4.922]],["content/181",[4,1.379,5,3.036,17,2.628,24,3.166,29,2.957,63,1.097,68,4.501,104,1.53,116,4.36,138,1.457,186,3.262,187,2.628,201,2.78,240,2.158,287,1.574,326,2.04,345,4.313,347,3.961,378,3.262,388,3.546,485,2.373,506,3.925,521,4.235,632,3.683,762,3.758,862,3.367,1093,4.501,1162,4.36,1194,5.077,1197,5.077,1511,4.663,1558,5.599,1564,5.361,1588,3.367,1700,5.077,1703,5.077,1704,5.077,1705,5.74,1706,5.74,1707,5.74,1711,5.74,1713,4.36,1714,6.316,1715,6.316]],["tags/181",[]],["title/182",[166,2.585]],["content/182",[]],["tags/182",[]],["title/183",[630,3.31]],["content/183",[3,0.358,10,1.151,21,0.965,22,1.242,28,0.95,30,1.092,31,1.414,32,1.121,58,3.031,63,1.152,64,1.634,85,1.218,87,1.397,97,1.195,104,1.747,122,1.81,165,2.631,166,2.538,171,0.972,186,2.631,187,1.336,189,1.565,204,1.659,207,2.191,214,3.492,215,1.872,216,2.914,224,2.592,240,0.83,244,2.217,251,2.416,295,2.043,328,2.096,330,2.672,331,3.201,359,3.325,386,1.872,388,1.803,395,2.289,398,2.466,419,2.371,489,2.098,499,2.918,500,2.918,604,1.61,630,3.953,633,2.153,635,2.581,650,1.336,674,3.631,693,2.153,716,5.187,919,1.685,939,2.371,1007,2.217,1092,4.324,1137,2.581,1150,2.371,1521,2.725,1556,2.725,1557,4.833,1558,4.246,1560,2.725,1575,2.918,1583,2.918,1588,1.712,1591,2.153,1609,3.913,1716,2.918,1717,5.755,1718,6.333,1719,8.147,1720,3.211,1721,6.551,1722,3.211,1723,3.211,1724,3.211,1725,5.095,1726,7.209,1727,3.211,1728,3.211,1729,3.211,1730,2.725,1731,2.918,1732,3.211,1733,3.211,1734,3.211,1735,3.211,1736,3.211,1737,2.918,1738,5.755,1739,3.211,1740,2.918,1741,2.918,1742,3.211]],["tags/183",[]],["title/184",[486,1.903,1591,4.016]],["content/184",[3,0.294,4,1.077,5,1.077,7,1.041,9,1.334,15,1.655,16,0.823,21,0.673,23,0.932,29,1.049,30,0.762,34,1.036,42,0.953,49,1.14,63,0.498,64,1.14,68,2.703,73,1.158,85,3.224,104,1.818,136,1.307,138,0.875,165,1.959,166,2.48,171,0.679,178,0.964,182,0.876,186,1.959,207,2.006,210,1.802,216,1.282,231,1.802,235,1.362,243,0.885,244,1.547,246,0.987,252,2.257,261,2.822,282,0.819,283,0.953,297,0.695,298,1.547,299,1.966,326,1.593,330,2.55,331,3.055,347,1.063,359,3.217,369,1.721,372,1.426,378,2.996,382,1.108,385,0.749,396,1.362,469,4.623,485,2.179,486,2.7,489,0.742,493,4.481,506,3.064,520,1.362,524,2.357,525,3.64,531,1.503,547,2.472,554,4.106,569,2.037,588,1.463,625,2.037,674,1.597,682,1.655,693,1.503,708,2.996,762,2.257,770,1.503,867,2.8,885,2.618,892,1.362,919,2.587,950,2.37,963,1.14,1093,1.597,1111,3.447,1210,1.426,1521,1.902,1555,1.902,1557,3.889,1558,3.889,1572,3.219,1588,3.092,1591,1.503,1609,4.455,1613,3.219,1614,1.721,1696,5.271,1700,3.049,1704,5.661,1719,5.506,1738,3.447,1740,2.037,1743,2.241,1744,4.93,1745,2.037,1746,4.481,1747,3.793,1748,3.447,1749,5.8,1750,2.241,1751,2.241,1752,2.241,1753,5.8,1754,7.948,1755,2.241,1756,7.888,1757,7.043,1758,2.241,1759,3.447,1760,2.037,1761,4.481,1762,2.241,1763,2.241,1764,3.793,1765,2.241,1766,3.793,1767,3.793,1768,2.241,1769,2.241,1770,2.241,1771,2.241,1772,2.241,1773,3.793,1774,3.447,1775,3.793,1776,2.241,1777,2.241,1778,2.241,1779,1.902,1780,2.241,1781,2.241]],["tags/184",[]],["title/185",[1541,6.671]],["content/185",[3,0.342,4,0.989,7,1.398,11,3.155,21,2.587,29,2.12,50,2.238,56,1.222,60,2.697,63,0.595,67,2.814,70,3.64,73,2.339,85,3.477,103,2.589,126,1.863,165,2.339,177,3.227,215,3.861,235,2.752,246,1.993,252,2.694,286,1.654,314,2.694,359,4.322,369,5.086,396,2.752,398,3.478,413,3.227,436,3.478,486,2.104,514,2.441,630,3.884,633,4.44,635,3.64,650,1.884,651,3.036,657,4.115,674,3.227,726,2.64,749,4.115,752,3.126,867,3.343,872,2.752,950,2.176,1091,2.304,1229,2.955,1557,3.036,1558,3.036,1588,3.531,1591,3.036,1617,4.115,1658,4.115,1677,4.115,1686,3.64,1697,4.115,1719,3.843,1721,7.116,1737,4.115,1754,4.115,1782,4.528,1783,6.622,1784,4.528,1785,8.615,1786,4.528,1787,3.64,1788,4.528,1789,4.528,1790,4.115,1791,4.115,1792,6.018,1793,4.528,1794,3.843,1795,4.528,1796,4.528]],["tags/185",[]],["title/186",[66,2.251,860,3.64]],["content/186",[3,0.37,4,1.368,5,2.019,6,2.899,7,1.753,8,2.741,9,2.499,10,1.506,11,3.755,12,2.552,13,2.137,14,0.747,15,3.1,16,1.625,17,2.606,22,1.625,28,1.242,38,5.317,48,2.673,56,1.134,60,1.71,63,0.552,66,2.815,84,2.358,104,1.018,108,1.917,121,1.453,124,2.203,143,1.593,162,1.729,169,1.52,173,2.499,191,1.593,192,1.806,207,1.453,235,2.552,244,2.899,251,1.992,262,2.993,265,2.316,275,2.899,286,2.288,290,2.499,297,1.942,305,1.806,329,1.391,330,1.428,331,1.71,332,1.992,345,2.169,349,1.334,382,2.075,445,2.023,470,3.1,473,1.345,485,1.578,489,2.075,492,2.673,508,2.673,518,3.053,531,2.816,618,1.871,628,2.899,675,2.047,703,3.817,711,2.019,781,2.61,800,2.61,845,2.023,903,2.61,904,2.552,905,2.993,906,2.899,907,2.993,908,2.899,918,5.339,949,2.277,950,2.019,961,2.239,1085,3.226,1209,2.741,1306,3.1,1307,2.993,1567,3.817,1686,5.036,1797,4.2]],["tags/186",[]],["title/187",[11,1.764,67,2.721,102,2.605,1798,3.979]],["content/187",[3,0.35,4,2.048,12,3.319,13,2.778,16,1.184,17,3.148,19,2.247,22,2.113,28,2.238,29,3.543,30,1.856,43,3.564,47,3.123,57,3.77,84,3.066,94,1.442,101,2.928,104,1.834,124,2.865,132,1.889,136,3.184,148,1.092,166,1.923,169,1.976,176,1.519,191,2.072,192,2.349,196,3.184,376,3.123,391,5.984,414,3.475,472,3.661,504,3.011,511,3.77,545,2.816,547,2.738,554,3.184,586,2.96,721,4.328,838,3.011,893,5.393,894,3.892,895,3.892,896,3.892,897,5.224,898,3.661,899,2.821,900,3.892,901,3.892,902,3.564,1150,4.031,1798,4.963,1799,5.461]],["tags/187",[]],["title/188",[19,2.465,42,2.548]],["content/188",[3,0.266,4,1.56,7,1.507,10,2.561,12,4.341,16,1.961,17,3.762,41,5.09,42,3.846,44,6.491,47,4.085,50,3.53,76,3.634,152,4.341,217,3.634,231,5.742,246,3.144,251,3.388,261,3.108,489,2.366,505,2.736,545,2.658,830,3.808,835,6.491,898,4.789,1321,4.545,1560,6.062,1800,7.143,1801,6.062]],["tags/188",[]],["title/189",[17,2.105,47,2.893,191,1.919]],["content/189",[3,0.264,10,3.545,16,1.537,17,2.949,19,2.917,41,5.051,42,4.424,47,4.054,51,5.444,53,6.016,55,6.442,213,5.051,248,4.405,305,3.049,314,4.217,399,3.842,515,5.698,674,6.414,931,5.051,934,4.893,1692,6.442,1802,7.088,1803,7.088,1804,7.088,1805,5.444,1806,7.088,1807,7.088]],["tags/189",[]],["title/190",[47,2.893,160,2.697,712,3.219]],["content/190",[3,0.341,4,1.316,11,2.429,14,0.681,22,2.332,28,1.783,32,2.104,41,4.296,47,3.448,51,4.63,63,0.792,66,2.265,69,4.296,76,3.067,94,1.592,113,5.117,125,2.786,146,4.63,160,3.214,162,2.481,163,2.654,171,1.825,174,3.114,199,2.067,240,1.558,266,1.335,275,4.162,283,2.564,355,3.268,381,4.162,389,4.296,393,3.163,395,4.296,414,3.836,440,3.747,484,2.123,545,2.244,546,2.752,571,2.223,606,4.042,611,5.479,712,3.836,892,3.664,943,3.163,955,3.268,1091,3.067,1369,4.846,1549,5.479,1787,4.846,1808,5.479,1809,6.029,1810,5.117,1811,6.029]],["tags/190",[]],["title/191",[168,2.919,404,1.441]],["content/191",[3,0.393,4,1.144,7,1.368,9,1.979,14,0.894,16,1.734,28,0.984,42,1.415,56,1.414,60,2.133,63,0.437,108,2.391,120,1.979,122,1.861,138,2.282,142,1.979,143,1.987,176,1.457,198,2.089,199,1.141,201,2.853,246,1.464,266,2.098,287,1.993,292,1.238,299,2.089,320,1.34,326,1.074,329,1.735,330,1.781,331,2.133,349,1.664,385,2.456,404,1.559,405,3.256,423,1.706,445,1.414,473,2.847,600,2.296,618,2.333,671,2.456,686,2.117,687,3.56,694,2.452,695,1.621,706,2.279,760,3.395,802,2.253,836,1.415,845,0.898,899,1.718,909,2.665,1082,2.23,1091,3.297,1152,3.616,1224,2.296,1227,4.027,1232,4.229,1279,2.23,1307,2.371,1574,2.555,1812,3.616,1813,3.616,1814,2.555]],["tags/191",[]],["title/192",[3,0.223,320,2.414]],["content/192",[3,0.339,60,3.708,138,2.101,385,3.042]],["tags/192",[]],["title/193",[1815,3.437]],["content/193",[3,0.339,60,3.708,138,2.101,385,3.042]],["tags/193",[]],["title/194",[384,2.171]],["content/194",[106,4.665,320,3.669,1816,4.263]],["tags/194",[]],["title/195",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/195",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/195",[]],["title/196",[3,0.189,201,2.227,320,2.039]],["content/196",[138,2.081,201,3.969,292,3.356,326,2.913,385,3.013]],["tags/196",[]],["title/197",[1815,3.437]],["content/197",[3,0.312,7,1.766,16,1.815,138,1.931,201,4.387,292,3.114,320,3.371,326,2.703,385,2.795,655,5.2,1822,8.367,1823,3.819]],["tags/197",[]],["title/198",[384,2.171]],["content/198",[4,1.832,7,1.342,16,1.379,63,1.234,94,2.216,105,3.285,106,3.737,129,4.047,201,2.799,266,1.408,268,3.507,287,1.585,319,3.783,326,2.71,329,2.107,334,5.397,386,5.82,414,4.047,529,4.047,574,7.12,763,2.46,981,5.112,1167,5.397,1816,2.977,1821,3.864,1824,6.359,1825,6.359,1826,6.359,1827,6.359,1828,6.359,1829,6.359,1830,6.359,1831,6.359,1832,6.359,1833,6.359,1834,6.359]],["tags/198",[]],["title/199",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/199",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/199",[]],["title/200",[3,0.163,122,1.556,320,1.764,405,2.721]],["content/200",[7,1.885,16,1.937,122,3.173,138,2.061,199,3.062,405,5.55]],["tags/200",[]],["title/201",[1815,3.437]],["content/201",[3,0.306,7,1.735,16,1.782,122,3.503,138,1.896,199,2.818,201,3.618,233,3.382,282,3.002,320,3.973,405,6.128,1823,3.751]],["tags/201",[]],["title/202",[384,2.171]],["content/202",[106,4.256,122,3.67,281,5.465,396,5.807,405,6.419,1302,7.092,1816,3.653,1821,3.933,1835,9.136,1836,7.092]],["tags/202",[]],["title/203",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/203",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/203",[]],["title/204",[3,0.163,299,1.746,320,1.764,1091,2.228]],["content/204",[7,1.885,16,1.937,299,3.562,445,2.411,1091,4.543,1152,6.165]],["tags/204",[]],["title/205",[1815,3.437]],["content/205",[3,0.318,7,1.798,16,1.848,299,4.018,320,3.433,445,2.3,1091,5.125,1152,5.882,1823,3.889]],["tags/205",[]],["title/206",[384,2.171]],["content/206",[106,4.639,299,3.596,1091,4.588,1816,4.221]],["tags/206",[]],["title/207",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/207",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/207",[]],["title/208",[3,0.163,4,0.956,287,1.092,320,1.764]],["content/208",[4,1.969,287,2.248,404,2.17,445,2.435,1152,6.225]],["tags/208",[]],["title/209",[1815,3.437]],["content/209",[3,0.321,4,2.212,287,2.525,320,3.465,404,2.069,445,2.322,1152,5.936,1823,3.925]],["tags/209",[]],["title/210",[384,2.171]],["content/210",[4,1.969,106,4.639,287,2.248,1816,4.221]],["tags/210",[]],["title/211",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/211",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/211",[]],["title/212",[3,0.189,320,2.039,694,2.368]],["content/212",[138,2.081,143,3.421,287,2.248,385,3.013,694,4.221]],["tags/212",[]],["title/213",[1815,3.437]],["content/213",[3,0.324,138,2.003,143,3.293,287,2.164,320,3.498,385,2.9,694,4.768,1823,3.962]],["tags/213",[]],["title/214",[384,2.171]],["content/214",[106,4.665,694,4.263,1816,4.263]],["tags/214",[]],["title/215",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/215",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/215",[]],["title/216",[3,0.223,266,1.326]],["content/216",[3,0.333,14,0.751,16,1.937,108,4.076,266,1.977,1091,4.543]],["tags/216",[]],["title/217",[1815,3.437]],["content/217",[3,0.38,14,0.73,16,1.883,108,3.962,266,2.255,1091,4.416,1823,3.962]],["tags/217",[]],["title/218",[384,2.171]],["content/218",[14,0.717,106,4.488,266,2.23,351,4.783,509,3.297,1216,4.968,1231,5.069,1593,4.968,1816,3.989]],["tags/218",[]],["title/219",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/219",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/219",[]],["title/220",[3,0.223,760,2.208]],["content/220",[3,0.339,14,0.766,138,2.101,760,3.357]],["tags/220",[]],["title/221",[1815,3.437]],["content/221",[3,0.378,14,0.852,138,1.984,198,3.43,473,2.755,760,3.734,1823,3.925]],["tags/221",[]],["title/222",[384,2.171]],["content/222",[3,0.202,17,2.259,105,2.804,106,3.357,145,3.374,148,2.126,153,4.008,171,1.644,199,1.861,261,2.362,268,2.994,270,5.789,317,3.64,325,2.418,326,1.754,342,2.61,349,2.395,351,3.048,385,2.518,423,1.768,457,6.17,473,1.739,509,3.35,545,2.02,571,2.001,600,3.748,607,1.798,707,4.58,760,2.001,763,2.1,836,2.309,929,3.105,968,3.748,977,3.869,1216,3.165,1231,3.23,1593,3.165,1816,2.541,1821,2.234,1837,6.397,1838,5.789,1839,4.608,1840,6.649,1841,6.17,1842,4.008,1843,4.934,1844,4.934,1845,5.429,1846,4.608,1847,4.17,1848,4.17]],["tags/222",[]],["title/223",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/223",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/223",[]],["title/224",[3,0.223,1279,4.016]],["content/224",[14,0.773,56,2.483,1232,6.001]],["tags/224",[]],["title/225",[1815,3.437]],["content/225",[14,0.773,56,2.483,1232,6.001]],["tags/225",[]],["title/226",[384,2.171]],["content/226",[106,4.665,1279,6.105,1816,4.263]],["tags/226",[]],["title/227",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/227",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/227",[]],["title/228",[3,0.189,246,2.227,1279,3.392]],["content/228",[14,0.758,143,3.421,198,3.596,266,1.996,1232,5.885]],["tags/228",[]],["title/229",[1815,3.437]],["content/229",[3,0.293,14,0.808,63,1.034,143,2.986,198,3.139,235,4.783,240,2.034,246,3.464,266,1.742,298,5.433,303,2.675,667,3.274,721,4.501,862,4.196,1232,5.136,1279,6.44,1823,3.592,1849,7.87]],["tags/229",[]],["title/230",[384,2.171]],["content/230",[3,0.304,106,4.369,246,3.586,326,3.168,385,3.277,457,7.5,1124,5.063,1816,3.814,1838,7.533,1839,6.914]],["tags/230",[]],["title/231",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/231",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/231",[]],["title/232",[3,0.189,1082,3.392,1279,3.392]],["content/232",[14,0.773,1227,5.715,1232,6.001]],["tags/232",[]],["title/233",[1815,3.437]],["content/233",[3,0.33,14,0.744,1082,5.931,1227,5.497,1232,5.772,1279,5.931,1823,4.037]],["tags/233",[]],["title/234",[384,2.171]],["content/234",[14,0.717,106,4.488,351,4.783,509,3.297,802,3.665,1082,5.713,1216,4.968,1231,5.069,1593,4.968,1816,3.989]],["tags/234",[]],["title/235",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/235",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/235",[]],["title/236",[3,0.223,909,3.047]],["content/236",[3,0.339,14,0.766,899,4.703,909,4.633]],["tags/236",[]],["title/237",[1815,3.437]],["content/237",[3,0.36,4,1.733,14,0.812,199,2.722,287,2.407,424,3.815,473,2.543,607,2.629,650,3.302,899,5.375,909,5.294,1823,3.623]],["tags/237",[]],["title/238",[384,2.171]],["content/238",[106,4.665,909,4.633,1816,4.263]],["tags/238",[]],["title/239",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/239",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/239",[]],["title/240",[3,0.223,176,1.666]],["content/240",[3,0.336,14,0.758,28,2.666,142,5.365,176,2.508]],["tags/240",[]],["title/241",[1815,3.437]],["content/241",[3,0.394,14,0.691,28,2.43,142,4.89,144,4.312,176,2.743,261,3.576,310,5.363,319,4.89,1823,3.751,1850,7.469,1851,6.067]],["tags/241",[]],["title/242",[384,2.171]],["content/242",[2,3.866,14,0.776,61,4.297,94,1.946,106,4.108,176,2.565,240,2.383,276,4.58,277,4.58,430,6.184,529,4.69,974,5.66,1127,5.087,1152,5.087,1221,5.275,1291,5.252,1816,3.45,1821,4.143,1852,6.698,1853,7.37]],["tags/242",[]],["title/243",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/243",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/243",[]],["title/244",[3,0.223,473,1.919]],["content/244",[3,0.336,14,0.758,473,2.889,706,3.923,760,3.324]],["tags/244",[]],["title/245",[1815,3.437]],["content/245",[3,0.336,14,0.758,473,2.889,706,3.923,760,3.324]],["tags/245",[]],["title/246",[384,2.171]],["content/246",[106,4.665,473,2.917,1816,4.263]],["tags/246",[]],["title/247",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/247",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/247",[]],["title/248",[3,0.189,423,1.648,473,1.621]],["content/248",[9,5.471,423,2.995,473,2.946]],["tags/248",[]],["title/249",[1815,3.437]],["content/249",[3,0.38,14,0.73,423,3.318,473,3.263,760,3.2,1823,3.962]],["tags/249",[]],["title/250",[384,2.171]],["content/250",[63,1.188,106,4.028,143,3.431,148,1.808,168,3.481,287,2.474,319,4.25,320,3.644,325,4.028,326,2.921,327,5.742,385,2.386,423,2.327,1816,3.344,1821,3.722,1836,6.491,1854,7.143,1855,9.043,1856,8.219,1857,6.491]],["tags/250",[]],["title/251",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/251",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/251",[]],["title/252",[3,0.189,473,1.621,760,1.865]],["content/252",[3,0.339,14,0.766,473,2.917,760,3.357]],["tags/252",[]],["title/253",[1815,3.437]],["content/253",[3,0.376,14,0.717,138,1.966,473,3.227,760,3.954,1614,6.544,1823,3.889]],["tags/253",[]],["title/254",[384,2.171]],["content/254",[14,0.663,17,2.414,56,1.567,63,0.762,64,2.952,105,2.997,106,3.514,122,2.062,148,2.011,153,4.283,171,2.388,199,1.99,261,2.525,270,6.059,317,3.89,342,2.789,351,3.257,473,2.527,509,3.052,545,2.159,571,2.139,607,1.922,707,4.795,760,2.139,763,2.245,836,2.468,929,3.318,953,2.997,968,4.005,977,4.135,1216,3.383,1231,3.452,1593,3.383,1816,2.716,1821,2.388,1837,6.696,1840,6.885,1841,6.389,1842,4.283,1843,5.273,1846,4.925,1847,6.059,1848,4.456,1858,5.803,1859,5.803]],["tags/254",[]],["title/255",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/255",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/255",[]],["title/256",[3,0.223,618,2.668]],["content/256",[3,0.336,14,0.758,618,4.017,671,6.657,1224,6.225]],["tags/256",[]],["title/257",[1815,3.437]],["content/257",[3,0.36,14,0.667,80,2.675,121,2.746,158,3.979,256,6.381,297,2.461,421,4.302,456,5.18,509,3.071,616,3.979,618,4.301,1091,5.294,1823,3.623,1860,6.096]],["tags/257",[]],["title/258",[384,2.171]],["content/258",[106,4.488,430,6.754,618,3.795,974,6.544,1091,4.335,1291,6.072,1816,3.989,1821,3.507,1852,7.744]],["tags/258",[]],["title/259",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/259",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/259",[]],["title/260",[3,0.223,802,2.577]],["content/260",[3,0.343,14,0.773,802,3.956]],["tags/260",[]],["title/261",[1815,3.437]],["content/261",[3,0.372,14,0.838,93,5.085,481,5.963,485,3.144,486,2.658,802,4.287,803,6.177,1228,6.726,1823,3.819]],["tags/261",[]],["title/262",[384,2.171]],["content/262",[14,0.717,106,4.488,351,4.783,509,3.297,802,4.333,1216,4.968,1231,5.069,1593,4.968,1816,3.989]],["tags/262",[]],["title/263",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/263",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/263",[]],["title/264",[3,0.223,687,2.251]],["content/264",[7,1.903,16,1.956,60,3.672,138,2.081,687,3.388]],["tags/264",[]],["title/265",[1815,3.437]],["content/265",[7,1.903,16,1.956,60,3.672,138,2.081,687,3.388]],["tags/265",[]],["title/266",[384,2.171]],["content/266",[106,4.665,687,3.421,1816,4.263]],["tags/266",[]],["title/267",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/267",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/267",[]],["title/268",[3,0.189,266,1.12,687,1.901]],["content/268",[3,0.33,14,0.744,16,1.918,108,4.037,138,2.041,266,1.958,687,3.324]],["tags/268",[]],["title/269",[1815,3.437]],["content/269",[3,0.33,14,0.744,16,1.918,108,4.037,138,2.041,266,1.958,687,3.324]],["tags/269",[]],["title/270",[384,2.171]],["content/270",[31,3.464,36,3.548,106,4.278,138,1.816,266,2.126,320,3.87,325,4.278,351,4.418,385,2.629,509,3.045,687,3.609,1216,4.589,1231,4.682,1593,4.589,1816,3.684]],["tags/270",[]],["title/271",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/271",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/271",[]],["title/272",[3,0.163,266,0.969,329,1.45,687,1.645]],["content/272",[3,0.333,14,0.751,138,2.061,266,1.977,329,2.958,687,3.356]],["tags/272",[]],["title/273",[1815,3.437]],["content/273",[3,0.376,14,0.717,138,1.966,266,2.23,329,3.337,687,3.785,1823,3.889]],["tags/273",[]],["title/274",[384,2.171]],["content/274",[3,0.275,34,3.406,80,3.108,105,3.807,106,4.108,266,1.632,297,2.285,329,3.055,445,1.99,650,3.066,741,4.297,763,3.568,962,3.17,1011,5.66,1041,4.69,1160,6.255,1162,6.367,1163,6.809,1816,3.45,1821,3.796,1848,5.66]],["tags/274",[]],["title/275",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/275",[3,0.247,14,0.558,31,2.919,36,2.99,138,1.53,166,2.335,266,1.468,287,1.653,320,3.475,325,3.841,326,2.142,351,3.723,385,2.216,423,2.16,484,3.374,509,2.566,514,2.445,571,2.445,580,2.445,676,3.065,687,3.24,777,2.886,816,2.853,832,3.439,845,1.791,1123,3.027,1216,3.867,1231,3.946,1298,2.99,1562,3.065,1593,3.867,1819,3.796,1820,3.065,1821,3.549]],["tags/275",[]],["title/276",[3,0.163,266,0.969,330,1.488,687,1.645]],["content/276",[3,0.33,14,0.744,138,2.041,266,1.958,330,3.007,687,3.324,1307,6.304]],["tags/276",[]],["title/277",[1815,3.437]],["content/277",[3,0.374,14,0.71,138,1.948,266,2.218,330,3.406,687,3.765,1307,6.017,1823,3.854]],["tags/277",[]],["title/278",[384,2.171]],["content/278",[14,0.554,80,3.41,106,3.823,148,1.317,182,2.573,192,2.832,216,3.766,266,2.114,276,4.092,330,2.917,489,2.181,687,2.474,741,3.839,763,3.694,920,3.839,928,3.918,962,3.692,1041,5.462,1163,4.861,1174,5.589,1181,5.589,1182,4.002,1183,5.589,1323,5.058,1816,3.083,1821,4.164,1861,5.589,1862,6.585,1863,6.585]],["tags/278",[]],["title/279",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/279",[3,0.247,14,0.558,31,2.919,36,2.99,138,1.53,166,2.335,266,1.468,287,1.653,320,3.475,325,3.841,326,2.142,351,3.723,385,2.216,423,2.16,484,3.374,509,2.566,514,2.445,571,2.445,580,2.445,676,3.065,687,3.24,777,2.886,816,2.853,832,3.439,845,1.791,1123,3.027,1216,3.867,1231,3.946,1298,2.99,1562,3.065,1593,3.867,1819,3.796,1820,3.065,1821,3.549]],["tags/279",[]],["title/280",[3,0.163,266,0.969,331,1.783,687,1.645]],["content/280",[3,0.333,14,0.751,138,2.061,266,1.977,331,3.637,687,3.356]],["tags/280",[]],["title/281",[1815,3.437]],["content/281",[3,0.376,14,0.717,138,1.966,266,2.23,331,4.102,687,3.785,1823,3.889]],["tags/281",[]],["title/282",[384,2.171]],["content/282",[1,5.55,14,0.55,32,2.282,80,3.207,105,3.377,106,3.806,138,1.509,266,1.891,276,5.914,297,2.027,331,3.875,443,6.089,489,2.166,545,2.433,706,3.717,799,5.55,872,3.974,928,3.89,1162,6.569,1163,6.307,1816,3.061,1821,3.916,1864,6.539,1865,6.539,1866,6.539,1867,5.942,1868,6.539,1869,6.539,1870,6.539]],["tags/282",[]],["title/283",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/283",[3,0.247,14,0.558,31,2.919,36,2.99,138,1.53,166,2.335,266,1.468,287,1.653,320,3.475,325,3.841,326,2.142,351,3.723,385,2.216,423,2.16,484,3.374,509,2.566,514,2.445,571,2.445,580,2.445,676,3.065,687,3.24,777,2.886,816,2.853,832,3.439,845,1.791,1123,3.027,1216,3.867,1231,3.946,1298,2.99,1562,3.065,1593,3.867,1819,3.796,1820,3.065,1821,3.549]],["tags/283",[]],["title/284",[3,0.189,687,1.901,1227,3.144]],["content/284",[138,2.041,385,2.955,687,3.324,695,4.31,836,3.762,845,2.388,1227,5.497]],["tags/284",[]],["title/285",[1815,3.437]],["content/285",[3,0.318,138,1.966,385,2.847,687,3.785,695,4.152,836,3.624,845,2.3,1227,6.261,1823,3.889]],["tags/285",[]],["title/286",[384,2.171]],["content/286",[106,4.463,138,1.948,351,4.74,509,3.267,687,3.172,1056,7.166,1216,4.923,1227,6.227,1231,5.023,1816,3.953]],["tags/286",[]],["title/287",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/287",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/287",[]],["title/288",[3,0.189,473,1.621,687,1.901]],["content/288",[473,2.889,687,3.388,706,3.923,760,3.324,1812,6.225]],["tags/288",[]],["title/289",[1815,3.437]],["content/289",[473,2.889,687,3.388,706,3.923,760,3.324,1812,6.225]],["tags/289",[]],["title/290",[384,2.171]],["content/290",[106,4.665,473,2.917,1816,4.263]],["tags/290",[]],["title/291",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/291",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/291",[]],["title/292",[3,0.163,473,1.403,687,1.645,760,1.614]],["content/292",[473,2.917,687,3.421,760,3.357,1812,6.286]],["tags/292",[]],["title/293",[1815,3.437]],["content/293",[3,0.324,473,3.263,687,3.827,760,3.755,1812,5.992,1823,3.962]],["tags/293",[]],["title/294",[384,2.171]],["content/294",[106,4.488,171,2.579,351,4.783,473,2.73,509,3.297,760,3.141,1216,4.968,1231,5.069,1593,4.968,1816,3.989]],["tags/294",[]],["title/295",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/295",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/295",[]],["title/296",[3,0.223,287,1.493]],["content/296",[287,2.293,404,2.213,1574,7.063]],["tags/296",[]],["title/297",[1815,3.437]],["content/297",[3,0.333,287,2.582,404,2.149,1574,6.859,1823,4.076]],["tags/297",[]],["title/298",[384,2.171]],["content/298",[106,4.665,287,2.27,1816,4.263]],["tags/298",[]],["title/299",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/299",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/299",[]],["title/300",[3,0.223,600,4.135]],["content/300",[3,0.343,14,0.773,198,3.668]],["tags/300",[]],["title/301",[1815,3.437]],["content/301",[3,0.38,4,1.895,14,0.73,28,2.567,93,5.275,198,3.462,600,5.992,1823,3.962]],["tags/301",[]],["title/302",[384,2.171]],["content/302",[3,0.275,106,4.108,317,4.941,326,2.381,385,3.081,457,7.174,509,2.851,545,2.743,571,2.717,600,5.087,607,2.441,707,5.605,968,5.087,1816,3.45,1837,7.828,1838,7.084,1839,6.255,1840,5.66,1841,6.573,1842,5.44]],["tags/302",[]],["title/303",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/303",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/303",[]],["title/304",[3,0.223,1813,4.135]],["content/304",[42,3.835,120,5.365,201,3.969,1813,6.225,1814,6.926]],["tags/304",[]],["title/305",[1815,3.437]],["content/305",[3,0.374,14,0.71,42,3.591,120,5.023,201,3.717,571,3.113,1813,7.376,1814,6.485,1823,3.854]],["tags/305",[]],["title/306",[384,2.171]],["content/306",[106,4.488,121,3.485,145,5.295,440,5.295,816,3.665,1813,6.955,1816,3.989,1821,3.507]],["tags/306",[]],["title/307",[349,1.391,384,1.295,1817,2.05,1818,2.05]],["content/307",[3,0.279,14,0.63,166,2.637,287,1.867,326,2.419,423,2.439,484,3.571,514,2.761,571,2.761,580,2.761,676,3.461,777,3.258,816,3.221,832,3.715,845,2.022,1123,3.418,1298,3.376,1562,3.461,1819,4.101,1820,3.461,1821,3.834]],["tags/307",[]],["title/308",[694,3.437]],["content/308",[2,4.164,3,0.36,63,1.043,143,3.011,215,4.628,263,3.868,286,2.899,320,3.891,325,3.536,385,2.652,453,4.1,504,4.377,529,5.051,694,4.52,931,5.657,1871,5.859]],["tags/308",[]],["title/309",[694,2.804,1872,5.99]],["content/309",[]],["tags/309",[]],["title/310",[330,2.495]],["content/310",[3,0.271,4,1.126,7,1.088,11,2.078,14,0.434,49,2.624,123,3.807,148,2.056,176,1.434,207,2.515,233,2.123,239,3.068,246,2.27,269,2.624,276,3.205,305,2.218,316,3.366,319,3.068,320,2.078,324,2.446,330,1.753,342,2.479,404,1.241,473,1.652,616,2.585,630,2.325,694,2.414,696,5.845,763,1.995,836,3.89,899,2.664,962,3.934,1129,3.807,1165,3.282,1182,3.134,1259,6.171,1299,4.377,1301,8.581,1464,4.146,1495,6.171,1851,3.807,1871,3.807,1873,4.146,1874,5.157,1875,5.157,1876,5.157,1877,5.157,1878,5.157,1879,5.157,1880,5.157,1881,5.157,1882,5.157,1883,5.157,1884,7.271,1885,5.157,1886,4.687]],["tags/310",[]],["title/311",[163,1.699,287,0.962,404,0.929,694,1.807,1887,3.86]],["content/311",[]],["tags/311",[]],["title/312",[329,2.432]],["content/312",[3,0.286,14,0.645,30,2.609,63,1.243,80,2.586,263,3.74,329,2.542,473,3.03,687,3.852,760,3.487,763,2.969,899,3.964,929,4.389,952,4.026,1215,5.298,1328,5.298,1888,5.665,1889,5.008]],["tags/312",[]],["title/313",[163,1.699,287,0.962,404,0.929,694,1.807,1890,3.86]],["content/313",[]],["tags/313",[]],["title/314",[330,2.495]],["content/314",[3,0.237,4,1.389,16,1.819,56,2.265,63,0.836,162,4.108,163,2.799,221,4.264,263,3.099,266,2.078,299,3.346,303,2.851,318,2.46,330,2.851,436,4.884,446,5.779,473,2.687,489,2.779,545,2.367,627,3.188,697,5.779,760,2.344,838,3.507,845,1.717,929,3.637,950,4.798,952,4.401,1049,4.884,1140,4.047,1219,4.047,1301,5.112,1891,5.779]],["tags/314",[]],["title/315",[163,1.699,287,0.962,404,0.929,694,1.807,1892,3.86]],["content/315",[3,0.339,14,0.675,16,1.291,40,3.617,56,1.607,63,1.193,143,2.258,144,3.122,145,4.988,182,2.326,185,3.282,266,1.777,303,2.023,320,2.398,330,2.023,445,1.607,458,3.99,465,3.403,506,3.698,518,2.9,521,3.99,622,4.784,687,2.236,694,2.786,716,2.9,726,3.47,838,4.426,951,3.173,1114,4.784,1124,3.698,1328,5.541,1369,4.784,1805,4.571,1860,4.571,1861,5.051,1888,4.393,1893,5.409,1894,5.951,1895,3.47,1896,9.082,1897,5.409,1898,5.951,1899,5.951,1900,5.951,1901,5.951,1902,5.409,1903,5.951]],["tags/315",[]],["title/316",[163,1.699,287,0.962,404,0.929,694,1.807,1904,3.86]],["content/316",[3,0.214,7,1.209,14,0.482,16,1.243,63,1.028,80,1.931,138,1.805,161,2.036,162,2.359,198,2.285,221,3.842,240,2.302,263,2.793,266,1.269,268,3.16,303,2.659,329,2.591,349,1.821,473,2.853,586,3.106,651,3.842,667,2.384,687,3.347,691,3.483,760,2.884,862,3.055,877,4.607,899,2.96,929,3.277,950,2.755,1182,4.754,1215,3.956,1219,3.647,1328,3.956,1805,4.401,1823,2.616,1888,4.23,1889,3.74,1895,5.193,1905,5.731,1906,4.864,1907,7.11,1908,4.864,1909,5.208,1910,5.208,1911,4.401,1912,7.16]],["tags/316",[]],["title/317",[163,1.699,287,0.962,404,0.929,694,1.807,1913,3.86]],["content/317",[56,2.343,321,5.992,431,5.523,465,4.964,694,4.063,838,4.787,1893,7.889,1895,5.061,1914,8.68]],["tags/317",[]],["title/318",[163,1.699,287,0.962,404,0.929,694,1.807,1915,3.86]],["content/318",[7,1.899,16,1.952,63,0.931,80,2.389,94,2.611,122,2.518,161,2.518,330,2.409,384,2.096,409,6.442,475,6.643,489,2.981,838,3.909,1219,4.511,1895,6.397,1906,8.392,1916,6.442,1917,7.088,1918,7.088,1919,7.088]],["tags/318",[]],["title/319",[163,1.699,287,0.962,404,0.929,694,1.807,1920,3.86]],["content/319",[3,0.1,7,0.568,16,0.583,61,2.575,63,0.353,87,1.17,104,0.652,122,2.551,123,1.986,138,1.019,143,1.675,148,1.543,161,0.956,171,0.814,199,2.646,214,1.483,240,0.695,283,1.878,320,2.263,329,2.92,330,3.084,331,2.924,343,6.203,344,2.479,345,3.358,356,4.147,396,1.635,405,1.672,423,0.876,449,1.131,475,3.26,489,0.891,526,2.162,672,1.986,694,2.63,705,2.445,838,3.585,887,2.445,899,1.389,1039,4.003,1124,1.672,1713,1.857,1813,1.857,1838,2.066,1871,3.26,1895,4.186,1906,2.283,1921,2.69,1922,2.69,1923,5.617,1924,2.69,1925,8.815,1926,2.69,1927,7.717,1928,2.69,1929,2.69,1930,2.69,1931,7.717,1932,2.69,1933,2.69,1934,2.69,1935,7.717,1936,2.69,1937,2.69,1938,9.073,1939,9.073,1940,9.073,1941,9.073,1942,9.073,1943,2.69,1944,2.69,1945,2.69,1946,2.69,1947,2.69,1948,2.69,1949,2.69,1950,5.617,1951,2.69,1952,2.69,1953,5.617,1954,2.69,1955,7.18,1956,7.18,1957,7.18,1958,6.502,1959,2.69,1960,2.283,1961,4.416,1962,4.013,1963,4.416]],["tags/319",[]],["title/320",[118,1.373,125,1.442,160,1.663,514,1.15,712,1.985,935,1.896,936,1.939]],["content/320",[3,0.231,5,3.961,11,2.494,80,2.086,95,2.468,98,3.22,118,2.725,125,2.861,159,3.544,160,3.3,164,2.975,172,2.662,263,4.015,275,4.273,302,3.103,307,2.861,401,3.683,486,1.967,504,3.413,514,3.415,627,3.103,678,3.016,712,3.939,752,5.688,885,4.273,892,3.761,904,3.761,909,3.149,933,4.569,935,6.25,936,5.121,937,4.754,938,4.754,939,4.569,940,4.039,941,4.273,942,4.754,1090,3.609,1964,5.625]],["tags/320",[]],["title/321",[344,2.84,514,1.865,936,3.144]],["content/321",[63,1.052,82,3.654,90,4.865,159,4.175,201,4.272,207,2.769,297,2.482,404,1.926,884,6.334,935,4.865,1873,6.436,1965,7.276,1966,6.795,1967,7.454]],["tags/321",[]],["title/322",[345,2.613,514,1.865,936,3.144]],["content/322",[3,0.239,63,1.366,83,3.662,90,5.121,159,4.052,163,2.819,176,1.781,180,4.647,201,4.406,282,2.339,287,1.596,302,3.21,303,2.176,399,3.471,404,2.267,465,3.662,489,2.792,588,4.179,721,3.662,884,6.786,935,5.121,1967,7.987,1968,5.819,1969,6.403]],["tags/322",[]],["title/323",[346,2.574,514,1.865,936,3.144]],["content/323",[3,0.136,7,0.768,46,2.795,63,1.014,80,2.971,87,1.584,90,2.212,104,0.882,117,1.531,118,1.602,131,2.795,143,1.381,154,3.343,159,3.792,161,1.997,163,1.602,164,1.749,171,1.102,172,2.217,176,1.012,180,2.007,182,1.422,191,1.381,192,2.417,195,3.853,201,3.021,204,1.88,207,1.259,216,3.214,217,1.852,218,2.44,233,1.498,241,2.44,263,3.761,269,1.852,297,1.129,302,2.817,303,1.237,322,4.148,342,1.749,346,1.852,355,1.973,385,1.216,431,2.316,437,3.659,442,3.089,465,2.081,476,2.687,481,2.594,494,2.926,514,1.342,627,1.825,650,1.514,672,5.067,689,2.926,708,3.415,721,4.414,836,1.548,858,5.107,871,3.308,884,6.194,892,2.212,922,2.44,935,4.171,1124,2.262,1156,2.122,1303,3.089,1384,2.795,1601,4.005,1731,3.308,1791,5.107,1838,2.795,1967,4.316,1970,6.864,1971,5.619,1972,6.238,1973,3.64,1974,3.64,1975,3.64,1976,3.64,1977,6.864,1978,5.619,1979,3.64,1980,3.64,1981,3.64,1982,5.107,1983,7.719,1984,5.107,1985,3.64,1986,3.308,1987,5.619,1988,3.64,1989,3.64,1990,3.64]],["tags/323",[]],["title/324",[347,2.4,514,1.865,1991,4.598]],["content/324",[5,3.689,61,4.475,98,2.999,154,4.566,177,5.469,263,3.74,347,4.486,401,4.566,445,2.072,514,3.487,588,5.008,909,3.904,935,6.231,936,4.769,1790,6.975,1964,6.975,1992,7.675,1993,7.675,1994,7.675]],["tags/324",[]],["title/325",[686,3.812,845,1.617]],["content/325",[2,3.53,3,0.324,16,1.459,17,2.799,30,2.958,34,3.11,36,3.033,56,1.817,63,1.144,80,2.267,83,3.848,95,3.471,96,3.587,126,2.769,238,4.181,303,2.287,305,3.744,314,4.003,324,3.191,452,3.071,627,3.373,679,5.711,686,4.282,763,3.367,845,2.605,932,5.168,933,4.967,934,4.645,954,3.071,1090,3.923,1995,6.728,1996,6.728]],["tags/325",[]],["title/326",[292,1.883,385,1.69,845,1.366]],["content/326",[3,0.376,14,0.491,40,3.548,60,2.378,63,0.767,90,3.548,138,1.828,157,4.31,164,2.807,233,2.403,238,3.629,242,3.339,250,3.915,258,3.81,265,3.22,266,1.293,282,2.133,292,3.347,324,2.769,349,2.517,385,3.369,404,1.405,650,2.429,659,4.694,687,3.379,741,3.404,760,2.153,763,2.259,788,4.031,802,2.511,832,3.16,834,3.548,836,2.483,845,2.871,846,8.186,1156,3.404,1801,4.956]],["tags/326",[]],["title/327",[324,2.4,459,3.605,845,1.366]],["content/327",[3,0.346,16,1.611,63,0.976,64,3.779,85,2.818,207,2.57,266,1.645,292,2.765,305,3.987,324,3.523,404,2.23,459,6.606,487,6.751,522,6.305,763,2.874,845,2.503,1129,5.484,1506,6.305,1616,6.305,1997,7.429,1998,7.429,1999,7.429]],["tags/327",[]],["title/328",[845,1.617,1819,2.637]],["content/328",[3,0.258,73,3.579,161,2.462,171,2.098,182,2.708,385,2.964,404,1.667,484,3.632,495,4.938,514,3.27,529,4.409,534,3.377,757,6.548,796,4.522,832,2.763,834,4.211,845,1.871,1090,4.04,1221,5.073,1819,3.905,1820,3.203,1823,3.163,1847,5.322,2000,6.929,2001,7.131,2002,6.929,2003,6.297]],["tags/328",[]],["title/329",[56,1.366,607,1.676,953,2.613]],["content/329",[3,0.342,14,0.436,30,1.763,31,2.283,56,2.78,63,0.959,104,1.257,143,2.769,144,2.721,154,4.343,161,1.843,172,1.675,182,2.027,216,2.966,222,3.983,233,2.134,251,2.46,253,3.828,266,1.148,286,1.894,287,2.285,326,1.675,342,2.493,424,2.493,586,2.811,607,3.411,621,4.098,763,2.006,805,3.58,806,5.389,924,2.563,953,5.177,954,2.367,955,2.811,956,2.86,957,2.721,958,2.911,966,2.721,1091,3.714,1208,3.3,1241,3.983,1713,3.58,2004,5.186,2005,5.186,2006,5.186,2007,9.168,2008,5.186,2009,5.186,2010,4.402]],["tags/329",[]],["title/330",[14,0.504,138,1.382]],["content/330",[7,1.519,14,0.605,16,1.561,42,3.061,56,1.943,95,2.871,126,2.962,138,1.661,162,2.962,163,3.169,186,3.718,233,2.962,240,1.86,243,2.841,261,3.132,266,1.594,299,2.871,431,4.581,489,2.384,505,2.758,539,3.508,675,3.508,678,3.508,687,2.705,943,3.776,944,3.838,945,3.838,1090,4.197,2011,5.528,2012,5.528,2013,5.786]],["tags/330",[]],["title/331",[138,1.167,266,1.12,385,1.69]],["content/331",[3,0.399,63,0.924,104,1.705,138,1.623,201,4.715,266,1.557,320,4.18,329,2.967,330,3.044,331,3.647,332,4.248,349,2.235,385,2.992,404,1.693,505,2.695,650,2.926,834,4.275,1165,4.476]],["tags/331",[]],["title/332",[32,1.766,299,2.018,2013,4.067]],["content/332",[2,1.503,3,0.36,14,0.568,32,3.233,63,1.1,87,1.246,92,1.553,93,1.741,94,1.228,104,1.126,105,3.03,138,1.557,148,0.929,171,1.407,186,1.479,187,1.934,218,4.525,251,3.201,266,1.494,299,4.152,312,1.823,320,2.72,326,2.397,329,0.949,330,0.974,331,1.166,332,2.205,333,2.302,347,4.137,356,2.114,384,2.35,385,2.479,386,2.71,387,1.823,388,1.608,392,3.431,404,1.118,445,2.434,504,1.579,571,1.714,599,5.729,706,1.246,762,1.704,927,5.613,929,1.638,962,1.232,1041,1.823,1091,4.821,1092,2.431,1093,3.312,1152,3.209,1166,2.302,1167,3.945,1168,2.603,1170,2.431,1171,2.603,1198,2.431,1239,6.298,1240,6.744,1383,2.603,1703,5.426,1759,2.603,1848,2.2,1889,1.869,1895,1.67,1908,6.298,2013,3.736,2014,2.864,2015,2.603,2016,2.864,2017,2.864,2018,2.864,2019,2.864,2020,2.864,2021,4.648,2022,4.648,2023,5.331,2024,2.864,2025,2.864,2026,2.864,2027,2.864,2028,2.864,2029,2.603]],["tags/332",[]],["title/333",[240,1.131,266,0.969,268,2.415,1182,2.661]],["content/333",[2,2.055,3,0.222,7,0.827,16,0.849,30,1.331,36,1.766,63,0.515,73,2.023,80,1.32,104,0.949,138,0.904,161,1.391,240,2.437,251,1.857,266,1.316,268,3.961,297,1.843,299,2.37,303,2.441,319,2.33,326,1.92,329,1.969,330,2.02,331,1.595,332,2.819,344,3.336,345,3.07,346,3.024,378,3.07,385,1.308,386,2.283,449,1.647,453,2.023,490,2.891,554,2.283,571,1.444,650,1.629,667,2.988,715,2.891,726,2.283,770,2.626,862,4.275,946,1.833,1014,5.302,1091,3.024,1162,6.707,1169,6.096,1182,5.515,1210,2.492,1215,4.958,1774,3.559,1779,3.324,1895,3.465,1907,3.559,1908,6.096,1909,6.528,1910,6.528,1911,3.008,2023,5.401,2029,3.559,2030,5.944,2031,5.944,2032,3.916,2033,5.944,2034,6.528,2035,7.183,2036,7.183,2037,5.944,2038,3.916,2039,3.916,2040,3.916,2041,7.183,2042,3.916]],["tags/333",[]],["title/334",[4,1.105,287,1.261,2013,4.067]],["content/334",[3,0.304,4,2.298,34,3.765,83,4.659,97,3.032,171,2.466,287,2.445,320,3.283,355,4.416,404,1.96,445,2.199,607,2.699,650,3.389]],["tags/334",[]],["title/335",[138,1.167,266,1.12,687,1.901]],["content/335",[1,0.982,2,3.583,3,0.293,7,0.762,10,0.758,11,0.466,14,0.527,16,0.251,29,1.69,30,1.761,36,2.335,42,0.492,43,0.755,46,2.773,53,3.064,56,0.571,63,0.681,73,0.598,80,2.212,82,0.965,83,0.662,87,0.503,104,1.145,105,2.675,121,0.4,128,0.736,132,0.4,136,3.256,138,1.73,141,1.507,143,1.792,144,1.533,168,2.049,178,0.498,179,0.755,182,1.411,186,1.092,187,1.216,199,1.915,201,0.931,207,0.732,227,0.617,233,0.87,240,0.547,248,0.719,251,0.549,261,0.92,265,1.611,266,1.989,276,1.816,279,0.755,282,0.772,297,1.732,299,0.461,303,0.393,305,1.809,306,0.888,320,0.852,324,1.386,325,0.942,329,1.97,330,2.321,331,2.673,332,1.712,344,2.652,345,1.509,346,1.076,349,1.336,355,1.146,374,0.598,385,1.405,390,0.854,396,1.776,404,0.703,426,2.573,431,3.554,432,2.773,443,2.573,445,0.312,447,1.166,452,1.919,453,0.598,462,1.285,465,1.671,469,0.824,486,0.368,489,1.716,504,0.638,505,0.443,545,1.087,630,0.522,650,1.502,667,0.481,675,0.564,682,1.561,687,2.817,706,2.43,726,1.233,741,3.656,745,0.688,754,1.076,763,2.822,802,0.498,826,1.7,832,0.461,836,0.492,845,1.275,854,1.7,862,0.617,899,1.092,919,1.11,920,1.704,928,3.323,954,1.334,962,2.402,1011,3.628,1014,2.665,1017,1.795,1019,1.795,1041,5.289,1049,0.888,1065,1.418,1069,2.244,1084,1.507,1091,1.837,1093,1.507,1107,0.982,1159,1.051,1160,2.48,1161,1.051,1162,3.855,1163,0.854,1164,1.922,1165,1.859,1169,4.009,1170,2.48,1172,3.281,1173,1.922,1174,0.982,1175,1.051,1176,2.655,1177,1.051,1178,1.051,1179,1.051,1180,1.051,1181,3.064,1182,2.871,1183,0.982,1184,1.051,1185,1.922,1186,1.922,1187,1.922,1188,1.922,1189,1.922,1190,3.38,1191,1.051,1192,1.922,1193,1.051,1194,1.7,1195,1.051,1196,1.051,1197,0.93,1198,0.982,1199,1.051,1200,2.665,1201,0.982,1210,0.736,1215,0.799,1219,0.736,1221,2.405,1321,0.736,1327,2.244,1328,2.492,1355,1.795,1369,0.93,1380,1.922,1384,0.888,1464,1.7,1465,2.655,1614,1.624,1812,3.855,1823,0.965,1861,0.982,1867,1.051,1873,1.7,1888,1.561,1895,3.256,1897,1.051,1902,1.051,2001,2.902,2043,1.157,2044,1.157,2045,1.051,2046,2.922,2047,1.157,2048,2.115,2049,1.157,2050,1.157,2051,1.157,2052,1.157,2053,1.157,2054,1.157,2055,3.064,2056,1.157,2057,2.115,2058,2.115,2059,2.115,2060,1.157,2061,1.157,2062,1.157,2063,1.157,2064,1.157,2065,1.157,2066,1.157,2067,1.157,2068,1.157,2069,2.115,2070,2.115,2071,1.157,2072,1.157,2073,1.157,2074,1.157,2075,1.157,2076,1.157,2077,1.157,2078,1.157,2079,0.93]],["tags/335",[]],["title/336",[138,1.167,687,1.901,836,2.152]],["content/336",[3,0.389,14,0.497,22,2.288,40,3.594,63,0.777,104,1.433,138,2.089,143,2.243,154,3.518,164,4.351,266,2.242,268,3.261,283,2.515,330,2.01,349,1.879,396,3.594,418,4.754,660,5.019,687,4.077,763,3.502,834,4.857,836,4.123,837,4.754,845,1.597,846,5.019,954,2.699,1156,3.448,1182,4.857,1208,3.763,1227,4.966,2080,5.913]],["tags/336",[]],["title/337",[14,0.504,266,1.326]],["content/337",[3,0.358,4,0.545,7,1.124,13,1.269,14,0.78,16,1.495,17,3.28,19,1.027,30,0.848,31,1.098,33,1.672,34,1.153,40,1.516,49,2.111,56,2.008,59,2.005,60,1.016,63,1.036,78,2.267,79,2.267,80,1.795,87,1.085,95,0.995,98,1.621,104,0.604,117,1.049,126,1.708,128,1.587,132,0.863,138,1.716,144,1.309,148,0.83,153,1.841,162,1.027,163,1.098,168,1.216,182,2.082,191,2.021,192,1.073,198,0.995,204,2.143,205,2.419,214,1.376,233,1.027,235,1.516,242,1.427,243,1.638,246,2.345,261,1.085,262,1.778,265,1.376,266,1.745,270,4.768,279,1.628,288,2.117,292,0.928,318,0.965,319,1.484,324,1.968,325,1.848,330,0.848,342,1.199,349,1.318,355,1.352,372,1.587,385,1.78,392,1.841,404,0.6,421,1.352,423,0.813,449,1.745,452,1.139,462,2.521,463,1.25,505,0.956,524,1.55,530,2.005,539,2.022,541,2.468,557,2.782,582,1.55,607,0.826,620,1.722,655,1.55,675,1.216,678,1.216,691,1.516,695,1.216,696,2.005,702,2.005,726,1.454,741,1.454,760,2.541,763,2.878,774,2.267,817,1.841,832,0.995,834,1.516,845,2.129,854,3.335,870,2.117,880,1.778,884,1.628,917,1.55,919,1.309,920,1.454,922,2.782,943,1.309,944,1.33,945,1.33,957,1.309,961,1.33,962,1.073,977,1.778,1007,1.722,1090,3.106,1156,1.454,1158,1.841,1166,3.335,1207,1.916,1218,1.916,1219,1.587,1220,2.117,1221,3.046,1229,1.628,1506,2.117,1601,1.778,1823,1.139,1835,4.521,1840,4.768,1851,1.841,1888,5.088,1895,2.419,2011,1.916,2012,1.916,2079,2.005,2081,2.495,2082,2.495,2083,4.149,2084,2.495,2085,2.117,2086,2.267,2087,4.841,2088,2.267,2089,2.495,2090,2.117,2091,2.267,2092,2.267,2093,2.495,2094,2.267,2095,2.495,2096,2.495,2097,2.495]],["tags/337",[]],["title/338",[798,3.735]],["content/338",[3,0.315,19,3.475,64,4.295,117,3.551,404,2.032,421,4.577,484,2.973,760,3.113,778,5.51,800,5.247,804,7.673,1091,4.295]],["tags/338",[]],["title/339",[383,2.734,489,1.984]],["content/339",[3,0.306,161,2.92,162,3.382,169,2.974,266,1.819,299,3.278,383,3.751,489,3.266,505,3.148,604,4.12,949,4.455,950,3.95,951,4.382,952,4.312]],["tags/339",[]],["title/340",[329,1.279,413,2.751,489,1.279,1300,3.103,2098,3.276]],["content/340",[4,1.229,14,0.473,30,1.912,34,3.571,36,2.537,49,2.862,56,1.519,63,0.739,80,1.896,162,3.908,163,2.477,178,2.42,182,2.199,201,2.477,238,3.497,241,3.772,243,2.221,287,1.403,299,2.244,303,2.999,326,1.817,329,2.922,383,2.568,395,4.01,413,5.506,489,2.922,545,2.094,630,2.537,669,2.952,680,5.113,704,4.153,763,2.177,802,2.42,836,2.393,950,4.565,952,2.952,954,2.568,1208,3.58,1300,6.21,1306,4.153,1505,4.775,1741,5.113,1848,4.321,2098,8.06,2099,7.021,2100,5.113,2101,5.627,2102,5.627]],["tags/340",[]],["title/341",[329,1.984,2103,5.444]],["content/341",[3,0.299,14,0.5,30,2.023,34,2.751,36,2.683,63,1.055,75,4.571,80,2.005,138,1.373,162,3.738,178,3.452,203,4.784,204,3.074,247,3.698,249,4.784,283,2.531,299,3.622,303,2.023,329,3.008,383,2.716,489,1.971,525,4.393,547,2.983,630,2.683,640,4.393,659,4.784,669,3.122,702,4.784,763,2.303,950,4.365,1007,4.108,1091,3.028,1140,5.779,1208,3.787,1306,4.393,2099,7.294,2103,7.294,2104,9.082,2105,5.951,2106,5.409,2107,5.951]],["tags/341",[]],["title/342",[14,0.504,618,2.668]],["content/342",[3,0.339,7,1.523,11,2.907,14,0.607,63,0.67,64,2.595,80,1.719,92,2.765,94,1.347,97,1.898,121,2.496,130,2.272,143,1.935,158,2.557,163,2.245,176,1.419,211,3.635,214,2.813,233,2.099,240,2.705,282,1.863,292,3.115,297,1.582,303,2.845,323,2.419,349,1.621,378,3.726,453,2.634,456,3.329,475,6.18,483,3.521,498,2.634,523,4.1,603,4.329,616,4.562,617,4.98,618,2.272,624,4.1,667,3.483,668,2.676,669,2.676,694,2.388,751,4.635,800,4.484,910,3.42,959,2.863,960,2.813,1041,3.246,1089,4.635,1229,3.329,1499,4.635,1686,4.1,2108,4.635,2109,4.329,2110,5.101,2111,5.101]],["tags/342",[]],["title/343",[14,0.425,277,3.144,2109,4.294]],["content/343",[3,0.075,4,0.24,7,0.426,14,0.384,16,0.239,19,0.453,32,0.705,34,1.605,36,0.496,56,0.297,58,2.066,82,0.502,87,0.479,89,0.885,90,0.669,95,0.806,98,0.43,104,1.4,105,1.793,121,1.874,128,0.7,145,2.158,148,1.854,158,1.74,161,0.718,171,0.848,172,0.356,179,2.266,182,1.095,186,1.044,207,0.699,214,4.338,227,0.587,233,1.429,236,3.159,240,1.842,242,1.156,243,1.106,250,0.738,252,3.223,277,1.256,282,1.481,292,2.479,296,0.934,303,2.264,307,0.509,323,2.569,324,1.647,329,0.669,330,0.687,331,0.823,332,0.958,344,0.618,378,3.441,423,2.083,425,2.397,430,2.328,443,0.784,445,0.297,460,2.328,461,0.684,484,2.148,489,0.365,492,0.7,505,0.774,541,0.655,616,1.013,617,4.599,618,1.547,627,2.716,655,2.52,667,2.771,706,1.219,707,2.11,739,0.934,742,0.784,763,0.782,764,0.784,785,2.947,796,5.643,798,1.028,800,2.158,909,1.425,946,1.625,962,1.493,968,0.76,983,1.492,1041,0.7,1058,1.552,1062,1.836,1063,1,1069,2.667,1091,3.513,1182,2.774,1207,1.552,1221,3.489,1293,7.666,1321,3.192,1322,2.947,1591,2.718,1613,2.947,1717,4.923,1787,2.791,1860,2.667,1886,2.546,1889,1.828,1911,0.845,1972,3.155,2109,3.441,2112,1.101,2113,4.598,2114,5.654,2115,1,2116,1.101,2117,0.934,2118,1.715,2119,3.472,2120,1.101,2121,1.101,2122,8.334,2123,2.801,2124,2.801,2125,2.801,2126,2.801,2127,3.472,2128,2.801,2129,3.472,2130,2.801,2131,2.801,2132,4.565,2133,8.161,2134,2.801,2135,5.417,2136,2.801,2137,5.417,2138,5.417,2139,7.526,2140,5.417,2141,7.526,2142,2.801,2143,2.801,2144,2.801,2145,2.801,2146,2.801,2147,2.801,2148,3.472,2149,2.801,2150,1,2151,1.836,2152,1.101,2153,1.101,2154,1.101,2155,1.101,2156,1.101,2157,1.101,2158,1.101,2159,1.101,2160,1.101,2161,1.101,2162,1.101,2163,1.101,2164,1.101,2165,1.101,2166,1.101,2167,1.101,2168,1.101,2169,1.101,2170,1.101,2171,0.885]],["tags/343",[]],["title/344",[14,0.504,618,2.668]],["content/344",[3,0.282,14,0.73,27,4.816,34,2.524,58,3.249,60,2.224,80,1.84,104,1.834,121,3.243,122,1.94,148,1.092,185,4.173,240,1.955,242,3.123,252,3.249,290,3.249,292,2.032,303,1.856,346,2.778,378,2.821,385,1.824,390,4.031,430,3.661,616,4.354,618,4.386,627,2.738,667,2.272,671,4.031,834,3.319,1082,3.661,1221,4.328,1293,7.958,1851,4.031,1856,4.963,2113,4.635,2114,4.635,2115,4.963,2122,8.358,2172,8.685,2173,5.461,2174,5.461,2175,5.461,2176,5.461,2177,5.461,2178,5.461,2179,5.461]],["tags/344",[]],["title/345",[118,2.227,286,1.848,304,2.465]],["content/345",[3,0.339,80,2.426,87,3.132,98,2.813,101,2.785,104,1.744,118,4.384,159,3.096,172,2.325,173,4.283,226,4.283,281,4.117,282,2.629,286,3.319,304,4.853,375,4.969,396,4.374,437,3.838,445,1.943,504,3.969,547,3.608,570,7.713,2180,9.088]],["tags/345",[]],["title/346",[159,2.176,192,2.176,1237,3.735]],["content/346",[3,0.28,8,3.522,39,3.28,63,0.986,104,1.308,125,2.495,152,3.28,159,4.218,166,2.643,172,2.788,216,3.087,259,3.726,284,4.145,286,1.971,287,1.345,304,3.658,358,2.527,374,2.788,399,2.926,414,3.435,449,2.27,479,4.339,481,3.846,518,2.63,534,2.63,536,4.905,539,2.63,541,3.211,550,4.339,580,1.99,621,3.03,721,4.936,919,2.832,956,4.759,1123,2.463,1224,3.726,1237,3.984,1247,4.581,1248,4.905,1301,4.339,1536,4.905,1568,6.822,1587,4.905,1960,7.325,1966,4.581,2181,4.905,2182,5.397,2183,5.397,2184,5.397,2185,5.397,2186,5.397,2187,5.397,2188,5.397,2189,4.905,2190,5.397,2191,5.397,2192,4.581]],["tags/346",[]],["title/347",[159,2.577,171,1.813]],["content/347",[3,0.327,31,2.447,82,2.537,104,1.857,118,2.447,124,2.916,133,4.469,159,4.406,165,2.871,166,1.957,171,1.683,246,2.447,265,3.066,286,3.202,287,1.91,304,4.272,319,3.307,338,4.27,342,2.672,393,2.916,395,3.962,399,3.013,423,1.811,447,3.066,574,4.718,607,2.538,672,5.656,856,5.884,919,2.916,1065,3.727,1140,4.875,1210,3.537,1229,3.628,1601,3.962,1966,6.503,1968,6.963,1984,5.052,2181,5.052,2193,5.559,2194,5.559,2195,5.559,2196,4.718,2197,5.559,2198,5.559,2199,5.559,2200,5.559,2201,5.559,2202,5.559,2203,5.559,2204,5.559]],["tags/347",[]],["title/348",[2205,7.341]],["content/348",[9,4.35,22,2.829,93,4.443,133,5.878,159,4.314,166,2.575,172,2.362,192,3.145,202,6.54,204,3.777,205,4.263,243,2.886,304,3.563,478,5.047,504,4.032,534,3.563,604,3.665,668,3.836,882,8.341,941,5.047,1157,5.878,1621,5.616,1792,6.645,2206,7.312,2207,7.312]],["tags/348",[]],["title/356",[581,2.96,607,1.984]],["content/356",[3,0.26,7,1.473,21,2.677,22,2.701,28,2.064,63,0.917,80,2.353,101,2.701,117,2.936,163,3.073,178,3.003,183,3.606,224,3.552,263,3.402,329,2.313,453,3.606,456,4.556,486,2.832,509,3.448,546,3.187,576,4.784,577,5.612,579,3.722,580,2.574,581,4.404,617,4.819,696,5.612,740,3.784,2208,6.982]],["tags/356",[]],["title/357",[688,4.671]],["content/357",[10,2.265,63,1.097,104,1.53,166,2.224,275,4.36,318,2.444,326,2.04,383,2.883,445,1.705,490,4.663,524,5.19,534,3.078,560,5.74,576,3.078,581,5.116,609,4.663,650,3.474,671,4.663,688,5.954,708,5.686,724,5.74,736,4.851,741,3.683,777,2.748,796,4.122,838,3.483,954,2.883,1074,5.74,1321,4.019,1578,5.077,1823,2.883,2209,6.316,2210,8.351,2211,6.316,2212,6.316,2213,6.316,2214,6.316]],["tags/357",[]],["title/358",[545,2.732]],["content/358",[3,0.239,14,0.538,63,0.841,104,1.552,171,1.938,172,2.068,178,2.754,182,3.681,325,2.852,399,3.471,423,2.086,437,4.493,449,2.693,458,4.293,459,4.563,545,2.383,576,3.12,581,5.139,607,2.121,620,4.42,726,5.492,954,3.846,976,5.435,992,5.147,1601,4.563,1841,6.713,1842,4.727,2215,8.427,2216,6.403,2217,6.403,2218,6.403,2219,6.403,2220,6.403,2221,6.403]],["tags/358",[]],["title/359",[243,2.365,612,5.084]],["content/359",[]],["tags/359",[]],["title/360",[21,2.205]],["content/360",[10,3.066,11,2.138,21,3.269,42,3.154,63,1.124,121,3.492,124,2.783,130,3.809,141,5.285,161,2.635,222,4.074,251,2.516,291,3.78,318,2.052,323,2.516,451,4.264,509,2.052,518,2.585,533,6.874,534,2.585,535,3.916,538,6.313,550,4.264,566,4.821,570,4.502,571,1.956,576,3.614,577,7.443,581,4.226,605,2.925,646,4.821,788,3.662,1200,3.916,1553,4.821,1891,4.821,2222,5.305,2223,5.305,2224,5.305,2225,5.305,2226,5.305,2227,5.305,2228,5.305,2229,5.305,2230,4.264]],["tags/360",[]],["title/361",[640,4.422,1066,5.444]],["content/361",[14,0.473,63,1.015,101,3.851,117,3.249,120,5.922,154,3.347,161,1.999,178,4.281,207,1.946,211,6.287,218,3.772,224,4.488,263,3.764,318,2.177,342,2.705,449,2.366,509,2.177,545,2.875,576,2.742,581,4.918,631,3.05,640,4.153,651,5.179,716,2.742,726,3.28,892,3.419,899,2.906,992,4.523,1044,8.018,1129,4.153,1888,5.703,2094,7.021,2231,5.627,2232,5.627,2233,7.725,2234,5.627,2235,5.627]],["tags/361",[]],["title/349",[125,1.784,615,3.103,923,2.588,963,1.964,964,1.907]],["content/349",[3,0.268,10,1.819,36,2.287,56,1.37,63,1.193,103,2.901,104,1.229,117,2.134,118,3.163,121,3.442,125,2.345,159,2.182,161,1.802,162,2.088,164,2.438,172,1.639,178,3.091,180,3.963,201,3.163,204,3.712,205,2.958,222,3.896,232,3.31,291,3.615,297,2.228,300,4.961,313,2.62,318,1.963,374,2.62,385,1.695,414,3.228,436,3.896,437,2.704,440,5.642,447,2.797,449,2.134,451,4.078,615,4.078,621,2.848,627,2.543,704,3.745,903,3.152,923,3.401,962,2.182,964,4.486,1087,4.305,1142,4.61,1501,4.305,1812,3.502,2011,3.896,2012,3.896,2236,6.1,2237,4.61,2238,5.073,2239,5.073,2240,4.61,2241,3.745,2242,4.61,2243,4.61,2244,4.078,2245,4.61,2246,4.078]],["tags/349",[]],["title/350",[176,1.407,447,2.79,964,2.5]],["content/350",[60,3.502,87,3.742,104,2.084,118,3.785,161,3.055,176,2.392,243,3.395,299,3.43,964,4.25,2247,7.815]],["tags/350",[]],["title/351",[3,0.223,404,1.441]],["content/351",[3,0.329,95,2.743,121,2.379,161,2.444,172,2.222,176,1.913,262,4.902,265,3.793,281,5.049,286,2.512,287,1.715,297,2.133,404,2.124,414,4.377,518,3.352,620,4.748,692,5.838,884,4.488,964,4.362,1067,5.838,1225,6.78,1272,7.493,2241,5.077,2246,5.529,2248,8.828,2249,8.828,2250,6.878,2251,6.878,2252,6.878]],["tags/351",[]],["title/352",[199,2.054,283,2.548]],["content/352",[3,0.166,60,1.817,63,0.861,85,1.693,94,2.259,104,1.081,121,2.686,148,2.019,154,3.898,161,1.586,166,1.571,167,2.602,176,2.535,181,3.437,199,2.247,226,6.131,252,2.655,281,3.747,283,3.302,284,3.427,291,3.18,299,2.613,319,2.655,374,2.305,385,2.189,423,1.454,440,2.773,447,3.613,449,1.877,489,1.478,490,3.294,620,3.081,784,5.955,825,3.587,826,3.587,843,5.267,963,2.27,964,3.837,1221,4.44,2090,5.561,2091,5.955,2241,6.727,2246,5.267,2247,4.056,2253,5.561,2254,7.764,2255,7.764,2256,6.552,2257,6.552,2258,6.552,2259,6.552,2260,5.955,2261,3.788]],["tags/352",[]],["title/353",[2236,5.084,2262,5.444]],["content/353",[7,1.543,31,3.219,60,2.977,63,0.961,64,3.72,80,2.464,87,3.181,166,2.575,215,4.263,216,4.181,299,2.916,300,5.047,312,4.653,385,2.443,462,6.096,529,4.653,906,5.047,963,4.669,964,3.613,1857,6.645,2240,6.645,2263,7.312,2264,7.312,2265,7.312,2266,6.645,2267,7.312]],["tags/353",[]],["title/354",[2268,6.671]],["content/354",[94,1.916,121,2.509,126,2.986,169,2.625,172,2.343,180,4.001,181,3.806,186,3.747,226,4.316,328,4.734,342,3.487,404,1.746,460,4.864,462,4.409,548,5.832,695,3.535,726,4.23,940,4.734,963,3.691,1126,6.593,1298,3.271,1986,6.593,2246,5.832,2260,6.593,2268,8.3,2269,7.255,2270,7.255,2271,7.255,2272,7.255]],["tags/354",[]],["title/355",[621,3.363,791,5.084]],["content/355",[7,1.543,48,4.653,56,1.974,125,3.379,143,2.774,164,3.515,197,4.443,247,4.544,342,3.515,445,1.974,529,4.653,544,4.263,621,4.105,791,6.206,886,6.645,964,3.613,1229,4.771,1548,5.878,2085,6.206,2236,7.789,2237,6.645,2262,6.645,2266,6.645,2273,7.312,2274,7.312,2275,6.645,2276,7.312,2277,7.312]],["tags/355",[]],["title/367",[14,0.504,946,2.804]],["content/367",[3,0.327,4,1.913,7,1.849,14,0.737,22,3.39,66,3.292,711,4.212,946,4.102]],["tags/367",[]],["title/368",[240,1.307,862,2.697,946,2.368]],["content/368",[]],["tags/368",[]],["title/369",[711,3.529]],["content/369",[3,0.122,7,1.09,14,0.434,16,1.12,30,1.111,34,1.51,48,2.079,90,1.986,104,0.792,105,1.688,138,0.754,148,1.884,163,1.438,165,1.688,171,0.989,172,1.669,233,1.345,240,2.434,265,1.802,266,0.723,268,1.802,326,1.056,352,3.566,392,2.412,393,3.361,425,2.256,453,1.688,463,4.723,475,2.412,525,3.813,545,3.137,554,1.905,571,1.904,621,1.834,663,2.774,706,1.422,707,1.986,711,4.052,716,1.592,726,1.905,763,1.999,777,1.422,805,3.566,862,4.706,880,6.007,909,1.662,912,1.986,946,3.946,954,2.358,962,3.797,986,3.371,1002,4.92,1100,2.627,1114,4.152,1124,3.21,1127,4.422,1182,5.365,1210,2.079,1219,3.287,1221,1.869,1278,3.967,1495,5.437,1566,2.97,1609,2.51,1628,2.97,1631,2.97,1760,2.97,1808,2.97,1889,2.133,1895,3.012,1912,2.627,2001,2.627,2278,7.929,2279,3.268,2280,3.268,2281,3.268,2282,3.268,2283,3.268,2284,3.268,2285,7.28,2286,3.268,2287,5.166,2288,5.166,2289,3.268,2290,5.822,2291,5.166,2292,2.51,2293,3.268]],["tags/369",[]],["title/370",[324,2.841,946,2.804]],["content/370",[3,0.208,5,2.688,14,0.647,29,2.618,69,3.986,143,3.336,182,3.881,246,3.386,286,2.043,324,2.653,325,2.491,329,1.853,330,1.901,331,2.277,332,3.649,342,2.688,393,2.934,396,3.399,445,2.077,460,5.896,520,3.399,655,4.781,706,2.433,763,2.164,862,4.689,877,4.496,946,4.805,1058,4.295,1082,3.75,1085,4.295,1091,4.819,1110,4.747,1158,5.679,1182,5.756,1794,4.747,1889,3.65,1912,4.496,2117,4.747,2118,4.747,2230,6.184]],["tags/370",[]],["title/371",[240,1.131,303,1.488,667,1.822,946,2.05]],["content/371",[3,0.173,4,1.013,5,2.231,14,0.567,29,2.173,69,6.211,80,1.564,82,2.118,104,1.125,143,3.013,171,1.405,182,3.618,240,2.252,246,2.968,286,1.695,303,3.283,324,2.201,325,2.067,327,3.731,329,1.537,330,1.578,331,1.89,332,3.198,342,2.231,372,2.953,393,4.166,445,1.82,460,5.324,470,3.426,520,2.82,655,4.19,667,4.018,706,2.019,763,1.796,838,2.559,877,3.731,946,4.78,1058,3.565,1071,3.731,1082,3.112,1085,3.565,1091,4.434,1110,3.939,1158,4.977,1182,5.297,1577,3.939,1794,3.939,1889,3.029,1912,3.731,2086,4.218,2117,3.939,2118,3.939,2150,4.218,2230,5.42,2294,4.641,2295,4.641]],["tags/371",[]],["title/362",[63,0.665,485,1.901,486,1.607]],["content/362",[4,2.078,7,1.38,16,2.064,31,2.878,73,4.413,80,2.203,138,1.509,172,2.112,191,2.481,247,5.309,260,4.514,283,4.292,305,2.812,318,2.53,328,4.267,382,4.222,383,2.984,385,2.185,485,2.457,486,3.412,489,2.166,505,2.505,506,5.309,524,4.063,531,4.384,762,3.89,1510,5.942,2296,6.539]],["tags/362",[]],["title/363",[28,1.771,486,1.903]],["content/363",[3,0.268,4,1.108,5,2.438,7,1.071,10,2.577,16,1.559,21,2.878,28,2.125,30,1.724,32,1.77,34,2.345,50,2.507,56,1.37,63,0.667,73,3.712,101,2.78,152,3.083,191,1.924,233,2.088,240,1.311,243,2.002,247,3.152,297,1.573,299,2.023,313,2.62,323,2.406,326,1.639,329,2.381,330,2.443,331,2.066,332,2.406,376,2.901,378,3.712,384,1.5,445,1.94,485,3.411,486,3.162,505,2.753,506,5.187,509,1.963,510,6.1,514,1.87,517,4.078,521,4.818,531,3.401,546,2.315,571,1.87,663,4.305,664,4.078,1150,3.745,1209,3.31,1210,3.228,1761,6.531,2297,7.187,2298,5.073,2299,4.61]],["tags/363",[]],["title/364",[506,3.723,521,4.016]],["content/364",[3,0.401,7,0.784,14,0.656,21,1.714,30,2.651,34,1.716,36,3.517,63,0.488,64,1.889,73,1.918,104,1.89,117,2.4,148,0.742,169,1.343,189,1.809,191,1.408,235,2.256,240,1.474,247,2.307,260,5.811,293,2.307,297,1.151,299,1.481,310,2.423,311,3.374,329,2.302,330,2.861,331,2.83,332,2.706,374,1.918,378,4.348,384,2.055,385,1.24,399,4.563,423,2.541,445,1.002,449,1.561,485,2.144,486,2.824,506,6.089,514,2.103,521,6.569,524,4.847,531,3.825,546,1.694,580,1.369,606,2.489,607,2.584,716,1.809,768,3.151,780,4.587,856,5.991,1209,2.423,1601,5.559,2299,5.185,2300,3.374,2301,3.713,2302,3.713]],["tags/364",[]],["title/365",[607,2.432]],["content/365",[3,0.094,10,2.684,14,0.118,21,2.941,30,1.426,36,1.891,48,2.669,58,1.503,63,1.014,85,1.833,97,0.524,104,0.612,121,1.451,130,1.868,142,0.838,148,0.505,168,2.354,169,3.669,172,1.355,177,1.003,178,0.606,182,2.587,189,4.045,199,0.483,207,0.487,216,2.398,233,1.04,259,5.168,260,0.972,266,1.466,283,0.599,299,2.496,306,1.081,319,2.495,320,0.567,326,2.242,329,0.837,330,0.859,331,1.029,332,1.199,347,2.968,374,2.166,378,4.587,385,1.614,390,4.62,396,2.549,404,0.339,426,4.46,445,1.132,449,1.063,453,1.305,463,1.267,485,2.98,486,2.928,492,1.608,495,5.335,505,0.539,506,1.57,520,2.549,521,1.694,531,5.446,532,3.812,545,0.524,547,4.318,549,4.806,554,2.445,571,1.546,607,0.837,651,2.812,655,0.875,708,2.089,716,1.675,741,2.445,760,0.932,762,1.503,763,0.545,777,0.613,788,1.744,806,1.866,954,1.914,962,2.078,995,2.145,996,3.56,998,2.145,1000,2.145,1001,2.031,1032,1.28,1034,1.28,1048,1.801,1084,1.003,1090,2.445,1107,2.145,1109,1.195,1156,0.821,1239,1.195,1713,1.744,1745,2.297,1746,2.297,1748,4.391,1860,1.081,2034,2.297,2108,3.812,2151,3.812,2189,3.812,2261,5.311,2290,1.28,2300,1.28,2303,1.195,2304,1.408,2305,7.827,2306,6.258,2307,4.391,2308,6.258,2309,4.194,2310,1.408,2311,2.527,2312,1.408,2313,1.408,2314,1.408,2315,2.527,2316,1.408,2317,1.408]],["tags/365",[]],["title/366",[263,2.134,326,1.414,486,1.391,547,2.195]],["content/366",[3,0.15,14,0.339,21,2.862,63,0.53,64,2.053,82,1.842,104,0.978,105,2.084,123,2.979,143,1.531,169,2.647,176,1.122,182,1.577,252,3.617,263,1.966,266,0.893,272,5.4,306,3.099,322,2.979,326,3.437,408,3.244,426,2.876,463,4.082,485,1.516,486,3.027,531,2.706,547,5.029,571,1.488,590,3.099,708,2.452,788,4.197,836,3.463,838,2.225,880,4.333,962,2.615,1124,3.778,1156,2.353,1221,3.477,1278,4.669,1287,5.525,1614,3.099,1713,4.197,1871,2.979,2100,3.667,2261,3.425,2303,3.425,2305,8.343,2307,3.667,2318,8.142,2319,6.08,2320,6.08,2321,6.08,2322,6.08,2323,8.142,2324,8.142,2325,8.142,2326,6.08,2327,4.036,2328,4.036]],["tags/366",[]],["title/372",[14,0.504,802,2.577]],["content/372",[3,0.383,10,2.209,14,0.777,16,0.891,21,1.234,56,1.109,63,0.54,64,2.089,95,1.638,98,1.605,117,1.727,121,1.421,126,1.69,138,1.421,162,1.69,171,2.238,178,1.766,192,1.766,204,2.121,205,2.395,233,3.043,243,1.621,261,1.787,266,1.637,268,3.397,292,2.293,324,1.948,342,1.974,349,1.957,351,2.306,385,2.744,404,1.482,453,2.121,485,1.543,486,1.957,509,1.589,539,2.001,621,2.306,650,1.709,661,3.486,675,2.001,678,2.001,695,2.001,741,2.395,760,1.514,763,2.86,800,2.552,802,4.24,803,3.032,833,2.927,834,3.744,836,3.493,845,2.218,852,4.952,902,2.68,940,2.68,943,2.155,944,2.19,945,2.19,962,1.766,1049,3.154,1071,3.301,1090,2.395,1119,3.732,1208,2.613,1218,3.154,1223,3.486,1227,2.552,1228,3.301,1229,2.68,1231,2.443,1578,3.301,1805,3.154,1851,3.032,1965,3.732,1982,3.732,2011,3.154,2012,3.154,2329,4.107,2330,4.107,2331,3.486]],["tags/372",[]],["title/384",[7,1.068,63,0.665,845,1.366]],["content/384",[3,0.379,7,1.976,14,0.635,49,3.841,56,2.038,82,3.446,200,6.408,207,2.611,286,3.419,297,2.341,318,2.921,452,3.446,473,2.419,675,3.679,836,3.211,845,2.748,961,4.025,962,3.247,2253,6.408]],["tags/384",[]],["title/385",[1237,5.419]],["content/385",[148,1.704,172,2.752,287,2.124,293,5.295,358,3.989,518,4.152,607,2.823,845,2.3,2332,8.521,2333,8.521,2334,8.521]],["tags/385",[]],["title/386",[541,3.564,2335,5.444]],["content/386",[2,1.882,3,0.347,7,1.929,14,0.525,17,1.954,49,1.825,63,1.051,66,0.789,73,1.084,80,0.707,85,0.796,95,0.837,104,0.509,106,2.475,109,2.405,123,1.55,138,2.109,148,1.961,163,0.924,168,1.023,174,1.084,182,0.82,198,2.489,214,1.158,233,0.864,246,0.924,248,1.305,265,1.158,266,1.382,286,0.767,287,0.523,297,0.651,302,1.052,324,2.961,326,0.678,329,0.695,330,0.714,331,0.855,332,0.996,340,1.908,342,1.009,349,1.766,350,1.37,355,1.945,384,1.643,385,1.199,386,1.224,387,1.336,404,0.863,447,1.158,449,2.861,457,1.496,484,1.957,505,0.804,520,1.276,539,1.023,541,2.134,563,1.612,600,4.309,674,3.96,687,1.765,695,1.023,760,3.653,763,2.632,778,3.626,816,2.39,817,1.55,832,2.216,834,2.18,845,2.834,880,4.449,899,1.084,954,0.958,963,1.068,1090,1.224,1140,2.989,1158,2.648,1163,4.102,1166,1.688,1190,1.688,1210,1.336,1218,2.755,1221,4.156,1303,1.782,1355,1.782,1517,3.26,1716,1.908,1730,1.782,1819,2.446,2087,4.269,2196,1.782,2336,2.099,2337,2.099,2338,5.557,2339,2.099,2340,4.716,2341,2.099,2342,2.099,2343,2.099,2344,2.099,2345,2.099,2346,6.243,2347,6.243,2348,6.243,2349,2.099,2350,6.802,2351,6.802,2352,2.099,2353,2.099,2354,2.099,2355,2.099,2356,2.099,2357,1.908,2358,2.099,2359,2.099]],["tags/386",[]],["title/387",[17,2.492,516,4.815]],["content/387",[3,0.289,7,1.195,14,0.744,16,1.228,17,4.15,40,3.44,63,1.163,80,1.908,86,4.551,93,3.44,109,6.383,146,4.348,148,1.551,168,2.758,171,1.714,204,2.924,205,3.3,218,3.795,221,3.795,233,3.193,248,3.518,263,2.758,283,2.408,286,2.833,374,2.924,389,4.034,423,1.844,447,3.122,449,2.381,473,1.813,490,4.179,505,2.972,541,4.615,557,3.795,587,4.551,687,3.325,691,3.44,715,4.179,763,3.001,845,1.528,884,3.694,931,4.034,957,2.97,2335,5.145,2360,5.661,2361,5.661]],["tags/387",[]],["title/388",[14,0.504,473,1.919]],["content/388",[2,2.447,3,0.252,7,1.681,10,1.672,14,0.392,17,3.635,19,1.92,30,1.585,33,3.127,34,3.128,36,2.103,82,2.129,97,1.736,104,1.13,109,6.219,138,2.016,148,1.592,161,1.657,168,3.298,174,2.409,182,1.823,201,2.053,204,2.409,205,2.72,263,2.273,287,2.488,302,4.38,325,3.892,355,2.528,393,2.447,408,3.75,445,1.827,473,2.799,524,2.899,600,3.22,621,3.799,687,2.992,695,2.273,737,3.959,741,2.72,760,2.936,763,1.805,816,2.006,845,2.504,1067,3.959,1140,4.306,1150,4.996,1730,3.959,1895,2.72,2088,4.239,2340,3.959,2362,4.665,2363,4.665,2364,4.665,2365,4.665,2366,4.665,2367,4.665]],["tags/388",[]],["title/373",[798,3.735]],["content/373",[3,0.333,60,3.637,87,3.886,706,3.886,965,5.014,966,4.685]],["tags/373",[]],["title/374",[534,2.919,679,5.084]],["content/374",[]],["tags/374",[]],["title/375",[14,0.368,143,1.661,266,0.969,534,2.134]],["content/375",[14,0.697,20,5.724,60,3.377,63,1.09,143,3.146,266,1.836,286,3.028,312,5.277,375,5.724,394,5.559,399,4.495,423,2.701,534,4.041,2368,7.536]],["tags/375",[]],["title/376",[7,0.815,139,2.849,330,1.312,481,2.751,763,1.493]],["content/376",[3,0.287,7,2.096,63,0.735,80,1.885,104,1.355,126,2.302,139,6.993,148,1.118,171,2.329,173,5.232,182,2.185,192,2.405,330,1.901,381,3.861,396,3.399,445,1.51,449,2.352,453,2.889,524,3.475,525,4.128,542,4.128,557,3.75,687,2.101,688,3.559,760,3.242,763,3.842,777,2.433,796,5.739,802,4.074,803,4.128,845,1.51,920,3.261,929,3.198,1049,4.295,1156,3.261,1229,3.65,1323,4.295,1328,5.311,1810,4.747,1823,2.553,2303,4.747,2369,5.593,2370,8.795]],["tags/376",[]],["title/377",[94,1.019,325,1.719,330,1.312,355,2.092,481,2.751]],["content/377",[32,2.578,56,2.302,63,0.693,80,2.489,94,1.393,96,2.812,104,1.278,171,1.597,192,3.667,221,4.953,238,3.278,247,3.278,248,3.278,263,2.57,325,2.349,330,3.589,355,4.004,381,3.641,404,1.777,431,5.425,449,2.218,458,4.953,461,3.278,465,4.224,467,4.24,534,2.57,541,3.138,627,2.644,650,2.194,665,4.794,713,3.894,726,3.075,729,4.307,741,3.075,760,1.944,796,4.821,880,3.759,909,2.683,928,3.138,929,3.016,966,2.767,1321,3.356,1328,3.641,1810,4.477,1889,3.442,2079,4.24,2085,6.27,2275,4.794,2371,6.713,2372,5.275,2373,5.275,2374,5.275,2375,5.275,2376,5.275]],["tags/377",[]],["title/378",[122,1.108,144,1.637,239,1.856,240,0.806,796,2.036,800,1.939,2377,3.12]],["content/378",[3,0.298,4,0.726,7,0.702,11,1.34,14,0.618,16,0.721,23,1.384,33,2.23,40,2.021,50,1.644,58,1.979,61,3.778,63,0.437,83,1.902,94,2.112,101,2.027,105,1.718,117,1.399,121,1.812,122,3.018,138,1.209,144,3.857,148,1.047,171,2.226,172,2.744,181,1.745,182,1.3,183,1.718,199,1.141,218,3.512,236,1.939,239,3.855,263,3.582,269,1.692,283,1.415,287,2.216,294,2.23,312,2.117,320,3.711,324,1.578,325,1.482,337,3.023,349,1.664,423,1.083,424,1.599,445,0.898,449,1.399,461,2.067,463,3.249,473,2.076,475,2.456,489,1.102,526,2.674,530,2.674,534,1.621,639,2.674,650,2.179,652,2.23,668,1.745,695,1.621,700,1.979,723,3.023,746,3.023,760,2.71,796,3.419,800,3.256,805,5.863,806,2.456,869,3.023,880,2.371,930,2.23,986,5.219,1127,4.473,1156,1.939,1157,2.674,1165,2.117,1201,2.823,1208,2.117,1278,2.555,1462,2.823,1611,2.823,1621,2.555,1787,2.674,1841,2.371,1844,3.023,1871,2.456,2001,4.211,2015,3.023,2090,4.446,2331,2.823,2378,2.823,2379,3.326,2380,3.326,2381,3.326,2382,5.239,2383,3.023,2384,5.239,2385,3.326,2386,3.326,2387,5.239,2388,3.326,2389,3.326]],["tags/378",[]],["title/379",[4,0.956,473,1.403,763,1.694,800,2.721]],["content/379",[3,0.364,4,1.316,14,0.507,56,1.628,63,1.064,144,3.163,263,2.938,312,3.836,324,3.84,378,3.114,385,2.014,404,1.451,423,1.964,425,4.162,445,1.628,473,2.928,534,2.938,545,2.244,607,1.997,650,2.508,652,4.042,760,3.37,763,3.132,800,3.747,832,2.404,930,4.042,1157,4.846,1208,5.152,1227,3.747,1462,5.117,1508,5.479,1518,5.479,1616,5.117,1841,4.296,1842,7.525,2230,4.846,2390,6.029,2391,6.029,2392,6.029,2393,6.029,2394,6.029]],["tags/379",[]],["title/380",[534,2.919,2395,5.084]],["content/380",[]],["tags/380",[]],["title/381",[484,2.585]],["content/381",[3,0.321,4,1.448,14,0.558,49,3.374,63,0.871,73,3.426,93,4.03,106,2.954,126,2.73,158,4.803,169,2.4,186,3.426,240,2.228,261,2.886,297,2.056,307,3.065,382,4.261,484,3.572,505,2.541,534,4.202,588,4.328,716,3.232,762,3.946,763,2.566,778,4.328,1069,5.094,1593,3.867,1819,2.919,2113,5.629,2114,5.629,2371,6.027,2395,5.629,2396,6.632]],["tags/381",[]],["title/382",[42,2.152,240,1.307,1327,3.886]],["content/382",[3,0.226,4,1.325,30,2.063,34,2.805,36,2.736,50,2.999,148,1.213,172,1.96,207,2.099,214,4.484,240,2.775,246,2.671,260,4.189,328,3.96,385,2.027,399,3.289,445,1.638,463,4.911,544,3.538,678,2.957,716,3.962,721,3.47,836,2.581,862,4.335,1007,4.189,1127,4.189,1299,5.15,1327,4.661,1467,5.515,1819,4.037,2010,5.15,2292,4.661,2397,6.068,2398,6.068,2399,8.132,2400,8.132,2401,6.068,2402,6.068,2403,6.068]],["tags/382",[]],["title/383",[42,2.152,1813,3.492,1814,3.886]],["content/383",[3,0.378,4,0.801,10,1.315,14,0.308,42,3.561,63,1.211,88,3.334,104,0.889,120,4.611,121,2.896,138,1.305,145,2.28,148,1.674,162,2.327,179,2.394,180,2.023,185,2.023,191,1.392,203,2.949,214,3.118,224,1.866,240,2.523,253,2.708,258,2.394,290,2.183,305,1.578,320,1.478,447,2.023,460,2.459,461,2.28,465,2.098,492,2.334,495,2.614,515,2.949,520,2.229,534,1.788,571,2.084,620,2.532,630,1.654,669,1.925,721,3.945,740,1.988,760,1.352,787,3.334,832,2.255,834,2.229,837,2.949,845,1.862,950,2.718,962,2.967,1007,3.903,1048,2.614,1064,2.817,1070,3.334,1124,2.28,1127,2.532,1156,2.139,1219,2.334,1259,3.114,1298,1.654,1498,7.11,1528,6.269,1546,3.114,1548,2.949,1813,6.362,1814,4.342,2092,3.334,2098,4.798,2196,4.798,2368,3.334,2395,3.114,2404,3.668,2405,3.668,2406,3.668,2407,3.668,2408,3.668,2409,3.668,2410,3.668,2411,5.654,2412,3.668,2413,3.668,2414,5.654,2415,3.668,2416,3.668,2417,3.334]],["tags/383",[]],["title/389",[32,1.347,63,0.507,101,1.493,330,1.312,373,2.849]],["content/389",[3,0.339,7,1.523,11,2.055,16,1.106,21,1.532,23,2.122,28,1.508,29,2.388,30,1.734,32,3.653,40,3.1,63,0.67,73,3.726,94,1.905,101,3.965,105,2.634,129,4.591,154,3.035,171,1.544,174,3.726,176,1.419,191,3.176,215,2.974,222,3.917,240,1.318,251,2.419,297,1.582,299,3.338,320,2.055,330,1.734,373,7.359,399,2.765,445,2.26,489,1.69,494,4.1,505,1.954,514,1.88,1041,3.246,1091,4.259,1156,4.881,1208,3.246,1307,3.635,1546,4.329,1779,4.329,2418,5.101,2419,5.101,2420,5.101,2421,5.101]],["tags/389",[]],["title/390",[32,2.09,199,2.054]],["content/390",[3,0.351,7,0.82,16,0.842,32,1.355,63,0.776,64,1.976,101,1.502,104,0.941,122,2.098,138,0.896,143,2.24,152,2.36,163,1.709,182,1.518,199,3.746,233,1.598,240,1.003,266,1.307,276,2.413,286,1.418,287,1.99,297,1.204,310,2.534,320,1.565,324,2.801,326,1.908,330,2.007,349,1.234,373,2.867,375,4.077,393,2.037,394,2.604,405,3.67,423,1.265,437,2.07,445,1.048,447,3.257,534,1.892,544,2.264,545,1.445,594,3.122,631,2.105,650,1.616,760,1.432,763,2.285,860,4.343,904,2.36,920,3.443,929,2.221,941,2.681,951,2.07,962,2.54,1011,2.983,1065,2.604,1075,3.296,1090,2.264,1125,3.529,1165,2.471,1182,2.36,1224,2.681,1548,6.904,1713,2.681,1847,4.536,1873,4.747,1895,2.264,1916,3.529,2079,3.122,2192,3.296,2340,3.296,2422,5.906,2423,3.883,2424,3.883,2425,3.883,2426,3.883,2427,5.906,2428,3.883,2429,3.883,2430,3.883,2431,3.883,2432,3.883,2433,3.883,2434,3.883,2435,3.883,2436,3.883,2437,3.883,2438,3.883,2439,3.883,2440,3.883,2441,3.883,2442,3.883,2443,3.883,2444,3.883,2445,3.883]],["tags/390",[]],["title/391",[14,0.504,473,1.919]],["content/391",[3,0.358,4,1.459,7,1.41,14,0.562,31,2.94,63,1.138,83,3.82,132,2.311,138,1.999,183,3.45,199,2.29,240,1.726,287,2.628,297,2.981,349,2.753,404,1.607,423,2.176,424,3.211,473,3.259,509,2.584,621,3.75,695,3.255,760,2.463,947,3.684,948,3.75,1100,5.37,1889,4.359]],["tags/391",[]],["title/392",[325,2.668,404,1.441]],["content/392",[3,0.201,4,2.141,14,0.785,48,3.435,63,0.709,81,3.726,83,3.087,161,1.918,171,1.634,182,2.109,282,1.971,285,4.581,287,2.751,320,2.175,323,2.56,342,3.608,374,2.788,394,3.619,404,2.595,414,3.435,424,2.594,445,2.33,449,2.27,473,3.252,476,3.984,520,3.28,588,3.522,650,3.591,878,5.765,1229,3.522,1960,4.581,2192,4.581,2446,5.397,2447,5.397,2448,7.507,2449,7.507]],["tags/392",[]],["title/393",[138,1.382,694,2.804]],["content/393",[3,0.375,63,0.968,138,2.128,141,5.252,143,2.796,168,4.494,233,3.033,320,3.716,325,4.108,385,3.525,423,2.401,453,3.807,529,4.69,694,4.318,832,2.939,1165,4.69,1871,5.44,1895,4.297]],["tags/393",[]],["title/394",[423,1.951,473,1.919]],["content/394",[3,0.309,9,4.924,14,0.524,63,0.819,83,3.563,94,1.646,148,1.655,171,2.506,199,2.137,202,4.441,287,2.063,293,3.872,297,1.932,320,3.99,324,2.955,325,3.687,349,1.98,385,2.082,404,1.499,423,2.696,469,4.441,473,3.394,607,2.064,650,2.592,783,5.663,899,4.275,1064,4.786,1140,3.965,1823,3.778,1895,3.633,2450,6.231,2451,6.231,2452,6.231,2453,6.231]],["tags/394",[]],["title/395",[473,1.919,760,2.208]],["content/395",[3,0.22,4,1.56,14,0.497,16,0.842,49,3.004,56,1.929,63,0.939,64,1.976,98,1.518,133,3.122,136,2.264,143,1.473,161,1.38,172,1.254,199,2.45,207,1.343,239,2.31,240,1.846,246,1.709,248,2.413,250,2.604,253,2.867,266,1.307,270,5.488,287,1.472,292,2.198,298,2.681,305,1.67,313,3.05,320,1.565,324,2.801,325,1.73,349,1.234,374,2.006,385,1.973,389,5.69,424,2.839,453,2.006,462,2.36,463,1.947,473,3.296,476,2.867,544,2.264,554,2.264,621,2.18,647,4.36,682,2.867,691,2.36,694,1.818,716,1.892,741,2.264,760,2.944,763,3.84,764,2.768,800,3.67,805,2.681,806,2.867,836,1.652,845,1.929,854,3.122,934,2.681,940,2.534,941,4.933,1086,3.296,1100,3.122,1611,3.296,1805,2.983,1823,1.773,1840,4.536,1841,5.093,1842,5.275,1846,3.296,1860,2.983,1889,2.534,1911,2.983,2292,2.983,2331,6.065,2383,5.367,2454,3.883,2455,3.883,2456,3.883]],["tags/395",[]],["title/396",[423,1.951,909,3.047]],["content/396",[3,0.307,4,1.963,14,0.694,36,2.238,56,1.34,61,2.894,104,1.203,107,3.538,161,1.764,171,2.497,199,3.083,216,2.839,240,2.456,246,2.185,287,2.535,313,2.564,349,1.577,399,3.836,400,6.432,401,2.953,449,2.088,473,2.88,478,3.427,489,2.732,498,2.564,518,3.449,607,2.344,633,3.328,722,3.813,760,1.83,909,3.6,953,2.564,1140,4.503,1221,4.047,1224,3.427,1384,3.813,1574,3.813,1621,3.813,1695,7,1991,4.511,2292,3.813,2457,4.964,2458,4.964,2459,4.964,2460,4.964,2461,4.964,2462,4.964,2463,4.964,2464,4.964,2465,4.964,2466,4.964,2467,4.964,2468,4.964]],["tags/396",[]],["title/397",[473,1.621,760,1.865,1593,2.95]],["content/397",[3,0.312,30,2.844,34,3.867,98,3.27,171,2.533,297,2.594,423,2.725,473,3.41,803,6.177,849,7.604,2292,6.426]],["tags/397",[]],["title/402",[176,1.666,404,1.441]],["content/402",[3,0.266,11,1.558,20,2.67,51,2.97,63,0.774,95,1.542,103,2.212,104,0.937,118,2.591,121,3.248,125,1.787,126,1.592,132,1.338,160,2.062,162,1.592,164,1.859,172,2.574,173,3.502,176,1.637,180,3.931,199,2.018,203,3.109,217,1.967,232,2.524,233,1.592,240,1.521,243,1.527,244,2.67,261,1.683,265,3.246,281,4.556,293,2.403,297,1.199,298,2.67,307,1.787,315,2.67,318,1.496,344,2.171,345,1.997,374,1.997,404,1.715,437,4.248,440,6.014,441,3.515,442,4.996,447,2.133,451,3.109,453,1.997,484,3.019,498,1.997,504,2.133,534,1.884,539,1.884,546,3.913,571,1.426,627,1.939,675,1.884,678,1.884,712,2.461,754,1.967,788,2.67,825,3.109,833,2.756,935,2.35,943,3.088,944,2.062,945,2.062,1039,2.756,1087,3.282,1090,3.432,1129,4.346,1156,2.255,1498,3.109,1501,3.282,1812,2.67,2003,3.515,2011,2.97,2012,2.97,2241,4.346,2242,3.515,2243,3.515,2244,3.109,2245,3.515,2469,7.276,2470,3.867,2471,3.867,2472,3.867,2473,3.867,2474,3.867,2475,3.867]],["tags/402",[]],["title/403",[176,1.666,281,3.426]],["content/403",[3,0.334,7,1.037,81,3.39,82,2.242,85,1.863,108,2.242,116,3.39,121,2.836,145,3.052,148,1.639,164,3.941,172,1.586,176,2.82,180,2.708,226,2.922,251,2.33,265,2.708,281,5.117,282,1.794,286,1.794,293,3.052,341,4.169,358,4.431,379,2.922,398,3.772,404,1.973,432,3.772,437,2.618,440,4.365,447,2.708,449,2.066,484,1.729,546,2.242,607,1.627,692,5.961,726,2.864,916,3.5,1039,5.005,1090,2.864,1219,3.125,1274,6.297,1323,3.772,1505,4.169,1565,6.383,2055,4.169,2171,3.948,2241,6.052,2244,5.646,2469,4.169,2476,4.912,2477,4.912,2478,7.024,2479,7.024,2480,4.464,2481,4.464,2482,4.464]],["tags/403",[]],["title/404",[324,1.831,384,1.141,484,1.359,546,1.762,2483,3.508]],["content/404",[3,0.159,10,1.534,63,0.562,104,1.036,105,3.912,118,2.795,121,2.62,131,3.285,144,2.244,148,2.172,164,2.056,172,2.446,207,1.48,235,2.599,281,3.632,283,2.701,295,2.722,349,2.018,358,2.002,374,2.209,404,2.154,437,4.038,440,4.707,476,3.158,484,2.236,529,2.722,534,2.084,546,2.898,549,3.285,573,3.887,607,1.417,675,2.084,764,3.048,843,3.438,844,3.63,957,2.244,1039,4.526,1205,3.887,1274,3.285,1322,6.428,1498,3.438,1593,2.494,1895,2.494,2055,7.962,2122,3.63,2171,3.438,2241,3.158,2244,3.438,2378,3.63,2417,5.771,2469,7.599,2481,3.887,2482,3.887,2483,3.887,2484,4.277,2485,4.277,2486,4.277,2487,4.277,2488,4.277,2489,4.277,2490,4.277,2491,4.277,2492,4.277,2493,4.277,2494,6.35,2495,4.277,2496,4.277,2497,4.277,2498,4.277,2499,4.277,2500,4.277,2501,4.277]],["tags/404",[]],["title/405",[176,1.666,1967,4.601]],["content/405",[3,0.319,30,1.517,31,1.964,36,2.012,61,2.602,63,0.861,83,2.552,85,1.693,94,1.179,95,1.78,98,1.744,108,2.037,113,3.788,118,3.418,125,2.063,148,1.552,154,2.655,159,3.339,164,2.145,167,2.602,172,1.441,176,2.809,204,2.305,205,2.602,244,3.081,281,3.747,282,1.63,286,1.63,287,1.112,297,1.384,300,4.523,302,2.237,358,2.089,385,2.189,404,1.868,414,2.84,423,2.529,447,2.461,607,1.478,620,3.081,816,1.919,884,4.276,935,5.199,936,2.773,990,4.056,1039,3.18,1090,2.602,1140,2.84,1274,3.427,1291,3.18,1317,4.056,1601,3.18,1801,3.788,1835,3.788,1967,7.756,2045,5.955,2171,3.587,2480,4.056,2502,4.463,2503,4.463,2504,6.552,2505,6.552,2506,4.463,2507,4.463,2508,4.463,2509,4.463,2510,4.463,2511,4.463,2512,4.463,2513,4.463,2514,4.463,2515,4.463]],["tags/405",[]],["title/398",[14,0.504,176,1.666]],["content/398",[3,0.318,14,0.717,28,2.519,66,3.201,94,2.25,97,3.171,169,3.083,176,2.37,217,4.335,318,3.297,830,4.543]],["tags/398",[]],["title/399",[122,2.128,405,3.723]],["content/399",[3,0.243,14,0.282,61,5.778,63,0.855,82,1.529,85,1.271,94,1.719,101,1.296,104,1.277,105,1.731,121,1.159,122,3.675,138,1.502,143,1.271,144,1.758,148,1.476,161,2.313,165,1.731,167,1.953,169,1.212,172,2.103,176,2.053,180,2.905,182,2.059,199,1.806,202,2.388,233,1.379,239,3.874,240,2.073,252,1.993,269,1.704,281,1.916,282,1.224,283,1.425,286,1.224,297,1.039,304,1.633,319,1.993,320,1.35,321,3.637,326,1.702,343,2.693,347,1.589,349,1.065,352,2.313,356,2.473,357,3.045,363,2.693,365,3.045,367,3.045,368,3.045,369,2.573,385,1.76,404,1.268,405,2.082,427,4.788,437,3.471,440,3.274,447,2.905,469,2.388,484,1.18,489,1.11,520,2.036,534,1.633,579,2.809,620,2.313,695,1.633,786,4.788,796,2.186,800,3.274,1039,2.388,1124,4.587,1606,3.045,1713,6.709,1847,4.046,1911,2.573,1962,9.4,2253,2.844,2357,3.045,2516,3.35,2517,3.35,2518,3.35,2519,7.381,2520,3.35,2521,3.35,2522,3.35,2523,3.35]],["tags/399",[]],["title/400",[176,1.666,349,1.903]],["content/400",[3,0.371,14,0.861,19,2.088,28,1.5,32,1.77,49,2.581,63,0.667,65,3.502,71,4.305,82,3.28,89,4.078,94,1.898,104,1.229,122,1.802,123,3.745,126,2.088,142,4.276,148,1.437,164,2.438,171,2.176,176,2.768,179,4.69,181,3.77,187,2.99,198,2.023,199,2.464,207,1.755,240,1.857,276,5.187,277,3.152,293,3.152,299,2.023,338,3.896,342,2.438,349,2.652,374,2.62,384,1.5,385,1.695,432,3.896,435,4.305,453,2.62,476,3.745,544,2.958,589,6.531,606,3.401,760,1.87,1291,3.615,1544,4.61,1578,4.078,1682,4.61,1851,3.745,2378,4.305,2524,5.073,2525,5.073]],["tags/400",[]],["title/401",[389,4.269,1850,5.444]],["content/401",[3,0.363,14,0.82,30,2.036,34,2.768,42,2.547,60,2.439,61,3.492,63,0.787,104,1.451,122,2.128,171,2.44,176,2.534,207,2.072,233,2.465,237,5.565,240,1.548,241,5.404,242,4.61,243,2.364,273,4.269,276,3.722,318,2.317,349,1.903,383,2.734,385,2.001,431,3.812,449,2.519,463,3.003,489,1.984,545,2.229,630,2.7,834,3.64,974,4.6,1007,6.29,1065,4.016,1127,4.135,1150,5.951,1165,3.812,2010,5.084,2106,5.444,2526,5.99,2527,5.99]],["tags/401",[]]],"invertedIndex":[["",{"_index":148,"title":{"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"95":{},"96":{},"97":{},"98":{},"99":{},"100":{},"101":{},"102":{},"103":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"140":{}},"content":{"9":{},"26":{},"27":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"95":{},"96":{},"97":{},"98":{},"99":{},"100":{},"101":{},"102":{},"103":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"122":{},"125":{},"127":{},"129":{},"130":{},"131":{},"133":{},"134":{},"135":{},"136":{},"137":{},"138":{},"145":{},"148":{},"158":{},"165":{},"172":{},"187":{},"222":{},"250":{},"254":{},"278":{},"310":{},"319":{},"332":{},"337":{},"343":{},"344":{},"352":{},"364":{},"365":{},"369":{},"376":{},"378":{},"382":{},"383":{},"385":{},"386":{},"387":{},"388":{},"394":{},"399":{},"400":{},"403":{},"404":{},"405":{}},"tags":{}}],["0",{"_index":343,"title":{},"content":{"16":{},"136":{},"319":{},"399":{}},"tags":{}}],["0.000111",{"_index":1641,"title":{},"content":{"172":{}},"tags":{}}],["0.000133",{"_index":1633,"title":{},"content":{"172":{}},"tags":{}}],["0.000228",{"_index":1650,"title":{},"content":{"172":{}},"tags":{}}],["0.001610",{"_index":1644,"title":{},"content":{"172":{}},"tags":{}}],["0.002057",{"_index":1624,"title":{},"content":{"172":{}},"tags":{}}],["0.003615",{"_index":1635,"title":{},"content":{"172":{}},"tags":{}}],["0.010233",{"_index":1640,"title":{},"content":{"172":{}},"tags":{}}],["0.011415",{"_index":1632,"title":{},"content":{"172":{}},"tags":{}}],["0.013774",{"_index":1649,"title":{},"content":{"172":{}},"tags":{}}],["0.295851",{"_index":1657,"title":{},"content":{"172":{}},"tags":{}}],["0000",{"_index":1176,"title":{},"content":{"129":{},"335":{}},"tags":{}}],["000000",{"_index":2400,"title":{},"content":{"382":{}},"tags":{}}],["00000000",{"_index":1175,"title":{},"content":{"129":{},"335":{}},"tags":{}}],["000000000000",{"_index":1177,"title":{},"content":{"129":{},"335":{}},"tags":{}}],["0000000000000000000000000000000000000000000000000000000000000000",{"_index":2519,"title":{},"content":{"399":{}},"tags":{}}],["028ead928a9034b2f",{"_index":1929,"title":{},"content":{"319":{}},"tags":{}}],["02c7a67c01ec70ffaf23d73a12f749ab150a8ac6dc529bda2fe1096a98bf42ea",{"_index":2517,"title":{},"content":{"399":{}},"tags":{}}],["02e96dc04a9e438cd",{"_index":1928,"title":{},"content":{"319":{}},"tags":{}}],["032ac10dd8d8266e3",{"_index":1930,"title":{},"content":{"319":{}},"tags":{}}],["032e0d57cc4395088",{"_index":1932,"title":{},"content":{"319":{}},"tags":{}}],["04a87d302e2509aad",{"_index":1937,"title":{},"content":{"319":{}},"tags":{}}],["053c3e49e19b96bdd",{"_index":1933,"title":{},"content":{"319":{}},"tags":{}}],["06b8cbf4837a0a57c",{"_index":1926,"title":{},"content":{"319":{}},"tags":{}}],["08t09:56:41z\",\"caller\":\"cmd/main.go:55\",\"msg\":\"start",{"_index":2153,"title":{},"content":{"343":{}},"tags":{}}],["08t09:56:43z\",\"logger\":\"recoveryserver\",\"caller\":\"recoveryserver/server.go:59\",\"msg\":\"start",{"_index":2156,"title":{},"content":{"343":{}},"tags":{}}],["08t09:56:43z\",\"logger\":\"rejoinclient\",\"caller\":\"rejoinclient/client.go:65\",\"msg\":\"start",{"_index":2157,"title":{},"content":{"343":{}},"tags":{}}],["08t09:56:43z\",\"logger\":\"rejoinclient\",\"caller\":\"rejoinclient/client.go:77\",\"msg\":\"receiv",{"_index":2158,"title":{},"content":{"343":{}},"tags":{}}],["08t09:56:43z\",\"logger\":\"rejoinclient\",\"caller\":\"rejoinclient/client.go:96\",\"msg\":\"request",{"_index":2160,"title":{},"content":{"343":{}},"tags":{}}],["08t09:56:43z\",\"logger\":\"setupmanager\",\"caller\":\"setup/setup.go:72\",\"msg\":\"prepar",{"_index":2155,"title":{},"content":{"343":{}},"tags":{}}],["08t09:57:03z\",\"logger\":\"rejoinclient\",\"caller\":\"rejoinclient/client.go:101\",\"msg\":\"fail",{"_index":2162,"title":{},"content":{"343":{}},"tags":{}}],["08t09:57:03z\",\"logger\":\"rejoinclient\",\"caller\":\"rejoinclient/client.go:96\",\"msg\":\"request",{"_index":2165,"title":{},"content":{"343":{}},"tags":{}}],["08t09:57:23z\",\"logger\":\"rejoinclient\",\"caller\":\"rejoinclient/client.go:101\",\"msg\":\"fail",{"_index":2167,"title":{},"content":{"343":{}},"tags":{}}],["08t09:57:23z\",\"logger\":\"rejoinclient\",\"caller\":\"rejoinclient/client.go:110\",\"msg\":\"fail",{"_index":2170,"title":{},"content":{"343":{}},"tags":{}}],["08t10:21:53z\",\"caller\":\"cmd/main.go:55\",\"msg\":\"start",{"_index":2123,"title":{},"content":{"343":{}},"tags":{}}],["08t10:21:53z\",\"logger\":\"recoveryserver\",\"caller\":\"recoveryserver/server.go:59\",\"msg\":\"start",{"_index":2128,"title":{},"content":{"343":{}},"tags":{}}],["08t10:21:53z\",\"logger\":\"rejoinclient\",\"caller\":\"rejoinclient/client.go:101\",\"msg\":\"fail",{"_index":2136,"title":{},"content":{"343":{}},"tags":{}}],["08t10:21:53z\",\"logger\":\"rejoinclient\",\"caller\":\"rejoinclient/client.go:65\",\"msg\":\"start",{"_index":2126,"title":{},"content":{"343":{}},"tags":{}}],["08t10:21:53z\",\"logger\":\"rejoinclient\",\"caller\":\"rejoinclient/client.go:77\",\"msg\":\"receiv",{"_index":2130,"title":{},"content":{"343":{}},"tags":{}}],["08t10:21:53z\",\"logger\":\"rejoinclient\",\"caller\":\"rejoinclient/client.go:96\",\"msg\":\"request",{"_index":2132,"title":{},"content":{"343":{}},"tags":{}}],["08t10:21:53z\",\"logger\":\"setupmanager\",\"caller\":\"setup/setup.go:72\",\"msg\":\"prepar",{"_index":2125,"title":{},"content":{"343":{}},"tags":{}}],["08t10:22:13z\",\"logger\":\"rejoinclient\",\"caller\":\"rejoinclient/client.go:101\",\"msg\":\"fail",{"_index":2145,"title":{},"content":{"343":{}},"tags":{}}],["08t10:22:13z\",\"logger\":\"rejoinclient\",\"caller\":\"rejoinclient/client.go:110\",\"msg\":\"fail",{"_index":2149,"title":{},"content":{"343":{}},"tags":{}}],["08t10:26:59z\",\"logger\":\"recoveryserver\",\"caller\":\"recoveryserver/server.go:125\",\"msg\":\"receiv",{"_index":2174,"title":{},"content":{"344":{}},"tags":{}}],["08t10:26:59z\",\"logger\":\"recoveryserver\",\"caller\":\"recoveryserver/server.go:93\",\"msg\":\"receiv",{"_index":2173,"title":{},"content":{"344":{}},"tags":{}}],["08t10:26:59z\",\"logger\":\"recoveryserver.grpc\",\"caller\":\"zap/server_interceptors.go:61\",\"msg\":\"finish",{"_index":2176,"title":{},"content":{"344":{}},"tags":{}}],["08t10:26:59z\",\"system\":\"grpc\",\"span.kind\":\"server\",\"grpc.service\":\"recoverproto.api\",\"grpc.method\":\"recover\",\"peer.address\":\"192.0.2.3:41752\",\"grpc.code\":\"ok\",\"grpc.time_ms\":15.701",{"_index":2178,"title":{},"content":{"344":{}},"tags":{}}],["08t10:27:13z\",\"logger\":\"rejoinclient\",\"caller\":\"rejoinclient/client.go:87\",\"msg\":\"rejoincli",{"_index":2179,"title":{},"content":{"344":{}},"tags":{}}],["09",{"_index":2122,"title":{},"content":{"343":{},"344":{},"404":{}},"tags":{}}],["098cd37f66523b7c3",{"_index":1936,"title":{},"content":{"319":{}},"tags":{}}],["0df7",{"_index":2437,"title":{},"content":{"390":{}},"tags":{}}],["0e27ebcefc38f648b",{"_index":1934,"title":{},"content":{"319":{}},"tags":{}}],["0f35c214608d93c7a6e68ae7359b4a8be5a0e99eea9107ece427c4dea4e439cf",{"_index":2516,"title":{},"content":{"399":{}},"tags":{}}],["1",{"_index":344,"title":{"321":{}},"content":{"16":{},"122":{},"125":{},"129":{},"130":{},"135":{},"137":{},"140":{},"145":{},"163":{},"179":{},"319":{},"333":{},"335":{},"343":{},"402":{}},"tags":{}}],["1.0",{"_index":2344,"title":{},"content":{"386":{}},"tags":{}}],["1.171577",{"_index":1652,"title":{},"content":{"172":{}},"tags":{}}],["1.23",{"_index":1083,"title":{},"content":{"124":{}},"tags":{}}],["1.24.9",{"_index":1714,"title":{},"content":{"181":{}},"tags":{}}],["1.25",{"_index":1725,"title":{},"content":{"183":{}},"tags":{}}],["1.25.8",{"_index":2464,"title":{},"content":{"396":{}},"tags":{}}],["1.632200",{"_index":1622,"title":{},"content":{"172":{}},"tags":{}}],["1.651549",{"_index":1643,"title":{},"content":{"172":{}},"tags":{}}],["1.656435",{"_index":1634,"title":{},"content":{"172":{}},"tags":{}}],["1.amazonaws.com",{"_index":1012,"title":{},"content":{"122":{}},"tags":{}}],["10",{"_index":359,"title":{},"content":{"16":{},"125":{},"129":{},"135":{},"136":{},"145":{},"172":{},"183":{},"184":{},"185":{}},"tags":{}}],["10.9.0.5:30090",{"_index":2163,"title":{},"content":{"343":{}},"tags":{}}],["10.9.0.6:30090",{"_index":2168,"title":{},"content":{"343":{}},"tags":{}}],["100",{"_index":1617,"title":{},"content":{"172":{},"185":{}},"tags":{}}],["1024",{"_index":1776,"title":{},"content":{"184":{}},"tags":{}}],["11",{"_index":363,"title":{},"content":{"16":{},"120":{},"127":{},"399":{}},"tags":{}}],["112",{"_index":1767,"title":{},"content":{"184":{}},"tags":{}}],["12",{"_index":365,"title":{},"content":{"16":{},"399":{}},"tags":{}}],["12.5",{"_index":1723,"title":{},"content":{"183":{}},"tags":{}}],["120",{"_index":2026,"title":{},"content":{"332":{}},"tags":{}}],["12345",{"_index":1192,"title":{},"content":{"129":{},"335":{}},"tags":{}}],["128",{"_index":1774,"title":{},"content":{"184":{},"333":{}},"tags":{}}],["129857",{"_index":2069,"title":{},"content":{"335":{}},"tags":{}}],["12t22:28:16z",{"_index":2490,"title":{},"content":{"404":{}},"tags":{}}],["13",{"_index":367,"title":{},"content":{"16":{},"399":{}},"tags":{}}],["1300",{"_index":1612,"title":{},"content":{"172":{}},"tags":{}}],["14",{"_index":368,"title":{},"content":{"16":{},"399":{}},"tags":{}}],["14028",{"_index":2277,"title":{},"content":{"355":{}},"tags":{}}],["144",{"_index":1755,"title":{},"content":{"184":{}},"tags":{}}],["1450",{"_index":1729,"title":{},"content":{"183":{}},"tags":{}}],["14t09:32:20z\",\"caller\":\"cmd/main.go:48\",\"msg\":\"constel",{"_index":1294,"title":{},"content":{"136":{}},"tags":{}}],["14t09:32:20z\",\"logger\":\"validator\",\"caller\":\"watcher/validator.go:96\",\"msg\":\"upd",{"_index":1296,"title":{},"content":{"136":{}},"tags":{}}],["15",{"_index":369,"title":{},"content":{"16":{},"129":{},"184":{},"185":{},"399":{}},"tags":{}}],["15,000",{"_index":1763,"title":{},"content":{"184":{}},"tags":{}}],["150",{"_index":1760,"title":{},"content":{"184":{},"369":{}},"tags":{}}],["1500",{"_index":1727,"title":{},"content":{"183":{}},"tags":{}}],["15343dba46cb.json",{"_index":2078,"title":{},"content":{"335":{}},"tags":{}}],["16",{"_index":1703,"title":{},"content":{"179":{},"180":{},"181":{},"332":{}},"tags":{}}],["16–23",{"_index":370,"title":{},"content":{"16":{}},"tags":{}}],["17",{"_index":1330,"title":{},"content":{"145":{}},"tags":{}}],["17.128781",{"_index":1656,"title":{},"content":{"172":{}},"tags":{}}],["1804gen2containerd",{"_index":1709,"title":{},"content":{"180":{}},"tags":{}}],["18e9924b416323c37b9cdfd6cc728de8a947424a",{"_index":2515,"title":{},"content":{"405":{}},"tags":{}}],["192.0.2.1",{"_index":2526,"title":{},"content":{"401":{}},"tags":{}}],["192.168.178.2:30090",{"_index":2146,"title":{},"content":{"343":{}},"tags":{}}],["192.168.178.4:30090",{"_index":2142,"title":{},"content":{"343":{}},"tags":{}}],["1c",{"_index":2035,"title":{},"content":{"333":{}},"tags":{}}],["1d",{"_index":2325,"title":{},"content":{"366":{}},"tags":{}}],["2",{"_index":345,"title":{"322":{}},"content":{"16":{},"26":{},"27":{},"46":{},"50":{},"129":{},"135":{},"140":{},"160":{},"163":{},"168":{},"175":{},"176":{},"179":{},"180":{},"181":{},"186":{},"319":{},"333":{},"335":{},"402":{}},"tags":{}}],["2.0",{"_index":336,"title":{},"content":{"16":{}},"tags":{}}],["2.10",{"_index":1904,"title":{"316":{}},"content":{},"tags":{}}],["2.18.0",{"_index":1892,"title":{"315":{}},"content":{},"tags":{}}],["2.19.0",{"_index":1890,"title":{"313":{}},"content":{},"tags":{}}],["2.2.0",{"_index":2431,"title":{},"content":{"390":{}},"tags":{}}],["2.21.1",{"_index":1887,"title":{"311":{}},"content":{},"tags":{}}],["2.263700",{"_index":1627,"title":{},"content":{"172":{}},"tags":{}}],["2.3",{"_index":1920,"title":{"319":{}},"content":{},"tags":{}}],["2.6.0",{"_index":2468,"title":{},"content":{"396":{}},"tags":{}}],["2.8",{"_index":1915,"title":{"318":{}},"content":{},"tags":{}}],["2.808401",{"_index":1630,"title":{},"content":{"172":{}},"tags":{}}],["2.9",{"_index":1913,"title":{"317":{}},"content":{},"tags":{}}],["2.amazonaws.com",{"_index":1013,"title":{},"content":{"122":{}},"tags":{}}],["2.amazonaws.com//communitygalleries/constellationcvm",{"_index":2435,"title":{},"content":{"390":{}},"tags":{}}],["20",{"_index":1109,"title":{},"content":{"125":{},"133":{},"365":{}},"tags":{}}],["20000",{"_index":1752,"title":{},"content":{"184":{}},"tags":{}}],["2012",{"_index":1329,"title":{},"content":{"145":{}},"tags":{}}],["2017",{"_index":1683,"title":{},"content":{"175":{}},"tags":{}}],["2022",{"_index":2489,"title":{},"content":{"404":{}},"tags":{}}],["2023.02.15",{"_index":1710,"title":{},"content":{"180":{}},"tags":{}}],["20gi",{"_index":2313,"title":{},"content":{"365":{}},"tags":{}}],["22.04",{"_index":1248,"title":{},"content":{"133":{},"346":{}},"tags":{}}],["23",{"_index":2466,"title":{},"content":{"396":{}},"tags":{}}],["23/25",{"_index":2462,"title":{},"content":{"396":{}},"tags":{}}],["230",{"_index":2028,"title":{},"content":{"332":{}},"tags":{}}],["24",{"_index":2409,"title":{},"content":{"383":{}},"tags":{}}],["240",{"_index":1764,"title":{},"content":{"184":{}},"tags":{}}],["2400",{"_index":1766,"title":{},"content":{"184":{}},"tags":{}}],["25",{"_index":2467,"title":{},"content":{"396":{}},"tags":{}}],["25.710886",{"_index":1661,"title":{},"content":{"172":{}},"tags":{}}],["25/25",{"_index":2463,"title":{},"content":{"396":{}},"tags":{}}],["256",{"_index":2228,"title":{},"content":{"360":{}},"tags":{}}],["25th",{"_index":1670,"title":{},"content":{"173":{}},"tags":{}}],["2a",{"_index":1160,"title":{},"content":{"129":{},"274":{},"335":{}},"tags":{}}],["2m59",{"_index":1297,"title":{},"content":{"136":{}},"tags":{}}],["2nd",{"_index":1705,"title":{},"content":{"179":{},"181":{}},"tags":{}}],["3",{"_index":346,"title":{"323":{}},"content":{"16":{},"26":{},"27":{},"32":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"129":{},"135":{},"146":{},"163":{},"164":{},"165":{},"166":{},"179":{},"323":{},"333":{},"335":{},"344":{}},"tags":{}}],["3,000",{"_index":1762,"title":{},"content":{"184":{}},"tags":{}}],["3.016106",{"_index":1646,"title":{},"content":{"172":{}},"tags":{}}],["3.075796",{"_index":1648,"title":{},"content":{"172":{}},"tags":{}}],["3.195248",{"_index":1660,"title":{},"content":{"172":{}},"tags":{}}],["3.300004",{"_index":1639,"title":{},"content":{"172":{}},"tags":{}}],["3.955051",{"_index":1637,"title":{},"content":{"172":{}},"tags":{}}],["3.amazonaws.com",{"_index":1018,"title":{},"content":{"122":{}},"tags":{}}],["30",{"_index":2023,"title":{},"content":{"332":{},"333":{}},"tags":{}}],["32",{"_index":575,"title":{},"content":{"33":{},"136":{}},"tags":{}}],["3400e5a2",{"_index":2061,"title":{},"content":{"335":{}},"tags":{}}],["3477047",{"_index":2482,"title":{},"content":{"403":{},"404":{}},"tags":{}}],["362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13",{"_index":2484,"title":{},"content":{"404":{}},"tags":{}}],["38cb66170f25",{"_index":2065,"title":{},"content":{"335":{}},"tags":{}}],["38f",{"_index":2226,"title":{},"content":{"360":{}},"tags":{}}],["3rd",{"_index":1679,"title":{},"content":{"175":{},"176":{},"179":{},"180":{}},"tags":{}}],["4",{"_index":347,"title":{"324":{}},"content":{"16":{},"26":{},"27":{},"32":{},"95":{},"96":{},"97":{},"98":{},"99":{},"124":{},"127":{},"129":{},"133":{},"163":{},"164":{},"165":{},"166":{},"168":{},"176":{},"179":{},"180":{},"181":{},"184":{},"324":{},"332":{},"365":{},"399":{}},"tags":{}}],["4.205618",{"_index":1655,"title":{},"content":{"172":{}},"tags":{}}],["4.331603",{"_index":1659,"title":{},"content":{"172":{}},"tags":{}}],["4.amazonaws.com",{"_index":1023,"title":{},"content":{"122":{}},"tags":{}}],["40",{"_index":1742,"title":{},"content":{"183":{}},"tags":{}}],["400",{"_index":1749,"title":{},"content":{"184":{}},"tags":{}}],["403",{"_index":2372,"title":{},"content":{"377":{}},"tags":{}}],["4096",{"_index":555,"title":{},"content":{"32":{}},"tags":{}}],["40e137b9b9b8204d672642fd1e181c6d5ccb50cfc5cc7fcbb06a8c2c78f44aff",{"_index":2493,"title":{},"content":{"404":{}},"tags":{}}],["4113",{"_index":2058,"title":{},"content":{"335":{}},"tags":{}}],["492a",{"_index":2063,"title":{},"content":{"335":{}},"tags":{}}],["4af8",{"_index":1940,"title":{},"content":{"319":{}},"tags":{}}],["4f2f",{"_index":2438,"title":{},"content":{"390":{}},"tags":{}}],["4fa7",{"_index":1939,"title":{},"content":{"319":{}},"tags":{}}],["5",{"_index":352,"title":{},"content":{"16":{},"163":{},"164":{},"165":{},"166":{},"172":{},"369":{},"399":{}},"tags":{}}],["5.185495",{"_index":1654,"title":{},"content":{"172":{}},"tags":{}}],["5.480679",{"_index":1626,"title":{},"content":{"172":{}},"tags":{}}],["5.780422",{"_index":1645,"title":{},"content":{"172":{}},"tags":{}}],["500",{"_index":1758,"title":{},"content":{"184":{}},"tags":{}}],["50th",{"_index":1674,"title":{},"content":{"173":{}},"tags":{}}],["512",{"_index":569,"title":{},"content":{"32":{},"184":{}},"tags":{}}],["58",{"_index":1737,"title":{},"content":{"183":{},"185":{}},"tags":{}}],["58c269a05435/resourcegroups/constel",{"_index":1942,"title":{},"content":{"319":{}},"tags":{}}],["6",{"_index":353,"title":{},"content":{"16":{},"133":{}},"tags":{}}],["6.030807",{"_index":1636,"title":{},"content":{"172":{}},"tags":{}}],["6.2",{"_index":1538,"title":{},"content":{"168":{}},"tags":{}}],["6.651001",{"_index":1629,"title":{},"content":{"172":{}},"tags":{}}],["6.942997",{"_index":1647,"title":{},"content":{"172":{}},"tags":{}}],["60",{"_index":1759,"title":{},"content":{"184":{},"332":{}},"tags":{}}],["600",{"_index":1111,"title":{},"content":{"125":{},"184":{}},"tags":{}}],["600m",{"_index":1106,"title":{},"content":{"125":{}},"tags":{}}],["64",{"_index":561,"title":{},"content":{"32":{},"133":{},"135":{}},"tags":{}}],["6400",{"_index":1751,"title":{},"content":{"184":{}},"tags":{}}],["66",{"_index":1288,"title":{},"content":{"136":{}},"tags":{}}],["7",{"_index":354,"title":{},"content":{"16":{}},"tags":{}}],["7.164843",{"_index":1638,"title":{},"content":{"172":{}},"tags":{}}],["75th",{"_index":1671,"title":{},"content":{"173":{}},"tags":{}}],["7763v",{"_index":1702,"title":{},"content":{"179":{},"180":{}},"tags":{}}],["7771317",{"_index":2508,"title":{},"content":{"405":{}},"tags":{}}],["8",{"_index":356,"title":{},"content":{"16":{},"160":{},"175":{},"319":{},"332":{},"399":{}},"tags":{}}],["80",{"_index":1104,"title":{},"content":{"125":{}},"tags":{}}],["800",{"_index":2225,"title":{},"content":{"360":{}},"tags":{}}],["8080:80",{"_index":989,"title":{},"content":{"121":{},"130":{},"137":{}},"tags":{}}],["8125",{"_index":1941,"title":{},"content":{"319":{}},"tags":{}}],["8334",{"_index":1031,"title":{},"content":{"122":{}},"tags":{}}],["8334:8334",{"_index":1053,"title":{},"content":{"122":{}},"tags":{}}],["886c",{"_index":2064,"title":{},"content":{"335":{}},"tags":{}}],["8896",{"_index":1728,"title":{},"content":{"183":{}},"tags":{}}],["8b8bd01f",{"_index":2056,"title":{},"content":{"335":{}},"tags":{}}],["8fe2",{"_index":2062,"title":{},"content":{"335":{}},"tags":{}}],["9",{"_index":357,"title":{},"content":{"16":{},"399":{}},"tags":{}}],["900m",{"_index":1105,"title":{},"content":{"125":{}},"tags":{}}],["963e",{"_index":2439,"title":{},"content":{"390":{}},"tags":{}}],["99th",{"_index":1607,"title":{},"content":{"172":{},"173":{}},"tags":{}}],["9bd1",{"_index":2059,"title":{},"content":{"335":{}},"tags":{}}],["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",{"_index":1963,"title":{},"content":{"319":{}},"tags":{}}],["aadclientid",{"_index":1898,"title":{},"content":{"315":{}},"tags":{}}],["aadclientsecret",{"_index":1899,"title":{},"content":{"315":{}},"tags":{}}],["abil",{"_index":743,"title":{},"content":{"56":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"163":{}},"tags":{}}],["abov",{"_index":293,"title":{},"content":{"16":{},"145":{},"154":{},"156":{},"157":{},"173":{},"364":{},"385":{},"394":{},"400":{},"402":{},"403":{}},"tags":{}}],["abstract",{"_index":2296,"title":{},"content":{"362":{}},"tags":{}}],["accept",{"_index":410,"title":{},"content":{"17":{},"134":{},"140":{},"146":{},"148":{}},"tags":{}}],["access",{"_index":42,"title":{"140":{},"188":{},"382":{},"383":{}},"content":{"2":{},"12":{},"29":{},"30":{},"49":{},"60":{},"66":{},"68":{},"122":{},"128":{},"129":{},"133":{},"140":{},"145":{},"146":{},"148":{},"157":{},"158":{},"164":{},"165":{},"166":{},"172":{},"184":{},"188":{},"189":{},"191":{},"304":{},"305":{},"330":{},"335":{},"360":{},"383":{},"401":{}},"tags":{}}],["access_key",{"_index":2217,"title":{},"content":{"358":{}},"tags":{}}],["access_secret",{"_index":2218,"title":{},"content":{"358":{}},"tags":{}}],["accessmod",{"_index":2312,"title":{},"content":{"365":{}},"tags":{}}],["accident",{"_index":1042,"title":{},"content":{"122":{}},"tags":{}}],["accompani",{"_index":2477,"title":{},"content":{"403":{}},"tags":{}}],["accord",{"_index":861,"title":{},"content":{"72":{}},"tags":{}}],["accordingli",{"_index":2367,"title":{},"content":{"388":{}},"tags":{}}],["account",{"_index":928,"title":{},"content":{"95":{},"96":{},"97":{},"98":{},"99":{},"129":{},"145":{},"146":{},"148":{},"155":{},"278":{},"282":{},"335":{},"377":{}},"tags":{}}],["accur",{"_index":1770,"title":{},"content":{"184":{}},"tags":{}}],["achiev",{"_index":1741,"title":{},"content":{"183":{},"340":{}},"tags":{}}],["action",{"_index":90,"title":{},"content":{"4":{},"28":{},"30":{},"122":{},"131":{},"138":{},"145":{},"321":{},"322":{},"323":{},"326":{},"343":{},"369":{}},"tags":{}}],["activ",{"_index":653,"title":{},"content":{"47":{},"49":{},"55":{},"65":{}},"tags":{}}],["actor",{"_index":1809,"title":{},"content":{"190":{}},"tags":{}}],["actual",{"_index":594,"title":{},"content":{"39":{},"59":{},"162":{},"390":{}},"tags":{}}],["ad",{"_index":651,"title":{},"content":{"47":{},"73":{},"78":{},"122":{},"125":{},"185":{},"316":{},"361":{},"365":{}},"tags":{}}],["add",{"_index":726,"title":{},"content":{"55":{},"122":{},"123":{},"143":{},"185":{},"315":{},"333":{},"335":{},"337":{},"354":{},"358":{},"361":{},"369":{},"377":{},"403":{}},"tags":{}}],["addit",{"_index":268,"title":{"333":{}},"content":{"15":{},"17":{},"30":{},"40":{},"66":{},"77":{},"124":{},"125":{},"136":{},"154":{},"198":{},"222":{},"316":{},"333":{},"336":{},"369":{},"372":{}},"tags":{}}],["addition",{"_index":1985,"title":{},"content":{"323":{}},"tags":{}}],["address",{"_index":1150,"title":{},"content":{"127":{},"183":{},"187":{},"363":{},"388":{},"401":{}},"tags":{}}],["adher",{"_index":335,"title":{},"content":{"16":{}},"tags":{}}],["adjust",{"_index":2340,"title":{},"content":{"386":{},"388":{},"390":{}},"tags":{}}],["admin",{"_index":46,"title":{},"content":{"2":{},"122":{},"142":{},"323":{},"335":{}},"tags":{}}],["admin.conf",{"_index":1218,"title":{},"content":{"129":{},"135":{},"337":{},"372":{},"386":{}},"tags":{}}],["administr",{"_index":542,"title":{},"content":{"30":{},"47":{},"72":{},"122":{},"145":{},"376":{}},"tags":{}}],["administratoraccess",{"_index":1353,"title":{},"content":{"145":{}},"tags":{}}],["adopt",{"_index":936,"title":{"103":{},"320":{},"321":{},"322":{},"323":{}},"content":{"100":{},"101":{},"102":{},"103":{},"320":{},"324":{},"405":{}},"tags":{}}],["advanc",{"_index":934,"title":{},"content":{"100":{},"101":{},"102":{},"103":{},"143":{},"189":{},"325":{},"395":{}},"tags":{}}],["advisori",{"_index":614,"title":{},"content":{"43":{}},"tags":{}}],["ae",{"_index":566,"title":{},"content":{"32":{},"360":{}},"tags":{}}],["afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13",{"_index":2481,"title":{},"content":{"403":{},"404":{}},"tags":{}}],["affect",{"_index":1587,"title":{},"content":{"160":{},"346":{}},"tags":{}}],["affero",{"_index":1569,"title":{},"content":{"150":{}},"tags":{}}],["aforement",{"_index":434,"title":{},"content":{"21":{}},"tags":{}}],["afterward",{"_index":1049,"title":{},"content":{"122":{},"314":{},"335":{},"372":{},"376":{}},"tags":{}}],["ag",{"_index":1287,"title":{},"content":{"136":{},"366":{}},"tags":{}}],["again",{"_index":803,"title":{},"content":{"60":{},"123":{},"261":{},"372":{},"376":{},"397":{}},"tags":{}}],["against",{"_index":167,"title":{},"content":{"10":{},"12":{},"15":{},"16":{},"17":{},"19":{},"20":{},"26":{},"27":{},"39":{},"163":{},"177":{},"352":{},"399":{},"405":{}},"tags":{}}],["agent",{"_index":634,"title":{},"content":{"46":{},"63":{}},"tags":{}}],["aggreg",{"_index":1603,"title":{},"content":{"172":{}},"tags":{}}],["agnost",{"_index":1566,"title":{},"content":{"158":{},"369":{}},"tags":{}}],["aid",{"_index":965,"title":{},"content":{"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"373":{}},"tags":{}}],["aim",{"_index":6,"title":{},"content":{"1":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"186":{}},"tags":{}}],["ak",{"_index":1557,"title":{"180":{}},"content":{"158":{},"171":{},"172":{},"177":{},"180":{},"183":{},"184":{},"185":{}},"tags":{}}],["aksubuntu",{"_index":1708,"title":{},"content":{"180":{}},"tags":{}}],["alb",{"_index":2104,"title":{},"content":{"341":{}},"tags":{}}],["algorithm",{"_index":549,"title":{"31":{}},"content":{"31":{},"33":{},"365":{},"404":{}},"tags":{}}],["align",{"_index":870,"title":{},"content":{"76":{},"78":{},"337":{}},"tags":{}}],["allcsp",{"_index":1924,"title":{},"content":{"319":{}},"tags":{}}],["allow",{"_index":318,"title":{},"content":{"16":{},"17":{},"36":{},"44":{},"48":{},"49":{},"66":{},"95":{},"96":{},"97":{},"98":{},"99":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"129":{},"135":{},"136":{},"145":{},"148":{},"155":{},"171":{},"314":{},"337":{},"349":{},"357":{},"360":{},"361":{},"362":{},"384":{},"398":{},"401":{},"402":{}},"tags":{}}],["allowvolumeexpans",{"_index":2322,"title":{},"content":{"366":{}},"tags":{}}],["along",{"_index":787,"title":{},"content":{"59":{},"383":{}},"tags":{}}],["alongsid",{"_index":699,"title":{},"content":{"49":{}},"tags":{}}],["alpha",{"_index":1964,"title":{},"content":{"320":{},"324":{}},"tags":{}}],["alreadi",{"_index":1384,"title":{},"content":{"145":{},"169":{},"323":{},"335":{},"396":{}},"tags":{}}],["altern",{"_index":396,"title":{},"content":{"17":{},"30":{},"143":{},"184":{},"185":{},"202":{},"319":{},"335":{},"336":{},"345":{},"365":{},"370":{},"376":{}},"tags":{}}],["altogeth",{"_index":842,"title":{},"content":{"66":{}},"tags":{}}],["alway",{"_index":20,"title":{},"content":{"1":{},"2":{},"9":{},"46":{},"65":{},"148":{},"375":{},"402":{}},"tags":{}}],["amazon",{"_index":1306,"title":{"164":{}},"content":{"142":{},"164":{},"186":{},"340":{},"341":{}},"tags":{}}],["amazon'",{"_index":1357,"title":{},"content":{"145":{}},"tags":{}}],["amd",{"_index":388,"title":{"175":{},"176":{}},"content":{"17":{},"129":{},"133":{},"163":{},"164":{},"166":{},"167":{},"168":{},"175":{},"176":{},"179":{},"180":{},"181":{},"183":{},"332":{}},"tags":{}}],["amd64",{"_index":1274,"title":{},"content":{"134":{},"143":{},"403":{},"404":{},"405":{}},"tags":{}}],["amd64.ex",{"_index":1318,"title":{},"content":{"143":{}},"tags":{}}],["amd64.sig",{"_index":2478,"title":{},"content":{"403":{}},"tags":{}}],["ami",{"_index":1925,"title":{},"content":{"319":{}},"tags":{}}],["amount",{"_index":540,"title":{},"content":{"30":{}},"tags":{}}],["amz",{"_index":1076,"title":{},"content":{"122":{}},"tags":{}}],["analog",{"_index":1692,"title":{},"content":{"176":{},"189":{}},"tags":{}}],["analysi",{"_index":1583,"title":{"159":{}},"content":{"183":{}},"tags":{}}],["annot",{"_index":2100,"title":{},"content":{"340":{},"366":{}},"tags":{}}],["annotations\":{\"storageclass.kubernetes.io/i",{"_index":2326,"title":{},"content":{"366":{}},"tags":{}}],["announc",{"_index":1531,"title":{},"content":{"165":{}},"tags":{}}],["anoth",{"_index":426,"title":{},"content":{"19":{},"46":{},"122":{},"129":{},"335":{},"365":{},"366":{}},"tags":{}}],["ansi",{"_index":1689,"title":{},"content":{"176":{}},"tags":{}}],["anymor",{"_index":837,"title":{},"content":{"65":{},"163":{},"336":{},"383":{}},"tags":{}}],["anyon",{"_index":513,"title":{},"content":{"29":{}},"tags":{}}],["anyway",{"_index":2413,"title":{},"content":{"383":{}},"tags":{}}],["ap",{"_index":1173,"title":{},"content":{"129":{},"335":{}},"tags":{}}],["apach",{"_index":1102,"title":{},"content":{"125":{},"126":{}},"tags":{}}],["apart",{"_index":2396,"title":{},"content":{"381":{}},"tags":{}}],["api",{"_index":461,"title":{},"content":{"23":{},"25":{},"55":{},"68":{},"144":{},"145":{},"146":{},"171":{},"343":{},"377":{},"378":{},"383":{}},"tags":{}}],["apivers",{"_index":998,"title":{},"content":{"122":{},"125":{},"365":{}},"tags":{}}],["app",{"_index":915,"title":{},"content":{"95":{},"96":{},"97":{},"98":{},"99":{},"122":{},"128":{},"130":{},"137":{},"143":{}},"tags":{}}],["apparmor",{"_index":2190,"title":{},"content":{"346":{}},"tags":{}}],["appdata%\\openstack\\clouds.yaml",{"_index":1474,"title":{},"content":{"146":{}},"tags":{}}],["append",{"_index":2003,"title":{},"content":{"328":{},"402":{}},"tags":{}}],["appl",{"_index":1310,"title":{},"content":{"143":{}},"tags":{}}],["appli",{"_index":760,"title":{"220":{},"252":{},"292":{},"395":{},"397":{}},"content":{"56":{},"61":{},"67":{},"121":{},"122":{},"125":{},"127":{},"129":{},"130":{},"135":{},"137":{},"191":{},"220":{},"221":{},"222":{},"244":{},"245":{},"249":{},"252":{},"253":{},"254":{},"288":{},"289":{},"292":{},"293":{},"294":{},"312":{},"314":{},"316":{},"326":{},"337":{},"338":{},"365":{},"372":{},"376":{},"377":{},"378":{},"379":{},"383":{},"386":{},"388":{},"390":{},"391":{},"395":{},"396":{},"400":{}},"tags":{}}],["applic",{"_index":178,"title":{"130":{},"137":{},"162":{},"170":{}},"content":{"11":{},"23":{},"28":{},"34":{},"56":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"120":{},"121":{},"122":{},"127":{},"146":{},"147":{},"162":{},"184":{},"335":{},"340":{},"341":{},"349":{},"356":{},"358":{},"361":{},"365":{},"372":{}},"tags":{}}],["approach",{"_index":291,"title":{},"content":{"16":{},"62":{},"63":{},"158":{},"349":{},"352":{},"360":{}},"tags":{}}],["appropri",{"_index":2465,"title":{},"content":{"396":{}},"tags":{}}],["approv",{"_index":1977,"title":{},"content":{"323":{}},"tags":{}}],["approxim",{"_index":1521,"title":{},"content":{"163":{},"183":{},"184":{}},"tags":{}}],["apps/v1",{"_index":999,"title":{},"content":{"122":{},"125":{}},"tags":{}}],["apt",{"_index":1268,"title":{},"content":{"134":{}},"tags":{}}],["arbitrari",{"_index":1510,"title":{},"content":{"163":{},"362":{}},"tags":{}}],["arch=amd64",{"_index":1261,"title":{},"content":{"134":{}},"tags":{}}],["architectur",{"_index":262,"title":{},"content":{"15":{},"42":{},"61":{},"71":{},"186":{},"337":{},"351":{}},"tags":{}}],["area",{"_index":1057,"title":{},"content":{"122":{}},"tags":{}}],["aren't",{"_index":310,"title":{},"content":{"16":{},"26":{},"27":{},"29":{},"65":{},"135":{},"140":{},"241":{},"364":{},"390":{}},"tags":{}}],["argon2id",{"_index":558,"title":{},"content":{"32":{}},"tags":{}}],["argument",{"_index":1850,"title":{"401":{}},"content":{"241":{}},"tags":{}}],["argumentofextend",{"_index":150,"title":{},"content":{"9":{}},"tags":{}}],["arithmet",{"_index":1605,"title":{},"content":{"172":{}},"tags":{}}],["arm64",{"_index":1309,"title":{},"content":{"143":{}},"tags":{}}],["arm64/amd64",{"_index":2333,"title":{},"content":{"385":{}},"tags":{}}],["arm_skip_provider_registr",{"_index":1385,"title":{},"content":{"145":{}},"tags":{}}],["arm_skip_provider_registration=tru",{"_index":2370,"title":{},"content":{"376":{}},"tags":{}}],["arm_subscription_id",{"_index":1863,"title":{},"content":{"278":{}},"tags":{}}],["around",{"_index":1994,"title":{},"content":{"324":{}},"tags":{}}],["art",{"_index":1542,"title":{},"content":{"169":{}},"tags":{}}],["articl",{"_index":1599,"title":{},"content":{"171":{}},"tags":{}}],["artifact",{"_index":118,"title":{"118":{},"320":{},"345":{}},"content":{"7":{},"66":{},"100":{},"101":{},"102":{},"103":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"320":{},"323":{},"345":{},"347":{},"349":{},"350":{},"402":{},"404":{},"405":{}},"tags":{}}],["asciinema",{"_index":2011,"title":{},"content":{"330":{},"337":{},"349":{},"372":{},"402":{}},"tags":{}}],["asg",{"_index":2118,"title":{},"content":{"343":{},"370":{},"371":{}},"tags":{}}],["asg'",{"_index":2120,"title":{},"content":{"343":{}},"tags":{}}],["ask",{"_index":1056,"title":{},"content":{"122":{},"146":{},"286":{}},"tags":{}}],["aspect",{"_index":1993,"title":{},"content":{"324":{}},"tags":{}}],["assess",{"_index":1694,"title":{},"content":{"177":{}},"tags":{}}],["assign",{"_index":1084,"title":{},"content":{"124":{},"127":{},"129":{},"145":{},"146":{},"335":{},"365":{}},"tags":{}}],["associ",{"_index":833,"title":{},"content":{"65":{},"129":{},"131":{},"138":{},"146":{},"372":{},"402":{}},"tags":{}}],["assum",{"_index":916,"title":{},"content":{"95":{},"96":{},"97":{},"98":{},"99":{},"128":{},"403":{}},"tags":{}}],["asynchron",{"_index":2457,"title":{},"content":{"396":{}},"tags":{}}],["atl",{"_index":212,"title":{"13":{}},"content":{"13":{},"19":{},"23":{},"52":{}},"tags":{}}],["att:verif",{"_index":2271,"title":{},"content":{"354":{}},"tags":{}}],["attach",{"_index":826,"title":{},"content":{"63":{},"135":{},"335":{},"352":{}},"tags":{}}],["attack",{"_index":47,"title":{"189":{},"190":{}},"content":{"2":{},"47":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"158":{},"163":{},"187":{},"188":{},"189":{},"190":{}},"tags":{}}],["attempt",{"_index":1810,"title":{},"content":{"190":{},"376":{},"377":{}},"tags":{}}],["attent",{"_index":955,"title":{},"content":{"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"135":{},"190":{},"329":{}},"tags":{}}],["attest",{"_index":94,"title":{"5":{},"11":{},"13":{},"15":{},"18":{},"19":{},"20":{},"70":{},"73":{},"83":{},"377":{}},"content":{"5":{},"6":{},"11":{},"12":{},"13":{},"14":{},"15":{},"16":{},"17":{},"18":{},"19":{},"20":{},"23":{},"43":{},"45":{},"49":{},"50":{},"52":{},"53":{},"67":{},"70":{},"73":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"129":{},"132":{},"136":{},"156":{},"157":{},"158":{},"163":{},"164":{},"165":{},"166":{},"187":{},"190":{},"198":{},"242":{},"318":{},"332":{},"342":{},"352":{},"354":{},"377":{},"378":{},"389":{},"394":{},"398":{},"399":{},"400":{},"405":{}},"tags":{}}],["attestation_url",{"_index":2089,"title":{},"content":{"337":{}},"tags":{}}],["attestationconfig",{"_index":1844,"title":{},"content":{"222":{},"378":{}},"tags":{}}],["attestationconfig_backup",{"_index":2382,"title":{},"content":{"378":{}},"tags":{}}],["attestationvari",{"_index":1919,"title":{},"content":{"318":{}},"tags":{}}],["attribut",{"_index":1730,"title":{},"content":{"183":{},"386":{},"388":{}},"tags":{}}],["audit",{"_index":1811,"title":{},"content":{"190":{}},"tags":{}}],["augment",{"_index":1551,"title":{},"content":{"157":{}},"tags":{}}],["auth",{"_index":1469,"title":{},"content":{"146":{}},"tags":{}}],["auth_url",{"_index":1475,"title":{},"content":{"146":{}},"tags":{}}],["authent",{"_index":465,"title":{"146":{}},"content":{"23":{},"40":{},"67":{},"68":{},"73":{},"122":{},"144":{},"146":{},"315":{},"317":{},"322":{},"323":{},"335":{},"377":{},"383":{}},"tags":{}}],["author",{"_index":208,"title":{},"content":{"12":{},"13":{},"146":{}},"tags":{}}],["authorizationrul",{"_index":2345,"title":{},"content":{"386":{}},"tags":{}}],["auto",{"_index":2117,"title":{},"content":{"343":{},"370":{},"371":{}},"tags":{}}],["autocomplet",{"_index":1325,"title":{},"content":{"143":{}},"tags":{}}],["autom",{"_index":1965,"title":{},"content":{"321":{},"372":{}},"tags":{}}],["automat",{"_index":453,"title":{},"content":{"23":{},"25":{},"37":{},"60":{},"70":{},"127":{},"132":{},"145":{},"146":{},"308":{},"333":{},"335":{},"342":{},"356":{},"365":{},"369":{},"372":{},"376":{},"393":{},"395":{},"400":{},"402":{}},"tags":{}}],["autosc",{"_index":711,"title":{"123":{},"369":{}},"content":{"52":{},"67":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"120":{},"123":{},"124":{},"135":{},"186":{},"367":{},"369":{}},"tags":{}}],["autoscal",{"_index":1114,"title":{},"content":{"125":{},"126":{},"315":{},"369":{}},"tags":{}}],["avail",{"_index":297,"title":{},"content":{"16":{},"17":{},"28":{},"47":{},"48":{},"49":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"95":{},"96":{},"97":{},"98":{},"99":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"121":{},"127":{},"129":{},"135":{},"136":{},"143":{},"148":{},"150":{},"151":{},"152":{},"155":{},"163":{},"166":{},"184":{},"186":{},"257":{},"274":{},"282":{},"321":{},"323":{},"333":{},"335":{},"342":{},"349":{},"351":{},"363":{},"364":{},"381":{},"384":{},"386":{},"389":{},"390":{},"391":{},"394":{},"397":{},"399":{},"402":{},"405":{}},"tags":{}}],["averag",{"_index":1108,"title":{},"content":{"125":{}},"tags":{}}],["avoid",{"_index":956,"title":{},"content":{"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"329":{},"346":{}},"tags":{}}],["aw",{"_index":329,"title":{"164":{},"272":{},"312":{},"340":{},"341":{}},"content":{"16":{},"17":{},"34":{},"49":{},"95":{},"96":{},"97":{},"98":{},"99":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"122":{},"129":{},"142":{},"145":{},"146":{},"148":{},"155":{},"157":{},"163":{},"164":{},"186":{},"191":{},"198":{},"272":{},"273":{},"274":{},"312":{},"316":{},"319":{},"331":{},"332":{},"333":{},"335":{},"340":{},"341":{},"343":{},"356":{},"363":{},"364":{},"365":{},"370":{},"371":{},"386":{}},"tags":{}}],["awar",{"_index":2006,"title":{},"content":{"329":{}},"tags":{}}],["awk",{"_index":1151,"title":{},"content":{"127":{}},"tags":{}}],["aws'",{"_index":1170,"title":{},"content":{"129":{},"332":{},"335":{}},"tags":{}}],["aws_iam_policy.control_plane_polici",{"_index":2051,"title":{},"content":{"335":{}},"tags":{}}],["aws_iam_policy.worker_node_polici",{"_index":2054,"title":{},"content":{"335":{}},"tags":{}}],["awsaccesskeyid=\"$access_key",{"_index":2220,"title":{},"content":{"358":{}},"tags":{}}],["awsnitrotpm",{"_index":1171,"title":{},"content":{"129":{},"332":{}},"tags":{}}],["awssecretaccesskey=\"$access_secret",{"_index":2221,"title":{},"content":{"358":{}},"tags":{}}],["awssevsnp",{"_index":1168,"title":{},"content":{"129":{},"332":{}},"tags":{}}],["aws|azure|gcp|openstack|qemu|stackit",{"_index":1822,"title":{},"content":{"197":{}},"tags":{}}],["az",{"_index":1464,"title":{},"content":{"146":{},"148":{},"310":{},"335":{}},"tags":{}}],["azur",{"_index":330,"title":{"165":{},"175":{},"276":{},"310":{},"314":{},"376":{},"377":{},"389":{}},"content":{"16":{},"17":{},"49":{},"95":{},"96":{},"97":{},"98":{},"99":{},"124":{},"129":{},"142":{},"145":{},"146":{},"148":{},"155":{},"160":{},"163":{},"165":{},"169":{},"175":{},"177":{},"179":{},"180":{},"183":{},"184":{},"186":{},"191":{},"276":{},"277":{},"278":{},"310":{},"314":{},"315":{},"318":{},"319":{},"331":{},"332":{},"333":{},"335":{},"336":{},"337":{},"343":{},"363":{},"364":{},"365":{},"370":{},"371":{},"376":{},"377":{},"386":{},"389":{},"390":{}},"tags":{}}],["azure'",{"_index":1190,"title":{},"content":{"129":{},"146":{},"335":{},"386":{}},"tags":{}}],["azure_image_file=./constellation.img",{"_index":2430,"title":{},"content":{"390":{}},"tags":{}}],["azure_image_version=2.2.0",{"_index":2428,"title":{},"content":{"390":{}},"tags":{}}],["azure_resource_group_name=constel",{"_index":2429,"title":{},"content":{"390":{}},"tags":{}}],["azureconfig",{"_index":1900,"title":{},"content":{"315":{}},"tags":{}}],["azurevm",{"_index":2348,"title":{},"content":{"386":{}},"tags":{}}],["b",{"_index":1564,"title":{},"content":{"158":{},"179":{},"181":{}},"tags":{}}],["b3782fa0",{"_index":2436,"title":{},"content":{"390":{}},"tags":{}}],["back",{"_index":669,"title":{},"content":{"48":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"340":{},"341":{},"342":{},"383":{}},"tags":{}}],["backend",{"_index":510,"title":{},"content":{"29":{},"122":{},"363":{}},"tags":{}}],["background",{"_index":1799,"title":{},"content":{"187":{}},"tags":{}}],["backup",{"_index":2331,"title":{},"content":{"372":{},"378":{},"395":{}},"tags":{}}],["backward",{"_index":2191,"title":{},"content":{"346":{}},"tags":{}}],["balanc",{"_index":950,"title":{},"content":{"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"127":{},"135":{},"184":{},"185":{},"186":{},"314":{},"316":{},"339":{},"340":{},"341":{},"383":{}},"tags":{}}],["bandwidth",{"_index":1719,"title":{},"content":{"183":{},"184":{},"185":{}},"tags":{}}],["bar",{"_index":1673,"title":{},"content":{"173":{}},"tags":{}}],["base",{"_index":191,"title":{"189":{}},"content":{"12":{},"16":{},"17":{},"20":{},"22":{},"23":{},"24":{},"45":{},"47":{},"49":{},"53":{},"63":{},"71":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"123":{},"132":{},"156":{},"157":{},"163":{},"164":{},"165":{},"166":{},"172":{},"186":{},"187":{},"323":{},"337":{},"362":{},"363":{},"364":{},"383":{},"389":{}},"tags":{}}],["base64",{"_index":843,"title":{},"content":{"66":{},"68":{},"352":{},"404":{}},"tags":{}}],["bash",{"_index":1875,"title":{},"content":{"310":{}},"tags":{}}],["basi",{"_index":925,"title":{},"content":{"95":{},"96":{},"97":{},"98":{},"99":{},"148":{},"155":{}},"tags":{}}],["basic",{"_index":86,"title":{},"content":{"4":{},"121":{},"168":{},"387":{}},"tags":{}}],["bazel",{"_index":1966,"title":{},"content":{"321":{},"346":{},"347":{}},"tags":{}}],["bazelvers",{"_index":2199,"title":{},"content":{"347":{}},"tags":{}}],["be",{"_index":279,"title":{},"content":{"15":{},"16":{},"49":{},"55":{},"65":{},"73":{},"125":{},"129":{},"335":{},"337":{}},"tags":{}}],["becom",{"_index":983,"title":{},"content":{"121":{},"127":{},"135":{},"136":{},"165":{},"343":{}},"tags":{}}],["befor",{"_index":163,"title":{"311":{},"313":{},"315":{},"316":{},"317":{},"318":{},"319":{}},"content":{"10":{},"11":{},"15":{},"29":{},"30":{},"36":{},"37":{},"38":{},"45":{},"49":{},"73":{},"77":{},"125":{},"136":{},"145":{},"190":{},"314":{},"322":{},"323":{},"330":{},"337":{},"340":{},"342":{},"356":{},"369":{},"386":{},"390":{}},"tags":{}}],["begin",{"_index":1087,"title":{},"content":{"124":{},"349":{},"402":{}},"tags":{}}],["behavior",{"_index":729,"title":{},"content":{"55":{},"56":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"125":{},"126":{},"377":{}},"tags":{}}],["below",{"_index":123,"title":{},"content":{"7":{},"310":{},"319":{},"366":{},"386":{},"400":{}},"tags":{}}],["benchmark",{"_index":1588,"title":{"161":{},"162":{},"170":{},"175":{},"176":{},"177":{}},"content":{"160":{},"161":{},"162":{},"171":{},"172":{},"175":{},"176":{},"177":{},"179":{},"180":{},"181":{},"183":{},"184":{},"185":{}},"tags":{}}],["benefit",{"_index":67,"title":{"90":{},"187":{}},"content":{"3":{},"4":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"158":{},"185":{}},"tags":{}}],["best",{"_index":8,"title":{},"content":{"1":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"165":{},"186":{},"346":{}},"tags":{}}],["better",{"_index":1137,"title":{},"content":{"126":{},"161":{},"172":{},"183":{}},"tags":{}}],["between",{"_index":215,"title":{},"content":{"13":{},"23":{},"46":{},"50":{},"55":{},"100":{},"101":{},"102":{},"103":{},"176":{},"183":{},"185":{},"308":{},"353":{},"389":{}},"tags":{}}],["beyond",{"_index":865,"title":{},"content":{"74":{},"172":{}},"tags":{}}],["biggest",{"_index":1790,"title":{},"content":{"185":{},"324":{}},"tags":{}}],["bill",{"_index":923,"title":{"349":{}},"content":{"95":{},"96":{},"97":{},"98":{},"99":{},"148":{},"155":{},"349":{}},"tags":{}}],["bin/sh",{"_index":1122,"title":{},"content":{"125":{}},"tags":{}}],["binari",{"_index":478,"title":{"151":{}},"content":{"26":{},"27":{},"143":{},"151":{},"153":{},"348":{},"396":{}},"tags":{}}],["bind",{"_index":267,"title":{},"content":{"15":{},"49":{}},"tags":{}}],["bios/uefi",{"_index":1242,"title":{},"content":{"133":{}},"tags":{}}],["bit",{"_index":570,"title":{},"content":{"32":{},"345":{},"360":{}},"tags":{}}],["bjthj",{"_index":2403,"title":{},"content":{"382":{}},"tags":{}}],["black",{"_index":767,"title":{},"content":{"57":{}},"tags":{}}],["blob",{"_index":692,"title":{},"content":{"49":{},"351":{},"403":{}},"tags":{}}],["block",{"_index":524,"title":{},"content":{"30":{},"39":{},"47":{},"75":{},"122":{},"184":{},"337":{},"357":{},"362":{},"364":{},"376":{},"388":{}},"tags":{}}],["blue",{"_index":1059,"title":{},"content":{"122":{}},"tags":{}}],["bodi",{"_index":2491,"title":{},"content":{"404":{}},"tags":{}}],["boot",{"_index":158,"title":{"10":{},"36":{},"74":{}},"content":{"10":{},"11":{},"15":{},"16":{},"35":{},"36":{},"37":{},"38":{},"45":{},"51":{},"67":{},"74":{},"157":{},"163":{},"164":{},"166":{},"167":{},"257":{},"342":{},"343":{},"381":{}},"tags":{}}],["bootload",{"_index":135,"title":{"38":{}},"content":{"8":{},"16":{},"37":{},"38":{}},"tags":{}}],["bootstrap",{"_index":421,"title":{},"content":{"19":{},"23":{},"44":{},"50":{},"52":{},"73":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"257":{},"337":{},"338":{}},"tags":{}}],["bootstrapp",{"_index":316,"title":{"51":{}},"content":{"16":{},"41":{},"45":{},"50":{},"51":{},"60":{},"67":{},"73":{},"310":{}},"tags":{}}],["both",{"_index":244,"title":{},"content":{"14":{},"132":{},"145":{},"183":{},"184":{},"186":{},"402":{},"405":{}},"tags":{}}],["bottleneck",{"_index":813,"title":{},"content":{"62":{}},"tags":{}}],["bounc",{"_index":1733,"title":{},"content":{"183":{}},"tags":{}}],["bound",{"_index":1572,"title":{},"content":{"151":{},"152":{},"184":{}},"tags":{}}],["boundari",{"_index":1780,"title":{},"content":{"184":{}},"tags":{}}],["boutiqu",{"_index":973,"title":{"127":{}},"content":{"120":{},"127":{}},"tags":{}}],["box",{"_index":768,"title":{},"content":{"57":{},"173":{},"364":{}},"tags":{}}],["break",{"_index":931,"title":{},"content":{"100":{},"101":{},"102":{},"103":{},"189":{},"308":{},"387":{}},"tags":{}}],["bring",{"_index":516,"title":{"387":{}},"content":{"29":{},"49":{},"122":{}},"tags":{}}],["broad",{"_index":1545,"title":{},"content":{"169":{}},"tags":{}}],["broken",{"_index":2394,"title":{},"content":{"379":{}},"tags":{}}],["brows",{"_index":1054,"title":{},"content":{"122":{},"127":{}},"tags":{}}],["browser",{"_index":1154,"title":{},"content":{"127":{}},"tags":{}}],["bucket",{"_index":1043,"title":{},"content":{"122":{}},"tags":{}}],["buffer",{"_index":1734,"title":{},"content":{"183":{}},"tags":{}}],["bug",{"_index":882,"title":{},"content":{"77":{},"348":{}},"tags":{}}],["build",{"_index":159,"title":{"346":{},"347":{}},"content":{"10":{},"75":{},"100":{},"101":{},"102":{},"103":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"165":{},"169":{},"320":{},"321":{},"322":{},"323":{},"345":{},"346":{},"347":{},"348":{},"349":{},"405":{}},"tags":{}}],["builder",{"_index":2510,"title":{},"content":{"405":{}},"tags":{}}],["built",{"_index":523,"title":{},"content":{"30":{},"145":{},"164":{},"342":{}},"tags":{}}],["burst",{"_index":1753,"title":{},"content":{"184":{}},"tags":{}}],["busybox",{"_index":2188,"title":{},"content":{"346":{}},"tags":{}}],["by=/etc/apt/keyrings/docker.gpg",{"_index":1262,"title":{},"content":{"134":{}},"tags":{}}],["byok",{"_index":681,"title":{},"content":{"49":{}},"tags":{}}],["byte",{"_index":556,"title":{},"content":{"32":{},"33":{}},"tags":{}}],["c",{"_index":1123,"title":{},"content":{"125":{},"195":{},"199":{},"203":{},"207":{},"211":{},"215":{},"219":{},"223":{},"227":{},"231":{},"235":{},"239":{},"243":{},"247":{},"251":{},"255":{},"259":{},"263":{},"267":{},"271":{},"275":{},"279":{},"283":{},"287":{},"291":{},"295":{},"299":{},"303":{},"307":{},"346":{}},"tags":{}}],["c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d",{"_index":2487,"title":{},"content":{"404":{}},"tags":{}}],["c11n",{"_index":1642,"title":{},"content":{"172":{}},"tags":{}}],["c2d",{"_index":1198,"title":{},"content":{"129":{},"332":{},"335":{}},"tags":{}}],["c6a.24xlarg",{"_index":2038,"title":{},"content":{"333":{}},"tags":{}}],["c6a.xlarg",{"_index":2033,"title":{},"content":{"333":{}},"tags":{}}],["c82137c32da7",{"_index":2060,"title":{},"content":{"335":{}},"tags":{}}],["c82137c32da7/resourcegroups/constel",{"_index":2067,"title":{},"content":{"335":{}},"tags":{}}],["c:\\program",{"_index":1319,"title":{},"content":{"143":{}},"tags":{}}],["ca",{"_index":1033,"title":{},"content":{"122":{}},"tags":{}}],["ca.crt",{"_index":1036,"title":{},"content":{"122":{}},"tags":{}}],["cach",{"_index":493,"title":{},"content":{"28":{},"184":{}},"tags":{}}],["calcul",{"_index":289,"title":{},"content":{"15":{},"172":{}},"tags":{}}],["call",{"_index":27,"title":{},"content":{"1":{},"7":{},"8":{},"12":{},"54":{},"55":{},"122":{},"135":{},"143":{},"144":{},"344":{}},"tags":{}}],["can't",{"_index":481,"title":{"376":{},"377":{}},"content":{"26":{},"27":{},"261":{},"323":{},"346":{}},"tags":{}}],["candid",{"_index":1134,"title":{},"content":{"125":{}},"tags":{}}],["capabl",{"_index":867,"title":{},"content":{"76":{},"120":{},"123":{},"163":{},"184":{},"185":{}},"tags":{}}],["capac",{"_index":1110,"title":{},"content":{"125":{},"370":{},"371":{}},"tags":{}}],["care",{"_index":700,"title":{},"content":{"50":{},"65":{},"76":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"378":{}},"tags":{}}],["carri",{"_index":1969,"title":{},"content":{"322":{}},"tags":{}}],["case",{"_index":64,"title":{"3":{}},"content":{"3":{},"11":{},"22":{},"44":{},"48":{},"49":{},"60":{},"129":{},"135":{},"172":{},"183":{},"184":{},"254":{},"327":{},"338":{},"342":{},"353":{},"364":{},"366":{},"372":{},"390":{},"395":{}},"tags":{}}],["cast",{"_index":2012,"title":{},"content":{"330":{},"337":{},"349":{},"372":{},"402":{}},"tags":{}}],["cat",{"_index":995,"title":{},"content":{"122":{},"125":{},"365":{}},"tags":{}}],["caus",{"_index":723,"title":{},"content":{"55":{},"378":{}},"tags":{}}],["caution",{"_index":1208,"title":{},"content":{"129":{},"135":{},"146":{},"329":{},"336":{},"340":{},"341":{},"372":{},"378":{},"379":{},"389":{}},"tags":{}}],["cc",{"_index":188,"title":{},"content":{"12":{},"13":{},"15":{}},"tags":{}}],["cd",{"_index":2196,"title":{},"content":{"347":{},"383":{},"386":{}},"tags":{}}],["cdn.confidential.cloud",{"_index":448,"title":{},"content":{"22":{}},"tags":{}}],["ce",{"_index":1269,"title":{},"content":{"134":{}},"tags":{}}],["center",{"_index":2048,"title":{},"content":{"335":{}},"tags":{}}],["central",{"_index":1019,"title":{},"content":{"122":{},"129":{},"335":{}},"tags":{}}],["central1",{"_index":2070,"title":{},"content":{"335":{}},"tags":{}}],["cert",{"_index":953,"title":{"110":{},"329":{}},"content":{"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"122":{},"254":{},"329":{},"396":{}},"tags":{}}],["certain",{"_index":177,"title":{},"content":{"11":{},"17":{},"158":{},"163":{},"185":{},"324":{},"365":{}},"tags":{}}],["certif",{"_index":120,"title":{},"content":{"7":{},"12":{},"13":{},"17":{},"52":{},"122":{},"136":{},"156":{},"157":{},"191":{},"304":{},"305":{},"361":{},"383":{}},"tags":{}}],["certificatefile=constellation_cert.pub",{"_index":2411,"title":{},"content":{"383":{}},"tags":{}}],["certsan",{"_index":1845,"title":{},"content":{"222":{}},"tags":{}}],["cf",{"_index":1690,"title":{},"content":{"176":{}},"tags":{}}],["chacha20",{"_index":642,"title":{},"content":{"46":{}},"tags":{}}],["chain",{"_index":160,"title":{"24":{},"190":{},"320":{}},"content":{"10":{},"15":{},"16":{},"17":{},"24":{},"38":{},"62":{},"67":{},"70":{},"100":{},"101":{},"102":{},"103":{},"140":{},"190":{},"320":{},"402":{}},"tags":{}}],["challeng",{"_index":228,"title":{},"content":{"14":{},"62":{},"63":{}},"tags":{}}],["chang",{"_index":263,"title":{"366":{}},"content":{"15":{},"16":{},"55":{},"100":{},"101":{},"102":{},"103":{},"129":{},"135":{},"172":{},"308":{},"312":{},"314":{},"316":{},"320":{},"323":{},"324":{},"356":{},"361":{},"366":{},"377":{},"378":{},"379":{},"387":{},"388":{}},"tags":{}}],["characterist",{"_index":1586,"title":{},"content":{"159":{}},"tags":{}}],["charg",{"_index":1571,"title":{},"content":{"151":{},"152":{}},"tags":{}}],["chart",{"_index":1842,"title":{},"content":{"222":{},"254":{},"302":{},"358":{},"379":{},"395":{}},"tags":{}}],["check",{"_index":423,"title":{"248":{},"394":{},"396":{}},"content":{"19":{},"34":{},"39":{},"55":{},"125":{},"126":{},"128":{},"129":{},"135":{},"136":{},"139":{},"191":{},"195":{},"199":{},"203":{},"207":{},"211":{},"215":{},"219":{},"222":{},"223":{},"227":{},"231":{},"235":{},"239":{},"243":{},"247":{},"248":{},"249":{},"250":{},"251":{},"255":{},"259":{},"263":{},"267":{},"271":{},"275":{},"279":{},"283":{},"287":{},"291":{},"295":{},"299":{},"303":{},"307":{},"319":{},"337":{},"343":{},"347":{},"352":{},"358":{},"364":{},"375":{},"378":{},"379":{},"387":{},"390":{},"391":{},"393":{},"394":{},"397":{},"405":{}},"tags":{}}],["checkout",{"_index":2197,"title":{},"content":{"347":{}},"tags":{}}],["chip",{"_index":111,"title":{},"content":{"7":{}},"tags":{}}],["chmod",{"_index":2426,"title":{},"content":{"390":{}},"tags":{}}],["choic",{"_index":854,"title":{},"content":{"68":{},"335":{},"337":{},"395":{}},"tags":{}}],["choos",{"_index":2013,"title":{"332":{},"334":{}},"content":{"330":{},"332":{}},"tags":{}}],["chosen",{"_index":1614,"title":{},"content":{"172":{},"184":{},"253":{},"335":{},"366":{}},"tags":{}}],["ci/cd",{"_index":2270,"title":{},"content":{"354":{}},"tags":{}}],["cidr",{"_index":735,"title":{},"content":{"55":{}},"tags":{}}],["cilium",{"_index":633,"title":{},"content":{"46":{},"55":{},"58":{},"61":{},"62":{},"179":{},"183":{},"185":{},"396":{}},"tags":{}}],["cilium'",{"_index":728,"title":{},"content":{"55":{}},"tags":{}}],["cinder",{"_index":2299,"title":{},"content":{"363":{},"364":{}},"tags":{}}],["circl",{"_index":1675,"title":{},"content":{"173":{}},"tags":{}}],["claim",{"_index":2261,"title":{},"content":{"352":{},"365":{},"366":{}},"tags":{}}],["claimnam",{"_index":2316,"title":{},"content":{"365":{}},"tags":{}}],["class",{"_index":547,"title":{"366":{}},"content":{"30":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"184":{},"187":{},"341":{},"345":{},"365":{},"366":{}},"tags":{}}],["class\":\"fals",{"_index":2327,"title":{},"content":{"366":{}},"tags":{}}],["class\":\"tru",{"_index":2328,"title":{},"content":{"366":{}},"tags":{}}],["classic",{"_index":1271,"title":{},"content":{"134":{}},"tags":{}}],["clean",{"_index":1299,"title":{},"content":{"138":{},"310":{},"382":{}},"tags":{}}],["cleanup",{"_index":2102,"title":{},"content":{"340":{}},"tags":{}}],["cli",{"_index":404,"title":{"22":{},"100":{},"104":{},"140":{},"143":{},"191":{},"311":{},"313":{},"315":{},"316":{},"317":{},"318":{},"319":{},"351":{},"392":{},"402":{}},"content":{"17":{},"22":{},"23":{},"24":{},"25":{},"60":{},"64":{},"65":{},"66":{},"67":{},"68":{},"69":{},"70":{},"72":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"95":{},"96":{},"97":{},"98":{},"99":{},"100":{},"101":{},"102":{},"103":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"120":{},"131":{},"134":{},"141":{},"143":{},"146":{},"148":{},"151":{},"191":{},"208":{},"209":{},"296":{},"297":{},"310":{},"321":{},"322":{},"326":{},"327":{},"328":{},"331":{},"332":{},"334":{},"335":{},"337":{},"338":{},"351":{},"354":{},"365":{},"372":{},"377":{},"379":{},"386":{},"391":{},"392":{},"394":{},"399":{},"402":{},"403":{},"404":{},"405":{}},"tags":{}}],["cli'",{"_index":446,"title":{},"content":{"22":{},"314":{}},"tags":{}}],["cli:cli_enterprise_darwin_amd64",{"_index":2200,"title":{},"content":{"347":{}},"tags":{}}],["cli:cli_enterprise_darwin_arm64",{"_index":2201,"title":{},"content":{"347":{}},"tags":{}}],["cli:cli_enterprise_linux_amd64",{"_index":2202,"title":{},"content":{"347":{}},"tags":{}}],["cli:cli_enterprise_linux_arm64",{"_index":2203,"title":{},"content":{"347":{}},"tags":{}}],["cli:cli_enterprise_windows_amd64",{"_index":2204,"title":{},"content":{"347":{}},"tags":{}}],["click",{"_index":1058,"title":{},"content":{"122":{},"143":{},"343":{},"370":{},"371":{}},"tags":{}}],["client",{"_index":224,"title":{},"content":{"13":{},"34":{},"53":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"183":{},"356":{},"361":{},"383":{}},"tags":{}}],["client'",{"_index":2233,"title":{},"content":{"361":{}},"tags":{}}],["clone",{"_index":2194,"title":{},"content":{"347":{}},"tags":{}}],["close",{"_index":301,"title":{},"content":{"16":{},"23":{},"165":{},"166":{}},"tags":{}}],["cloud",{"_index":16,"title":{"29":{},"57":{},"92":{},"96":{},"98":{},"144":{},"148":{},"163":{},"166":{}},"content":{"1":{},"2":{},"3":{},"16":{},"22":{},"28":{},"29":{},"30":{},"49":{},"57":{},"64":{},"66":{},"67":{},"71":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"95":{},"96":{},"97":{},"98":{},"99":{},"100":{},"101":{},"102":{},"103":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"122":{},"128":{},"129":{},"131":{},"132":{},"135":{},"141":{},"142":{},"144":{},"146":{},"148":{},"158":{},"161":{},"162":{},"163":{},"168":{},"169":{},"184":{},"186":{},"187":{},"188":{},"189":{},"191":{},"197":{},"198":{},"200":{},"201":{},"204":{},"205":{},"216":{},"217":{},"264":{},"265":{},"268":{},"269":{},"314":{},"315":{},"316":{},"318":{},"319":{},"325":{},"327":{},"330":{},"333":{},"335":{},"337":{},"343":{},"362":{},"363":{},"369":{},"372":{},"378":{},"387":{},"389":{},"390":{},"395":{}},"tags":{}}],["clouds.yaml",{"_index":1490,"title":{},"content":{"146":{}},"tags":{}}],["cloudshel",{"_index":1463,"title":{},"content":{"146":{}},"tags":{}}],["cluster",{"_index":14,"title":{"18":{},"19":{},"23":{},"45":{},"64":{},"66":{},"80":{},"105":{},"106":{},"107":{},"108":{},"112":{},"113":{},"114":{},"129":{},"131":{},"132":{},"135":{},"136":{},"138":{},"140":{},"330":{},"337":{},"342":{},"343":{},"344":{},"367":{},"372":{},"375":{},"388":{},"391":{},"398":{}},"content":{"1":{},"3":{},"14":{},"15":{},"16":{},"17":{},"18":{},"19":{},"20":{},"21":{},"23":{},"24":{},"25":{},"30":{},"42":{},"44":{},"45":{},"46":{},"47":{},"48":{},"49":{},"50":{},"51":{},"52":{},"53":{},"55":{},"58":{},"60":{},"61":{},"63":{},"64":{},"65":{},"66":{},"67":{},"68":{},"69":{},"72":{},"73":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"95":{},"96":{},"97":{},"98":{},"99":{},"100":{},"101":{},"102":{},"103":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"120":{},"121":{},"123":{},"124":{},"125":{},"126":{},"127":{},"128":{},"129":{},"131":{},"132":{},"135":{},"136":{},"138":{},"144":{},"145":{},"147":{},"148":{},"151":{},"155":{},"156":{},"157":{},"158":{},"172":{},"174":{},"186":{},"190":{},"191":{},"195":{},"199":{},"203":{},"207":{},"211":{},"215":{},"216":{},"217":{},"218":{},"219":{},"220":{},"221":{},"223":{},"224":{},"225":{},"227":{},"228":{},"229":{},"231":{},"232":{},"233":{},"234":{},"235":{},"236":{},"237":{},"239":{},"240":{},"241":{},"242":{},"243":{},"244":{},"245":{},"247":{},"249":{},"251":{},"252":{},"253":{},"254":{},"255":{},"256":{},"257":{},"259":{},"260":{},"261":{},"262":{},"263":{},"267":{},"268":{},"269":{},"271":{},"272":{},"273":{},"275":{},"276":{},"277":{},"278":{},"279":{},"280":{},"281":{},"282":{},"283":{},"287":{},"291":{},"295":{},"299":{},"300":{},"301":{},"303":{},"305":{},"307":{},"310":{},"312":{},"315":{},"316":{},"326":{},"329":{},"330":{},"332":{},"335":{},"336":{},"337":{},"340":{},"341":{},"342":{},"343":{},"344":{},"358":{},"361":{},"364":{},"365":{},"366":{},"367":{},"369":{},"370":{},"371":{},"372":{},"375":{},"378":{},"379":{},"381":{},"383":{},"384":{},"386":{},"387":{},"388":{},"391":{},"392":{},"394":{},"395":{},"396":{},"398":{},"399":{},"400":{},"401":{}},"tags":{}}],["cluster'",{"_index":242,"title":{},"content":{"14":{},"16":{},"48":{},"53":{},"66":{},"129":{},"135":{},"143":{},"151":{},"152":{},"156":{},"326":{},"337":{},"343":{},"344":{},"401":{}},"tags":{}}],["cluster.log",{"_index":804,"title":{},"content":{"60":{},"338":{}},"tags":{}}],["clusterid",{"_index":273,"title":{},"content":{"15":{},"16":{},"19":{},"44":{},"45":{},"68":{},"401":{}},"tags":{}}],["clusterip",{"_index":1736,"title":{},"content":{"183":{}},"tags":{}}],["cni",{"_index":632,"title":{},"content":{"46":{},"55":{},"58":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"180":{},"181":{}},"tags":{}}],["co",{"_index":52,"title":{},"content":{"2":{}},"tags":{}}],["code",{"_index":627,"title":{"150":{}},"content":{"45":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"100":{},"101":{},"102":{},"103":{},"150":{},"156":{},"163":{},"314":{},"320":{},"323":{},"325":{},"343":{},"344":{},"349":{},"377":{},"402":{}},"tags":{}}],["coher",{"_index":1554,"title":{},"content":{"157":{}},"tags":{}}],["collect",{"_index":778,"title":{},"content":{"58":{},"60":{},"61":{},"62":{},"63":{},"161":{},"175":{},"338":{},"381":{},"386":{}},"tags":{}}],["combin",{"_index":628,"title":{},"content":{"45":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"186":{}},"tags":{}}],["come",{"_index":48,"title":{},"content":{"2":{},"34":{},"43":{},"74":{},"154":{},"169":{},"186":{},"355":{},"365":{},"369":{},"392":{}},"tags":{}}],["comma",{"_index":1843,"title":{},"content":{"222":{},"254":{}},"tags":{}}],["command",{"_index":349,"title":{"195":{},"199":{},"203":{},"207":{},"211":{},"215":{},"219":{},"223":{},"227":{},"231":{},"235":{},"239":{},"243":{},"247":{},"251":{},"255":{},"259":{},"263":{},"267":{},"271":{},"275":{},"279":{},"283":{},"287":{},"291":{},"295":{},"299":{},"303":{},"307":{},"400":{}},"content":{"16":{},"22":{},"38":{},"39":{},"67":{},"95":{},"96":{},"97":{},"98":{},"99":{},"126":{},"129":{},"135":{},"138":{},"141":{},"143":{},"186":{},"191":{},"222":{},"316":{},"326":{},"331":{},"335":{},"336":{},"337":{},"342":{},"372":{},"378":{},"386":{},"390":{},"391":{},"394":{},"395":{},"396":{},"399":{},"400":{},"401":{},"404":{}},"tags":{}}],["commerc",{"_index":975,"title":{},"content":{"120":{},"127":{}},"tags":{}}],["commerci",{"_index":1579,"title":{},"content":{"153":{}},"tags":{}}],["commit",{"_index":2514,"title":{},"content":{"405":{}},"tags":{}}],["common",{"_index":679,"title":{"374":{}},"content":{"49":{},"325":{}},"tags":{}}],["commun",{"_index":631,"title":{"153":{}},"content":{"46":{},"51":{},"55":{},"62":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"151":{},"152":{},"361":{},"390":{}},"tags":{}}],["compar",{"_index":165,"title":{},"content":{"10":{},"11":{},"15":{},"16":{},"17":{},"19":{},"20":{},"26":{},"27":{},"126":{},"161":{},"162":{},"172":{},"175":{},"176":{},"177":{},"183":{},"184":{},"185":{},"347":{},"369":{},"399":{}},"tags":{}}],["comparison",{"_index":1556,"title":{"158":{}},"content":{"158":{},"183":{}},"tags":{}}],["compat",{"_index":580,"title":{},"content":{"34":{},"49":{},"63":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"195":{},"199":{},"203":{},"207":{},"211":{},"215":{},"219":{},"223":{},"227":{},"231":{},"235":{},"239":{},"243":{},"247":{},"251":{},"255":{},"259":{},"263":{},"267":{},"271":{},"275":{},"279":{},"283":{},"287":{},"291":{},"295":{},"299":{},"303":{},"307":{},"346":{},"356":{},"364":{}},"tags":{}}],["complet",{"_index":1224,"title":{},"content":{"129":{},"135":{},"143":{},"191":{},"256":{},"346":{},"390":{},"396":{}},"tags":{}}],["complex",{"_index":810,"title":{},"content":{"62":{}},"tags":{}}],["compli",{"_index":2275,"title":{},"content":{"355":{},"377":{}},"tags":{}}],["complianc",{"_index":610,"title":{},"content":{"42":{},"49":{},"63":{}},"tags":{}}],["compon",{"_index":132,"title":{"41":{}},"content":{"8":{},"9":{},"10":{},"13":{},"15":{},"16":{},"17":{},"20":{},"38":{},"41":{},"42":{},"43":{},"51":{},"58":{},"61":{},"62":{},"67":{},"77":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"129":{},"135":{},"187":{},"335":{},"337":{},"391":{},"402":{}},"tags":{}}],["comprehens",{"_index":1584,"title":{},"content":{"159":{}},"tags":{}}],["compromis",{"_index":57,"title":{},"content":{"2":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"187":{}},"tags":{}}],["comput",{"_index":29,"title":{"174":{}},"content":{"1":{},"12":{},"29":{},"56":{},"75":{},"76":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"145":{},"156":{},"157":{},"160":{},"165":{},"167":{},"175":{},"176":{},"181":{},"184":{},"185":{},"187":{},"335":{},"370":{},"371":{},"389":{}},"tags":{}}],["compute.addresses.createintern",{"_index":1399,"title":{},"content":{"145":{}},"tags":{}}],["compute.addresses.deleteintern",{"_index":1400,"title":{},"content":{"145":{}},"tags":{}}],["compute.addresses.get",{"_index":1401,"title":{},"content":{"145":{}},"tags":{}}],["compute.addresses.useintern",{"_index":1402,"title":{},"content":{"145":{}},"tags":{}}],["compute.backendservices.cr",{"_index":1403,"title":{},"content":{"145":{}},"tags":{}}],["compute.backendservices.delet",{"_index":1404,"title":{},"content":{"145":{}},"tags":{}}],["compute.backendservices.get",{"_index":1405,"title":{},"content":{"145":{}},"tags":{}}],["compute.backendservices.us",{"_index":1406,"title":{},"content":{"145":{}},"tags":{}}],["compute.disks.cr",{"_index":1407,"title":{},"content":{"145":{}},"tags":{}}],["compute.firewalls.cr",{"_index":1408,"title":{},"content":{"145":{}},"tags":{}}],["compute.firewalls.delet",{"_index":1409,"title":{},"content":{"145":{}},"tags":{}}],["compute.firewalls.get",{"_index":1410,"title":{},"content":{"145":{}},"tags":{}}],["compute.firewalls.upd",{"_index":1411,"title":{},"content":{"145":{}},"tags":{}}],["compute.globaladdresses.cr",{"_index":1412,"title":{},"content":{"145":{}},"tags":{}}],["compute.globaladdresses.delet",{"_index":1413,"title":{},"content":{"145":{}},"tags":{}}],["compute.globaladdresses.get",{"_index":1414,"title":{},"content":{"145":{}},"tags":{}}],["compute.globaladdresses.us",{"_index":1415,"title":{},"content":{"145":{}},"tags":{}}],["compute.globalforwardingrules.cr",{"_index":1416,"title":{},"content":{"145":{}},"tags":{}}],["compute.globalforwardingrules.delet",{"_index":1417,"title":{},"content":{"145":{}},"tags":{}}],["compute.globalforwardingrules.get",{"_index":1418,"title":{},"content":{"145":{}},"tags":{}}],["compute.globalforwardingrules.setlabel",{"_index":1419,"title":{},"content":{"145":{}},"tags":{}}],["compute.globaloperations.get",{"_index":1420,"title":{},"content":{"145":{}},"tags":{}}],["compute.healthchecks.cr",{"_index":1421,"title":{},"content":{"145":{}},"tags":{}}],["compute.healthchecks.delet",{"_index":1422,"title":{},"content":{"145":{}},"tags":{}}],["compute.healthchecks.get",{"_index":1423,"title":{},"content":{"145":{}},"tags":{}}],["compute.healthchecks.usereadonli",{"_index":1424,"title":{},"content":{"145":{}},"tags":{}}],["compute.instancegroupmanagers.cr",{"_index":1425,"title":{},"content":{"145":{}},"tags":{}}],["compute.instancegroupmanagers.delet",{"_index":1426,"title":{},"content":{"145":{}},"tags":{}}],["compute.instancegroupmanagers.get",{"_index":1427,"title":{},"content":{"145":{}},"tags":{}}],["compute.instancegroupmanagers.upd",{"_index":1428,"title":{},"content":{"145":{}},"tags":{}}],["compute.instancegroups.cr",{"_index":1429,"title":{},"content":{"145":{}},"tags":{}}],["compute.instancegroups.delet",{"_index":1430,"title":{},"content":{"145":{}},"tags":{}}],["compute.instancegroups.get",{"_index":1431,"title":{},"content":{"145":{}},"tags":{}}],["compute.instancegroups.upd",{"_index":1432,"title":{},"content":{"145":{}},"tags":{}}],["compute.instancegroups.us",{"_index":1433,"title":{},"content":{"145":{}},"tags":{}}],["compute.instances.cr",{"_index":1434,"title":{},"content":{"145":{}},"tags":{}}],["compute.instances.setlabel",{"_index":1435,"title":{},"content":{"145":{}},"tags":{}}],["compute.instances.setmetadata",{"_index":1436,"title":{},"content":{"145":{}},"tags":{}}],["compute.instances.settag",{"_index":1437,"title":{},"content":{"145":{}},"tags":{}}],["compute.instancetemplates.cr",{"_index":1438,"title":{},"content":{"145":{}},"tags":{}}],["compute.instancetemplates.delet",{"_index":1439,"title":{},"content":{"145":{}},"tags":{}}],["compute.instancetemplates.get",{"_index":1440,"title":{},"content":{"145":{}},"tags":{}}],["compute.instancetemplates.usereadonli",{"_index":1441,"title":{},"content":{"145":{}},"tags":{}}],["compute.networks.cr",{"_index":1442,"title":{},"content":{"145":{}},"tags":{}}],["compute.networks.delet",{"_index":1443,"title":{},"content":{"145":{}},"tags":{}}],["compute.networks.get",{"_index":1444,"title":{},"content":{"145":{}},"tags":{}}],["compute.networks.updatepolici",{"_index":1445,"title":{},"content":{"145":{}},"tags":{}}],["compute.routers.cr",{"_index":1446,"title":{},"content":{"145":{}},"tags":{}}],["compute.routers.delet",{"_index":1447,"title":{},"content":{"145":{}},"tags":{}}],["compute.routers.get",{"_index":1448,"title":{},"content":{"145":{}},"tags":{}}],["compute.routers.upd",{"_index":1449,"title":{},"content":{"145":{}},"tags":{}}],["compute.subnetworks.cr",{"_index":1450,"title":{},"content":{"145":{}},"tags":{}}],["compute.subnetworks.delet",{"_index":1451,"title":{},"content":{"145":{}},"tags":{}}],["compute.subnetworks.get",{"_index":1452,"title":{},"content":{"145":{}},"tags":{}}],["compute.subnetworks.us",{"_index":1453,"title":{},"content":{"145":{}},"tags":{}}],["compute.targettcpproxies.cr",{"_index":1454,"title":{},"content":{"145":{}},"tags":{}}],["compute.targettcpproxies.delet",{"_index":1455,"title":{},"content":{"145":{}},"tags":{}}],["compute.targettcpproxies.get",{"_index":1456,"title":{},"content":{"145":{}},"tags":{}}],["compute.targettcpproxies.us",{"_index":1457,"title":{},"content":{"145":{}},"tags":{}}],["concept",{"_index":84,"title":{},"content":{"4":{},"6":{},"10":{},"15":{},"21":{},"29":{},"70":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"156":{},"157":{},"186":{},"187":{}},"tags":{}}],["conceptu",{"_index":1280,"title":{},"content":{"135":{}},"tags":{}}],["concern",{"_index":1285,"title":{},"content":{"135":{}},"tags":{}}],["conclus",{"_index":1541,"title":{"169":{},"185":{}},"content":{},"tags":{}}],["concret",{"_index":893,"title":{},"content":{"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"187":{}},"tags":{}}],["concurr",{"_index":960,"title":{},"content":{"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"172":{},"342":{}},"tags":{}}],["conduct",{"_index":1697,"title":{},"content":{"179":{},"185":{}},"tags":{}}],["conf.yaml",{"_index":1165,"title":{},"content":{"129":{},"135":{},"138":{},"148":{},"310":{},"331":{},"335":{},"378":{},"390":{},"393":{},"401":{}},"tags":{}}],["conf.yml",{"_index":2029,"title":{},"content":{"332":{},"333":{}},"tags":{}}],["confid",{"_index":1793,"title":{},"content":{"185":{}},"tags":{}}],["confidenti",{"_index":28,"title":{"12":{},"43":{},"89":{},"156":{},"363":{}},"content":{"1":{},"4":{},"11":{},"12":{},"28":{},"29":{},"30":{},"35":{},"37":{},"42":{},"43":{},"50":{},"56":{},"67":{},"71":{},"74":{},"75":{},"76":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"127":{},"132":{},"147":{},"156":{},"157":{},"158":{},"160":{},"163":{},"174":{},"183":{},"186":{},"187":{},"190":{},"191":{},"240":{},"241":{},"301":{},"356":{},"363":{},"389":{},"398":{},"400":{}},"tags":{}}],["confidentialvm",{"_index":1916,"title":{},"content":{"318":{},"390":{}},"tags":{}}],["config",{"_index":320,"title":{"192":{},"196":{},"200":{},"204":{},"208":{},"212":{}},"content":{"16":{},"17":{},"65":{},"129":{},"135":{},"148":{},"191":{},"194":{},"197":{},"201":{},"205":{},"209":{},"213":{},"250":{},"270":{},"275":{},"279":{},"283":{},"308":{},"310":{},"315":{},"319":{},"331":{},"332":{},"334":{},"335":{},"365":{},"378":{},"383":{},"389":{},"390":{},"392":{},"393":{},"394":{},"395":{},"399":{}},"tags":{}}],["config/openstack/clouds.yaml",{"_index":1470,"title":{},"content":{"146":{}},"tags":{}}],["configmap",{"_index":2384,"title":{},"content":{"378":{}},"tags":{}}],["configur",{"_index":138,"title":{"9":{},"68":{},"101":{},"105":{},"178":{},"330":{},"331":{},"335":{},"336":{},"393":{}},"content":{"9":{},"14":{},"16":{},"17":{},"18":{},"20":{},"30":{},"31":{},"41":{},"49":{},"51":{},"55":{},"64":{},"65":{},"66":{},"67":{},"68":{},"100":{},"101":{},"102":{},"103":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"125":{},"129":{},"135":{},"138":{},"145":{},"146":{},"156":{},"172":{},"179":{},"180":{},"181":{},"184":{},"191":{},"192":{},"193":{},"196":{},"197":{},"200":{},"201":{},"212":{},"213":{},"220":{},"221":{},"253":{},"264":{},"265":{},"268":{},"269":{},"270":{},"272":{},"273":{},"275":{},"276":{},"277":{},"279":{},"280":{},"281":{},"282":{},"283":{},"284":{},"285":{},"286":{},"316":{},"319":{},"326":{},"330":{},"331":{},"332":{},"333":{},"335":{},"336":{},"337":{},"341":{},"362":{},"369":{},"372":{},"378":{},"383":{},"386":{},"388":{},"390":{},"391":{},"393":{},"399":{}},"tags":{}}],["confirm",{"_index":1231,"title":{},"content":{"131":{},"138":{},"218":{},"222":{},"234":{},"254":{},"262":{},"270":{},"275":{},"279":{},"283":{},"286":{},"294":{},"372":{}},"tags":{}}],["conform",{"_index":1837,"title":{},"content":{"222":{},"254":{},"302":{}},"tags":{}}],["conjunct",{"_index":1549,"title":{},"content":{"156":{},"190":{}},"tags":{}}],["connect",{"_index":214,"title":{"136":{}},"content":{"13":{},"19":{},"23":{},"28":{},"46":{},"67":{},"68":{},"129":{},"135":{},"183":{},"319":{},"337":{},"342":{},"343":{},"382":{},"383":{},"386":{}},"tags":{}}],["consecut",{"_index":814,"title":{},"content":{"62":{}},"tags":{}}],["consequ",{"_index":519,"title":{},"content":{"29":{},"158":{},"174":{}},"tags":{}}],["consid",{"_index":490,"title":{},"content":{"28":{},"55":{},"333":{},"352":{},"357":{},"387":{}},"tags":{}}],["consist",{"_index":298,"title":{},"content":{"16":{},"120":{},"127":{},"136":{},"184":{},"229":{},"395":{},"402":{}},"tags":{}}],["consol",{"_index":2114,"title":{},"content":{"343":{},"344":{},"381":{}},"tags":{}}],["constant",{"_index":482,"title":{},"content":{"26":{},"27":{}},"tags":{}}],["constel",{"_index":3,"title":{"30":{},"35":{},"48":{},"64":{},"128":{},"143":{},"148":{},"157":{},"159":{},"179":{},"192":{},"196":{},"200":{},"204":{},"208":{},"212":{},"216":{},"220":{},"224":{},"228":{},"232":{},"236":{},"240":{},"244":{},"248":{},"252":{},"256":{},"260":{},"264":{},"268":{},"272":{},"276":{},"280":{},"284":{},"288":{},"292":{},"296":{},"300":{},"304":{},"351":{}},"content":{"1":{},"2":{},"3":{},"4":{},"6":{},"14":{},"15":{},"16":{},"17":{},"19":{},"20":{},"21":{},"22":{},"29":{},"30":{},"32":{},"33":{},"34":{},"35":{},"38":{},"39":{},"40":{},"42":{},"44":{},"45":{},"46":{},"47":{},"48":{},"49":{},"50":{},"51":{},"53":{},"54":{},"55":{},"56":{},"58":{},"60":{},"61":{},"62":{},"63":{},"65":{},"66":{},"67":{},"68":{},"69":{},"70":{},"71":{},"72":{},"73":{},"74":{},"75":{},"76":{},"77":{},"78":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"95":{},"96":{},"97":{},"98":{},"99":{},"100":{},"101":{},"102":{},"103":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"122":{},"123":{},"124":{},"127":{},"128":{},"129":{},"131":{},"132":{},"134":{},"135":{},"138":{},"141":{},"143":{},"144":{},"145":{},"146":{},"148":{},"151":{},"152":{},"153":{},"154":{},"155":{},"157":{},"158":{},"159":{},"161":{},"162":{},"163":{},"165":{},"166":{},"168":{},"169":{},"171":{},"172":{},"174":{},"175":{},"176":{},"177":{},"179":{},"183":{},"184":{},"185":{},"186":{},"187":{},"188":{},"189":{},"190":{},"191":{},"192":{},"193":{},"195":{},"197":{},"199":{},"201":{},"203":{},"205":{},"207":{},"209":{},"211":{},"213":{},"215":{},"216":{},"217":{},"219":{},"220":{},"221":{},"222":{},"223":{},"227":{},"229":{},"230":{},"231":{},"233":{},"235":{},"236":{},"237":{},"239":{},"240":{},"241":{},"243":{},"244":{},"245":{},"247":{},"249":{},"251":{},"252":{},"253":{},"255":{},"256":{},"257":{},"259":{},"260":{},"261":{},"263":{},"267":{},"268":{},"269":{},"271":{},"272":{},"273":{},"274":{},"275":{},"276":{},"277":{},"279":{},"280":{},"281":{},"283":{},"285":{},"287":{},"291":{},"293":{},"295":{},"297":{},"299":{},"300":{},"301":{},"302":{},"303":{},"305":{},"307":{},"308":{},"310":{},"312":{},"314":{},"315":{},"316":{},"319":{},"320":{},"322":{},"323":{},"325":{},"326":{},"327":{},"328":{},"329":{},"331":{},"332":{},"333":{},"334":{},"335":{},"336":{},"337":{},"338":{},"339":{},"341":{},"342":{},"343":{},"344":{},"345":{},"346":{},"347":{},"349":{},"351":{},"352":{},"356":{},"358":{},"363":{},"364":{},"365":{},"366":{},"367":{},"369":{},"370":{},"371":{},"372":{},"373":{},"376":{},"378":{},"379":{},"381":{},"382":{},"383":{},"384":{},"386":{},"387":{},"388":{},"389":{},"390":{},"391":{},"392":{},"393":{},"394":{},"395":{},"396":{},"397":{},"398":{},"399":{},"400":{},"401":{},"402":{},"403":{},"404":{},"405":{}},"tags":{}}],["constellation'",{"_index":97,"title":{},"content":{"5":{},"18":{},"30":{},"31":{},"57":{},"58":{},"63":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"120":{},"123":{},"148":{},"150":{},"151":{},"152":{},"162":{},"164":{},"165":{},"166":{},"167":{},"183":{},"334":{},"342":{},"365":{},"388":{},"398":{}},"tags":{}}],["constellation.ex",{"_index":1316,"title":{},"content":{"143":{}},"tags":{}}],["constellation.intoto.jsonl",{"_index":2505,"title":{},"content":{"405":{}},"tags":{}}],["constellation.licens",{"_index":1582,"title":{},"content":{"154":{}},"tags":{}}],["constellation.s3.u",{"_index":2434,"title":{},"content":{"390":{}},"tags":{}}],["constellation.spdx.sbom",{"_index":2248,"title":{},"content":{"351":{}},"tags":{}}],["constellation.spdx.sbom.sig",{"_index":2249,"title":{},"content":{"351":{}},"tags":{}}],["constellation_cert.pub",{"_index":2408,"title":{},"content":{"383":{}},"tags":{}}],["constellation_cluster.azure_exampl",{"_index":2343,"title":{},"content":{"386":{}},"tags":{}}],["constellation_microservice_vers",{"_index":2365,"title":{},"content":{"388":{}},"tags":{}}],["constelltest",{"_index":1164,"title":{},"content":{"129":{},"335":{}},"tags":{}}],["constrain",{"_index":559,"title":{},"content":{"32":{}},"tags":{}}],["constraint",{"_index":2362,"title":{},"content":{"388":{}},"tags":{}}],["consult",{"_index":2042,"title":{},"content":{"333":{}},"tags":{}}],["consum",{"_index":963,"title":{"117":{},"349":{}},"content":{"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"184":{},"352":{},"353":{},"354":{},"386":{}},"tags":{}}],["consumpt",{"_index":769,"title":{},"content":{"57":{},"153":{}},"tags":{}}],["contact",{"_index":930,"title":{},"content":{"95":{},"96":{},"97":{},"98":{},"99":{},"148":{},"155":{},"378":{},"379":{}},"tags":{}}],["contain",{"_index":283,"title":{"352":{}},"content":{"15":{},"22":{},"28":{},"35":{},"39":{},"40":{},"46":{},"55":{},"59":{},"61":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"122":{},"125":{},"126":{},"143":{},"184":{},"190":{},"319":{},"336":{},"341":{},"352":{},"362":{},"365":{},"378":{},"387":{},"399":{},"404":{}},"tags":{}}],["container",{"_index":864,"title":{},"content":{"74":{}},"tags":{}}],["container'",{"_index":1046,"title":{},"content":{"122":{}},"tags":{}}],["containerport",{"_index":1030,"title":{},"content":{"122":{},"125":{}},"tags":{}}],["content",{"_index":2494,"title":{},"content":{"404":{}},"tags":{}}],["context",{"_index":376,"title":{},"content":{"16":{},"28":{},"29":{},"48":{},"49":{},"56":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"157":{},"158":{},"187":{},"363":{}},"tags":{}}],["continu",{"_index":1229,"title":{},"content":{"131":{},"138":{},"185":{},"337":{},"342":{},"347":{},"355":{},"372":{},"376":{},"392":{}},"tags":{}}],["contractor",{"_index":1800,"title":{},"content":{"188":{}},"tags":{}}],["contributor",{"_index":1380,"title":{},"content":{"145":{},"335":{}},"tags":{}}],["control",{"_index":303,"title":{"371":{}},"content":{"16":{},"17":{},"48":{},"49":{},"52":{},"54":{},"69":{},"74":{},"95":{},"96":{},"97":{},"98":{},"99":{},"100":{},"101":{},"102":{},"103":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"124":{},"129":{},"132":{},"135":{},"136":{},"141":{},"156":{},"157":{},"158":{},"163":{},"179":{},"229":{},"314":{},"315":{},"316":{},"322":{},"323":{},"325":{},"333":{},"335":{},"340":{},"341":{},"342":{},"343":{},"344":{},"371":{}},"tags":{}}],["control_plane_default",{"_index":2030,"title":{},"content":{"333":{}},"tags":{}}],["control_plane_instance_profile_nam",{"_index":2050,"title":{},"content":{"335":{}},"tags":{}}],["controlplan",{"_index":2150,"title":{},"content":{"343":{},"371":{}},"tags":{}}],["convert",{"_index":2267,"title":{},"content":{"353":{}},"tags":{}}],["copi",{"_index":835,"title":{},"content":{"65":{},"188":{}},"tags":{}}],["core",{"_index":68,"title":{},"content":{"3":{},"125":{},"133":{},"179":{},"180":{},"181":{},"184":{}},"tags":{}}],["coremark",{"_index":1684,"title":{},"content":{"175":{}},"tags":{}}],["coreutil",{"_index":2186,"title":{},"content":{"346":{}},"tags":{}}],["corner",{"_index":1063,"title":{},"content":{"122":{},"343":{}},"tags":{}}],["cornerston",{"_index":100,"title":{},"content":{"5":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{}},"tags":{}}],["correct",{"_index":589,"title":{},"content":{"36":{},"400":{}},"tags":{}}],["correctli",{"_index":2086,"title":{},"content":{"337":{},"371":{}},"tags":{}}],["correspond",{"_index":265,"title":{},"content":{"15":{},"22":{},"25":{},"70":{},"129":{},"131":{},"157":{},"168":{},"186":{},"326":{},"335":{},"337":{},"347":{},"351":{},"369":{},"386":{},"402":{},"403":{}},"tags":{}}],["corrupt",{"_index":1562,"title":{},"content":{"158":{},"195":{},"199":{},"203":{},"207":{},"211":{},"215":{},"219":{},"223":{},"227":{},"231":{},"235":{},"239":{},"243":{},"247":{},"251":{},"255":{},"259":{},"263":{},"267":{},"271":{},"275":{},"279":{},"283":{},"287":{},"291":{},"295":{},"299":{},"303":{},"307":{}},"tags":{}}],["cosign",{"_index":2241,"title":{},"content":{"349":{},"351":{},"352":{},"402":{},"403":{},"404":{}},"tags":{}}],["cosign.pub",{"_index":2246,"title":{},"content":{"349":{},"351":{},"352":{},"354":{}},"tags":{}}],["cosign_experimental=1",{"_index":2479,"title":{},"content":{"403":{}},"tags":{}}],["count",{"_index":1912,"title":{},"content":{"316":{},"369":{},"370":{},"371":{}},"tags":{}}],["coupl",{"_index":851,"title":{},"content":{"68":{},"136":{}},"tags":{}}],["cpe",{"_index":2272,"title":{},"content":{"354":{}},"tags":{}}],["cpu",{"_index":770,"title":{},"content":{"57":{},"125":{},"126":{},"133":{},"135":{},"163":{},"175":{},"184":{},"333":{}},"tags":{}}],["crd",{"_index":2007,"title":{},"content":{"329":{}},"tags":{}}],["creat",{"_index":266,"title":{"106":{},"129":{},"135":{},"216":{},"268":{},"272":{},"276":{},"280":{},"331":{},"333":{},"335":{},"337":{},"375":{}},"content":{"15":{},"23":{},"46":{},"47":{},"48":{},"51":{},"64":{},"67":{},"77":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"95":{},"96":{},"97":{},"98":{},"99":{},"100":{},"101":{},"102":{},"103":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"120":{},"122":{},"125":{},"126":{},"127":{},"128":{},"129":{},"132":{},"135":{},"138":{},"145":{},"146":{},"148":{},"153":{},"155":{},"190":{},"191":{},"198":{},"216":{},"217":{},"218":{},"228":{},"229":{},"268":{},"269":{},"270":{},"272":{},"273":{},"274":{},"275":{},"276":{},"277":{},"278":{},"279":{},"280":{},"281":{},"282":{},"283":{},"314":{},"315":{},"316":{},"326":{},"327":{},"329":{},"330":{},"331":{},"332":{},"333":{},"335":{},"336":{},"337":{},"339":{},"365":{},"366":{},"369":{},"372":{},"375":{},"386":{},"390":{},"395":{}},"tags":{}}],["creation",{"_index":452,"title":{"23":{},"66":{},"67":{}},"content":{"48":{},"49":{},"66":{},"100":{},"101":{},"102":{},"103":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"148":{},"325":{},"335":{},"337":{},"384":{}},"tags":{}}],["credenti",{"_index":458,"title":{"144":{}},"content":{"23":{},"68":{},"122":{},"144":{},"146":{},"315":{},"358":{},"377":{}},"tags":{}}],["crucial",{"_index":869,"title":{},"content":{"76":{},"378":{}},"tags":{}}],["crypt",{"_index":528,"title":{"32":{}},"content":{"30":{},"32":{},"47":{}},"tags":{}}],["crypto",{"_index":115,"title":{},"content":{"7":{}},"tags":{}}],["cryptograph",{"_index":130,"title":{"31":{},"42":{},"75":{},"85":{}},"content":{"8":{},"24":{},"29":{},"30":{},"31":{},"39":{},"40":{},"42":{},"43":{},"44":{},"45":{},"49":{},"55":{},"75":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"156":{},"157":{},"342":{},"360":{},"365":{}},"tags":{}}],["cryptographi",{"_index":543,"title":{},"content":{"30":{},"42":{}},"tags":{}}],["cs",{"_index":1265,"title":{},"content":{"134":{}},"tags":{}}],["csi",{"_index":506,"title":{"364":{}},"content":{"28":{},"30":{},"31":{},"180":{},"181":{},"184":{},"315":{},"362":{},"363":{},"364":{},"365":{}},"tags":{}}],["csi.storage.k8s.io/fstyp",{"_index":2308,"title":{},"content":{"365":{}},"tags":{}}],["csp",{"_index":505,"title":{"155":{}},"content":{"28":{},"29":{},"30":{},"95":{},"96":{},"97":{},"98":{},"99":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"127":{},"129":{},"142":{},"144":{},"146":{},"148":{},"155":{},"168":{},"188":{},"330":{},"331":{},"335":{},"337":{},"339":{},"343":{},"362":{},"363":{},"365":{},"381":{},"386":{},"387":{},"389":{}},"tags":{}}],["csp'",{"_index":2092,"title":{},"content":{"337":{},"383":{}},"tags":{}}],["csp.the",{"_index":2047,"title":{},"content":{"335":{}},"tags":{}}],["csp}.csi.confidential.cloud",{"_index":2323,"title":{},"content":{"366":{}},"tags":{}}],["ctrl+c",{"_index":1131,"title":{},"content":{"125":{}},"tags":{}}],["curl",{"_index":1225,"title":{},"content":{"130":{},"134":{},"137":{},"143":{},"351":{}},"tags":{}}],["current",{"_index":650,"title":{},"content":{"47":{},"49":{},"55":{},"65":{},"66":{},"78":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"122":{},"126":{},"129":{},"132":{},"135":{},"163":{},"164":{},"166":{},"167":{},"183":{},"185":{},"237":{},"274":{},"323":{},"326":{},"331":{},"333":{},"334":{},"335":{},"357":{},"372":{},"377":{},"378":{},"379":{},"390":{},"392":{},"394":{}},"tags":{}}],["curve25519",{"_index":637,"title":{},"content":{"46":{}},"tags":{}}],["custom",{"_index":389,"title":{"401":{}},"content":{"17":{},"28":{},"163":{},"190":{},"387":{},"395":{}},"tags":{}}],["cvm",{"_index":187,"title":{"12":{},"17":{},"158":{}},"content":{"12":{},"14":{},"15":{},"16":{},"17":{},"43":{},"47":{},"48":{},"49":{},"67":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"129":{},"132":{},"157":{},"158":{},"160":{},"163":{},"165":{},"166":{},"168":{},"169":{},"174":{},"175":{},"176":{},"179":{},"180":{},"181":{},"183":{},"332":{},"335":{},"400":{}},"tags":{}}],["cvm'",{"_index":230,"title":{},"content":{"14":{},"45":{}},"tags":{}}],["cyclonedx",{"_index":2266,"title":{},"content":{"353":{},"355":{}},"tags":{}}],["d",{"_index":2258,"title":{},"content":{"352":{}},"tags":{}}],["d4as_v5",{"_index":1712,"title":{},"content":{"180":{}},"tags":{}}],["d7c4cc7ff7933022f013e03bdee875b91720b5b86cf1753cad830f95e791926f",{"_index":2522,"title":{},"content":{"399":{}},"tags":{}}],["da99eb6cf7c7fbb692067c87fd5ca0b7117dc293578e4fea41f95d3d3d6af5e2",{"_index":2521,"title":{},"content":{"399":{}},"tags":{}}],["daemonset",{"_index":709,"title":{},"content":{"52":{},"53":{},"54":{}},"tags":{}}],["daemonsets/join",{"_index":1292,"title":{},"content":{"136":{}},"tags":{}}],["danger",{"_index":2329,"title":{},"content":{"372":{}},"tags":{}}],["darwin",{"_index":1312,"title":{},"content":{"143":{}},"tags":{}}],["data",{"_index":10,"title":{},"content":{"1":{},"2":{},"12":{},"28":{},"29":{},"30":{},"33":{},"40":{},"47":{},"48":{},"49":{},"58":{},"63":{},"65":{},"69":{},"75":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"122":{},"131":{},"138":{},"156":{},"158":{},"171":{},"172":{},"173":{},"183":{},"186":{},"188":{},"189":{},"335":{},"349":{},"357":{},"360":{},"363":{},"365":{},"372":{},"383":{},"388":{},"404":{}},"tags":{}}],["data\\\":{\\\"attestationconfig\\\":\\\"$(kubectl",{"_index":2385,"title":{},"content":{"378":{}},"tags":{}}],["datacent",{"_index":43,"title":{},"content":{"2":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"168":{},"187":{},"335":{}},"tags":{}}],["datadog",{"_index":820,"title":{},"content":{"63":{}},"tags":{}}],["date",{"_index":400,"title":{},"content":{"17":{},"396":{}},"tags":{}}],["day",{"_index":703,"title":{},"content":{"50":{},"186":{}},"tags":{}}],["dbvalid",{"_index":2355,"title":{},"content":{"386":{}},"tags":{}}],["dbxvalid",{"_index":2356,"title":{},"content":{"386":{}},"tags":{}}],["dc4a",{"_index":1750,"title":{},"content":{"184":{}},"tags":{}}],["dc4as_v5",{"_index":1701,"title":{},"content":{"179":{}},"tags":{}}],["dcadsv5",{"_index":2018,"title":{},"content":{"332":{}},"tags":{}}],["dcasv5",{"_index":2017,"title":{},"content":{"332":{}},"tags":{}}],["dealloc",{"_index":1136,"title":{},"content":{"125":{}},"tags":{}}],["dearmor",{"_index":1257,"title":{},"content":{"134":{}},"tags":{}}],["deb",{"_index":1260,"title":{},"content":{"134":{}},"tags":{}}],["debug",{"_index":1819,"title":{"328":{}},"content":{"195":{},"199":{},"203":{},"207":{},"211":{},"215":{},"219":{},"223":{},"227":{},"231":{},"235":{},"239":{},"243":{},"247":{},"251":{},"255":{},"259":{},"263":{},"267":{},"271":{},"275":{},"279":{},"283":{},"287":{},"291":{},"295":{},"299":{},"303":{},"307":{},"328":{},"381":{},"382":{},"386":{}},"tags":{}}],["debugd",{"_index":1882,"title":{},"content":{"310":{}},"tags":{}}],["debugg",{"_index":2402,"title":{},"content":{"382":{}},"tags":{}}],["debuggersdis",{"_index":2352,"title":{},"content":{"386":{}},"tags":{}}],["decid",{"_index":2375,"title":{},"content":{"377":{}},"tags":{}}],["decis",{"_index":1142,"title":{},"content":{"126":{},"349":{}},"tags":{}}],["declin",{"_index":429,"title":{},"content":{"19":{}},"tags":{}}],["decreas",{"_index":894,"title":{},"content":{"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"187":{}},"tags":{}}],["decrypt",{"_index":617,"title":{},"content":{"44":{},"46":{},"49":{},"122":{},"171":{},"342":{},"343":{},"356":{}},"tags":{}}],["dedic",{"_index":112,"title":{},"content":{"7":{},"49":{},"95":{},"96":{},"97":{},"98":{},"99":{},"141":{}},"tags":{}}],["deeper",{"_index":1141,"title":{},"content":{"126":{}},"tags":{}}],["default",{"_index":326,"title":{"366":{}},"content":{"16":{},"28":{},"30":{},"55":{},"58":{},"61":{},"62":{},"66":{},"68":{},"122":{},"129":{},"145":{},"146":{},"180":{},"181":{},"184":{},"191":{},"195":{},"196":{},"197":{},"198":{},"199":{},"203":{},"207":{},"211":{},"215":{},"219":{},"222":{},"223":{},"227":{},"230":{},"231":{},"235":{},"239":{},"243":{},"247":{},"250":{},"251":{},"255":{},"259":{},"263":{},"267":{},"271":{},"275":{},"279":{},"283":{},"287":{},"291":{},"295":{},"299":{},"302":{},"303":{},"307":{},"329":{},"332":{},"333":{},"340":{},"357":{},"363":{},"365":{},"366":{},"369":{},"386":{},"390":{},"399":{}},"tags":{}}],["defin",{"_index":892,"title":{},"content":{"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"122":{},"156":{},"184":{},"190":{},"320":{},"323":{},"361":{}},"tags":{}}],["definit",{"_index":941,"title":{},"content":{"100":{},"101":{},"102":{},"103":{},"320":{},"348":{},"390":{},"395":{}},"tags":{}}],["degrad",{"_index":1589,"title":{},"content":{"160":{},"175":{},"176":{}},"tags":{}}],["dek",{"_index":533,"title":{},"content":{"30":{},"48":{},"49":{},"360":{}},"tags":{}}],["delet",{"_index":836,"title":{"336":{}},"content":{"65":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"123":{},"125":{},"131":{},"191":{},"222":{},"254":{},"284":{},"285":{},"310":{},"323":{},"326":{},"335":{},"336":{},"340":{},"366":{},"372":{},"382":{},"384":{},"395":{}},"tags":{}}],["delic",{"_index":758,"title":{},"content":{"56":{}},"tags":{}}],["demand",{"_index":662,"title":{},"content":{"48":{},"77":{},"123":{}},"tags":{}}],["demo",{"_index":976,"title":{},"content":{"120":{},"127":{},"358":{}},"tags":{}}],["demo/raw/main/release/kubernet",{"_index":1146,"title":{},"content":{"127":{}},"tags":{}}],["demonstr",{"_index":979,"title":{},"content":{"120":{},"123":{},"175":{}},"tags":{}}],["deni",{"_index":2351,"title":{},"content":{"386":{}},"tags":{}}],["denot",{"_index":1668,"title":{},"content":{"173":{}},"tags":{}}],["depend",{"_index":621,"title":{"355":{}},"content":{"45":{},"54":{},"129":{},"134":{},"135":{},"163":{},"168":{},"329":{},"346":{},"349":{},"355":{},"369":{},"372":{},"388":{},"391":{},"395":{}},"tags":{}}],["depict",{"_index":1555,"title":{},"content":{"157":{},"158":{},"184":{}},"tags":{}}],["deploy",{"_index":545,"title":{"122":{},"130":{},"137":{},"358":{}},"content":{"30":{},"55":{},"67":{},"72":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"95":{},"96":{},"97":{},"98":{},"99":{},"120":{},"121":{},"122":{},"125":{},"127":{},"128":{},"130":{},"132":{},"135":{},"137":{},"147":{},"162":{},"171":{},"172":{},"187":{},"188":{},"190":{},"222":{},"254":{},"282":{},"302":{},"314":{},"335":{},"340":{},"358":{},"361":{},"365":{},"369":{},"379":{},"390":{},"401":{}},"tags":{}}],["deploycsidriv",{"_index":2304,"title":{},"content":{"365":{}},"tags":{}}],["deployment'",{"_index":1807,"title":{},"content":{"189":{}},"tags":{}}],["deployment/constel",{"_index":1143,"title":{},"content":{"126":{}},"tags":{}}],["deprec",{"_index":887,"title":{},"content":{"78":{},"319":{}},"tags":{}}],["deriv",{"_index":537,"title":{},"content":{"30":{},"32":{},"44":{},"45":{},"48":{},"54":{}},"tags":{}}],["desc",{"_index":2139,"title":{},"content":{"343":{}},"tags":{}}],["describ",{"_index":504,"title":{},"content":{"28":{},"59":{},"70":{},"100":{},"101":{},"102":{},"103":{},"122":{},"146":{},"171":{},"187":{},"308":{},"320":{},"332":{},"335":{},"345":{},"348":{},"402":{}},"tags":{}}],["descript",{"_index":296,"title":{},"content":{"16":{},"19":{},"343":{}},"tags":{}}],["design",{"_index":39,"title":{},"content":{"2":{},"35":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"346":{}},"tags":{}}],["desir",{"_index":1889,"title":{},"content":{"312":{},"316":{},"332":{},"343":{},"369":{},"370":{},"371":{},"377":{},"391":{},"395":{}},"tags":{}}],["despit",{"_index":1782,"title":{},"content":{"185":{}},"tags":{}}],["destin",{"_index":730,"title":{},"content":{"55":{}},"tags":{}}],["destroy",{"_index":1227,"title":{"284":{}},"content":{"131":{},"138":{},"191":{},"232":{},"233":{},"284":{},"285":{},"286":{},"336":{},"372":{},"379":{}},"tags":{}}],["detail",{"_index":243,"title":{"67":{},"359":{}},"content":{"14":{},"15":{},"16":{},"19":{},"30":{},"42":{},"43":{},"45":{},"46":{},"47":{},"48":{},"60":{},"70":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"126":{},"129":{},"184":{},"330":{},"337":{},"340":{},"343":{},"348":{},"350":{},"363":{},"372":{},"401":{},"402":{}},"tags":{}}],["detect",{"_index":2500,"title":{},"content":{"404":{}},"tags":{}}],["determin",{"_index":623,"title":{},"content":{"45":{}},"tags":{}}],["determinist",{"_index":479,"title":{},"content":{"26":{},"27":{},"48":{},"346":{}},"tags":{}}],["dev/nul",{"_index":1267,"title":{},"content":{"134":{}},"tags":{}}],["develop",{"_index":548,"title":{},"content":{"30":{},"47":{},"49":{},"354":{}},"tags":{}}],["deviat",{"_index":2376,"title":{},"content":{"377":{}},"tags":{}}],["devic",{"_index":503,"title":{},"content":{"28":{},"29":{},"32":{},"39":{},"47":{}},"tags":{}}],["devop",{"_index":59,"title":{},"content":{"2":{},"145":{},"157":{},"337":{}},"tags":{}}],["diagnos",{"_index":2395,"title":{"380":{}},"content":{"381":{},"383":{}},"tags":{}}],["diagram",{"_index":472,"title":{},"content":{"24":{},"50":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"187":{}},"tags":{}}],["dial",{"_index":2141,"title":{},"content":{"343":{}},"tags":{}}],["differ",{"_index":251,"title":{},"content":{"15":{},"16":{},"22":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"122":{},"126":{},"129":{},"135":{},"145":{},"158":{},"162":{},"163":{},"169":{},"183":{},"186":{},"188":{},"329":{},"332":{},"333":{},"335":{},"360":{},"389":{},"403":{}},"tags":{}}],["diffoscop",{"_index":2207,"title":{},"content":{"348":{}},"tags":{}}],["digest",{"_index":411,"title":{},"content":{"17":{}},"tags":{}}],["digit",{"_index":872,"title":{},"content":{"77":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"185":{},"282":{}},"tags":{}}],["direct",{"_index":197,"title":{},"content":{"12":{},"95":{},"96":{},"97":{},"98":{},"99":{},"148":{},"155":{},"158":{},"164":{},"165":{},"166":{},"355":{}},"tags":{}}],["directli",{"_index":328,"title":{},"content":{"16":{},"30":{},"54":{},"57":{},"60":{},"122":{},"183":{},"354":{},"362":{},"382":{}},"tags":{}}],["directori",{"_index":834,"title":{},"content":{"65":{},"129":{},"135":{},"326":{},"328":{},"331":{},"336":{},"337":{},"344":{},"372":{},"383":{},"386":{},"401":{}},"tags":{}}],["disabl",{"_index":777,"title":{},"content":{"58":{},"62":{},"195":{},"199":{},"203":{},"207":{},"211":{},"215":{},"219":{},"223":{},"227":{},"231":{},"235":{},"239":{},"243":{},"247":{},"251":{},"255":{},"259":{},"263":{},"267":{},"271":{},"275":{},"279":{},"283":{},"287":{},"291":{},"295":{},"299":{},"303":{},"307":{},"357":{},"365":{},"369":{},"376":{}},"tags":{}}],["disast",{"_index":670,"title":{},"content":{"48":{},"49":{},"129":{},"135":{}},"tags":{}}],["discov",{"_index":848,"title":{},"content":{"67":{}},"tags":{}}],["discret",{"_index":782,"title":{},"content":{"59":{}},"tags":{}}],["discuss",{"_index":1600,"title":{},"content":{"171":{}},"tags":{}}],["disk",{"_index":378,"title":{"40":{}},"content":{"16":{},"29":{},"30":{},"39":{},"40":{},"48":{},"52":{},"54":{},"61":{},"133":{},"180":{},"181":{},"184":{},"333":{},"342":{},"343":{},"344":{},"363":{},"364":{},"365":{},"379":{}},"tags":{}}],["display",{"_index":1574,"title":{},"content":{"151":{},"191":{},"296":{},"297":{},"396":{}},"tags":{}}],["disrupt",{"_index":948,"title":{},"content":{"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"391":{}},"tags":{}}],["distinguish",{"_index":733,"title":{},"content":{"55":{}},"tags":{}}],["distribut",{"_index":406,"title":{},"content":{"17":{},"35":{},"46":{},"48":{},"62":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"171":{},"172":{}},"tags":{}}],["divid",{"_index":1672,"title":{},"content":{"173":{}},"tags":{}}],["dm",{"_index":527,"title":{"32":{},"33":{}},"content":{"30":{},"32":{},"33":{},"39":{},"47":{}},"tags":{}}],["dma",{"_index":1735,"title":{},"content":{"183":{}},"tags":{}}],["dn",{"_index":2094,"title":{},"content":{"337":{},"361":{}},"tags":{}}],["do",{"_index":2214,"title":{},"content":{"357":{}},"tags":{}}],["doc",{"_index":1848,"title":{},"content":{"222":{},"254":{},"274":{},"332":{},"340":{}},"tags":{}}],["docker",{"_index":1250,"title":{},"content":{"133":{},"134":{},"140":{}},"tags":{}}],["document",{"_index":2,"title":{},"content":{"1":{},"15":{},"34":{},"43":{},"100":{},"101":{},"102":{},"103":{},"122":{},"129":{},"145":{},"146":{},"148":{},"242":{},"308":{},"325":{},"332":{},"333":{},"335":{},"386":{},"388":{}},"tags":{}}],["doesn't",{"_index":375,"title":{},"content":{"16":{},"29":{},"56":{},"151":{},"152":{},"345":{},"375":{},"390":{}},"tags":{}}],["domain",{"_index":1528,"title":{},"content":{"165":{},"383":{}},"tags":{}}],["don't",{"_index":1156,"title":{},"content":{"128":{},"132":{},"144":{},"154":{},"323":{},"326":{},"336":{},"337":{},"365":{},"366":{},"376":{},"378":{},"383":{},"389":{},"402":{}},"tags":{}}],["done",{"_index":1129,"title":{},"content":{"125":{},"138":{},"310":{},"327":{},"361":{},"402":{}},"tags":{}}],["doubl",{"_index":2444,"title":{},"content":{"390":{}},"tags":{}}],["doubt",{"_index":1462,"title":{},"content":{"146":{},"378":{},"379":{}},"tags":{}}],["down",{"_index":1082,"title":{"232":{}},"content":{"123":{},"138":{},"191":{},"233":{},"234":{},"344":{},"370":{},"371":{}},"tags":{}}],["download",{"_index":447,"title":{"350":{}},"content":{"22":{},"41":{},"51":{},"122":{},"143":{},"335":{},"347":{},"349":{},"352":{},"383":{},"386":{},"387":{},"390":{},"399":{},"402":{},"403":{},"405":{}},"tags":{}}],["downtim",{"_index":750,"title":{},"content":{"56":{},"69":{}},"tags":{}}],["driven",{"_index":2238,"title":{},"content":{"349":{}},"tags":{}}],["driver",{"_index":521,"title":{"364":{}},"content":{"30":{},"31":{},"180":{},"181":{},"315":{},"363":{},"364":{},"365":{}},"tags":{}}],["drop",{"_index":732,"title":{},"content":{"55":{},"78":{},"134":{},"140":{}},"tags":{}}],["dubiou",{"_index":2475,"title":{},"content":{"402":{}},"tags":{}}],["due",{"_index":1787,"title":{},"content":{"185":{},"190":{},"343":{},"378":{}},"tags":{}}],["dure",{"_index":269,"title":{},"content":{"15":{},"16":{},"18":{},"19":{},"41":{},"44":{},"48":{},"49":{},"50":{},"53":{},"60":{},"66":{},"69":{},"70":{},"74":{},"123":{},"129":{},"157":{},"171":{},"310":{},"323":{},"378":{},"399":{}},"tags":{}}],["dynam",{"_index":1085,"title":{},"content":{"124":{},"148":{},"186":{},"370":{},"371":{}},"tags":{}}],["dynatrac",{"_index":822,"title":{},"content":{"63":{}},"tags":{}}],["dzxcfgcnk8em5ornnztki+wg6z7qkqfs5cfe3qtkoc8",{"_index":1961,"title":{},"content":{"319":{}},"tags":{}}],["e",{"_index":974,"title":{},"content":{"120":{},"127":{},"242":{},"258":{},"401":{}},"tags":{}}],["e.g",{"_index":741,"title":{},"content":{"55":{},"67":{},"145":{},"163":{},"274":{},"278":{},"326":{},"335":{},"337":{},"357":{},"365":{},"372":{},"377":{},"388":{},"395":{}},"tags":{}}],["e6949026b72e5045706cd1318889b3874480f7a3f7c5c590912391a2d15e6975",{"_index":2518,"title":{},"content":{"399":{}},"tags":{}}],["each",{"_index":161,"title":{},"content":{"10":{},"15":{},"18":{},"19":{},"36":{},"40":{},"46":{},"52":{},"53":{},"54":{},"65":{},"67":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"122":{},"135":{},"136":{},"156":{},"157":{},"158":{},"172":{},"316":{},"318":{},"319":{},"323":{},"328":{},"329":{},"333":{},"339":{},"343":{},"349":{},"350":{},"351":{},"352":{},"360":{},"361":{},"388":{},"392":{},"395":{},"396":{},"399":{}},"tags":{}}],["easi",{"_index":947,"title":{},"content":{"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"127":{},"391":{}},"tags":{}}],["east",{"_index":1011,"title":{},"content":{"122":{},"129":{},"274":{},"335":{},"390":{}},"tags":{}}],["eastu",{"_index":1186,"title":{},"content":{"129":{},"335":{}},"tags":{}}],["eb",{"_index":2298,"title":{},"content":{"363":{}},"tags":{}}],["ec2",{"_index":1525,"title":{},"content":{"164":{}},"tags":{}}],["ec2:describeaccountattribut",{"_index":1331,"title":{},"content":{"145":{}},"tags":{}}],["ecadsv5",{"_index":2020,"title":{},"content":{"332":{}},"tags":{}}],["ecasv5",{"_index":2019,"title":{},"content":{"332":{}},"tags":{}}],["echo",{"_index":1259,"title":{},"content":{"134":{},"310":{},"383":{}},"tags":{}}],["edgeless",{"_index":437,"title":{},"content":{"22":{},"95":{},"96":{},"97":{},"98":{},"99":{},"148":{},"151":{},"152":{},"153":{},"155":{},"323":{},"345":{},"349":{},"358":{},"390":{},"399":{},"402":{},"403":{},"404":{}},"tags":{}}],["edgeless/s3proxi",{"_index":2219,"title":{},"content":{"358":{}},"tags":{}}],["edgelesssystem",{"_index":1501,"title":{},"content":{"148":{},"349":{},"402":{}},"tags":{}}],["edit",{"_index":1158,"title":{},"content":{"129":{},"143":{},"337":{},"370":{},"371":{},"386":{}},"tags":{}}],["editor",{"_index":1460,"title":{},"content":{"145":{},"146":{}},"tags":{}}],["ef",{"_index":2301,"title":{},"content":{"364":{}},"tags":{}}],["efd9",{"_index":2057,"title":{},"content":{"335":{}},"tags":{}}],["effect",{"_index":747,"title":{},"content":{"56":{},"145":{}},"tags":{}}],["effici",{"_index":753,"title":{},"content":{"56":{}},"tags":{}}],["ek",{"_index":2099,"title":{},"content":{"340":{},"341":{}},"tags":{}}],["elast",{"_index":780,"title":{},"content":{"58":{},"60":{},"61":{},"364":{}},"tags":{}}],["element",{"_index":896,"title":{},"content":{"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"187":{}},"tags":{}}],["embed",{"_index":220,"title":{},"content":{"13":{},"163":{}},"tags":{}}],["emerg",{"_index":1814,"title":{"383":{}},"content":{"191":{},"304":{},"305":{},"383":{}},"tags":{}}],["emergency_ssh",{"_index":2405,"title":{},"content":{"383":{}},"tags":{}}],["emit",{"_index":786,"title":{},"content":{"59":{},"399":{}},"tags":{}}],["emojivoto",{"_index":969,"title":{"121":{}},"content":{"120":{},"121":{},"130":{},"137":{}},"tags":{}}],["empir",{"_index":1615,"title":{},"content":{"172":{}},"tags":{}}],["employ",{"_index":1537,"title":{},"content":{"168":{},"176":{}},"tags":{}}],["employe",{"_index":44,"title":{},"content":{"2":{},"188":{}},"tags":{}}],["empti",{"_index":2039,"title":{},"content":{"333":{}},"tags":{}}],["emul",{"_index":377,"title":{},"content":{"16":{}},"tags":{}}],["enabl",{"_index":571,"title":{},"content":{"33":{},"55":{},"58":{},"62":{},"124":{},"133":{},"145":{},"148":{},"190":{},"195":{},"199":{},"203":{},"207":{},"211":{},"215":{},"219":{},"222":{},"223":{},"227":{},"231":{},"235":{},"239":{},"243":{},"247":{},"251":{},"254":{},"255":{},"259":{},"263":{},"267":{},"271":{},"275":{},"279":{},"283":{},"287":{},"291":{},"295":{},"299":{},"302":{},"303":{},"305":{},"307":{},"332":{},"333":{},"360":{},"363":{},"365":{},"366":{},"369":{},"383":{},"402":{}},"tags":{}}],["encapsul",{"_index":194,"title":{},"content":{"12":{}},"tags":{}}],["encod",{"_index":844,"title":{},"content":{"66":{},"68":{},"404":{}},"tags":{}}],["encount",{"_index":1157,"title":{},"content":{"128":{},"348":{},"378":{},"379":{}},"tags":{}}],["encrypt",{"_index":21,"title":{"28":{},"29":{},"30":{},"34":{},"46":{},"47":{},"55":{},"86":{},"160":{},"174":{},"360":{}},"content":{"1":{},"2":{},"7":{},"12":{},"17":{},"28":{},"29":{},"30":{},"32":{},"34":{},"40":{},"43":{},"44":{},"46":{},"47":{},"48":{},"49":{},"52":{},"54":{},"55":{},"61":{},"75":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"122":{},"157":{},"158":{},"160":{},"171":{},"183":{},"184":{},"185":{},"356":{},"360":{},"363":{},"364":{},"365":{},"366":{},"372":{},"389":{}},"tags":{}}],["encrypted/decrypt",{"_index":2211,"title":{},"content":{"357":{}},"tags":{}}],["end",{"_index":232,"title":{},"content":{"14":{},"28":{},"40":{},"42":{},"51":{},"55":{},"62":{},"157":{},"349":{},"402":{}},"tags":{}}],["endang",{"_index":1577,"title":{},"content":{"151":{},"152":{},"371":{}},"tags":{}}],["endpoint",{"_index":430,"title":{},"content":{"20":{},"46":{},"53":{},"55":{},"58":{},"242":{},"258":{},"343":{},"344":{}},"tags":{}}],["endpoint\",\"error\":\"rpc",{"_index":2137,"title":{},"content":{"343":{}},"tags":{}}],["endpoints\",\"endpoints\":[\"10.9.0.5:30090\",\"10.9.0.6:30090",{"_index":2159,"title":{},"content":{"343":{}},"tags":{}}],["endpoints\",\"endpoints\":[\"192.168.178.4:30090\",\"192.168.178.2:30090",{"_index":2131,"title":{},"content":{"343":{}},"tags":{}}],["enforc",{"_index":321,"title":{},"content":{"16":{},"17":{},"18":{},"151":{},"152":{},"156":{},"317":{},"399":{}},"tags":{}}],["enforcedmeasur",{"_index":1958,"title":{},"content":{"319":{}},"tags":{}}],["enforceidkeydigest",{"_index":1917,"title":{},"content":{"318":{}},"tags":{}}],["engin",{"_index":5,"title":{},"content":{"1":{},"2":{},"26":{},"27":{},"55":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"100":{},"101":{},"102":{},"103":{},"145":{},"157":{},"167":{},"171":{},"181":{},"184":{},"186":{},"320":{},"324":{},"363":{},"370":{},"371":{}},"tags":{}}],["enough",{"_index":2119,"title":{},"content":{"343":{}},"tags":{}}],["ensur",{"_index":173,"title":{},"content":{"10":{},"11":{},"22":{},"30":{},"36":{},"42":{},"56":{},"69":{},"74":{},"148":{},"186":{},"345":{},"376":{},"402":{}},"tags":{}}],["enter",{"_index":1064,"title":{},"content":{"122":{},"127":{},"143":{},"383":{},"394":{}},"tags":{}}],["enterpris",{"_index":903,"title":{"154":{}},"content":{"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"151":{},"152":{},"154":{},"186":{},"349":{}},"tags":{}}],["entir",{"_index":13,"title":{},"content":{"1":{},"10":{},"12":{},"14":{},"20":{},"73":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"95":{},"96":{},"97":{},"98":{},"99":{},"141":{},"156":{},"157":{},"186":{},"187":{},"337":{}},"tags":{}}],["entitl",{"_index":1503,"title":{},"content":{"148":{}},"tags":{}}],["entri",{"_index":1039,"title":{},"content":{"122":{},"319":{},"399":{},"402":{},"403":{},"404":{},"405":{}},"tags":{}}],["envelop",{"_index":2229,"title":{},"content":{"360":{}},"tags":{}}],["environ",{"_index":192,"title":{"346":{}},"content":{"12":{},"13":{},"15":{},"16":{},"29":{},"30":{},"32":{},"64":{},"66":{},"67":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"95":{},"96":{},"97":{},"98":{},"99":{},"141":{},"143":{},"145":{},"146":{},"163":{},"186":{},"187":{},"278":{},"323":{},"337":{},"348":{},"372":{},"376":{},"377":{}},"tags":{}}],["eof",{"_index":996,"title":{},"content":{"122":{},"125":{},"365":{}},"tags":{}}],["ephemer",{"_index":1982,"title":{},"content":{"323":{},"372":{}},"tags":{}}],["epyc",{"_index":1511,"title":{},"content":{"163":{},"175":{},"176":{},"179":{},"180":{},"181":{}},"tags":{}}],["equal",{"_index":1547,"title":{},"content":{"156":{}},"tags":{}}],["equival",{"_index":1724,"title":{},"content":{"183":{}},"tags":{}}],["erron",{"_index":1611,"title":{},"content":{"172":{},"378":{},"395":{}},"tags":{}}],["error",{"_index":796,"title":{"378":{}},"content":{"60":{},"122":{},"328":{},"343":{},"357":{},"376":{},"377":{},"378":{},"399":{}},"tags":{}}],["es",{"_index":412,"title":{},"content":{"17":{},"166":{},"167":{}},"tags":{}}],["escal",{"_index":54,"title":{},"content":{"2":{}},"tags":{}}],["essenc",{"_index":944,"title":{},"content":{"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"330":{},"337":{},"372":{},"402":{}},"tags":{}}],["essenti",{"_index":774,"title":{},"content":{"58":{},"337":{}},"tags":{}}],["establish",{"_index":213,"title":{},"content":{"13":{},"15":{},"17":{},"21":{},"23":{},"46":{},"189":{}},"tags":{}}],["es|qemu",{"_index":1830,"title":{},"content":{"198":{}},"tags":{}}],["etc/apt/keyrings/docker.gpg",{"_index":1258,"title":{},"content":{"134":{}},"tags":{}}],["etc/apt/sources.list.d/docker.list",{"_index":1266,"title":{},"content":{"134":{}},"tags":{}}],["etc/host",{"_index":1040,"title":{},"content":{"122":{}},"tags":{}}],["etc/openstack/clouds.yaml",{"_index":1473,"title":{},"content":{"146":{}},"tags":{}}],["etc/ssl/certs/kub",{"_index":1035,"title":{},"content":{"122":{}},"tags":{}}],["etcd",{"_index":470,"title":{},"content":{"23":{},"25":{},"48":{},"58":{},"186":{},"371":{}},"tags":{}}],["eu",{"_index":1169,"title":{},"content":{"129":{},"333":{},"335":{}},"tags":{}}],["eu01",{"_index":2041,"title":{},"content":{"333":{}},"tags":{}}],["europ",{"_index":1197,"title":{},"content":{"129":{},"179":{},"181":{},"335":{}},"tags":{}}],["eval",{"_index":1496,"title":{},"content":{"148":{}},"tags":{}}],["evalu",{"_index":609,"title":{},"content":{"42":{},"63":{},"153":{},"161":{},"177":{},"357":{}},"tags":{}}],["even",{"_index":515,"title":{},"content":{"29":{},"48":{},"189":{},"383":{}},"tags":{}}],["event",{"_index":483,"title":{},"content":{"26":{},"27":{},"48":{},"59":{},"60":{},"62":{},"125":{},"342":{}},"tags":{}}],["eventu",{"_index":1135,"title":{},"content":{"125":{}},"tags":{}}],["everyon",{"_index":2472,"title":{},"content":{"402":{}},"tags":{}}],["everyth",{"_index":18,"title":{},"content":{"1":{}},"tags":{}}],["exact",{"_index":2476,"title":{},"content":{"403":{}},"tags":{}}],["examin",{"_index":1585,"title":{},"content":{"159":{}},"tags":{}}],["exampl",{"_index":449,"title":{"99":{},"120":{}},"content":{"22":{},"28":{},"49":{},"60":{},"95":{},"96":{},"97":{},"98":{},"99":{},"120":{},"123":{},"124":{},"125":{},"128":{},"129":{},"146":{},"158":{},"319":{},"333":{},"337":{},"346":{},"349":{},"352":{},"358":{},"361":{},"364":{},"365":{},"376":{},"377":{},"378":{},"386":{},"387":{},"392":{},"396":{},"401":{},"403":{}},"tags":{}}],["exce",{"_index":1777,"title":{},"content":{"184":{}},"tags":{}}],["except",{"_index":661,"title":{},"content":{"48":{},"172":{},"372":{}},"tags":{}}],["exclud",{"_index":1045,"title":{},"content":{"122":{}},"tags":{}}],["execut",{"_index":164,"title":{},"content":{"10":{},"12":{},"15":{},"22":{},"29":{},"37":{},"45":{},"100":{},"101":{},"102":{},"103":{},"129":{},"135":{},"143":{},"146":{},"174":{},"320":{},"323":{},"326":{},"336":{},"349":{},"355":{},"400":{},"402":{},"403":{},"404":{},"405":{}},"tags":{}}],["exhaust",{"_index":2497,"title":{},"content":{"404":{}},"tags":{}}],["exist",{"_index":145,"title":{},"content":{"9":{},"34":{},"50":{},"51":{},"145":{},"172":{},"222":{},"306":{},"315":{},"343":{},"383":{},"403":{}},"tags":{}}],["exit",{"_index":2294,"title":{},"content":{"371":{}},"tags":{}}],["expand",{"_index":234,"title":{},"content":{"14":{}},"tags":{}}],["expans",{"_index":532,"title":{},"content":{"30":{},"365":{}},"tags":{}}],["expect",{"_index":61,"title":{},"content":{"2":{},"20":{},"136":{},"157":{},"169":{},"175":{},"176":{},"242":{},"319":{},"324":{},"378":{},"396":{},"399":{},"401":{},"405":{}},"tags":{}}],["experi",{"_index":908,"title":{},"content":{"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"175":{},"186":{}},"tags":{}}],["experienc",{"_index":1997,"title":{},"content":{"327":{}},"tags":{}}],["explain",{"_index":96,"title":{},"content":{"5":{},"14":{},"42":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"100":{},"101":{},"102":{},"103":{},"148":{},"325":{},"377":{}},"tags":{}}],["explan",{"_index":1778,"title":{},"content":{"184":{}},"tags":{}}],["explicit",{"_index":1976,"title":{},"content":{"323":{}},"tags":{}}],["explicitli",{"_index":408,"title":{},"content":{"17":{},"122":{},"366":{},"388":{}},"tags":{}}],["export",{"_index":817,"title":{},"content":{"62":{},"63":{},"129":{},"135":{},"337":{},"386":{}},"tags":{}}],["expos",{"_index":383,"title":{"109":{},"339":{}},"content":{"17":{},"58":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"127":{},"130":{},"137":{},"146":{},"165":{},"339":{},"340":{},"341":{},"357":{},"362":{},"401":{}},"tags":{}}],["ext",{"_index":2306,"title":{},"content":{"365":{}},"tags":{}}],["ext4",{"_index":2189,"title":{},"content":{"346":{},"365":{}},"tags":{}}],["extend",{"_index":146,"title":{},"content":{"9":{},"15":{},"16":{},"190":{},"387":{}},"tags":{}}],["extens",{"_index":151,"title":{},"content":{"9":{},"66":{}},"tags":{}}],["extern",{"_index":241,"title":{},"content":{"14":{},"44":{},"54":{},"55":{},"127":{},"158":{},"323":{},"340":{},"401":{}},"tags":{}}],["extra",{"_index":2381,"title":{},"content":{"378":{}},"tags":{}}],["extract",{"_index":2247,"title":{},"content":{"350":{},"352":{}},"tags":{}}],["f",{"_index":1048,"title":{},"content":{"122":{},"125":{},"126":{},"127":{},"136":{},"365":{},"383":{}},"tags":{}}],["f0a6e8601b00e2fdc57195686cd4ef45eb43a556ac1209b8e25d993213d68384",{"_index":2520,"title":{},"content":{"399":{}},"tags":{}}],["face",{"_index":413,"title":{"19":{},"20":{},"340":{}},"content":{"18":{},"53":{},"185":{},"340":{}},"tags":{}}],["facilit",{"_index":824,"title":{},"content":{"63":{},"125":{}},"tags":{}}],["factor",{"_index":1731,"title":{},"content":{"183":{},"323":{}},"tags":{}}],["fail",{"_index":800,"title":{"378":{},"379":{}},"content":{"60":{},"186":{},"338":{},"342":{},"343":{},"372":{},"378":{},"379":{},"395":{},"399":{}},"tags":{}}],["failur",{"_index":668,"title":{},"content":{"48":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"172":{},"342":{},"348":{},"378":{}},"tags":{}}],["fals",{"_index":1713,"title":{},"content":{"180":{},"181":{},"319":{},"329":{},"365":{},"366":{},"390":{},"399":{}},"tags":{}}],["falsifi",{"_index":1987,"title":{},"content":{"323":{}},"tags":{}}],["famili",{"_index":2021,"title":{},"content":{"332":{}},"tags":{}}],["familiar",{"_index":1996,"title":{},"content":{"325":{}},"tags":{}}],["faster",{"_index":1653,"title":{},"content":{"172":{}},"tags":{}}],["fatal",{"_index":666,"title":{},"content":{"48":{}},"tags":{}}],["favor",{"_index":1918,"title":{},"content":{"318":{}},"tags":{}}],["fc7fc42663df/images/constellation/versions/$image_version/measurements.yaml",{"_index":2440,"title":{},"content":{"390":{}},"tags":{}}],["featur",{"_index":66,"title":{"91":{},"92":{},"157":{},"163":{},"186":{}},"content":{"3":{},"4":{},"13":{},"16":{},"47":{},"50":{},"53":{},"55":{},"77":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"135":{},"154":{},"157":{},"158":{},"163":{},"168":{},"169":{},"172":{},"186":{},"190":{},"367":{},"386":{},"398":{}},"tags":{}}],["fedora",{"_index":583,"title":{},"content":{"35":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{}},"tags":{}}],["feedback",{"_index":2205,"title":{"348":{}},"content":{},"tags":{}}],["fetch",{"_index":405,"title":{"200":{},"399":{}},"content":{"17":{},"22":{},"60":{},"191":{},"200":{},"201":{},"202":{},"319":{},"390":{},"399":{}},"tags":{}}],["few",{"_index":1086,"title":{},"content":{"124":{},"125":{},"395":{}},"tags":{}}],["field",{"_index":1895,"title":{},"content":{"315":{},"316":{},"317":{},"318":{},"319":{},"332":{},"333":{},"335":{},"337":{},"369":{},"388":{},"390":{},"393":{},"394":{},"404":{}},"tags":{}}],["figur",{"_index":2397,"title":{},"content":{"382":{}},"tags":{}}],["file",{"_index":385,"title":{"326":{},"331":{}},"content":{"17":{},"22":{},"23":{},"60":{},"64":{},"65":{},"66":{},"68":{},"122":{},"129":{},"135":{},"138":{},"146":{},"148":{},"154":{},"184":{},"191":{},"192":{},"193":{},"196":{},"197":{},"212":{},"213":{},"222":{},"230":{},"250":{},"270":{},"275":{},"279":{},"283":{},"284":{},"285":{},"302":{},"308":{},"323":{},"326":{},"328":{},"331":{},"332":{},"333":{},"335":{},"337":{},"344":{},"349":{},"352":{},"353":{},"362":{},"364":{},"365":{},"372":{},"379":{},"382":{},"386":{},"393":{},"394":{},"395":{},"399":{},"400":{},"401":{},"405":{}},"tags":{}}],["filebeat",{"_index":794,"title":{},"content":{"60":{}},"tags":{}}],["filenam",{"_index":2077,"title":{},"content":{"335":{}},"tags":{}}],["files\\constellation\\bin",{"_index":1324,"title":{},"content":{"143":{}},"tags":{}}],["files\\constellation\\bin\\constellation.ex",{"_index":1320,"title":{},"content":{"143":{}},"tags":{}}],["filestash",{"_index":992,"title":{"122":{}},"content":{"122":{},"358":{},"361":{}},"tags":{}}],["filestash.yaml",{"_index":997,"title":{},"content":{"122":{}},"tags":{}}],["filestor",{"_index":2302,"title":{},"content":{"364":{}},"tags":{}}],["filesystem",{"_index":259,"title":{},"content":{"15":{},"35":{},"39":{},"40":{},"45":{},"65":{},"346":{},"365":{}},"tags":{}}],["filesystem'",{"_index":597,"title":{},"content":{"39":{}},"tags":{}}],["fill",{"_index":1166,"title":{},"content":{"129":{},"332":{},"337":{},"386":{}},"tags":{}}],["filter",{"_index":1201,"title":{},"content":{"129":{},"335":{},"378":{}},"tags":{}}],["final",{"_index":288,"title":{},"content":{"15":{},"73":{},"337":{}},"tags":{}}],["find",{"_index":706,"title":{},"content":{"51":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"129":{},"148":{},"154":{},"171":{},"176":{},"191":{},"244":{},"245":{},"282":{},"288":{},"289":{},"332":{},"335":{},"343":{},"369":{},"370":{},"371":{},"373":{}},"tags":{}}],["fine",{"_index":839,"title":{},"content":{"66":{},"132":{}},"tags":{}}],["finish",{"_index":2292,"title":{},"content":{"369":{},"382":{},"395":{},"396":{},"397":{}},"tags":{}}],["fio",{"_index":1696,"title":{},"content":{"177":{},"184":{}},"tags":{}}],["firmwar",{"_index":294,"title":{"37":{}},"content":{"16":{},"17":{},"37":{},"163":{},"164":{},"165":{},"166":{},"378":{}},"tags":{}}],["first",{"_index":282,"title":{"96":{},"97":{},"128":{},"132":{}},"content":{"15":{},"16":{},"18":{},"23":{},"38":{},"51":{},"58":{},"62":{},"66":{},"67":{},"77":{},"95":{},"96":{},"97":{},"98":{},"99":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"120":{},"135":{},"146":{},"147":{},"184":{},"201":{},"322":{},"326":{},"335":{},"342":{},"343":{},"345":{},"392":{},"399":{},"403":{},"405":{}},"tags":{}}],["five",{"_index":1618,"title":{},"content":{"172":{}},"tags":{}}],["fix",{"_index":881,"title":{},"content":{"77":{}},"tags":{}}],["flag",{"_index":1823,"title":{},"content":{"197":{},"201":{},"205":{},"209":{},"213":{},"217":{},"221":{},"229":{},"233":{},"237":{},"241":{},"249":{},"253":{},"257":{},"261":{},"273":{},"277":{},"281":{},"285":{},"293":{},"297":{},"301":{},"305":{},"316":{},"328":{},"335":{},"337":{},"357":{},"376":{},"394":{},"395":{}},"tags":{}}],["flexibl",{"_index":2083,"title":{},"content":{"337":{}},"tags":{}}],["flow",{"_index":811,"title":{},"content":{"62":{},"166":{}},"tags":{}}],["fluentd",{"_index":807,"title":{},"content":{"61":{}},"tags":{}}],["focus",{"_index":939,"title":{},"content":{"100":{},"101":{},"102":{},"103":{},"183":{},"320":{}},"tags":{}}],["folder",{"_index":1286,"title":{},"content":{"135":{},"143":{}},"tags":{}}],["follow",{"_index":104,"title":{},"content":{"6":{},"9":{},"14":{},"15":{},"16":{},"22":{},"24":{},"42":{},"47":{},"49":{},"50":{},"56":{},"66":{},"70":{},"78":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"95":{},"96":{},"97":{},"98":{},"99":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"120":{},"122":{},"123":{},"128":{},"129":{},"131":{},"135":{},"136":{},"138":{},"140":{},"142":{},"143":{},"145":{},"146":{},"157":{},"158":{},"163":{},"172":{},"173":{},"179":{},"180":{},"181":{},"183":{},"184":{},"186":{},"187":{},"319":{},"323":{},"329":{},"331":{},"332":{},"333":{},"335":{},"336":{},"337":{},"343":{},"344":{},"345":{},"346":{},"347":{},"349":{},"350":{},"352":{},"357":{},"358":{},"364":{},"365":{},"366":{},"369":{},"371":{},"376":{},"377":{},"383":{},"386":{},"388":{},"390":{},"396":{},"399":{},"400":{},"401":{},"402":{},"404":{}},"tags":{}}],["foothold",{"_index":1804,"title":{},"content":{"189":{}},"tags":{}}],["footnot",{"_index":477,"title":{"27":{}},"content":{"26":{}},"tags":{}}],["for=condition=avail",{"_index":984,"title":{},"content":{"121":{},"127":{},"130":{},"137":{}},"tags":{}}],["forbidden",{"_index":2373,"title":{},"content":{"377":{}},"tags":{}}],["forc",{"_index":676,"title":{},"content":{"49":{},"195":{},"199":{},"203":{},"207":{},"211":{},"215":{},"219":{},"223":{},"227":{},"231":{},"235":{},"239":{},"243":{},"247":{},"251":{},"255":{},"259":{},"263":{},"267":{},"271":{},"275":{},"279":{},"283":{},"287":{},"291":{},"295":{},"299":{},"303":{},"307":{}},"tags":{}}],["form",{"_index":501,"title":{},"content":{"28":{},"49":{},"77":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"145":{}},"tags":{}}],["format",{"_index":529,"title":{},"content":{"30":{},"32":{},"129":{},"198":{},"242":{},"308":{},"328":{},"353":{},"355":{},"393":{},"404":{}},"tags":{}}],["former",{"_index":2419,"title":{},"content":{"389":{}},"tags":{}}],["forward",{"_index":644,"title":{},"content":{"46":{},"55":{},"121":{},"122":{},"130":{},"134":{},"137":{},"140":{},"168":{}},"tags":{}}],["found",{"_index":1205,"title":{},"content":{"129":{},"404":{}},"tags":{}}],["foundat",{"_index":608,"title":{},"content":{"42":{},"71":{},"165":{}},"tags":{}}],["four",{"_index":885,"title":{},"content":{"78":{},"100":{},"101":{},"102":{},"103":{},"172":{},"184":{},"320":{}},"tags":{}}],["framework",{"_index":933,"title":{},"content":{"100":{},"101":{},"102":{},"103":{},"320":{},"325":{}},"tags":{}}],["framework/slsa",{"_index":2512,"title":{},"content":{"405":{}},"tags":{}}],["free",{"_index":1241,"title":{},"content":{"133":{},"151":{},"152":{},"153":{},"329":{}},"tags":{}}],["frequent",{"_index":309,"title":{},"content":{"16":{}},"tags":{}}],["front",{"_index":491,"title":{},"content":{"28":{}},"tags":{}}],["frontend",{"_index":993,"title":{},"content":{"122":{},"127":{},"130":{},"137":{}},"tags":{}}],["frontend'",{"_index":1149,"title":{},"content":{"127":{}},"tags":{}}],["fssl",{"_index":1253,"title":{},"content":{"134":{}},"tags":{}}],["fulcio",{"_index":2470,"title":{},"content":{"402":{}},"tags":{}}],["fulfil",{"_index":1988,"title":{},"content":{"323":{}},"tags":{}}],["full",{"_index":675,"title":{},"content":{"49":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"158":{},"186":{},"330":{},"335":{},"337":{},"372":{},"384":{},"402":{},"404":{}},"tags":{}}],["fulli",{"_index":1519,"title":{},"content":{"163":{},"165":{}},"tags":{}}],["fun",{"_index":971,"title":{},"content":{"120":{},"121":{}},"tags":{}}],["function",{"_index":557,"title":{},"content":{"32":{},"33":{},"50":{},"53":{},"121":{},"163":{},"337":{},"376":{},"387":{}},"tags":{}}],["fundament",{"_index":866,"title":{},"content":{"75":{}},"tags":{}}],["further",{"_index":1593,"title":{"397":{}},"content":{"161":{},"172":{},"218":{},"222":{},"234":{},"254":{},"262":{},"270":{},"275":{},"279":{},"283":{},"294":{},"381":{},"404":{}},"tags":{}}],["furthermor",{"_index":2043,"title":{},"content":{"335":{}},"tags":{}}],["futur",{"_index":275,"title":{},"content":{"15":{},"47":{},"49":{},"165":{},"186":{},"190":{},"320":{},"357":{}},"tags":{}}],["g6imp5wru1b7mpoz2weisliysfdahb0onaog6xewkfi",{"_index":1217,"title":{},"content":{"129":{},"135":{}},"tags":{}}],["gain",{"_index":744,"title":{},"content":{"56":{},"58":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"148":{}},"tags":{}}],["galleri",{"_index":2422,"title":{},"content":{"390":{}},"tags":{}}],["gap",{"_index":1550,"title":{},"content":{"156":{}},"tags":{}}],["gaug",{"_index":1596,"title":{},"content":{"162":{}},"tags":{}}],["gb",{"_index":1239,"title":{},"content":{"133":{},"332":{},"365":{}},"tags":{}}],["gbp",{"_index":1721,"title":{},"content":{"183":{},"185":{}},"tags":{}}],["gce",{"_index":2297,"title":{},"content":{"363":{}},"tags":{}}],["gcloud",{"_index":1468,"title":{},"content":{"146":{}},"tags":{}}],["gcm",{"_index":2227,"title":{},"content":{"360":{}},"tags":{}}],["gcp",{"_index":331,"title":{"166":{},"280":{}},"content":{"16":{},"17":{},"49":{},"95":{},"96":{},"97":{},"98":{},"99":{},"124":{},"129":{},"142":{},"145":{},"146":{},"148":{},"155":{},"163":{},"166":{},"176":{},"177":{},"179":{},"183":{},"184":{},"186":{},"191":{},"280":{},"281":{},"282":{},"319":{},"331":{},"332":{},"333":{},"335":{},"343":{},"363":{},"364":{},"365":{},"370":{},"371":{},"386":{}},"tags":{}}],["gen",{"_index":1680,"title":{},"content":{"175":{},"176":{}},"tags":{}}],["gener",{"_index":201,"title":{"196":{}},"content":{"12":{},"15":{},"16":{},"23":{},"44":{},"49":{},"66":{},"125":{},"129":{},"135":{},"150":{},"163":{},"166":{},"171":{},"172":{},"179":{},"180":{},"181":{},"191":{},"196":{},"197":{},"198":{},"201":{},"304":{},"305":{},"321":{},"322":{},"323":{},"331":{},"335":{},"340":{},"349":{},"388":{}},"tags":{}}],["generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v1.2.2",{"_index":2513,"title":{},"content":{"405":{}},"tags":{}}],["germanywestcentr",{"_index":1185,"title":{},"content":{"129":{},"335":{}},"tags":{}}],["get",{"_index":92,"title":{},"content":{"4":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"332":{},"342":{}},"tags":{}}],["getobject",{"_index":2210,"title":{},"content":{"357":{}},"tags":{}}],["ghcr.io/edgelesssys/constellation/verif",{"_index":2254,"title":{},"content":{"352":{}},"tags":{}}],["gib",{"_index":1704,"title":{},"content":{"179":{},"180":{},"181":{},"184":{}},"tags":{}}],["git",{"_index":1968,"title":{},"content":{"322":{},"347":{}},"tags":{}}],["github",{"_index":884,"title":{},"content":{"77":{},"143":{},"150":{},"321":{},"322":{},"323":{},"337":{},"351":{},"387":{},"405":{}},"tags":{}}],["github.com/buoyantio/emojivoto/kustomize/deploy",{"_index":982,"title":{},"content":{"121":{},"130":{},"137":{}},"tags":{}}],["github.com/edgelesssys/constel",{"_index":2507,"title":{},"content":{"405":{}},"tags":{}}],["give",{"_index":295,"title":{},"content":{"16":{},"31":{},"42":{},"56":{},"131":{},"138":{},"153":{},"157":{},"172":{},"183":{},"404":{}},"tags":{}}],["given",{"_index":414,"title":{},"content":{"18":{},"48":{},"143":{},"187":{},"190":{},"198":{},"346":{},"349":{},"351":{},"392":{},"405":{}},"tags":{}}],["gke",{"_index":1558,"title":{"181":{}},"content":{"158":{},"171":{},"172":{},"177":{},"181":{},"183":{},"184":{},"185":{}},"tags":{}}],["gke.3200",{"_index":1715,"title":{},"content":{"181":{}},"tags":{}}],["global",{"_index":1906,"title":{},"content":{"316":{},"318":{},"319":{}},"tags":{}}],["gnu",{"_index":1568,"title":{},"content":{"150":{},"346":{}},"tags":{}}],["go",{"_index":460,"title":{},"content":{"23":{},"122":{},"143":{},"168":{},"343":{},"354":{},"370":{},"371":{},"383":{}},"tags":{}}],["goal",{"_index":37,"title":{"2":{}},"content":{"11":{}},"tags":{}}],["goe",{"_index":257,"title":{},"content":{"15":{},"24":{}},"tags":{}}],["good",{"_index":338,"title":{},"content":{"16":{},"157":{},"158":{},"347":{},"400":{}},"tags":{}}],["googl",{"_index":508,"title":{"166":{},"176":{}},"content":{"28":{},"120":{},"127":{},"142":{},"146":{},"160":{},"166":{},"176":{},"186":{}},"tags":{}}],["google'",{"_index":1200,"title":{},"content":{"129":{},"145":{},"146":{},"166":{},"335":{},"360":{}},"tags":{}}],["gp3",{"_index":2034,"title":{},"content":{"333":{},"365":{}},"tags":{}}],["gpg",{"_index":1256,"title":{},"content":{"134":{}},"tags":{}}],["grade",{"_index":904,"title":{},"content":{"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"100":{},"101":{},"102":{},"103":{},"186":{},"320":{},"390":{}},"tags":{}}],["grain",{"_index":840,"title":{},"content":{"66":{},"132":{}},"tags":{}}],["grant",{"_index":847,"title":{},"content":{"66":{}},"tags":{}}],["great",{"_index":1796,"title":{},"content":{"185":{}},"tags":{}}],["greater",{"_index":1959,"title":{},"content":{"319":{}},"tags":{}}],["green",{"_index":901,"title":{},"content":{"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"187":{}},"tags":{}}],["ground",{"_index":415,"title":{},"content":{"18":{},"19":{},"20":{}},"tags":{}}],["group",{"_index":1182,"title":{"333":{}},"content":{"129":{},"278":{},"310":{},"316":{},"333":{},"335":{},"336":{},"343":{},"369":{},"370":{},"371":{},"390":{}},"tags":{}}],["grype",{"_index":2268,"title":{"354":{}},"content":{"354":{}},"tags":{}}],["gsutil",{"_index":1466,"title":{},"content":{"146":{}},"tags":{}}],["guarante",{"_index":210,"title":{},"content":{"12":{},"49":{},"63":{},"184":{}},"tags":{}}],["guest",{"_index":206,"title":{},"content":{"12":{},"16":{},"163":{}},"tags":{}}],["guid",{"_index":379,"title":{},"content":{"16":{},"22":{},"68":{},"95":{},"96":{},"97":{},"98":{},"99":{},"122":{},"128":{},"129":{},"145":{},"146":{},"403":{}},"tags":{}}],["guidanc",{"_index":2274,"title":{},"content":{"355":{}},"tags":{}}],["h",{"_index":1816,"title":{},"content":{"194":{},"198":{},"202":{},"206":{},"210":{},"214":{},"218":{},"222":{},"226":{},"230":{},"234":{},"238":{},"242":{},"246":{},"250":{},"254":{},"258":{},"262":{},"266":{},"270":{},"274":{},"278":{},"282":{},"286":{},"290":{},"294":{},"298":{},"302":{},"306":{}},"tags":{}}],["hacker",{"_index":55,"title":{},"content":{"2":{},"189":{}},"tags":{}}],["handl",{"_index":702,"title":{},"content":{"50":{},"172":{},"337":{},"341":{}},"tags":{}}],["handler",{"_index":2107,"title":{},"content":{"341":{}},"tags":{}}],["handshak",{"_index":219,"title":{},"content":{"13":{},"19":{}},"tags":{}}],["happen",{"_index":530,"title":{},"content":{"30":{},"59":{},"337":{},"378":{}},"tags":{}}],["hardwar",{"_index":190,"title":{},"content":{"12":{},"15":{},"16":{},"20":{},"29":{},"43":{},"53":{},"132":{},"133":{},"135":{},"156":{},"157":{},"163":{},"168":{}},"tags":{}}],["hardware'",{"_index":280,"title":{},"content":{"15":{}},"tags":{}}],["hash",{"_index":131,"title":{},"content":{"8":{},"33":{},"39":{},"323":{},"404":{}},"tags":{}}],["hashalg",{"_index":149,"title":{},"content":{"9":{}},"tags":{}}],["hashedrekordobj",{"_index":2492,"title":{},"content":{"404":{}},"tags":{}}],["hashicorp",{"_index":1597,"title":{"171":{}},"content":{"162":{},"171":{}},"tags":{}}],["hasn't",{"_index":2045,"title":{},"content":{"335":{},"405":{}},"tags":{}}],["have",{"_index":2208,"title":{},"content":{"356":{}},"tags":{}}],["haven't",{"_index":1363,"title":{},"content":{"145":{}},"tags":{}}],["head",{"_index":91,"title":{},"content":{"4":{}},"tags":{}}],["header",{"_index":1074,"title":{},"content":{"122":{},"357":{}},"tags":{}}],["health",{"_index":739,"title":{},"content":{"55":{},"58":{},"343":{}},"tags":{}}],["healthi",{"_index":959,"title":{},"content":{"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"342":{}},"tags":{}}],["helm",{"_index":1841,"title":{},"content":{"222":{},"254":{},"302":{},"358":{},"378":{},"379":{},"395":{}},"tags":{}}],["help",{"_index":106,"title":{},"content":{"6":{},"56":{},"194":{},"198":{},"202":{},"206":{},"210":{},"214":{},"218":{},"222":{},"226":{},"230":{},"234":{},"238":{},"242":{},"246":{},"250":{},"254":{},"258":{},"262":{},"266":{},"270":{},"274":{},"278":{},"282":{},"286":{},"290":{},"294":{},"298":{},"302":{},"306":{},"381":{},"386":{}},"tags":{}}],["henc",{"_index":512,"title":{},"content":{"29":{},"48":{},"65":{},"164":{},"166":{},"167":{}},"tags":{}}],["here",{"_index":799,"title":{},"content":{"60":{},"158":{},"282":{}},"tags":{}}],["here'",{"_index":2458,"title":{},"content":{"396":{}},"tags":{}}],["high",{"_index":1686,"title":{},"content":{"176":{},"185":{},"186":{},"342":{}},"tags":{}}],["high_cpu",{"_index":2037,"title":{},"content":{"333":{}},"tags":{}}],["higher",{"_index":1740,"title":{},"content":{"183":{},"184":{}},"tags":{}}],["highli",{"_index":863,"title":{},"content":{"74":{}},"tags":{}}],["highlight",{"_index":99,"title":{},"content":{"5":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"158":{}},"tags":{}}],["histori",{"_index":1970,"title":{},"content":{"323":{}},"tags":{}}],["hit",{"_index":1781,"title":{},"content":{"184":{}},"tags":{}}],["hkdf",{"_index":658,"title":{},"content":{"48":{}},"tags":{}}],["hmac",{"_index":572,"title":{},"content":{"33":{}},"tags":{}}],["hold",{"_index":689,"title":{},"content":{"49":{},"54":{},"122":{},"323":{}},"tags":{}}],["home/.kube/config",{"_index":1839,"title":{},"content":{"222":{},"230":{},"302":{}},"tags":{}}],["horizont",{"_index":978,"title":{"123":{}},"content":{"120":{}},"tags":{}}],["horizontalpodautoscal",{"_index":1078,"title":{},"content":{"123":{},"125":{},"126":{}},"tags":{}}],["host",{"_index":721,"title":{},"content":{"55":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"125":{},"153":{},"187":{},"229":{},"322":{},"323":{},"346":{},"382":{},"383":{}},"tags":{}}],["host[:port",{"_index":1852,"title":{},"content":{"242":{},"258":{}},"tags":{}}],["hostalias",{"_index":1006,"title":{},"content":{"122":{}},"tags":{}}],["hostnam",{"_index":1009,"title":{},"content":{"122":{}},"tags":{}}],["hour",{"_index":2410,"title":{},"content":{"383":{}},"tags":{}}],["hourli",{"_index":926,"title":{},"content":{"95":{},"96":{},"97":{},"98":{},"99":{},"148":{},"155":{}},"tags":{}}],["hpa",{"_index":1097,"title":{},"content":{"125":{},"126":{}},"tags":{}}],["http",{"_index":2234,"title":{},"content":{"361":{}},"tags":{}}],["http://localhost:8080",{"_index":991,"title":{},"content":{"121":{},"130":{},"137":{}},"tags":{}}],["http://php",{"_index":1128,"title":{},"content":{"125":{}},"tags":{}}],["https://cdn.confidential.cloud/constellation/images/azure/trust",{"_index":2423,"title":{},"content":{"390":{}},"tags":{}}],["https://cloud.google.com/compute/docs/region",{"_index":1869,"title":{},"content":{"282":{}},"tags":{}}],["https://console.cloud.google.com/welcom",{"_index":1868,"title":{},"content":{"282":{}},"tags":{}}],["https://cyclonedx.org/bom",{"_index":2256,"title":{},"content":{"352":{}},"tags":{}}],["https://download.docker.com/linux/ubuntu",{"_index":1263,"title":{},"content":{"134":{}},"tags":{}}],["https://download.docker.com/linux/ubuntu/gpg",{"_index":1254,"title":{},"content":{"134":{}},"tags":{}}],["https://edgeless.systems/es.pub",{"_index":2244,"title":{},"content":{"349":{},"402":{},"403":{},"404":{}},"tags":{}}],["https://github.com/edgelesssys/constellation.git",{"_index":2195,"title":{},"content":{"347":{}},"tags":{}}],["https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom",{"_index":2251,"title":{},"content":{"351":{}},"tags":{}}],["https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom.sig",{"_index":2252,"title":{},"content":{"351":{}},"tags":{}}],["https://github.com/edgelesssys/constellation/releases/latest/download/constel",{"_index":1273,"title":{},"content":{"134":{},"143":{}},"tags":{}}],["https://github.com/googlecloudplatform/microservic",{"_index":1145,"title":{},"content":{"127":{}},"tags":{}}],["https://github.com/kubernet",{"_index":1094,"title":{},"content":{"125":{}},"tags":{}}],["https://github.com/slsa",{"_index":2511,"title":{},"content":{"405":{}},"tags":{}}],["https://helm.edgeless.systems/st",{"_index":2216,"title":{},"content":{"358":{}},"tags":{}}],["https://keystone.api.iaas.eu01.stackit.cloud/v3",{"_index":1476,"title":{},"content":{"146":{}},"tags":{}}],["https://raw.githubusercontent.com/edgelesssys/constellation/main/hack/importazure.sh",{"_index":2425,"title":{},"content":{"390":{}},"tags":{}}],["https://rekor.sigstore.dev",{"_index":2471,"title":{},"content":{"402":{}},"tags":{}}],["https://rekor.sigstore.dev/api/v1/log/entries/24296fb24b8ad77af2c04c8b4ae0d5bc5",{"_index":2509,"title":{},"content":{"405":{}},"tags":{}}],["hyok",{"_index":690,"title":{},"content":{"49":{}},"tags":{}}],["hypervisor",{"_index":196,"title":{},"content":{"12":{},"16":{},"17":{},"57":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"164":{},"166":{},"167":{},"168":{},"187":{}},"tags":{}}],["hyphen",{"_index":1865,"title":{},"content":{"282":{}},"tags":{}}],["i.",{"_index":1506,"title":{},"content":{"148":{},"327":{},"337":{}},"tags":{}}],["i/o",{"_index":1591,"title":{"161":{},"177":{},"184":{}},"content":{"161":{},"177":{},"183":{},"184":{},"185":{},"343":{}},"tags":{}}],["iac",{"_index":932,"title":{},"content":{"100":{},"101":{},"102":{},"103":{},"325":{}},"tags":{}}],["iam",{"_index":687,"title":{"264":{},"268":{},"272":{},"276":{},"280":{},"284":{},"288":{},"292":{},"335":{},"336":{}},"content":{"49":{},"129":{},"131":{},"145":{},"191":{},"264":{},"265":{},"266":{},"268":{},"269":{},"270":{},"272":{},"273":{},"275":{},"276":{},"277":{},"278":{},"279":{},"280":{},"281":{},"283":{},"284":{},"285":{},"286":{},"288":{},"289":{},"292":{},"293":{},"312":{},"315":{},"316":{},"326":{},"330":{},"335":{},"336":{},"376":{},"386":{},"387":{},"388":{}},"tags":{}}],["iam.roles.cr",{"_index":1386,"title":{},"content":{"145":{}},"tags":{}}],["iam.roles.delet",{"_index":1387,"title":{},"content":{"145":{}},"tags":{}}],["iam.roles.get",{"_index":1388,"title":{},"content":{"145":{}},"tags":{}}],["iam.serviceaccountkeys.cr",{"_index":1389,"title":{},"content":{"145":{}},"tags":{}}],["iam.serviceaccountkeys.delet",{"_index":1390,"title":{},"content":{"145":{}},"tags":{}}],["iam.serviceaccountkeys.get",{"_index":1391,"title":{},"content":{"145":{}},"tags":{}}],["iam.serviceaccounts.acta",{"_index":1458,"title":{},"content":{"145":{}},"tags":{}}],["iam.serviceaccounts.cr",{"_index":1392,"title":{},"content":{"145":{}},"tags":{}}],["iam.serviceaccounts.delet",{"_index":1393,"title":{},"content":{"145":{}},"tags":{}}],["iam.serviceaccounts.get",{"_index":1394,"title":{},"content":{"145":{}},"tags":{}}],["iam/{csp",{"_index":2361,"title":{},"content":{"387":{}},"tags":{}}],["iam:addroletoinstanceprofil",{"_index":1332,"title":{},"content":{"145":{}},"tags":{}}],["iam:attachrolepolici",{"_index":1333,"title":{},"content":{"145":{}},"tags":{}}],["iam:createinstanceprofil",{"_index":1334,"title":{},"content":{"145":{}},"tags":{}}],["iam:createpolici",{"_index":1335,"title":{},"content":{"145":{}},"tags":{}}],["iam:createrol",{"_index":1336,"title":{},"content":{"145":{}},"tags":{}}],["iam:deleteinstanceprofil",{"_index":1337,"title":{},"content":{"145":{}},"tags":{}}],["iam:deletepolici",{"_index":1338,"title":{},"content":{"145":{}},"tags":{}}],["iam:deletepolicyvers",{"_index":1339,"title":{},"content":{"145":{}},"tags":{}}],["iam:deleterol",{"_index":1340,"title":{},"content":{"145":{}},"tags":{}}],["iam:detachrolepolici",{"_index":1341,"title":{},"content":{"145":{}},"tags":{}}],["iam:getinstanceprofil",{"_index":1342,"title":{},"content":{"145":{}},"tags":{}}],["iam:getpolici",{"_index":1343,"title":{},"content":{"145":{}},"tags":{}}],["iam:getpolicyvers",{"_index":1344,"title":{},"content":{"145":{}},"tags":{}}],["iam:getrol",{"_index":1345,"title":{},"content":{"145":{}},"tags":{}}],["iam:listattachedrolepolici",{"_index":1346,"title":{},"content":{"145":{}},"tags":{}}],["iam:listinstanceprofilesforrol",{"_index":1347,"title":{},"content":{"145":{}},"tags":{}}],["iam:listpolicyvers",{"_index":1348,"title":{},"content":{"145":{}},"tags":{}}],["iam:listrolepolici",{"_index":1349,"title":{},"content":{"145":{}},"tags":{}}],["iam:passrol",{"_index":1350,"title":{},"content":{"145":{}},"tags":{}}],["iam:removerolefrominstanceprofil",{"_index":1351,"title":{},"content":{"145":{}},"tags":{}}],["iamprofilecontrolplan",{"_index":2049,"title":{},"content":{"335":{}},"tags":{}}],["iamprofileworkernod",{"_index":2052,"title":{},"content":{"335":{}},"tags":{}}],["id",{"_index":276,"title":{},"content":{"15":{},"16":{},"129":{},"146":{},"242":{},"278":{},"282":{},"310":{},"335":{},"390":{},"400":{},"401":{}},"tags":{}}],["idea",{"_index":245,"title":{},"content":{"15":{}},"tags":{}}],["ideal",{"_index":1509,"title":{},"content":{"163":{}},"tags":{}}],["ident",{"_index":431,"title":{"45":{}},"content":{"20":{},"45":{},"49":{},"68":{},"317":{},"323":{},"330":{},"335":{},"377":{},"401":{}},"tags":{}}],["identif",{"_index":2474,"title":{},"content":{"402":{}},"tags":{}}],["identifi",{"_index":277,"title":{"343":{}},"content":{"15":{},"48":{},"56":{},"59":{},"66":{},"68":{},"129":{},"135":{},"242":{},"343":{},"400":{}},"tags":{}}],["identity/providers/microsoft.managedidentity/userassignedidentities/constel",{"_index":2068,"title":{},"content":{"335":{}},"tags":{}}],["identity_api_vers",{"_index":1489,"title":{},"content":{"146":{}},"tags":{}}],["identityfil",{"_index":2415,"title":{},"content":{"383":{}},"tags":{}}],["idkeydigest",{"_index":409,"title":{},"content":{"17":{},"318":{}},"tags":{}}],["ignor",{"_index":2445,"title":{},"content":{"390":{}},"tags":{}}],["illustr",{"_index":435,"title":{},"content":{"21":{},"24":{},"400":{}},"tags":{}}],["ima",{"_index":361,"title":{},"content":{"16":{},"26":{},"27":{}},"tags":{}}],["imag",{"_index":199,"title":{"22":{},"35":{},"74":{},"84":{},"352":{},"390":{}},"content":{"12":{},"15":{},"16":{},"19":{},"22":{},"23":{},"25":{},"35":{},"45":{},"51":{},"67":{},"69":{},"70":{},"74":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"122":{},"125":{},"129":{},"138":{},"148":{},"151":{},"157":{},"158":{},"163":{},"190":{},"191":{},"200":{},"201":{},"222":{},"237":{},"254":{},"319":{},"335":{},"352":{},"365":{},"378":{},"390":{},"391":{},"394":{},"395":{},"396":{},"399":{},"400":{},"402":{}},"tags":{}}],["image'",{"_index":1500,"title":{},"content":{"148":{}},"tags":{}}],["image=busybox",{"_index":2401,"title":{},"content":{"382":{}},"tags":{}}],["image=busybox:1.28",{"_index":1120,"title":{},"content":{"125":{}},"tags":{}}],["image=nginx",{"_index":2293,"title":{},"content":{"369":{}},"tags":{}}],["image=vx.y.z",{"_index":1507,"title":{},"content":{"148":{}},"tags":{}}],["image_vers",{"_index":2364,"title":{},"content":{"388":{}},"tags":{}}],["image_version=2.2.0",{"_index":2432,"title":{},"content":{"390":{}},"tags":{}}],["images/global/images/constel",{"_index":1956,"title":{},"content":{"319":{}},"tags":{}}],["images/providers/microsoft.compute/galleries/constellation/images/constellation/versions/2.0.0",{"_index":1952,"title":{},"content":{"319":{}},"tags":{}}],["images/providers/microsoft.compute/galleries/constellation/images/constellation/versions/2.1.0",{"_index":1949,"title":{},"content":{"319":{}},"tags":{}}],["images/providers/microsoft.compute/galleries/constellation/images/constellation/versions/2.2.0",{"_index":1947,"title":{},"content":{"319":{}},"tags":{}}],["images/providers/microsoft.compute/galleries/constellation/images/constellation/versions/2.2.1",{"_index":1945,"title":{},"content":{"319":{}},"tags":{}}],["images/providers/microsoft.compute/galleries/constellation/images/constellation/versions/2.2.2",{"_index":1943,"title":{},"content":{"319":{}},"tags":{}}],["images/providers/microsoft.compute/galleries/constellation_cvm/images/constellation/versions/2.0.0",{"_index":1954,"title":{},"content":{"319":{}},"tags":{}}],["images/providers/microsoft.compute/galleries/constellation_cvm/images/constellation/versions/2.1.0",{"_index":1951,"title":{},"content":{"319":{}},"tags":{}}],["images/providers/microsoft.compute/galleries/constellation_cvm/images/constellation/versions/2.2.0",{"_index":1948,"title":{},"content":{"319":{}},"tags":{}}],["images/providers/microsoft.compute/galleries/constellation_cvm/images/constellation/versions/2.2.1",{"_index":1946,"title":{},"content":{"319":{}},"tags":{}}],["images/providers/microsoft.compute/galleries/constellation_cvm/images/constellation/versions/2.2.2",{"_index":1944,"title":{},"content":{"319":{}},"tags":{}}],["immedi",{"_index":2324,"title":{},"content":{"366":{}},"tags":{}}],["immut",{"_index":585,"title":{},"content":{"35":{}},"tags":{}}],["impact",{"_index":1677,"title":{"174":{}},"content":{"185":{}},"tags":{}}],["implement",{"_index":124,"title":{},"content":{"7":{},"15":{},"16":{},"43":{},"46":{},"54":{},"55":{},"62":{},"69":{},"76":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"157":{},"186":{},"187":{},"347":{},"360":{}},"tags":{}}],["import",{"_index":1548,"title":{},"content":{"156":{},"355":{},"383":{},"390":{}},"tags":{}}],["importantli",{"_index":2446,"title":{},"content":{"392":{}},"tags":{}}],["importazure.sh",{"_index":2427,"title":{},"content":{"390":{}},"tags":{}}],["improv",{"_index":752,"title":{},"content":{"56":{},"77":{},"100":{},"101":{},"102":{},"103":{},"185":{},"320":{}},"tags":{}}],["inaccess",{"_index":765,"title":{},"content":{"57":{}},"tags":{}}],["includ",{"_index":22,"title":{},"content":{"1":{},"2":{},"8":{},"15":{},"16":{},"19":{},"20":{},"55":{},"61":{},"67":{},"77":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"122":{},"151":{},"158":{},"166":{},"175":{},"183":{},"186":{},"187":{},"190":{},"336":{},"348":{},"356":{},"367":{}},"tags":{}}],["incompat",{"_index":2105,"title":{},"content":{"341":{}},"tags":{}}],["increas",{"_index":69,"title":{},"content":{"3":{},"62":{},"125":{},"172":{},"190":{},"370":{},"371":{}},"tags":{}}],["increment",{"_index":879,"title":{},"content":{"77":{}},"tags":{}}],["incur",{"_index":1783,"title":{},"content":{"185":{}},"tags":{}}],["indefinit",{"_index":1974,"title":{},"content":{"323":{}},"tags":{}}],["independ",{"_index":2506,"title":{},"content":{"405":{}},"tags":{}}],["index",{"_index":2171,"title":{},"content":{"343":{},"403":{},"404":{},"405":{}},"tags":{}}],["indic",{"_index":1621,"title":{},"content":{"172":{},"175":{},"348":{},"378":{},"396":{}},"tags":{}}],["individu",{"_index":1911,"title":{},"content":{"316":{},"333":{},"343":{},"395":{},"399":{}},"tags":{}}],["inevit",{"_index":264,"title":{},"content":{"15":{},"19":{}},"tags":{}}],["influenc",{"_index":2379,"title":{},"content":{"378":{}},"tags":{}}],["info",{"_index":1090,"title":{},"content":{"124":{},"129":{},"135":{},"320":{},"325":{},"328":{},"330":{},"337":{},"365":{},"372":{},"386":{},"390":{},"402":{},"403":{},"405":{}},"tags":{}}],["inform",{"_index":36,"title":{},"content":{"1":{},"28":{},"40":{},"56":{},"62":{},"63":{},"95":{},"96":{},"97":{},"98":{},"99":{},"125":{},"148":{},"151":{},"155":{},"270":{},"275":{},"279":{},"283":{},"325":{},"333":{},"335":{},"340":{},"341":{},"343":{},"349":{},"364":{},"365":{},"382":{},"388":{},"396":{},"405":{}},"tags":{}}],["infrastractur",{"_index":2456,"title":{},"content":{"395":{}},"tags":{}}],["infrastructur",{"_index":17,"title":{"189":{},"387":{}},"content":{"1":{},"2":{},"16":{},"29":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"100":{},"101":{},"102":{},"103":{},"129":{},"135":{},"145":{},"146":{},"156":{},"158":{},"163":{},"168":{},"169":{},"179":{},"180":{},"181":{},"186":{},"187":{},"188":{},"189":{},"222":{},"254":{},"325":{},"337":{},"386":{},"387":{},"388":{}},"tags":{}}],["infrastructure.clusterendpoint",{"_index":2096,"title":{},"content":{"337":{}},"tags":{}}],["infrastructure.uid",{"_index":1878,"title":{},"content":{"310":{}},"tags":{}}],["infrastructure/cloud",{"_index":1520,"title":{},"content":{"163":{}},"tags":{}}],["ingress",{"_index":2103,"title":{"341":{}},"content":{"341":{}},"tags":{}}],["inher",{"_index":1678,"title":{},"content":{"174":{}},"tags":{}}],["inherit",{"_index":1817,"title":{"195":{},"199":{},"203":{},"207":{},"211":{},"215":{},"219":{},"223":{},"227":{},"231":{},"235":{},"239":{},"243":{},"247":{},"251":{},"255":{},"259":{},"263":{},"267":{},"271":{},"275":{},"279":{},"283":{},"287":{},"291":{},"295":{},"299":{},"303":{},"307":{}},"content":{},"tags":{}}],["init",{"_index":600,"title":{"300":{}},"content":{"39":{},"191":{},"222":{},"301":{},"302":{},"386":{},"388":{}},"tags":{}}],["initi",{"_index":198,"title":{"140":{}},"content":{"12":{},"15":{},"16":{},"18":{},"19":{},"37":{},"41":{},"45":{},"48":{},"49":{},"50":{},"51":{},"60":{},"64":{},"66":{},"67":{},"68":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"124":{},"129":{},"135":{},"136":{},"151":{},"191":{},"221":{},"228":{},"229":{},"300":{},"301":{},"316":{},"337":{},"386":{},"400":{}},"tags":{}}],["initialcount",{"_index":2036,"title":{},"content":{"333":{}},"tags":{}}],["initramf",{"_index":348,"title":{"39":{}},"content":{"16":{},"38":{},"39":{},"40":{}},"tags":{}}],["inner",{"_index":2082,"title":{},"content":{"337":{}},"tags":{}}],["input",{"_index":1303,"title":{},"content":{"140":{},"323":{},"386":{}},"tags":{}}],["insecur",{"_index":496,"title":{},"content":{"28":{}},"tags":{}}],["insert",{"_index":1211,"title":{},"content":{"129":{},"146":{}},"tags":{}}],["insid",{"_index":19,"title":{"188":{}},"content":{"1":{},"12":{},"15":{},"16":{},"17":{},"23":{},"29":{},"30":{},"35":{},"58":{},"61":{},"74":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"157":{},"163":{},"165":{},"174":{},"187":{},"189":{},"337":{},"338":{},"343":{},"388":{},"400":{}},"tags":{}}],["insight",{"_index":745,"title":{},"content":{"56":{},"58":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"126":{},"335":{}},"tags":{}}],["inspect",{"_index":2483,"title":{"404":{}},"content":{"404":{}},"tags":{}}],["instal",{"_index":607,"title":{"68":{},"95":{},"110":{},"111":{},"134":{},"141":{},"143":{},"329":{},"356":{},"365":{}},"content":{"41":{},"47":{},"63":{},"64":{},"68":{},"72":{},"95":{},"96":{},"97":{},"98":{},"99":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"120":{},"125":{},"128":{},"129":{},"134":{},"135":{},"142":{},"143":{},"222":{},"237":{},"254":{},"302":{},"329":{},"334":{},"337":{},"347":{},"358":{},"364":{},"365":{},"379":{},"385":{},"394":{},"396":{},"403":{},"404":{},"405":{}},"tags":{}}],["installcrd",{"_index":2009,"title":{},"content":{"329":{}},"tags":{}}],["instanc",{"_index":1091,"title":{"204":{}},"content":{"124":{},"158":{},"185":{},"190":{},"191":{},"204":{},"205":{},"206":{},"216":{},"217":{},"257":{},"258":{},"329":{},"332":{},"333":{},"335":{},"338":{},"341":{},"343":{},"370":{},"371":{},"389":{}},"tags":{}}],["instancetyp",{"_index":1908,"title":{},"content":{"316":{},"332":{},"333":{}},"tags":{}}],["instead",{"_index":221,"title":{},"content":{"13":{},"26":{},"27":{},"55":{},"68":{},"314":{},"316":{},"377":{},"387":{}},"tags":{}}],["instruct",{"_index":856,"title":{},"content":{"69":{},"129":{},"131":{},"347":{},"364":{}},"tags":{}}],["intact",{"_index":2360,"title":{},"content":{"387":{}},"tags":{}}],["integr",{"_index":169,"title":{"33":{},"63":{}},"content":{"10":{},"11":{},"12":{},"15":{},"17":{},"20":{},"28":{},"30":{},"33":{},"36":{},"39":{},"42":{},"47":{},"48":{},"51":{},"74":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"156":{},"157":{},"163":{},"186":{},"187":{},"339":{},"354":{},"364":{},"365":{},"366":{},"381":{},"398":{},"399":{}},"tags":{}}],["integratedtim",{"_index":2488,"title":{},"content":{"404":{}},"tags":{}}],["intel",{"_index":1243,"title":{},"content":{"133":{},"143":{},"163":{},"168":{}},"tags":{}}],["intend",{"_index":1995,"title":{},"content":{"325":{}},"tags":{}}],["intens",{"_index":1590,"title":{},"content":{"160":{},"175":{},"176":{}},"tags":{}}],["interact",{"_index":459,"title":{"327":{}},"content":{"23":{},"32":{},"33":{},"135":{},"327":{},"358":{}},"tags":{}}],["intercept",{"_index":1066,"title":{"361":{}},"content":{"122":{}},"tags":{}}],["interconnect",{"_index":809,"title":{},"content":{"62":{}},"tags":{}}],["interest",{"_index":133,"title":{},"content":{"8":{},"347":{},"348":{},"395":{}},"tags":{}}],["interfac",{"_index":382,"title":{},"content":{"17":{},"18":{},"28":{},"46":{},"55":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"95":{},"96":{},"97":{},"98":{},"99":{},"141":{},"184":{},"186":{},"362":{},"381":{}},"tags":{}}],["intermedi",{"_index":402,"title":{},"content":{"17":{}},"tags":{}}],["intern",{"_index":238,"title":{},"content":{"14":{},"50":{},"58":{},"100":{},"101":{},"102":{},"103":{},"153":{},"325":{},"326":{},"340":{},"377":{}},"tags":{}}],["internet",{"_index":1300,"title":{"140":{},"340":{}},"content":{"140":{},"340":{}},"tags":{}}],["interpret",{"_index":1662,"title":{},"content":{"172":{}},"tags":{}}],["interv",{"_index":773,"title":{},"content":{"58":{}},"tags":{}}],["introduc",{"_index":877,"title":{},"content":{"77":{},"316":{},"370":{},"371":{}},"tags":{}}],["introduct",{"_index":0,"title":{"1":{}},"content":{},"tags":{}}],["inventori",{"_index":2237,"title":{},"content":{"349":{},"355":{}},"tags":{}}],["invoc",{"_index":2502,"title":{},"content":{"405":{}},"tags":{}}],["invok",{"_index":1313,"title":{},"content":{"143":{}},"tags":{}}],["iodepth",{"_index":1775,"title":{},"content":{"184":{}},"tags":{}}],["iop",{"_index":1754,"title":{},"content":{"184":{},"185":{}},"tags":{}}],["ip",{"_index":1007,"title":{},"content":{"122":{},"127":{},"183":{},"337":{},"341":{},"382":{},"383":{},"401":{}},"tags":{}}],["iperf",{"_index":1720,"title":{},"content":{"183":{}},"tags":{}}],["ipsec",{"_index":718,"title":{},"content":{"55":{}},"tags":{}}],["iptabl",{"_index":1277,"title":{},"content":{"134":{},"140":{}},"tags":{}}],["irrevers",{"_index":155,"title":{},"content":{"9":{},"19":{},"131":{},"138":{}},"tags":{}}],["irrevoc",{"_index":271,"title":{},"content":{"15":{}},"tags":{}}],["isn't",{"_index":520,"title":{},"content":{"29":{},"30":{},"49":{},"55":{},"125":{},"184":{},"365":{},"370":{},"371":{},"383":{},"386":{},"392":{},"399":{}},"tags":{}}],["isol",{"_index":195,"title":{},"content":{"12":{},"42":{},"43":{},"49":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"140":{},"165":{},"323":{}},"tags":{}}],["issu",{"_index":534,"title":{"374":{},"375":{},"380":{}},"content":{"30":{},"55":{},"56":{},"76":{},"77":{},"128":{},"135":{},"139":{},"328":{},"346":{},"348":{},"357":{},"360":{},"375":{},"377":{},"378":{},"379":{},"381":{},"383":{},"390":{},"399":{},"402":{},"404":{}},"tags":{}}],["issuancerul",{"_index":2358,"title":{},"content":{"386":{}},"tags":{}}],["it'",{"_index":126,"title":{},"content":{"7":{},"17":{},"30":{},"44":{},"45":{},"48":{},"76":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"122":{},"123":{},"129":{},"157":{},"158":{},"165":{},"168":{},"185":{},"325":{},"330":{},"337":{},"354":{},"372":{},"376":{},"381":{},"400":{},"402":{}},"tags":{}}],["item",{"_index":912,"title":{},"content":{"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"95":{},"96":{},"97":{},"98":{},"99":{},"122":{},"369":{}},"tags":{}}],["iter",{"_index":560,"title":{},"content":{"32":{},"357":{}},"tags":{}}],["itself",{"_index":1986,"title":{},"content":{"323":{},"354":{}},"tags":{}}],["jaeger",{"_index":818,"title":{},"content":{"62":{}},"tags":{}}],["jmee5islvg1syqsaew7wdmkf6o9t8e2tfuckzlohhlws2ohwbifznfwcfw",{"_index":2243,"title":{},"content":{"349":{},"402":{}},"tags":{}}],["join",{"_index":239,"title":{"378":{}},"content":{"14":{},"17":{},"18":{},"19":{},"23":{},"50":{},"51":{},"67":{},"136":{},"310":{},"378":{},"395":{},"399":{}},"tags":{}}],["joinservic",{"_index":236,"title":{"52":{}},"content":{"14":{},"18":{},"19":{},"23":{},"25":{},"50":{},"51":{},"52":{},"67":{},"70":{},"73":{},"136":{},"343":{},"378":{}},"tags":{}}],["jointli",{"_index":1685,"title":{},"content":{"176":{}},"tags":{}}],["journald",{"_index":793,"title":{},"content":{"60":{}},"tags":{}}],["jq",{"_index":2090,"title":{},"content":{"337":{},"352":{},"378":{}},"tags":{}}],["json",{"_index":2001,"title":{},"content":{"328":{},"335":{},"369":{},"378":{}},"tags":{}}],["jsonpath='{.spec",{"_index":2288,"title":{},"content":{"369":{}},"tags":{}}],["jsonpath={.data.attestationconfig_backup",{"_index":2386,"title":{},"content":{"378":{}},"tags":{}}],["json|raw",{"_index":1853,"title":{},"content":{"242":{}},"tags":{}}],["jump",{"_index":88,"title":{},"content":{"4":{},"383":{}},"tags":{}}],["k",{"_index":981,"title":{},"content":{"121":{},"130":{},"137":{},"198":{}},"tags":{}}],["k3",{"_index":1282,"title":{},"content":{"135":{}},"tags":{}}],["k8",{"_index":1846,"title":{},"content":{"222":{},"254":{},"395":{}},"tags":{}}],["kb",{"_index":1773,"title":{},"content":{"184":{}},"tags":{}}],["keep",{"_index":40,"title":{},"content":{"2":{},"28":{},"49":{},"129":{},"135":{},"163":{},"315":{},"326":{},"336":{},"337":{},"378":{},"387":{},"389":{}},"tags":{}}],["kek",{"_index":538,"title":{},"content":{"30":{},"44":{},"48":{},"49":{},"54":{},"360":{}},"tags":{}}],["kept",{"_index":853,"title":{},"content":{"68":{},"138":{}},"tags":{}}],["kernel",{"_index":137,"title":{},"content":{"8":{},"16":{},"30":{},"32":{},"33":{},"38":{},"39":{},"133":{},"168":{},"169":{}},"tags":{}}],["kernel'",{"_index":648,"title":{},"content":{"47":{}},"tags":{}}],["kernel/hv",{"_index":1524,"title":{},"content":{"163":{}},"tags":{}}],["key",{"_index":121,"title":{"42":{},"48":{},"49":{},"75":{},"85":{}},"content":{"7":{},"12":{},"17":{},"22":{},"29":{},"30":{},"32":{},"40":{},"42":{},"44":{},"46":{},"47":{},"48":{},"49":{},"50":{},"52":{},"54":{},"68":{},"75":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"122":{},"136":{},"157":{},"158":{},"186":{},"257":{},"306":{},"335":{},"342":{},"343":{},"344":{},"349":{},"351":{},"352":{},"354":{},"360":{},"365":{},"372":{},"378":{},"383":{},"399":{},"402":{},"403":{},"404":{}},"tags":{}}],["key=valu",{"_index":1834,"title":{},"content":{"198":{}},"tags":{}}],["keyservic",{"_index":535,"title":{"54":{}},"content":{"30":{},"50":{},"52":{},"54":{},"360":{}},"tags":{}}],["kill",{"_index":1226,"title":{},"content":{"130":{},"137":{}},"tags":{}}],["kind",{"_index":1000,"title":{},"content":{"122":{},"125":{},"365":{}},"tags":{}}],["km",{"_index":677,"title":{},"content":{"49":{},"54":{}},"tags":{}}],["kmip",{"_index":685,"title":{},"content":{"49":{}},"tags":{}}],["kmss",{"_index":683,"title":{},"content":{"49":{}},"tags":{}}],["know",{"_index":432,"title":{},"content":{"20":{},"129":{},"335":{},"400":{},"403":{}},"tags":{}}],["known",{"_index":312,"title":{},"content":{"16":{},"46":{},"55":{},"128":{},"139":{},"162":{},"332":{},"353":{},"375":{},"378":{},"379":{}},"tags":{}}],["konnect",{"_index":1883,"title":{},"content":{"310":{}},"tags":{}}],["kube",{"_index":805,"title":{},"content":{"61":{},"122":{},"126":{},"136":{},"329":{},"369":{},"378":{},"395":{}},"tags":{}}],["kubeconfig",{"_index":457,"title":{},"content":{"23":{},"66":{},"68":{},"222":{},"230":{},"302":{},"386":{}},"tags":{}}],["kubeconfig=\"$pwd/constel",{"_index":1220,"title":{},"content":{"129":{},"135":{},"337":{}},"tags":{}}],["kubeconfig=$(realpath",{"_index":2359,"title":{},"content":{"386":{}},"tags":{}}],["kubectl",{"_index":463,"title":{},"content":{"23":{},"55":{},"66":{},"68":{},"121":{},"122":{},"125":{},"126":{},"127":{},"129":{},"130":{},"134":{},"135":{},"136":{},"137":{},"142":{},"337":{},"365":{},"366":{},"369":{},"378":{},"382":{},"395":{},"401":{}},"tags":{}}],["kubenet",{"_index":1711,"title":{},"content":{"180":{},"181":{}},"tags":{}}],["kubernet",{"_index":4,"title":{"41":{},"61":{},"78":{},"89":{},"156":{},"158":{},"208":{},"334":{},"379":{}},"content":{"1":{},"2":{},"4":{},"14":{},"15":{},"23":{},"25":{},"28":{},"30":{},"41":{},"46":{},"48":{},"50":{},"51":{},"52":{},"54":{},"55":{},"56":{},"58":{},"61":{},"62":{},"63":{},"66":{},"67":{},"68":{},"71":{},"74":{},"76":{},"78":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"122":{},"123":{},"124":{},"125":{},"129":{},"135":{},"147":{},"156":{},"157":{},"158":{},"161":{},"162":{},"171":{},"177":{},"179":{},"180":{},"181":{},"184":{},"185":{},"186":{},"187":{},"188":{},"190":{},"191":{},"198":{},"208":{},"209":{},"210":{},"237":{},"301":{},"310":{},"314":{},"334":{},"337":{},"340":{},"343":{},"362":{},"363":{},"367":{},"371":{},"378":{},"379":{},"381":{},"382":{},"383":{},"391":{},"392":{},"395":{},"396":{}},"tags":{}}],["kubernetesvers",{"_index":2450,"title":{},"content":{"394":{}},"tags":{}}],["kubestr",{"_index":1768,"title":{},"content":{"184":{}},"tags":{}}],["kvm",{"_index":1246,"title":{},"content":{"133":{}},"tags":{}}],["kvm/qemu",{"_index":1234,"title":{},"content":{"132":{}},"tags":{}}],["label",{"_index":790,"title":{},"content":{"59":{},"122":{},"125":{}},"tags":{}}],["lake",{"_index":502,"title":{},"content":{"28":{},"63":{}},"tags":{}}],["larg",{"_index":1560,"title":{},"content":{"158":{},"183":{},"188":{}},"tags":{}}],["larger",{"_index":1779,"title":{},"content":{"184":{},"333":{},"389":{}},"tags":{}}],["latenc",{"_index":1602,"title":{},"content":{"172":{},"173":{}},"tags":{}}],["later",{"_index":710,"title":{},"content":{"52":{},"67":{},"124":{},"125":{}},"tags":{}}],["latest",{"_index":394,"title":{},"content":{"17":{},"22":{},"128":{},"139":{},"146":{},"168":{},"375":{},"390":{},"392":{}},"tags":{}}],["latter",{"_index":340,"title":{},"content":{"16":{},"386":{}},"tags":{}}],["launch",{"_index":373,"title":{"389":{}},"content":{"16":{},"51":{},"67":{},"389":{},"390":{}},"tags":{}}],["launch/v2.2.0/constellation.img",{"_index":2424,"title":{},"content":{"390":{}},"tags":{}}],["layer",{"_index":231,"title":{},"content":{"14":{},"15":{},"184":{},"188":{}},"tags":{}}],["lb",{"_index":2098,"title":{"340":{}},"content":{"340":{},"383":{}},"tags":{}}],["lead",{"_index":1616,"title":{},"content":{"172":{},"327":{},"379":{}},"tags":{}}],["leak",{"_index":761,"title":{},"content":{"56":{},"122":{}},"tags":{}}],["learn",{"_index":83,"title":{},"content":{"4":{},"34":{},"71":{},"74":{},"75":{},"76":{},"129":{},"322":{},"325":{},"334":{},"335":{},"378":{},"391":{},"392":{},"394":{},"405":{}},"tags":{}}],["leav",{"_index":664,"title":{},"content":{"48":{},"122":{},"158":{},"363":{}},"tags":{}}],["ledger",{"_index":441,"title":{},"content":{"22":{},"402":{}},"tags":{}}],["left",{"_index":1062,"title":{},"content":{"122":{},"343":{}},"tags":{}}],["legal",{"_index":1980,"title":{},"content":{"323":{}},"tags":{}}],["lend",{"_index":2269,"title":{},"content":{"354":{}},"tags":{}}],["less",{"_index":1738,"title":{},"content":{"183":{},"184":{}},"tags":{}}],["let",{"_index":918,"title":{},"content":{"95":{},"96":{},"97":{},"98":{},"99":{},"132":{},"186":{}},"tags":{}}],["letter",{"_index":1864,"title":{},"content":{"282":{}},"tags":{}}],["level",{"_index":514,"title":{"320":{},"321":{},"322":{},"323":{},"324":{}},"content":{"29":{},"47":{},"60":{},"100":{},"101":{},"102":{},"103":{},"165":{},"172":{},"185":{},"195":{},"199":{},"203":{},"207":{},"211":{},"215":{},"219":{},"223":{},"227":{},"231":{},"235":{},"239":{},"243":{},"247":{},"251":{},"255":{},"259":{},"263":{},"267":{},"271":{},"275":{},"279":{},"283":{},"287":{},"291":{},"295":{},"299":{},"303":{},"307":{},"320":{},"323":{},"324":{},"328":{},"363":{},"364":{},"389":{}},"tags":{}}],["level\":\"error\",\"ts\":\"2022",{"_index":2148,"title":{},"content":{"343":{}},"tags":{}}],["level\":\"info\",\"ts\":\"2022",{"_index":1293,"title":{},"content":{"136":{},"343":{},"344":{}},"tags":{}}],["level\":\"warn\",\"ts\":\"2022",{"_index":2135,"title":{},"content":{"343":{}},"tags":{}}],["leverag",{"_index":25,"title":{},"content":{"1":{}},"tags":{}}],["libcryptsetup",{"_index":551,"title":{},"content":{"32":{},"33":{}},"tags":{}}],["librari",{"_index":550,"title":{},"content":{"31":{},"122":{},"346":{},"360":{}},"tags":{}}],["licens",{"_index":913,"title":{"94":{},"149":{},"153":{},"154":{}},"content":{"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"150":{},"151":{},"152":{},"154":{}},"tags":{}}],["lifecycl",{"_index":961,"title":{},"content":{"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"143":{},"186":{},"337":{},"384":{}},"tags":{}}],["lifetim",{"_index":701,"title":{},"content":{"50":{},"53":{},"69":{}},"tags":{}}],["lift",{"_index":229,"title":{},"content":{"14":{}},"tags":{}}],["limit",{"_index":688,"title":{"357":{}},"content":{"49":{},"125":{},"126":{},"151":{},"152":{},"154":{},"158":{},"172":{},"357":{},"376":{}},"tags":{}}],["line",{"_index":350,"title":{},"content":{"16":{},"38":{},"39":{},"95":{},"96":{},"97":{},"98":{},"99":{},"141":{},"386":{}},"tags":{}}],["link",{"_index":156,"title":{},"content":{"9":{},"174":{}},"tags":{}}],["linux",{"_index":358,"title":{},"content":{"16":{},"26":{},"27":{},"35":{},"47":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"132":{},"133":{},"134":{},"135":{},"142":{},"143":{},"146":{},"168":{},"169":{},"346":{},"385":{},"403":{},"404":{},"405":{}},"tags":{}}],["list",{"_index":105,"title":{},"content":{"6":{},"16":{},"17":{},"125":{},"126":{},"129":{},"140":{},"146":{},"198":{},"222":{},"254":{},"274":{},"282":{},"332":{},"335":{},"343":{},"366":{},"369":{},"378":{},"389":{},"399":{},"404":{}},"tags":{}}],["lo",{"_index":1272,"title":{},"content":{"134":{},"143":{},"351":{}},"tags":{}}],["load",{"_index":162,"title":{},"content":{"10":{},"12":{},"37":{},"38":{},"39":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"123":{},"125":{},"127":{},"135":{},"146":{},"171":{},"186":{},"190":{},"314":{},"316":{},"330":{},"337":{},"339":{},"340":{},"341":{},"349":{},"372":{},"383":{},"402":{}},"tags":{}}],["loadbalanc",{"_index":952,"title":{},"content":{"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"145":{},"312":{},"314":{},"339":{},"340":{}},"tags":{}}],["local",{"_index":695,"title":{"97":{},"132":{}},"content":{"49":{},"65":{},"95":{},"96":{},"97":{},"98":{},"99":{},"128":{},"130":{},"132":{},"135":{},"137":{},"144":{},"191":{},"284":{},"285":{},"337":{},"354":{},"372":{},"378":{},"386":{},"388":{},"391":{},"399":{}},"tags":{}}],["localhost:8443",{"_index":1055,"title":{},"content":{"122":{}},"tags":{}}],["locat",{"_index":141,"title":{},"content":{"9":{},"11":{},"65":{},"122":{},"335":{},"360":{},"393":{}},"tags":{}}],["lock",{"_index":200,"title":{},"content":{"12":{},"77":{},"384":{}},"tags":{}}],["log",{"_index":484,"title":{"59":{},"60":{},"61":{},"381":{},"404":{}},"content":{"26":{},"27":{},"56":{},"59":{},"60":{},"61":{},"63":{},"76":{},"122":{},"126":{},"136":{},"146":{},"190":{},"195":{},"199":{},"203":{},"207":{},"211":{},"215":{},"219":{},"223":{},"227":{},"231":{},"235":{},"239":{},"243":{},"247":{},"251":{},"255":{},"259":{},"263":{},"267":{},"271":{},"275":{},"279":{},"283":{},"287":{},"291":{},"295":{},"299":{},"303":{},"307":{},"328":{},"338":{},"343":{},"381":{},"386":{},"399":{},"402":{},"403":{},"404":{}},"tags":{}}],["logid",{"_index":2486,"title":{},"content":{"404":{}},"tags":{}}],["login",{"_index":1206,"title":{},"content":{"129":{},"146":{}},"tags":{}}],["logstash",{"_index":795,"title":{},"content":{"60":{}},"tags":{}}],["logz.io",{"_index":821,"title":{},"content":{"63":{}},"tags":{}}],["loki",{"_index":808,"title":{},"content":{"61":{}},"tags":{}}],["long",{"_index":451,"title":{},"content":{"22":{},"349":{},"360":{},"402":{}},"tags":{}}],["longer",{"_index":1805,"title":{},"content":{"189":{},"315":{},"316":{},"372":{},"395":{}},"tags":{}}],["look",{"_index":1065,"title":{},"content":{"122":{},"129":{},"135":{},"140":{},"145":{},"335":{},"347":{},"390":{},"401":{}},"tags":{}}],["loss",{"_index":1999,"title":{},"content":{"327":{}},"tags":{}}],["lost",{"_index":1228,"title":{},"content":{"131":{},"138":{},"261":{},"372":{}},"tags":{}}],["lot",{"_index":1808,"title":{},"content":{"190":{},"369":{}},"tags":{}}],["low",{"_index":1088,"title":{},"content":{"124":{}},"tags":{}}],["lower",{"_index":397,"title":{},"content":{"17":{},"172":{}},"tags":{}}],["lowest",{"_index":1663,"title":{},"content":{"172":{}},"tags":{}}],["ls0tls1crudjtibqvujmsumgs0vzls0tls0ktuzrd0v3wuhlb1pjemowq0frwullb1pjemowrefry0rrz0ffzjhgmwhwbxdfk1ldrlh6akd0yvfjckw2wfpwvapkbuvlnwltthzhmvn5uvnbzxc3v2rns0y2bzl0oguyvez1q2t6be9oagx3czjpsfdiauzabkzxq0z3pt0kls0tls1ftkqgufvcteldietfws0tls0tcg",{"_index":2496,"title":{},"content":{"404":{}},"tags":{}}],["ls_dyna",{"_index":1691,"title":{},"content":{"176":{}},"tags":{}}],["lsb_releas",{"_index":1264,"title":{},"content":{"134":{}},"tags":{}}],["lt",{"_index":1249,"title":{},"content":{"133":{}},"tags":{}}],["luks2",{"_index":552,"title":{},"content":{"32":{}},"tags":{}}],["m1a.16cd",{"_index":2025,"title":{},"content":{"332":{}},"tags":{}}],["m1a.30cd",{"_index":2027,"title":{},"content":{"332":{}},"tags":{}}],["m1a.4cd",{"_index":2022,"title":{},"content":{"332":{}},"tags":{}}],["m1a.8cd",{"_index":2024,"title":{},"content":{"332":{}},"tags":{}}],["m6a.xlarg",{"_index":2014,"title":{},"content":{"332":{}},"tags":{}}],["maa",{"_index":2087,"title":{},"content":{"337":{},"386":{}},"tags":{}}],["maa_url",{"_index":2342,"title":{},"content":{"386":{}},"tags":{}}],["mac",{"_index":2332,"title":{},"content":{"385":{}},"tags":{}}],["machin",{"_index":186,"title":{"12":{}},"content":{"12":{},"17":{},"48":{},"51":{},"121":{},"129":{},"132":{},"133":{},"142":{},"146":{},"179":{},"180":{},"181":{},"183":{},"184":{},"330":{},"332":{},"335":{},"343":{},"354":{},"381":{}},"tags":{}}],["machines/filestash:latest",{"_index":1029,"title":{},"content":{"122":{}},"tags":{}}],["maco",{"_index":1305,"title":{},"content":{"142":{},"143":{},"146":{}},"tags":{}}],["made",{"_index":1067,"title":{},"content":{"122":{},"351":{},"388":{}},"tags":{}}],["main",{"_index":494,"title":{},"content":{"28":{},"49":{},"323":{},"389":{}},"tags":{}}],["main.tf",{"_index":1355,"title":{},"content":{"145":{},"335":{},"386":{}},"tags":{}}],["mainli",{"_index":738,"title":{},"content":{"55":{},"62":{}},"tags":{}}],["maintain",{"_index":436,"title":{},"content":{"21":{},"171":{},"185":{},"314":{},"349":{}},"tags":{}}],["major",{"_index":522,"title":{},"content":{"30":{},"158":{},"327":{}},"tags":{}}],["major.minor",{"_index":1831,"title":{},"content":{"198":{}},"tags":{}}],["make",{"_index":204,"title":{},"content":{"12":{},"14":{},"28":{},"65":{},"127":{},"128":{},"129":{},"139":{},"140":{},"142":{},"144":{},"146":{},"183":{},"323":{},"337":{},"341":{},"348":{},"349":{},"372":{},"387":{},"388":{},"405":{}},"tags":{}}],["malici",{"_index":51,"title":{},"content":{"2":{},"29":{},"189":{},"190":{},"402":{}},"tags":{}}],["manag",{"_index":56,"title":{"29":{},"30":{},"42":{},"48":{},"49":{},"75":{},"110":{},"158":{},"329":{}},"content":{"2":{},"29":{},"30":{},"44":{},"46":{},"47":{},"48":{},"49":{},"50":{},"54":{},"64":{},"65":{},"68":{},"73":{},"95":{},"96":{},"97":{},"98":{},"99":{},"100":{},"101":{},"102":{},"103":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"129":{},"131":{},"143":{},"145":{},"148":{},"155":{},"157":{},"158":{},"161":{},"162":{},"164":{},"166":{},"167":{},"168":{},"171":{},"177":{},"185":{},"186":{},"191":{},"224":{},"225":{},"254":{},"314":{},"315":{},"317":{},"325":{},"329":{},"330":{},"335":{},"337":{},"340":{},"343":{},"349":{},"355":{},"363":{},"372":{},"377":{},"379":{},"384":{},"395":{},"396":{}},"tags":{}}],["mani",{"_index":498,"title":{},"content":{"28":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"158":{},"168":{},"342":{},"396":{},"402":{}},"tags":{}}],["manifest",{"_index":1099,"title":{},"content":{"125":{}},"tags":{}}],["manifests.yaml",{"_index":1147,"title":{},"content":{"127":{}},"tags":{}}],["manipul",{"_index":1801,"title":{},"content":{"188":{},"326":{},"405":{}},"tags":{}}],["manual",{"_index":324,"title":{"327":{},"370":{},"404":{}},"content":{"16":{},"68":{},"100":{},"101":{},"102":{},"103":{},"129":{},"131":{},"146":{},"310":{},"325":{},"326":{},"327":{},"335":{},"337":{},"343":{},"370":{},"371":{},"372":{},"378":{},"379":{},"386":{},"390":{},"394":{},"395":{}},"tags":{}}],["map",{"_index":526,"title":{},"content":{"30":{},"39":{},"319":{},"378":{}},"tags":{}}],["mapper",{"_index":649,"title":{},"content":{"47":{}},"tags":{}}],["mapper\",\"version\":\"2.0.0\",\"cloudprovider\":\"azur",{"_index":2154,"title":{},"content":{"343":{}},"tags":{}}],["mapper\",\"version\":\"2.0.0\",\"cloudprovider\":\"gcp",{"_index":2124,"title":{},"content":{"343":{}},"tags":{}}],["mark",{"_index":272,"title":{},"content":{"15":{},"16":{},"19":{},"172":{},"173":{},"366":{}},"tags":{}}],["marketplac",{"_index":921,"title":{"98":{},"148":{},"155":{}},"content":{"95":{},"96":{},"97":{},"98":{},"99":{},"148":{},"155":{}},"tags":{}}],["master",{"_index":290,"title":{"44":{}},"content":{"15":{},"23":{},"30":{},"44":{},"45":{},"48":{},"66":{},"68":{},"129":{},"135":{},"186":{},"344":{},"383":{}},"tags":{}}],["mastersecret.json",{"_index":852,"title":{},"content":{"68":{},"129":{},"135":{},"372":{}},"tags":{}}],["match",{"_index":2378,"title":{},"content":{"378":{},"400":{},"404":{}},"tags":{}}],["matchlabel",{"_index":1004,"title":{},"content":{"122":{},"125":{}},"tags":{}}],["materi",{"_index":615,"title":{"349":{}},"content":{"44":{},"48":{},"349":{}},"tags":{}}],["matur",{"_index":2273,"title":{},"content":{"355":{}},"tags":{}}],["max",{"_index":1628,"title":{},"content":{"172":{},"369":{}},"tags":{}}],["max=10",{"_index":1117,"title":{},"content":{"125":{}},"tags":{}}],["maximum",{"_index":1609,"title":{},"content":{"172":{},"173":{},"183":{},"184":{},"369":{}},"tags":{}}],["mb/",{"_index":1756,"title":{},"content":{"184":{}},"tags":{}}],["mean",{"_index":323,"title":{},"content":{"16":{},"48":{},"68":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"158":{},"169":{},"172":{},"173":{},"342":{},"343":{},"360":{},"363":{},"392":{}},"tags":{}}],["meanwhil",{"_index":1789,"title":{},"content":{"185":{}},"tags":{}}],["measur",{"_index":122,"title":{"8":{},"10":{},"16":{},"36":{},"200":{},"378":{},"399":{}},"content":{"7":{},"8":{},"9":{},"10":{},"11":{},"12":{},"15":{},"16":{},"17":{},"18":{},"19":{},"20":{},"22":{},"23":{},"25":{},"26":{},"27":{},"35":{},"36":{},"37":{},"38":{},"39":{},"45":{},"58":{},"67":{},"70":{},"136":{},"157":{},"163":{},"164":{},"166":{},"167":{},"171":{},"172":{},"183":{},"191":{},"200":{},"201":{},"202":{},"254":{},"318":{},"319":{},"344":{},"378":{},"390":{},"399":{},"400":{},"401":{}},"tags":{}}],["mechan",{"_index":624,"title":{},"content":{"45":{},"61":{},"69":{},"342":{}},"tags":{}}],["medium",{"_index":497,"title":{},"content":{"28":{}},"tags":{}}],["meet",{"_index":78,"title":{},"content":{"3":{},"337":{}},"tags":{}}],["member",{"_index":1972,"title":{},"content":{"323":{},"343":{}},"tags":{}}],["memori",{"_index":24,"title":{},"content":{"1":{},"8":{},"9":{},"12":{},"28":{},"32":{},"43":{},"48":{},"49":{},"57":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"158":{},"179":{},"180":{},"181":{}},"tags":{}}],["mention",{"_index":1383,"title":{},"content":{"145":{},"332":{}},"tags":{}}],["merg",{"_index":1838,"title":{},"content":{"222":{},"230":{},"302":{},"319":{},"323":{}},"tags":{}}],["messag",{"_index":785,"title":{},"content":{"59":{},"122":{},"343":{}},"tags":{}}],["met",{"_index":1304,"title":{},"content":{"142":{}},"tags":{}}],["meta",{"_index":1077,"title":{},"content":{"122":{}},"tags":{}}],["metadata",{"_index":788,"title":{},"content":{"59":{},"122":{},"125":{},"326":{},"360":{},"365":{},"366":{},"402":{}},"tags":{}}],["metadata.nam",{"_index":2280,"title":{},"content":{"369":{}},"tags":{}}],["method",{"_index":656,"title":{},"content":{"47":{}},"tags":{}}],["metric",{"_index":756,"title":{"58":{}},"content":{"56":{},"57":{},"58":{},"63":{},"76":{},"125":{}},"tags":{}}],["meuciqcser3mgj+j5pr2koxtlcihqc3gt30i7qklr9awt6euuqigclukrily50un8jgwvengkbzyyd8hmxwc/lfrwomn180",{"_index":2495,"title":{},"content":{"404":{}},"tags":{}}],["mfkwewyhkozizj0caqyikozizj0daqcdqgaef8f1hpmwe+ycfxzjgtaqcrl6xzvt",{"_index":2242,"title":{},"content":{"349":{},"402":{}},"tags":{}}],["mib",{"_index":562,"title":{},"content":{"32":{}},"tags":{}}],["microk8",{"_index":1281,"title":{},"content":{"135":{}},"tags":{}}],["microservic",{"_index":424,"title":{"50":{},"73":{},"82":{}},"content":{"19":{},"50":{},"51":{},"62":{},"67":{},"69":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"120":{},"127":{},"237":{},"329":{},"378":{},"391":{},"392":{},"395":{}},"tags":{}}],["microservicevers",{"_index":2451,"title":{},"content":{"394":{}},"tags":{}}],["microsoft",{"_index":1307,"title":{"165":{}},"content":{"142":{},"186":{},"191":{},"276":{},"277":{},"389":{}},"tags":{}}],["microsoft'",{"_index":1381,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.attest",{"_index":1358,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.attestation/attestationprovid",{"_index":1370,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.authorization/roleassign",{"_index":1365,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.authorization/roledefinit",{"_index":1366,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.comput",{"_index":1359,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.compute/virtualmachinescaleset",{"_index":1371,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.insight",{"_index":1360,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.insights/compon",{"_index":1372,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.managedident",{"_index":1361,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.managedidentity/userassignedident",{"_index":1367,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.network",{"_index":1362,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.network/loadbalanc",{"_index":1373,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.network/loadbalancers/backendaddresspool",{"_index":1374,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.network/natgateway",{"_index":1379,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.network/networksecuritygroup",{"_index":1375,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.network/publicipaddress",{"_index":1376,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.network/virtualnetwork",{"_index":1377,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.network/virtualnetworks/subnet",{"_index":1378,"title":{},"content":{"145":{}},"tags":{}}],["microsoft.resources/subscriptions/resourcegroup",{"_index":1368,"title":{},"content":{"145":{}},"tags":{}}],["migrat",{"_index":694,"title":{"101":{},"212":{},"308":{},"309":{},"311":{},"313":{},"315":{},"316":{},"317":{},"318":{},"319":{},"393":{}},"content":{"49":{},"100":{},"101":{},"102":{},"103":{},"191":{},"212":{},"213":{},"214":{},"308":{},"310":{},"315":{},"317":{},"319":{},"342":{},"393":{},"395":{}},"tags":{}}],["milan",{"_index":1512,"title":{},"content":{"163":{},"175":{},"176":{},"179":{},"180":{}},"tags":{}}],["milli",{"_index":1112,"title":{},"content":{"125":{}},"tags":{}}],["min",{"_index":1631,"title":{},"content":{"172":{},"369":{}},"tags":{}}],["min=1",{"_index":1116,"title":{},"content":{"125":{}},"tags":{}}],["mind",{"_index":2015,"title":{},"content":{"332":{},"378":{}},"tags":{}}],["mini",{"_index":1279,"title":{"224":{},"228":{},"232":{}},"content":{"135":{},"138":{},"191":{},"226":{},"229":{},"233":{}},"tags":{}}],["miniconstel",{"_index":1232,"title":{},"content":{"132":{},"135":{},"138":{},"191":{},"224":{},"225":{},"228":{},"229":{},"232":{},"233":{}},"tags":{}}],["minikub",{"_index":1283,"title":{},"content":{"135":{}},"tags":{}}],["minim",{"_index":582,"title":{},"content":{"35":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"337":{}},"tags":{}}],["minimum",{"_index":392,"title":{},"content":{"17":{},"172":{},"173":{},"332":{},"337":{},"369":{}},"tags":{}}],["minor",{"_index":878,"title":{},"content":{"77":{},"78":{},"175":{},"176":{},"392":{}},"tags":{}}],["minut",{"_index":647,"title":{},"content":{"46":{},"125":{},"129":{},"135":{},"136":{},"395":{}},"tags":{}}],["misconfigur",{"_index":2455,"title":{},"content":{"395":{}},"tags":{}}],["mismatch",{"_index":427,"title":{},"content":{"19":{},"399":{}},"tags":{}}],["mitig",{"_index":725,"title":{},"content":{"55":{}},"tags":{}}],["mkdir",{"_index":2337,"title":{},"content":{"386":{}},"tags":{}}],["mode",{"_index":317,"title":{},"content":{"16":{},"30":{},"49":{},"54":{},"55":{},"135":{},"222":{},"254":{},"302":{}},"tags":{}}],["model",{"_index":102,"title":{"187":{}},"content":{"5":{},"29":{},"47":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{}},"tags":{}}],["modern",{"_index":62,"title":{},"content":{"2":{},"62":{}},"tags":{}}],["modif",{"_index":2232,"title":{},"content":{"361":{}},"tags":{}}],["modifi",{"_index":218,"title":{},"content":{"13":{},"38":{},"39":{},"62":{},"323":{},"332":{},"361":{},"378":{},"387":{}},"tags":{}}],["modul",{"_index":109,"title":{"7":{}},"content":{"30":{},"32":{},"33":{},"36":{},"133":{},"386":{},"387":{},"388":{}},"tags":{}}],["module.azure_iam",{"_index":2339,"title":{},"content":{"386":{}},"tags":{}}],["module.azure_infrastructur",{"_index":2341,"title":{},"content":{"386":{}},"tags":{}}],["modules.zip",{"_index":2336,"title":{},"content":{"386":{}},"tags":{}}],["monitor",{"_index":764,"title":{"57":{},"126":{}},"content":{"57":{},"125":{},"343":{},"395":{},"404":{}},"tags":{}}],["month",{"_index":875,"title":{},"content":{"77":{}},"tags":{}}],["more",{"_index":30,"title":{},"content":{"1":{},"4":{},"7":{},"17":{},"30":{},"34":{},"40":{},"46":{},"47":{},"53":{},"55":{},"56":{},"68":{},"71":{},"74":{},"75":{},"76":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"95":{},"96":{},"97":{},"98":{},"99":{},"100":{},"101":{},"102":{},"103":{},"125":{},"126":{},"132":{},"148":{},"154":{},"155":{},"172":{},"183":{},"184":{},"187":{},"312":{},"325":{},"329":{},"333":{},"335":{},"337":{},"340":{},"341":{},"363":{},"364":{},"365":{},"369":{},"382":{},"388":{},"389":{},"397":{},"401":{},"405":{}},"tags":{}}],["mostli",{"_index":1682,"title":{},"content":{"175":{},"400":{}},"tags":{}}],["motiv",{"_index":945,"title":{},"content":{"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"330":{},"337":{},"372":{},"402":{}},"tags":{}}],["mount",{"_index":260,"title":{},"content":{"15":{},"39":{},"40":{},"122":{},"362":{},"364":{},"365":{},"382":{}},"tags":{}}],["mountpath",{"_index":1034,"title":{},"content":{"122":{},"365":{}},"tags":{}}],["move",{"_index":74,"title":{},"content":{"3":{},"65":{}},"tags":{}}],["ms",{"_index":2347,"title":{},"content":{"386":{}},"tags":{}}],["mtl",{"_index":468,"title":{},"content":{"23":{}},"tags":{}}],["mtu",{"_index":1726,"title":{},"content":{"183":{}},"tags":{}}],["much",{"_index":1536,"title":{},"content":{"168":{},"346":{}},"tags":{}}],["multi",{"_index":1567,"title":{},"content":{"158":{},"186":{}},"tags":{}}],["multipart",{"_index":2213,"title":{},"content":{"357":{}},"tags":{}}],["multipl",{"_index":153,"title":{},"content":{"9":{},"65":{},"135":{},"222":{},"254":{},"337":{}},"tags":{}}],["musl",{"_index":2185,"title":{},"content":{"346":{}},"tags":{}}],["mutual",{"_index":225,"title":{},"content":{"13":{}},"tags":{}}],["mypvc",{"_index":2315,"title":{},"content":{"365":{}},"tags":{}}],["n",{"_index":986,"title":{},"content":{"121":{},"126":{},"127":{},"130":{},"136":{},"137":{},"140":{},"172":{},"369":{},"378":{}},"tags":{}}],["n2d",{"_index":1093,"title":{},"content":{"124":{},"129":{},"179":{},"181":{},"184":{},"332":{},"335":{}},"tags":{}}],["namd",{"_index":1688,"title":{},"content":{"176":{}},"tags":{}}],["name",{"_index":962,"title":{},"content":{"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"122":{},"125":{},"129":{},"136":{},"154":{},"274":{},"278":{},"310":{},"332":{},"335":{},"337":{},"343":{},"349":{},"365":{},"366":{},"369":{},"372":{},"383":{},"384":{},"390":{}},"tags":{}}],["name=\"/helm",{"_index":2393,"title":{},"content":{"379":{}},"tags":{}}],["tink",{"_index":2222,"title":{},"content":{"360":{}},"tags":{}}],["tip",{"_index":33,"title":{},"content":{"1":{},"126":{},"128":{},"129":{},"143":{},"144":{},"337":{},"378":{},"388":{}},"tags":{}}],["tl",{"_index":211,"title":{"13":{}},"content":{"13":{},"23":{},"52":{},"122":{},"342":{},"361":{}},"tags":{}}],["tlog",{"_index":2480,"title":{},"content":{"403":{},"405":{}},"tags":{}}],["togeth",{"_index":157,"title":{"21":{}},"content":{"9":{},"14":{},"21":{},"145":{},"326":{}},"tags":{}}],["token",{"_index":713,"title":{},"content":{"52":{},"68":{},"129":{},"145":{},"146":{},"377":{}},"tags":{}}],["tool",{"_index":462,"title":{},"content":{"23":{},"56":{},"58":{},"60":{},"61":{},"62":{},"66":{},"171":{},"335":{},"337":{},"353":{},"354":{},"395":{}},"tags":{}}],["top",{"_index":1061,"title":{},"content":{"122":{}},"tags":{}}],["topolog",{"_index":1797,"title":{},"content":{"186":{}},"tags":{}}],["total",{"_index":895,"title":{},"content":{"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"187":{}},"tags":{}}],["toward",{"_index":467,"title":{},"content":{"23":{},"122":{},"157":{},"377":{}},"tags":{}}],["tpm",{"_index":110,"title":{"7":{}},"content":{"7":{},"9":{},"15":{},"16":{},"26":{},"27":{},"36":{},"163":{}},"tags":{}}],["tpm|azur",{"_index":1825,"title":{},"content":{"198":{}},"tags":{}}],["trace",{"_index":757,"title":{"62":{}},"content":{"56":{},"62":{},"63":{},"76":{},"328":{}},"tags":{}}],["track",{"_index":791,"title":{"355":{}},"content":{"59":{},"355":{}},"tags":{}}],["traffic",{"_index":640,"title":{"361":{}},"content":{"46":{},"55":{},"122":{},"341":{},"361":{}},"tags":{}}],["transfer",{"_index":698,"title":{},"content":{"49":{}},"tags":{}}],["transit",{"_index":419,"title":{},"content":{"18":{},"36":{},"75":{},"157":{},"171":{},"183":{}},"tags":{}}],["transmit",{"_index":422,"title":{},"content":{"19":{}},"tags":{}}],["transpar",{"_index":546,"title":{"404":{}},"content":{"30":{},"34":{},"47":{},"54":{},"55":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"157":{},"158":{},"190":{},"356":{},"363":{},"364":{},"402":{},"403":{},"404":{}},"tags":{}}],["transport",{"_index":2140,"title":{},"content":{"343":{}},"tags":{}}],["tree",{"_index":596,"title":{},"content":{"39":{}},"tags":{}}],["tri",{"_index":425,"title":{},"content":{"19":{},"39":{},"51":{},"60":{},"145":{},"343":{},"369":{},"379":{}},"tags":{}}],["trigger",{"_index":1100,"title":{},"content":{"125":{},"369":{},"391":{},"395":{}},"tags":{}}],["troubleshoot",{"_index":798,"title":{"119":{},"139":{},"338":{},"373":{}},"content":{"60":{},"76":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"343":{}},"tags":{}}],["true",{"_index":1124,"title":{},"content":{"125":{},"145":{},"148":{},"179":{},"230":{},"315":{},"319":{},"323":{},"366":{},"369":{},"383":{},"399":{}},"tags":{}}],["truli",{"_index":1552,"title":{},"content":{"157":{}},"tags":{}}],["trust",{"_index":101,"title":{"7":{},"24":{},"389":{}},"content":{"5":{},"10":{},"11":{},"12":{},"13":{},"15":{},"16":{},"17":{},"21":{},"24":{},"29":{},"30":{},"36":{},"37":{},"39":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"122":{},"146":{},"165":{},"187":{},"345":{},"356":{},"361":{},"363":{},"378":{},"389":{},"390":{},"399":{}},"tags":{}}],["trustedlaunch|gcp",{"_index":1828,"title":{},"content":{"198":{}},"tags":{}}],["trustworthi",{"_index":71,"title":{},"content":{"3":{},"20":{},"400":{}},"tags":{}}],["truth",{"_index":416,"title":{},"content":{"18":{},"19":{},"20":{}},"tags":{}}],["tti",{"_index":1118,"title":{},"content":{"125":{}},"tags":{}}],["tuesday",{"_index":874,"title":{},"content":{"77":{}},"tags":{}}],["tunnel",{"_index":636,"title":{},"content":{"46":{},"55":{}},"tags":{}}],["turn",{"_index":536,"title":{},"content":{"30":{},"346":{}},"tags":{}}],["tutori",{"_index":1113,"title":{},"content":{"125":{}},"tags":{}}],["twitter",{"_index":2245,"title":{},"content":{"349":{},"402":{}},"tags":{}}],["two",{"_index":216,"title":{},"content":{"13":{},"16":{},"23":{},"48":{},"132":{},"145":{},"156":{},"183":{},"184":{},"278":{},"323":{},"329":{},"346":{},"353":{},"365":{},"396":{}},"tags":{}}],["ty",{"_index":274,"title":{},"content":{"15":{}},"tags":{}}],["type",{"_index":299,"title":{"204":{},"332":{}},"content":{"16":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{},"114":{},"115":{},"116":{},"117":{},"118":{},"119":{},"124":{},"129":{},"135":{},"184":{},"191":{},"204":{},"205":{},"206":{},"314":{},"330":{},"332":{},"333":{},"335":{},"339":{},"340":{},"341":{},"350":{},"352":{},"353":{},"363":{},"364":{},"365":{},"389":{},"400":{}},"tags":{}}],["type='merg",{"_index":2287,"title":{},"content":{"369":{}},"tags":{}}],["type==\"secureboot",{"_index":2353,"title":{},"content":{"386":{}},"tags":{}}],["type==\"x",{"_index":2346,"title":{},"content":{"386":{}},"tags":{}}],["typic",{"_index":127,"title":{},"content":{"7":{},"8":{},"9":{},"66":{},"158":{}},"tags":{}}],["u",{"_index":1836,"title":{},"content":{"202":{},"250":{}},"tags":{}}],["u$url",{"_index":2441,"title":{},"content":{"390":{}},"tags":{}}],["u.",{"_index":2276,"title":{},"content":{"355":{}},"tags":{}}],["uami",{"_index":1896,"title":{},"content":{"315":{}},"tags":{}}],["uat",{"_index":1202,"title":{},"content":{"129":{},"145":{},"146":{}},"tags":{}}],["ubuntu",{"_index":1247,"title":{"134":{}},"content":{"133":{},"346":{}},"tags":{}}],["udp",{"_index":1718,"title":{},"content":{"183":{}},"tags":{}}],["ui",{"_index":1070,"title":{},"content":{"122":{},"383":{}},"tags":{}}],["uid",{"_index":1886,"title":{},"content":{"310":{},"343":{}},"tags":{}}],["uid=\"/library/appl",{"_index":1471,"title":{},"content":{"146":{}},"tags":{}}],["usr/bin/env",{"_index":1874,"title":{},"content":{"310":{}},"tags":{}}],["usr/local/bin/constel",{"_index":1275,"title":{},"content":{"134":{},"143":{}},"tags":{}}],["usual",{"_index":250,"title":{},"content":{"15":{},"29":{},"59":{},"77":{},"78":{},"148":{},"326":{},"343":{},"395":{}},"tags":{}}],["util",{"_index":563,"title":{},"content":{"32":{},"57":{},"161":{},"175":{},"386":{}},"tags":{}}],["uuid",{"_index":2055,"title":{},"content":{"335":{},"403":{},"404":{}},"tags":{}}],["uuid=362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13",{"_index":2485,"title":{},"content":{"404":{}},"tags":{}}],["v",{"_index":891,"title":{},"content":{"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{}},"tags":{}}],["v/svm",{"_index":1245,"title":{},"content":{"133":{}},"tags":{}}],["v1",{"_index":1107,"title":{},"content":{"125":{},"335":{},"365":{}},"tags":{}}],["v1.10.0",{"_index":2461,"title":{},"content":{"396":{}},"tags":{}}],["v1.12",{"_index":1699,"title":{},"content":{"179":{}},"tags":{}}],["v1.12.1",{"_index":2460,"title":{},"content":{"396":{}},"tags":{}}],["v1.24.6",{"_index":1289,"title":{},"content":{"136":{}},"tags":{}}],["v1.24.9",{"_index":1707,"title":{},"content":{"180":{},"181":{}},"tags":{}}],["v1.25.7",{"_index":1698,"title":{},"content":{"179":{}},"tags":{}}],["v1.25.8",{"_index":2459,"title":{},"content":{"396":{}},"tags":{}}],["v1.29.15",{"_index":888,"title":{},"content":{"78":{}},"tags":{}}],["v1.30",{"_index":1832,"title":{},"content":{"198":{}},"tags":{}}],["v1.30.11",{"_index":889,"title":{},"content":{"78":{}},"tags":{}}],["v1.31.7",{"_index":890,"title":{},"content":{"78":{}},"tags":{}}],["v1.4.4",{"_index":2334,"title":{},"content":{"385":{}},"tags":{}}],["v2",{"_index":1957,"title":{},"content":{"319":{}},"tags":{}}],["v2.0.0",{"_index":1953,"title":{},"content":{"319":{}},"tags":{}}],["v2.1.0",{"_index":1950,"title":{},"content":{"319":{}},"tags":{}}],["v2.16.3",{"_index":450,"title":{},"content":{"22":{}},"tags":{}}],["v2.19.1",{"_index":1872,"title":{"309":{}},"content":{},"tags":{}}],["v2.2",{"_index":1922,"title":{},"content":{"319":{}},"tags":{}}],["v2.2.0",{"_index":1935,"title":{},"content":{"319":{}},"tags":{}}],["v2.2.1",{"_index":1931,"title":{},"content":{"319":{}},"tags":{}}],["v2.2.2",{"_index":1927,"title":{},"content":{"319":{}},"tags":{}}],["v2.20.0",{"_index":2198,"title":{},"content":{"347":{}},"tags":{}}],["v2.3",{"_index":1923,"title":{},"content":{"319":{}},"tags":{}}],["v2.31",{"_index":2184,"title":{},"content":{"346":{}},"tags":{}}],["v2.6",{"_index":2447,"title":{},"content":{"392":{}},"tags":{}}],["v2.6.0",{"_index":1695,"title":{},"content":{"177":{},"179":{},"396":{}},"tags":{}}],["v2.7",{"_index":2449,"title":{},"content":{"392":{}},"tags":{}}],["v2.8",{"_index":2448,"title":{},"content":{"392":{}},"tags":{}}],["v3.0",{"_index":1570,"title":{},"content":{"150":{}},"tags":{}}],["v5.4",{"_index":2183,"title":{},"content":{"346":{}},"tags":{}}],["v8.30",{"_index":2187,"title":{},"content":{"346":{}},"tags":{}}],["v../helm",{"_index":2395,"title":{},"content":{"782":{}},"tags":{}}],["tink",{"_index":2224,"title":{},"content":{"756":{}},"tags":{}}],["tip",{"_index":33,"title":{},"content":{"406":{},"531":{},"533":{},"534":{},"549":{},"550":{},"740":{},"781":{},"791":{}},"tags":{}}],["tl",{"_index":211,"title":{"418":{}},"content":{"418":{},"428":{},"457":{},"527":{},"749":{},"757":{}},"tags":{}}],["tlog",{"_index":2482,"title":{},"content":{"806":{},"808":{}},"tags":{}}],["togeth",{"_index":157,"title":{"426":{}},"content":{"414":{},"419":{},"426":{},"551":{},"729":{}},"tags":{}}],["token",{"_index":713,"title":{},"content":{"457":{},"472":{},"534":{},"551":{},"552":{},"780":{}},"tags":{}}],["tool",{"_index":462,"title":{},"content":{"428":{},"460":{},"462":{},"464":{},"465":{},"466":{},"470":{},"572":{},"738":{},"740":{},"762":{},"763":{},"798":{}},"tags":{}}],["top",{"_index":1063,"title":{},"content":{"527":{}},"tags":{}}],["topolog",{"_index":1795,"title":{},"content":{"587":{}},"tags":{}}],["total",{"_index":895,"title":{},"content":{"519":{},"520":{},"521":{},"522":{},"523":{},"524":{},"705":{}},"tags":{}}],["toward",{"_index":467,"title":{},"content":{"428":{},"527":{},"562":{},"780":{}},"tags":{}}],["tpm",{"_index":110,"title":{"412":{}},"content":{"412":{},"414":{},"420":{},"421":{},"431":{},"432":{},"434":{},"554":{}},"tags":{}}],["tpm|azur",{"_index":1824,"title":{},"content":{"595":{}},"tags":{}}],["trace",{"_index":757,"title":{"466":{}},"content":{"460":{},"466":{},"467":{},"481":{},"731":{}},"tags":{}}],["track",{"_index":791,"title":{"764":{}},"content":{"463":{},"764":{}},"tags":{}}],["traffic",{"_index":640,"title":{"757":{}},"content":{"451":{},"475":{},"527":{},"744":{},"757":{}},"tags":{}}],["transfer",{"_index":698,"title":{},"content":{"454":{}},"tags":{}}],["transit",{"_index":419,"title":{},"content":{"423":{},"434":{},"480":{},"562":{},"572":{},"584":{}},"tags":{}}],["transmit",{"_index":422,"title":{},"content":{"424":{}},"tags":{}}],["transpar",{"_index":546,"title":{"807":{}},"content":{"442":{},"446":{},"452":{},"459":{},"475":{},"499":{},"500":{},"501":{},"502":{},"503":{},"504":{},"505":{},"506":{},"507":{},"508":{},"509":{},"510":{},"511":{},"512":{},"513":{},"514":{},"562":{},"563":{},"708":{},"752":{},"771":{},"772":{},"805":{},"806":{},"807":{}},"tags":{}}],["transport",{"_index":2140,"title":{},"content":{"750":{}},"tags":{}}],["tree",{"_index":596,"title":{},"content":{"437":{}},"tags":{}}],["tri",{"_index":425,"title":{},"content":{"424":{},"437":{},"456":{},"464":{},"551":{},"750":{},"767":{},"782":{}},"tags":{}}],["trigger",{"_index":1102,"title":{},"content":{"530":{},"767":{},"794":{},"798":{}},"tags":{}}],["troubleshoot",{"_index":798,"title":{"514":{},"544":{},"741":{},"776":{}},"content":{"464":{},"481":{},"499":{},"500":{},"501":{},"502":{},"503":{},"504":{},"505":{},"506":{},"507":{},"508":{},"509":{},"510":{},"511":{},"512":{},"513":{},"514":{},"750":{}},"tags":{}}],["true",{"_index":1126,"title":{},"content":{"530":{},"546":{},"551":{},"580":{},"627":{},"718":{},"722":{},"726":{},"767":{},"774":{},"786":{},"802":{}},"tags":{}}],["truli",{"_index":1559,"title":{},"content":{"562":{}},"tags":{}}],["trust",{"_index":101,"title":{"412":{},"429":{},"792":{}},"content":{"410":{},"415":{},"416":{},"417":{},"418":{},"420":{},"421":{},"422":{},"426":{},"429":{},"434":{},"435":{},"437":{},"441":{},"442":{},"484":{},"485":{},"486":{},"487":{},"488":{},"489":{},"490":{},"491":{},"492":{},"493":{},"519":{},"520":{},"521":{},"522":{},"523":{},"524":{},"527":{},"552":{},"556":{},"705":{},"745":{},"752":{},"757":{},"771":{},"781":{},"792":{},"793":{},"802":{}},"tags":{}}],["trustedlaunch|gcp",{"_index":1827,"title":{},"content":{"595":{}},"tags":{}}],["trustworthi",{"_index":71,"title":{},"content":{"408":{},"425":{},"803":{}},"tags":{}}],["truth",{"_index":416,"title":{},"content":{"423":{},"424":{},"425":{}},"tags":{}}],["tti",{"_index":1120,"title":{},"content":{"530":{}},"tags":{}}],["tuesday",{"_index":874,"title":{},"content":{"482":{}},"tags":{}}],["tunnel",{"_index":636,"title":{},"content":{"451":{},"475":{}},"tags":{}}],["turn",{"_index":536,"title":{},"content":{"442":{},"746":{}},"tags":{}}],["tutori",{"_index":1115,"title":{},"content":{"530":{}},"tags":{}}],["twitter",{"_index":2247,"title":{},"content":{"758":{},"805":{}},"tags":{}}],["two",{"_index":216,"title":{},"content":{"418":{},"421":{},"428":{},"453":{},"537":{},"551":{},"561":{},"584":{},"585":{},"675":{},"726":{},"732":{},"746":{},"762":{},"773":{},"799":{}},"tags":{}}],["ty",{"_index":274,"title":{},"content":{"420":{}},"tags":{}}],["type",{"_index":299,"title":{"601":{},"735":{}},"content":{"421":{},"499":{},"500":{},"501":{},"502":{},"503":{},"504":{},"505":{},"506":{},"507":{},"508":{},"509":{},"510":{},"511":{},"512":{},"513":{},"514":{},"529":{},"534":{},"540":{},"585":{},"588":{},"601":{},"602":{},"603":{},"717":{},"733":{},"735":{},"736":{},"738":{},"742":{},"743":{},"744":{},"759":{},"761":{},"762":{},"771":{},"772":{},"773":{},"792":{},"803":{}},"tags":{}}],["type='merg",{"_index":2289,"title":{},"content":{"767":{}},"tags":{}}],["type==\"secureboot",{"_index":2356,"title":{},"content":{"789":{}},"tags":{}}],["type==\"x",{"_index":2349,"title":{},"content":{"789":{}},"tags":{}}],["typic",{"_index":127,"title":{},"content":{"412":{},"413":{},"414":{},"470":{},"563":{}},"tags":{}}],["u",{"_index":1835,"title":{},"content":{"599":{},"647":{}},"tags":{}}],["u$url",{"_index":2443,"title":{},"content":{"793":{}},"tags":{}}],["u.",{"_index":2278,"title":{},"content":{"764":{}},"tags":{}}],["uami",{"_index":1896,"title":{},"content":{"718":{}},"tags":{}}],["uat",{"_index":1204,"title":{},"content":{"534":{},"551":{},"552":{}},"tags":{}}],["ubuntu",{"_index":1249,"title":{"539":{}},"content":{"538":{},"746":{}},"tags":{}}],["udp",{"_index":1714,"title":{},"content":{"584":{}},"tags":{}}],["ui",{"_index":1072,"title":{},"content":{"527":{},"786":{}},"tags":{}}],["uid",{"_index":1886,"title":{},"content":{"713":{},"750":{}},"tags":{}}],["uid=\"/library/appl",{"_index":1478,"title":{},"content":{"552":{}},"tags":{}}],["usr/bin/env",{"_index":1874,"title":{},"content":{"713":{}},"tags":{}}],["usr/local/bin/constel",{"_index":1277,"title":{},"content":{"539":{},"549":{}},"tags":{}}],["usual",{"_index":250,"title":{},"content":{"420":{},"441":{},"463":{},"482":{},"483":{},"546":{},"729":{},"750":{},"798":{}},"tags":{}}],["util",{"_index":563,"title":{},"content":{"444":{},"461":{},"569":{},"576":{},"789":{}},"tags":{}}],["uuid",{"_index":2055,"title":{},"content":{"738":{},"806":{},"807":{}},"tags":{}}],["uuid=362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13",{"_index":2487,"title":{},"content":{"807":{}},"tags":{}}],["v",{"_index":891,"title":{},"content":{"484":{},"485":{},"486":{},"487":{},"488":{},"489":{},"490":{},"491":{},"492":{},"493":{}},"tags":{}}],["v/svm",{"_index":1247,"title":{},"content":{"538":{}},"tags":{}}],["v1",{"_index":1109,"title":{},"content":{"530":{},"738":{},"773":{}},"tags":{}}],["v1.10.0",{"_index":2463,"title":{},"content":{"799":{}},"tags":{}}],["v1.12",{"_index":1695,"title":{},"content":{"580":{}},"tags":{}}],["v1.12.1",{"_index":2462,"title":{},"content":{"799":{}},"tags":{}}],["v1.24.6",{"_index":1291,"title":{},"content":{"541":{}},"tags":{}}],["v1.24.9",{"_index":1703,"title":{},"content":{"581":{},"582":{}},"tags":{}}],["v1.25.7",{"_index":1694,"title":{},"content":{"580":{}},"tags":{}}],["v1.25.8",{"_index":2461,"title":{},"content":{"799":{}},"tags":{}}],["v1.29.15",{"_index":888,"title":{},"content":{"483":{}},"tags":{}}],["v1.30",{"_index":1831,"title":{},"content":{"595":{}},"tags":{}}],["v1.30.12",{"_index":889,"title":{},"content":{"483":{}},"tags":{}}],["v1.31.8",{"_index":890,"title":{},"content":{"483":{}},"tags":{}}],["v1.4.4",{"_index":2337,"title":{},"content":{"788":{}},"tags":{}}],["v2",{"_index":1957,"title":{},"content":{"722":{}},"tags":{}}],["v2.0.0",{"_index":1953,"title":{},"content":{"722":{}},"tags":{}}],["v2.1.0",{"_index":1950,"title":{},"content":{"722":{}},"tags":{}}],["v2.16.3",{"_index":450,"title":{},"content":{"427":{}},"tags":{}}],["v2.19.1",{"_index":1872,"title":{"712":{}},"content":{},"tags":{}}],["v2.2",{"_index":1922,"title":{},"content":{"722":{}},"tags":{}}],["v2.2.0",{"_index":1935,"title":{},"content":{"722":{}},"tags":{}}],["v2.2.1",{"_index":1931,"title":{},"content":{"722":{}},"tags":{}}],["v2.2.2",{"_index":1927,"title":{},"content":{"722":{}},"tags":{}}],["v2.20.0",{"_index":2199,"title":{},"content":{"747":{}},"tags":{}}],["v2.23.0",{"_index":1871,"title":{"710":{}},"content":{},"tags":{}}],["v2.3",{"_index":1923,"title":{},"content":{"722":{}},"tags":{}}],["v2.31",{"_index":2185,"title":{},"content":{"746":{}},"tags":{}}],["v2.6",{"_index":2449,"title":{},"content":{"795":{}},"tags":{}}],["v2.6.0",{"_index":1691,"title":{},"content":{"578":{},"580":{},"799":{}},"tags":{}}],["v2.7",{"_index":2451,"title":{},"content":{"795":{}},"tags":{}}],["v2.8",{"_index":2450,"title":{},"content":{"795":{}},"tags":{}}],["v5.4",{"_index":2183,"title":{},"content":{"746":{}},"tags":{}}],["v8.30",{"_index":2188,"title":{},"content":{"746":{}},"tags":{}}],["v../helm",{"_index":2387,"title":{},"content":{"1589":{}},"tags":{}}],["tink",{"_index":2216,"title":{},"content":{"1554":{}},"tags":{}}],["tip",{"_index":1119,"title":{},"content":{"1332":{},"1344":{},"1345":{},"1350":{},"1351":{},"1542":{},"1581":{},"1588":{},"1611":{}},"tags":{}}],["tl",{"_index":140,"title":{"1216":{}},"content":{"1216":{},"1226":{},"1255":{},"1333":{},"1547":{},"1555":{}},"tags":{}}],["tlog",{"_index":2476,"title":{},"content":{"1608":{},"1610":{}},"tags":{}}],["togeth",{"_index":76,"title":{"1224":{}},"content":{"1212":{},"1217":{},"1224":{},"1352":{},"1526":{}},"tags":{}}],["token",{"_index":677,"title":{},"content":{"1255":{},"1263":{},"1345":{},"1352":{},"1353":{},"1587":{}},"tags":{}}],["tool",{"_index":410,"title":{},"content":{"1226":{},"1261":{},"1272":{},"1274":{},"1276":{},"1277":{},"1278":{},"1374":{},"1540":{},"1542":{},"1564":{},"1565":{},"1600":{}},"tags":{}}],["top",{"_index":1042,"title":{},"content":{"1333":{}},"tags":{}}],["topolog",{"_index":1781,"title":{},"content":{"1380":{}},"tags":{}}],["total",{"_index":865,"title":{},"content":{"1292":{},"1293":{},"1294":{},"1295":{},"1296":{},"1297":{},"1390":{}},"tags":{}}],["toward",{"_index":415,"title":{},"content":{"1226":{},"1333":{},"1357":{},"1587":{}},"tags":{}}],["tpm",{"_index":18,"title":{"1210":{}},"content":{"1210":{},"1212":{},"1218":{},"1219":{},"1229":{},"1230":{},"1239":{},"1363":{}},"tags":{}}],["tpm|azur",{"_index":1813,"title":{},"content":{"1401":{}},"tags":{}}],["trace",{"_index":722,"title":{"1278":{}},"content":{"1271":{},"1272":{},"1278":{},"1279":{},"1528":{}},"tags":{}}],["track",{"_index":756,"title":{"1566":{}},"content":{"1275":{},"1566":{}},"tags":{}}],["traffic",{"_index":600,"title":{"1555":{}},"content":{"1249":{},"1258":{},"1333":{},"1546":{},"1555":{}},"tags":{}}],["transfer",{"_index":661,"title":{},"content":{"1252":{}},"tags":{}}],["transit",{"_index":363,"title":{},"content":{"1221":{},"1239":{},"1270":{},"1357":{},"1374":{},"1387":{}},"tags":{}}],["transmit",{"_index":366,"title":{},"content":{"1222":{}},"tags":{}}],["transpar",{"_index":503,"title":{"1609":{}},"content":{"1233":{},"1237":{},"1250":{},"1257":{},"1258":{},"1307":{},"1308":{},"1309":{},"1310":{},"1311":{},"1312":{},"1313":{},"1314":{},"1315":{},"1316":{},"1317":{},"1318":{},"1319":{},"1320":{},"1321":{},"1322":{},"1357":{},"1358":{},"1393":{},"1550":{},"1573":{},"1574":{},"1607":{},"1608":{},"1609":{}},"tags":{}}],["transport",{"_index":2132,"title":{},"content":{"1548":{}},"tags":{}}],["tree",{"_index":556,"title":{},"content":{"1242":{}},"tags":{}}],["tri",{"_index":369,"title":{},"content":{"1222":{},"1242":{},"1254":{},"1276":{},"1352":{},"1548":{},"1569":{},"1589":{}},"tags":{}}],["trigger",{"_index":1081,"title":{},"content":{"1331":{},"1569":{},"1596":{},"1600":{}},"tags":{}}],["troubleshoot",{"_index":763,"title":{"1322":{},"1342":{},"1543":{},"1583":{}},"content":{"1271":{},"1276":{},"1307":{},"1308":{},"1309":{},"1310":{},"1311":{},"1312":{},"1313":{},"1314":{},"1315":{},"1316":{},"1317":{},"1318":{},"1319":{},"1320":{},"1321":{},"1322":{},"1548":{}},"tags":{}}],["true",{"_index":1106,"title":{},"content":{"1331":{},"1352":{},"1355":{},"1383":{},"1433":{},"1520":{},"1524":{},"1532":{},"1569":{},"1576":{},"1593":{},"1604":{}},"tags":{}}],["truli",{"_index":1543,"title":{},"content":{"1357":{}},"tags":{}}],["trust",{"_index":7,"title":{"1210":{},"1227":{},"1594":{}},"content":{"1208":{},"1213":{},"1214":{},"1215":{},"1216":{},"1218":{},"1219":{},"1220":{},"1224":{},"1227":{},"1232":{},"1233":{},"1239":{},"1240":{},"1242":{},"1282":{},"1283":{},"1284":{},"1285":{},"1286":{},"1287":{},"1288":{},"1289":{},"1290":{},"1291":{},"1292":{},"1293":{},"1294":{},"1295":{},"1296":{},"1297":{},"1333":{},"1353":{},"1365":{},"1390":{},"1550":{},"1555":{},"1556":{},"1573":{},"1588":{},"1594":{},"1595":{},"1604":{}},"tags":{}}],["trustedlaunch|gcp",{"_index":1816,"title":{},"content":{"1401":{}},"tags":{}}],["trustworthi",{"_index":378,"title":{},"content":{"1223":{},"1605":{},"1613":{}},"tags":{}}],["truth",{"_index":360,"title":{},"content":{"1221":{},"1222":{},"1223":{}},"tags":{}}],["tti",{"_index":1100,"title":{},"content":{"1331":{}},"tags":{}}],["tuesday",{"_index":843,"title":{},"content":{"1280":{}},"tags":{}}],["tunnel",{"_index":596,"title":{},"content":{"1249":{},"1258":{}},"tags":{}}],["turn",{"_index":493,"title":{},"content":{"1233":{},"1557":{}},"tags":{}}],["tutori",{"_index":1095,"title":{},"content":{"1331":{}},"tags":{}}],["twitter",{"_index":2239,"title":{},"content":{"1560":{},"1607":{}},"tags":{}}],["two",{"_index":145,"title":{},"content":{"1216":{},"1219":{},"1226":{},"1251":{},"1335":{},"1352":{},"1356":{},"1387":{},"1388":{},"1481":{},"1532":{},"1534":{},"1557":{},"1564":{},"1575":{},"1601":{}},"tags":{}}],["ty",{"_index":212,"title":{},"content":{"1218":{}},"tags":{}}],["type",{"_index":239,"title":{"1407":{},"1537":{}},"content":{"1219":{},"1307":{},"1308":{},"1309":{},"1310":{},"1311":{},"1312":{},"1313":{},"1314":{},"1315":{},"1316":{},"1317":{},"1318":{},"1319":{},"1320":{},"1321":{},"1322":{},"1330":{},"1338":{},"1345":{},"1388":{},"1394":{},"1407":{},"1408":{},"1409":{},"1519":{},"1535":{},"1537":{},"1538":{},"1540":{},"1544":{},"1545":{},"1546":{},"1561":{},"1563":{},"1564":{},"1573":{},"1574":{},"1575":{},"1594":{},"1605":{}},"tags":{}}],["type='merg",{"_index":2281,"title":{},"content":{"1569":{}},"tags":{}}],["type==\"secureboot",{"_index":2348,"title":{},"content":{"1579":{}},"tags":{}}],["type==\"x",{"_index":2341,"title":{},"content":{"1579":{}},"tags":{}}],["typic",{"_index":40,"title":{},"content":{"1210":{},"1211":{},"1212":{},"1261":{},"1358":{}},"tags":{}}],["u",{"_index":1824,"title":{},"content":{"1405":{},"1453":{}},"tags":{}}],["u$url",{"_index":2437,"title":{},"content":{"1595":{}},"tags":{}}],["u.",{"_index":2270,"title":{},"content":{"1566":{}},"tags":{}}],["uami",{"_index":1886,"title":{},"content":{"1520":{}},"tags":{}}],["uat",{"_index":1185,"title":{},"content":{"1345":{},"1352":{},"1353":{}},"tags":{}}],["ubuntu",{"_index":1230,"title":{"1337":{}},"content":{"1336":{},"1557":{}},"tags":{}}],["udp",{"_index":1700,"title":{},"content":{"1387":{}},"tags":{}}],["ui",{"_index":1051,"title":{},"content":{"1333":{},"1593":{}},"tags":{}}],["uid",{"_index":1876,"title":{},"content":{"1515":{},"1548":{}},"tags":{}}],["uid=\"/library/appl",{"_index":1461,"title":{},"content":{"1353":{}},"tags":{}}],["usr/bin/env",{"_index":1864,"title":{},"content":{"1515":{}},"tags":{}}],["usr/local/bin/constel",{"_index":1258,"title":{},"content":{"1337":{},"1350":{}},"tags":{}}],["usual",{"_index":185,"title":{},"content":{"1218":{},"1232":{},"1275":{},"1280":{},"1281":{},"1355":{},"1526":{},"1548":{},"1600":{}},"tags":{}}],["util",{"_index":520,"title":{},"content":{"1235":{},"1273":{},"1361":{},"1378":{},"1579":{}},"tags":{}}],["uuid",{"_index":2045,"title":{},"content":{"1540":{},"1608":{},"1609":{}},"tags":{}}],["uuid=362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13",{"_index":2481,"title":{},"content":{"1609":{}},"tags":{}}],["v",{"_index":860,"title":{},"content":{"1282":{},"1283":{},"1284":{},"1285":{},"1286":{},"1287":{},"1288":{},"1289":{},"1290":{},"1291":{}},"tags":{}}],["v/svm",{"_index":1228,"title":{},"content":{"1336":{}},"tags":{}}],["v1",{"_index":1088,"title":{},"content":{"1331":{},"1540":{},"1575":{}},"tags":{}}],["v1.10.0",{"_index":2457,"title":{},"content":{"1601":{}},"tags":{}}],["v1.12",{"_index":1681,"title":{},"content":{"1383":{}},"tags":{}}],["v1.12.1",{"_index":2456,"title":{},"content":{"1601":{}},"tags":{}}],["v1.24.6",{"_index":1272,"title":{},"content":{"1339":{}},"tags":{}}],["v1.24.9",{"_index":1689,"title":{},"content":{"1384":{},"1385":{}},"tags":{}}],["v1.25.7",{"_index":1680,"title":{},"content":{"1383":{}},"tags":{}}],["v1.25.8",{"_index":2455,"title":{},"content":{"1601":{}},"tags":{}}],["v1.30.14",{"_index":857,"title":{},"content":{"1281":{}},"tags":{}}],["v1.31",{"_index":1820,"title":{},"content":{"1401":{}},"tags":{}}],["v1.31.12",{"_index":858,"title":{},"content":{"1281":{}},"tags":{}}],["v1.32.8",{"_index":859,"title":{},"content":{"1281":{}},"tags":{}}],["v1.4.4",{"_index":2329,"title":{},"content":{"1578":{}},"tags":{}}],["v2",{"_index":1947,"title":{},"content":{"1524":{}},"tags":{}}],["v2.0.0",{"_index":1943,"title":{},"content":{"1524":{}},"tags":{}}],["v2.1.0",{"_index":1940,"title":{},"content":{"1524":{}},"tags":{}}],["v2.16.3",{"_index":398,"title":{},"content":{"1225":{}},"tags":{}}],["v2.19.1",{"_index":1862,"title":{"1514":{}},"content":{},"tags":{}}],["v2.2",{"_index":1912,"title":{},"content":{"1524":{}},"tags":{}}],["v2.2.0",{"_index":1925,"title":{},"content":{"1524":{}},"tags":{}}],["v2.2.1",{"_index":1921,"title":{},"content":{"1524":{}},"tags":{}}],["v2.2.2",{"_index":1917,"title":{},"content":{"1524":{}},"tags":{}}],["v2.20.0",{"_index":2191,"title":{},"content":{"1558":{}},"tags":{}}],["v2.23.0",{"_index":1861,"title":{"1512":{}},"content":{},"tags":{}}],["v2.3",{"_index":1913,"title":{},"content":{"1524":{}},"tags":{}}],["v2.31",{"_index":2177,"title":{},"content":{"1557":{}},"tags":{}}],["v2.6",{"_index":2443,"title":{},"content":{"1597":{}},"tags":{}}],["v2.6.0",{"_index":1677,"title":{},"content":{"1381":{},"1383":{},"1601":{}},"tags":{}}],["v2.7",{"_index":2445,"title":{},"content":{"1597":{}},"tags":{}}],["v2.8",{"_index":2444,"title":{},"content":{"1597":{}},"tags":{}}],["v5.4",{"_index":2175,"title":{},"content":{"1557":{}},"tags":{}}],["v8.30",{"_index":2180,"title":{},"content":{"1557":{}},"tags":{}}],["v../helm",{"_index":2398,"title":{},"content":{"1190":{}},"tags":{}}],["tink",{"_index":2227,"title":{},"content":{"1155":{}},"tags":{}}],["tip",{"_index":51,"title":{},"content":{"809":{},"934":{},"935":{},"936":{},"952":{},"953":{},"1135":{},"1183":{},"1189":{}},"tags":{}}],["tl",{"_index":227,"title":{"828":{}},"content":{"828":{},"838":{},"861":{},"930":{},"1138":{},"1156":{}},"tags":{}}],["tlog",{"_index":2486,"title":{},"content":{"1324":{},"1326":{}},"tags":{}}],["togeth",{"_index":174,"title":{"836":{}},"content":{"824":{},"829":{},"836":{},"954":{},"1132":{}},"tags":{}}],["token",{"_index":720,"title":{},"content":{"861":{},"876":{},"936":{},"954":{},"955":{},"1188":{}},"tags":{}}],["tool",{"_index":471,"title":{},"content":{"838":{},"864":{},"866":{},"868":{},"869":{},"870":{},"874":{},"975":{},"1135":{},"1149":{},"1165":{},"1166":{},"1205":{}},"tags":{}}],["top",{"_index":1069,"title":{},"content":{"930":{}},"tags":{}}],["topolog",{"_index":1800,"title":{},"content":{"981":{}},"tags":{}}],["total",{"_index":902,"title":{},"content":{"897":{},"898":{},"899":{},"900":{},"901":{},"902":{},"1108":{}},"tags":{}}],["toward",{"_index":476,"title":{},"content":{"838":{},"930":{},"965":{},"1188":{}},"tags":{}}],["tpm",{"_index":127,"title":{"822":{}},"content":{"822":{},"824":{},"830":{},"831":{},"841":{},"842":{},"844":{},"957":{}},"tags":{}}],["tpm|azur",{"_index":1828,"title":{},"content":{"998":{}},"tags":{}}],["trace",{"_index":764,"title":{"870":{}},"content":{"864":{},"870":{},"871":{},"884":{},"1134":{}},"tags":{}}],["track",{"_index":798,"title":{"1167":{}},"content":{"867":{},"1167":{}},"tags":{}}],["traffic",{"_index":648,"title":{"1156":{}},"content":{"854":{},"858":{},"930":{},"1143":{},"1156":{}},"tags":{}}],["transfer",{"_index":705,"title":{},"content":{"857":{}},"tags":{}}],["transit",{"_index":432,"title":{},"content":{"833":{},"844":{},"883":{},"965":{},"975":{},"988":{}},"tags":{}}],["transmit",{"_index":435,"title":{},"content":{"834":{}},"tags":{}}],["transpar",{"_index":555,"title":{"1325":{}},"content":{"815":{},"819":{},"855":{},"858":{},"863":{},"913":{},"914":{},"915":{},"916":{},"917":{},"918":{},"919":{},"920":{},"921":{},"922":{},"923":{},"924":{},"925":{},"926":{},"927":{},"928":{},"965":{},"966":{},"1111":{},"1151":{},"1169":{},"1170":{},"1323":{},"1324":{},"1325":{}},"tags":{}}],["transport",{"_index":2144,"title":{},"content":{"1139":{}},"tags":{}}],["tree",{"_index":605,"title":{},"content":{"847":{}},"tags":{}}],["tri",{"_index":438,"title":{},"content":{"834":{},"847":{},"860":{},"868":{},"954":{},"1139":{},"1175":{},"1190":{}},"tags":{}}],["trigger",{"_index":1108,"title":{},"content":{"933":{},"1175":{},"1201":{},"1205":{}},"tags":{}}],["troubleshoot",{"_index":805,"title":{"928":{},"946":{},"1136":{},"1184":{}},"content":{"868":{},"884":{},"913":{},"914":{},"915":{},"916":{},"917":{},"918":{},"919":{},"920":{},"921":{},"922":{},"923":{},"924":{},"925":{},"926":{},"927":{},"928":{},"1139":{}},"tags":{}}],["true",{"_index":1132,"title":{},"content":{"933":{},"948":{},"954":{},"984":{},"1030":{},"1121":{},"1125":{},"1129":{},"1172":{},"1175":{},"1194":{},"1198":{}},"tags":{}}],["truli",{"_index":1565,"title":{},"content":{"965":{}},"tags":{}}],["trust",{"_index":118,"title":{"822":{},"839":{},"1195":{}},"content":{"814":{},"815":{},"820":{},"825":{},"826":{},"827":{},"828":{},"830":{},"831":{},"832":{},"836":{},"839":{},"844":{},"845":{},"847":{},"887":{},"888":{},"889":{},"890":{},"891":{},"892":{},"893":{},"894":{},"895":{},"896":{},"897":{},"898":{},"899":{},"900":{},"901":{},"902":{},"930":{},"955":{},"959":{},"1108":{},"1151":{},"1156":{},"1157":{},"1169":{},"1189":{},"1195":{},"1196":{},"1198":{}},"tags":{}}],["trustedlaunch|gcp",{"_index":1831,"title":{},"content":{"998":{}},"tags":{}}],["trustworthi",{"_index":88,"title":{},"content":{"811":{},"835":{},"1199":{}},"tags":{}}],["truth",{"_index":429,"title":{},"content":{"833":{},"834":{},"835":{}},"tags":{}}],["tti",{"_index":1126,"title":{},"content":{"933":{}},"tags":{}}],["tuesday",{"_index":881,"title":{},"content":{"885":{}},"tags":{}}],["tunnel",{"_index":644,"title":{},"content":{"854":{},"858":{}},"tags":{}}],["turn",{"_index":545,"title":{},"content":{"815":{},"1158":{}},"tags":{}}],["tutori",{"_index":1121,"title":{},"content":{"933":{}},"tags":{}}],["twitter",{"_index":2250,"title":{},"content":{"1161":{},"1323":{}},"tags":{}}],["two",{"_index":232,"title":{},"content":{"828":{},"831":{},"838":{},"856":{},"939":{},"954":{},"964":{},"988":{},"989":{},"1078":{},"1129":{},"1137":{},"1158":{},"1165":{},"1171":{},"1206":{}},"tags":{}}],["ty",{"_index":290,"title":{},"content":{"830":{}},"tags":{}}],["type",{"_index":314,"title":{"1004":{},"1146":{}},"content":{"831":{},"913":{},"914":{},"915":{},"916":{},"917":{},"918":{},"919":{},"920":{},"921":{},"922":{},"923":{},"924":{},"925":{},"926":{},"927":{},"928":{},"932":{},"936":{},"942":{},"989":{},"991":{},"1004":{},"1005":{},"1006":{},"1120":{},"1141":{},"1142":{},"1143":{},"1144":{},"1146":{},"1147":{},"1149":{},"1162":{},"1164":{},"1165":{},"1169":{},"1170":{},"1171":{},"1195":{},"1199":{}},"tags":{}}],["type='merg",{"_index":2292,"title":{},"content":{"1175":{}},"tags":{}}],["type==\"secureboot",{"_index":2359,"title":{},"content":{"1181":{}},"tags":{}}],["type==\"x",{"_index":2352,"title":{},"content":{"1181":{}},"tags":{}}],["typic",{"_index":144,"title":{},"content":{"822":{},"823":{},"824":{},"874":{},"966":{}},"tags":{}}],["u",{"_index":1839,"title":{},"content":{"1002":{},"1050":{}},"tags":{}}],["u$url",{"_index":2447,"title":{},"content":{"1196":{}},"tags":{}}],["u.",{"_index":2281,"title":{},"content":{"1167":{}},"tags":{}}],["uami",{"_index":1900,"title":{},"content":{"1121":{}},"tags":{}}],["uat",{"_index":1210,"title":{},"content":{"936":{},"954":{},"955":{}},"tags":{}}],["ubuntu",{"_index":1255,"title":{"941":{}},"content":{"940":{},"1158":{}},"tags":{}}],["udp",{"_index":1719,"title":{},"content":{"988":{}},"tags":{}}],["ui",{"_index":1078,"title":{},"content":{"930":{},"1194":{}},"tags":{}}],["uid",{"_index":1890,"title":{},"content":{"1116":{},"1139":{}},"tags":{}}],["uid=\"/library/appl",{"_index":1484,"title":{},"content":{"955":{}},"tags":{}}],["usr/bin/env",{"_index":1878,"title":{},"content":{"1116":{}},"tags":{}}],["usr/local/bin/constel",{"_index":1283,"title":{},"content":{"941":{},"952":{}},"tags":{}}],["usual",{"_index":266,"title":{},"content":{"814":{},"830":{},"867":{},"885":{},"886":{},"948":{},"1132":{},"1139":{},"1205":{}},"tags":{}}],["util",{"_index":572,"title":{},"content":{"817":{},"865":{},"972":{},"979":{},"1181":{}},"tags":{}}],["uuid",{"_index":2059,"title":{},"content":{"1149":{},"1324":{},"1325":{}},"tags":{}}],["uuid=362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13",{"_index":2491,"title":{},"content":{"1325":{}},"tags":{}}],["v",{"_index":898,"title":{},"content":{"887":{},"888":{},"889":{},"890":{},"891":{},"892":{},"893":{},"894":{},"895":{},"896":{}},"tags":{}}],["v/svm",{"_index":1253,"title":{},"content":{"940":{}},"tags":{}}],["v1",{"_index":1115,"title":{},"content":{"933":{},"1149":{},"1171":{}},"tags":{}}],["v1.10.0",{"_index":2467,"title":{},"content":{"1206":{}},"tags":{}}],["v1.12",{"_index":1700,"title":{},"content":{"984":{}},"tags":{}}],["v1.12.1",{"_index":2466,"title":{},"content":{"1206":{}},"tags":{}}],["v1.24.6",{"_index":1297,"title":{},"content":{"943":{}},"tags":{}}],["v1.24.9",{"_index":1708,"title":{},"content":{"985":{},"986":{}},"tags":{}}],["v1.25.7",{"_index":1699,"title":{},"content":{"984":{}},"tags":{}}],["v1.25.8",{"_index":2465,"title":{},"content":{"1206":{}},"tags":{}}],["v1.30.14",{"_index":895,"title":{},"content":{"886":{}},"tags":{}}],["v1.31",{"_index":1835,"title":{},"content":{"998":{}},"tags":{}}],["v1.31.13",{"_index":896,"title":{},"content":{"886":{}},"tags":{}}],["v1.32.9",{"_index":897,"title":{},"content":{"886":{}},"tags":{}}],["v1.4.4",{"_index":2340,"title":{},"content":{"1180":{}},"tags":{}}],["v2",{"_index":1961,"title":{},"content":{"1125":{}},"tags":{}}],["v2.0.0",{"_index":1957,"title":{},"content":{"1125":{}},"tags":{}}],["v2.1.0",{"_index":1954,"title":{},"content":{"1125":{}},"tags":{}}],["v2.16.3",{"_index":459,"title":{},"content":{"837":{}},"tags":{}}],["v2.19.1",{"_index":1876,"title":{"1115":{}},"content":{},"tags":{}}],["v2.2",{"_index":1926,"title":{},"content":{"1125":{}},"tags":{}}],["v2.2.0",{"_index":1939,"title":{},"content":{"1125":{}},"tags":{}}],["v2.2.1",{"_index":1935,"title":{},"content":{"1125":{}},"tags":{}}],["v2.2.2",{"_index":1931,"title":{},"content":{"1125":{}},"tags":{}}],["v2.20.0",{"_index":2203,"title":{},"content":{"1159":{}},"tags":{}}],["v2.23.0",{"_index":1875,"title":{"1113":{}},"content":{},"tags":{}}],["v2.3",{"_index":1927,"title":{},"content":{"1125":{}},"tags":{}}],["v2.31",{"_index":2189,"title":{},"content":{"1158":{}},"tags":{}}],["v2.6",{"_index":2453,"title":{},"content":{"1202":{}},"tags":{}}],["v2.6.0",{"_index":1696,"title":{},"content":{"982":{},"984":{},"1206":{}},"tags":{}}],["v2.7",{"_index":2455,"title":{},"content":{"1202":{}},"tags":{}}],["v2.8",{"_index":2454,"title":{},"content":{"1202":{}},"tags":{}}],["v5.4",{"_index":2187,"title":{},"content":{"1158":{}},"tags":{}}],["v8.30",{"_index":2192,"title":{},"content":{"1158":{}},"tags":{}}],["v..https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/weekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/architecture/attestationweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/architecture/encrypted-storageweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/architecture/imagesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/architecture/keysweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/architecture/microservicesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/architecture/networkingweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/architecture/observabilityweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/architecture/orchestrationweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/architecture/overviewweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/architecture/versionsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/category/architectureweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/category/basicsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/category/getting-startedweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/category/referenceweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/category/workflowsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/getting-started/examplesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/getting-started/examples/emojivotoweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/getting-started/examples/filestash-s3proxyweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/getting-started/examples/horizontal-scalingweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/getting-started/examples/online-boutiqueweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/getting-started/first-stepsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/getting-started/first-steps-localweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/getting-started/installweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/getting-started/marketplacesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/overview/cloudsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/overview/confidential-kubernetesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/overview/licenseweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/overview/performance/weekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/overview/performance/applicationweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/overview/performance/computeweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/overview/performance/ioweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/overview/productweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/overview/security-benefitsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/reference/cliweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/reference/migrationweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/reference/slsaweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/reference/terraformweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/workflows/cert-managerweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/workflows/configweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/workflows/createweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/workflows/lbweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/workflows/recoveryweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/workflows/reproducible-buildsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/workflows/s3proxyweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/workflows/sbomweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/workflows/scaleweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/workflows/storageweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/workflows/terminateweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/workflows/terraform-providerweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/workflows/troubleshootingweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/workflows/trusted-launchweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/workflows/upgradeweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/workflows/verify-cliweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.22/workflows/verify-clusterweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/weekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/architecture/attestationweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/architecture/encrypted-storageweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/architecture/imagesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/architecture/keysweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/architecture/microservicesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/architecture/networkingweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/architecture/observabilityweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/architecture/orchestrationweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/architecture/overviewweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/architecture/versionsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/category/architectureweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/category/basicsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/category/getting-startedweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/category/referenceweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/category/workflowsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/getting-started/examplesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/getting-started/examples/emojivotoweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/getting-started/examples/filestash-s3proxyweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/getting-started/examples/horizontal-scalingweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/getting-started/examples/online-boutiqueweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/getting-started/first-stepsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/getting-started/first-steps-localweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/getting-started/installweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/getting-started/marketplacesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/overview/cloudsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/overview/confidential-kubernetesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/overview/licenseweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/overview/performance/weekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/overview/performance/applicationweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/overview/performance/computeweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/overview/performance/ioweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/overview/productweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/overview/security-benefitsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/reference/cliweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/reference/migrationweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/reference/slsaweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/reference/terraformweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/workflows/cert-managerweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/workflows/configweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/workflows/createweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/workflows/lbweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/workflows/recoveryweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/workflows/reproducible-buildsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/workflows/s3proxyweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/workflows/sbomweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/workflows/scaleweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/workflows/storageweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/workflows/terminateweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/workflows/terraform-providerweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/workflows/troubleshootingweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/workflows/trusted-launchweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/workflows/upgradeweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/workflows/verify-cliweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/2.23/workflows/verify-clusterweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/weekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/architecture/attestationweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/architecture/encrypted-storageweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/architecture/imagesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/architecture/keysweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/architecture/microservicesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/architecture/networkingweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/architecture/observabilityweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/architecture/orchestrationweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/architecture/overviewweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/architecture/versionsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/category/architectureweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/category/basicsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/category/getting-startedweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/category/referenceweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/category/workflowsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/getting-started/examplesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/getting-started/examples/emojivotoweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/getting-started/examples/filestash-s3proxyweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/getting-started/examples/horizontal-scalingweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/getting-started/examples/online-boutiqueweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/getting-started/first-stepsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/getting-started/first-steps-localweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/getting-started/installweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/getting-started/marketplacesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/overview/cloudsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/overview/confidential-kubernetesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/overview/licenseweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/overview/performance/weekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/overview/performance/applicationweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/overview/performance/computeweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/overview/performance/ioweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/overview/productweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/overview/security-benefitsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/reference/cliweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/reference/migrationweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/reference/slsaweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/reference/terraformweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/workflows/cert-managerweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/workflows/configweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/workflows/createweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/workflows/lbweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/workflows/recoveryweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/workflows/reproducible-buildsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/workflows/s3proxyweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/workflows/sbomweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/workflows/scaleweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/workflows/storageweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/workflows/terminateweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/workflows/terraform-providerweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/workflows/troubleshootingweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/workflows/trusted-launchweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/workflows/upgradeweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/workflows/verify-cliweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/next/workflows/verify-clusterweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/architecture/attestationweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/architecture/encrypted-storageweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/architecture/imagesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/architecture/keysweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/architecture/microservicesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/architecture/networkingweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/architecture/observabilityweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/architecture/orchestrationweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/architecture/overviewweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/architecture/versionsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/category/architectureweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/category/basicsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/category/getting-startedweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/category/referenceweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/category/workflowsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/getting-started/examplesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/getting-started/examples/emojivotoweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/getting-started/examples/filestash-s3proxyweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/getting-started/examples/horizontal-scalingweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/getting-started/examples/online-boutiqueweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/getting-started/first-stepsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/getting-started/first-steps-localweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/getting-started/installweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/getting-started/marketplacesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/overview/cloudsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/overview/confidential-kubernetesweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/overview/licenseweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/overview/performance/weekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/overview/performance/applicationweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/overview/performance/computeweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/overview/performance/ioweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/overview/productweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/overview/security-benefitsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/reference/cliweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/reference/migrationweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/reference/slsaweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/reference/terraformweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/workflows/cert-managerweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/workflows/configweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/workflows/createweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/workflows/lbweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/workflows/recoveryweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/workflows/reproducible-buildsweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/workflows/s3proxyweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/workflows/sbomweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/workflows/scaleweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/workflows/storageweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/workflows/terminateweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/workflows/terraform-providerweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/workflows/troubleshootingweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/workflows/trusted-launchweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/workflows/upgradeweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/workflows/verify-cliweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/workflows/verify-clusterweekly0.5https://docs.edgeless.systems/constellation/pr-preview/pr-4027/weekly0.5 \ No newline at end of file diff --git a/pr-preview/pr-4027/workflows/cert-manager/index.html b/pr-preview/pr-4027/workflows/cert-manager/index.html deleted file mode 100644 index 31a34d20a..000000000 --- a/pr-preview/pr-4027/workflows/cert-manager/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - -Install cert-manager | Constellation - - - - - - - -
    Version: 2.24

    Install cert-manager

    -
    caution

    If you want to use cert-manager with Constellation, pay attention to the following to avoid potential pitfalls.

    -

    Constellation ships with cert-manager preinstalled. -The default installation is part of the kube-system namespace, as all other Constellation-managed microservices. -You are free to install more instances of cert-manager into other namespaces. -However, be aware that any new installation needs to use the same version as the one installed with Constellation or rely on the same CRD versions. -Also remember to set the installCRDs value to false when installing new cert-manager instances. -It will create problems if you have two installations of cert-manager depending on different versions of the installed CRDs. -CRDs are cluster-wide resources and cert-manager depends on specific versions of those CRDs for each release.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/workflows/config/index.html b/pr-preview/pr-4027/workflows/config/index.html deleted file mode 100644 index 1cd7e8237..000000000 --- a/pr-preview/pr-4027/workflows/config/index.html +++ /dev/null @@ -1,162 +0,0 @@ - - - - - -Configure your cluster | Constellation - - - - - - - -
    Version: 2.24

    Configure your cluster

    -
    info

    This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details.

    -
    Loading asciinema cast...
    -
    -

    Before you can create your cluster, you need to configure the identity and access management (IAM) for your cloud service provider (CSP) and choose machine types for the nodes.

    -

    Creating the configuration file

    -

    You can generate a configuration file for your CSP by using the following CLI command:

    -
    constellation config generate aws
    -

    This creates the file constellation-conf.yaml in the current directory.

    -

    Choosing a VM type

    -

    Constellation supports the following VM types:

    -

    By default, Constellation uses m6a.xlarge VMs (4 vCPUs, 16 GB RAM) to create your cluster. -Optionally, you can switch to a different VM type by modifying instanceType in the configuration file. -If you are using the default attestation variant awsSEVSNP, you can use the instance types described in AWS's AMD SEV-SNP docs. -Please mind the region restrictions mentioned in the Getting started section.

    If you are using the attestation variant awsNitroTPM, you can choose any of the nitroTPM-enabled instance types.

    The Constellation CLI can also print the supported instance types with: constellation config instance-types.

    -

    Fill the desired VM type into the instanceType fields in the constellation-conf.yml file.

    -

    Creating additional node groups

    -

    By default, Constellation creates the node groups control_plane_default and worker_default for control-plane nodes and workers, respectively. -If you require additional control-plane or worker groups with different instance types, zone placements, or disk sizes, you can add additional node groups to the constellation-conf.yml file. -Each node group can be scaled individually.

    -

    Consider the following example for AWS:

    -
    nodeGroups:
    control_plane_default:
    role: control-plane
    instanceType: c6a.xlarge
    stateDiskSizeGB: 30
    stateDiskType: gp3
    zone: eu-west-1c
    initialCount: 3
    worker_default:
    role: worker
    instanceType: c6a.xlarge
    stateDiskSizeGB: 30
    stateDiskType: gp3
    zone: eu-west-1c
    initialCount: 2
    high_cpu:
    role: worker
    instanceType: c6a.24xlarge
    stateDiskSizeGB: 128
    stateDiskType: gp3
    zone: eu-west-1c
    initialCount: 1
    -

    This configuration creates an additional node group high_cpu with a larger instance type and disk.

    -

    You can use the field zone to specify what availability zone nodes of the group are placed in. -On Azure, this field is empty by default and nodes are automatically spread across availability zones. -STACKIT currently offers SEV-enabled CPUs in the eu01-1, eu01-2, and eu01-3 zones. -Consult the documentation of your cloud provider for more information:

    - -

    Choosing a Kubernetes version

    -

    To learn which Kubernetes versions can be installed with your current CLI, you can run constellation config kubernetes-versions. -See also Constellation's Kubernetes support policy.

    -

    Creating an IAM configuration

    -

    You can create an IAM configuration for your cluster automatically using the constellation iam create command. -If you already have a Constellation configuration file, you can add the --update-config flag to the command. This writes the needed IAM fields into your configuration. Furthermore, the flag updates the zone/region of the configuration if it hasn't been set yet.

    -

    You must be authenticated with the AWS CLI in the shell session with a user that has the required permissions for IAM creation.

    constellation iam create aws --zone=us-east-2a --prefix=constellTest

    This command creates IAM configuration for the AWS zone us-east-2a using the prefix constellTest for all named resources being created.

    Constellation OS images are currently replicated to the following regions:

      -
    • eu-central-1
    • -
    • eu-west-1
    • -
    • eu-west-3
    • -
    • us-east-2
    • -
    • ap-south-1
    • -

    If you require the OS image to be available in another region, let us know.

    You can find a list of all regions in AWS's documentation.

    Paste the output into the corresponding fields of the constellation-conf.yaml file.

    -
    Alternatively, you can manually create the IAM configuration on your CSP.

    The following describes the configuration fields and how you obtain the required information or create the required resources.

      -
    • -

      region: The name of your chosen AWS data center region, e.g., us-east-2.

      -

      Constellation OS images are currently replicated to the following regions:

      -
        -
      • eu-central-1
      • -
      • eu-west-1
      • -
      • eu-west-3
      • -
      • us-east-2
      • -
      • ap-south-1
      • -
      -

      If you require the OS image to be available in another region, let us know.

      -

      You can find a list of all regions in AWS's documentation.

      -
    • -
    • -

      zone: The name of your chosen AWS data center availability zone, e.g., us-east-2a.

      -

      Learn more about availability zones in AWS's documentation.

      -
    • -
    • -

      iamProfileControlPlane: The name of an IAM instance profile attached to all control-plane nodes.

      -

      You can create the resource with Terraform. For that, use the provided Terraform script to generate the necessary profile. The profile name will be provided as Terraform output value: control_plane_instance_profile_name.

      -

      Alternatively, you can create the AWS profile with a tool of your choice. Use the JSON policy in main.tf in the resource aws_iam_policy.control_plane_policy.

      -
    • -
    • -

      iamProfileWorkerNodes: The name of an IAM instance profile attached to all worker nodes.

      -

      You can create the resource with Terraform. For that, use the provided Terraform script to generate the necessary profile. The profile name will be provided as Terraform output value: worker_nodes_instance_profile_name.

      -

      Alternatively, you can create the AWS profile with a tool of your choice. Use the JSON policy in main.tf in the resource aws_iam_policy.worker_node_policy.

      -
    • -
    -

    Now that you've configured your CSP, you can create your cluster.

    -

    Deleting an IAM configuration

    -

    You can keep a created IAM configuration and reuse it for new clusters. Alternatively, you can also delete it if you don't want to use it anymore.

    -

    Delete the IAM configuration by executing the following command in the same directory where you executed constellation iam create (the directory that contains constellation-iam-terraform as a subdirectory):

    -
    constellation iam destroy
    -
    caution

    For Azure, deleting the IAM configuration by executing constellation iam destroy will delete the whole resource group created by constellation iam create. -This also includes any additional resources in the resource group that weren't created by Constellation.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/workflows/create/index.html b/pr-preview/pr-4027/workflows/create/index.html deleted file mode 100644 index 56f595ac1..000000000 --- a/pr-preview/pr-4027/workflows/create/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -Create your cluster | Constellation - - - - - - - -
    Version: 2.24

    Create your cluster

    -
    info

    This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details.

    -
    Loading asciinema cast...
    -
    -

    Creating your cluster happens through multiple phases. -The most significant ones are:

    -
      -
    1. Creating the necessary resources in your cloud environment
    2. -
    3. Bootstrapping the Constellation cluster and setting up a connection
    4. -
    5. Installing the necessary Kubernetes components
    6. -
    -

    constellation apply handles all this in a single command. -You can use the --skip-phases flag to skip specific phases of the process. -For example, if you created the infrastructure manually, you can skip the cloud resource creation phase.

    -

    See the architecture section for details on the inner workings of this process.

    -
    tip

    If you don't have a cloud subscription, you can also set up a local Constellation cluster using virtualization for testing.

    -

    Before you create the cluster, make sure to have a valid configuration file.

    -
    constellation apply

    apply stores the state of your cluster's cloud resources in a constellation-terraform directory in your workspace.

    -

    Finally, configure kubectl for your cluster:

    -
    export KUBECONFIG="$PWD/constellation-admin.conf"
    -

    🏁 That's it. You've successfully created a Constellation cluster.

    -

    Troubleshooting

    -

    In case apply fails, the CLI collects logs from the bootstrapping instance and stores them inside constellation-cluster.log.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/workflows/lb/index.html b/pr-preview/pr-4027/workflows/lb/index.html deleted file mode 100644 index 6918333b9..000000000 --- a/pr-preview/pr-4027/workflows/lb/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - -Expose a service | Constellation - - - - - - - -
    Version: 2.24

    Expose a service

    -

    Constellation integrates the native load balancers of each CSP. Therefore, to expose a service simply create a service of type LoadBalancer.

    -

    Internet-facing LB service on AWS

    -

    To expose your application service externally you might want to use a Kubernetes Service of type LoadBalancer. On AWS, load-balancing is achieved through the AWS Load Balancer Controller as in the managed EKS.

    -

    Since recent versions, the controller deploy an internal LB by default requiring to set an annotation service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing to have an internet-facing LB. For more details, see the official docs.

    -

    For general information on LB with AWS see Network load balancing on Amazon EKS.

    -
    caution

    Before terminating the cluster, all LB backed services should be deleted, so that the controller can cleanup the related resources.

    -

    Ingress on AWS

    -

    The AWS Load Balancer Controller also provisions Ingress resources of class alb. -AWS Application Load Balancers (ALBs) can be configured with a target-type. -The target type ip requires using the EKS container network solution, which makes it incompatible with Constellation. -If a service can be exposed on a NodePort, the target type instance can be used.

    -

    See Application load balancing on Amazon EKS for more information.

    -
    caution

    Ingress handlers backed by AWS ALBs reside outside the Constellation cluster, so they shouldn't be handling sensitive traffic!

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/workflows/recovery/index.html b/pr-preview/pr-4027/workflows/recovery/index.html deleted file mode 100644 index 0c372f98e..000000000 --- a/pr-preview/pr-4027/workflows/recovery/index.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - -Recover your cluster | Constellation - - - - - - - -
    Version: 2.24

    Recover your cluster

    -

    Recovery of a Constellation cluster means getting it back into a healthy state after too many concurrent node failures in the control plane. -Reasons for an unhealthy cluster can vary from a power outage, or planned reboot, to migration of nodes and regions. -Recovery events are rare, because Constellation is built for high availability and automatically and securely replaces failed nodes. When a node is replaced, Constellation's control plane first verifies the new node before it sends the node the cryptographic keys required to decrypt its state disk.

    -

    Constellation provides a recovery mechanism for cases where the control plane has failed and is unable to replace nodes. -The constellation recover command securely connects to all nodes in need of recovery using attested TLS and provides them with the keys to decrypt their state disks and continue booting.

    -

    Identify unhealthy clusters

    -

    The first step to recovery is identifying when a cluster becomes unhealthy. -Usually, this can be first observed when the Kubernetes API server becomes unresponsive.

    -

    You can check the health status of the nodes via the cloud service provider (CSP). -Constellation provides logging information on the boot process and status via serial console output. -In the following, you'll find detailed descriptions for identifying clusters stuck in recovery for each CSP.

    -

    First, open the AWS console to view all Auto Scaling Groups (ASGs) in the region of your cluster. Select the ASG of the control plane <cluster-name>-<UID>-control-plane and check that enough members are in a Running state.

    Second, check the boot logs of these Instances. In the ASG's Instance management view, select each desired instance. In the upper right corner, select Action > Monitor and troubleshoot > Get system log.

    In the serial console output, search for Waiting for decryption key. -Similar output to the following means your node was restarted and needs to decrypt the state disk:

    {"level":"INFO","ts":"2022-09-08T10:21:53Z","caller":"cmd/main.go:55","msg":"Starting disk-mapper","version":"2.0.0","cloudProvider":"gcp"}
    {"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"setupManager","caller":"setup/setup.go:72","msg":"Preparing existing state disk"}
    {"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:65","msg":"Starting RejoinClient"}
    {"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"recoveryServer","caller":"recoveryserver/server.go:59","msg":"Starting RecoveryServer"}

    The node will then try to connect to the JoinService and obtain the decryption key. -If this fails due to an unhealthy control plane, you will see log messages similar to the following:

    {"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:77","msg":"Received list with JoinService endpoints","endpoints":["192.168.178.4:30090","192.168.178.2:30090"]}
    {"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.4:30090"}
    {"level":"WARN","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing dial tcp 192.168.178.4:30090: connect: connection refused\"","endpoint":"192.168.178.4:30090"}
    {"level":"INFO","ts":"2022-09-08T10:21:53Z","logger":"rejoinClient","caller":"rejoinclient/client.go:96","msg":"Requesting rejoin ticket","endpoint":"192.168.178.2:30090"}
    {"level":"WARN","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:101","msg":"Failed to rejoin on endpoint","error":"rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing dial tcp 192.168.178.2:30090: i/o timeout\"","endpoint":"192.168.178.2:30090"}
    {"level":"ERROR","ts":"2022-09-08T10:22:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:110","msg":"Failed to rejoin on all endpoints"}

    This means that you have to recover the node manually.

    -

    Recover a cluster

    -

    Recovering a cluster requires the following parameters:

    -
      -
    • The constellation-state.yaml file in your working directory or the cluster's endpoint
    • -
    • The master secret of the cluster
    • -
    -

    A cluster can be recovered like this:

    -
    $ constellation recover
    Pushed recovery key.
    Pushed recovery key.
    Pushed recovery key.
    Recovered 3 control-plane nodes.
    -

    In the serial console output of the node you'll see a similar output to the following:

    -
    {"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer","caller":"recoveryserver/server.go:93","msg":"Received recover call"}
    {"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer","caller":"recoveryserver/server.go:125","msg":"Received state disk key and measurement secret, shutting down server"}
    {"level":"INFO","ts":"2022-09-08T10:26:59Z","logger":"recoveryServer.gRPC","caller":"zap/server_interceptors.go:61","msg":"finished streaming call with code OK","grpc.start_time":"2022-09-08T10:26:59Z","system":"grpc","span.kind":"server","grpc.service":"recoverproto.API","grpc.method":"Recover","peer.address":"192.0.2.3:41752","grpc.code":"OK","grpc.time_ms":15.701}
    {"level":"INFO","ts":"2022-09-08T10:27:13Z","logger":"rejoinClient","caller":"rejoinclient/client.go:87","msg":"RejoinClient stopped"}
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/workflows/reproducible-builds/index.html b/pr-preview/pr-4027/workflows/reproducible-builds/index.html deleted file mode 100644 index 2f08880d8..000000000 --- a/pr-preview/pr-4027/workflows/reproducible-builds/index.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - -Reproduce released artifacts | Constellation - - - - - - - -
    Version: 2.24

    Reproduce released artifacts

    -

    Constellation has first-class support for reproducible builds. -Reproducing the released artifacts is an alternative to signature verification that doesn't require trusting Edgeless Systems' release process. -The following sections describe how to rebuild an artifact and how Constellation ensures that the rebuild reproduces the artifacts bit-by-bit.

    -

    Build environment prerequisites

    -

    The build systems used by Constellation - Bazel and Nix - are designed for deterministic, reproducible builds. -These two dependencies should be the only prerequisites for a successful build. -However, it can't be ruled out completely that peculiarities of the host affect the build result. -Thus, we recommend the following host setup for best results:

    -
      -
    1. A Linux operating system not older than v5.4.
    2. -
    3. The GNU C library not older than v2.31 (avoid musl).
    4. -
    5. GNU coreutils not older than v8.30 (avoid busybox).
    6. -
    7. An ext4 filesystem for building.
    8. -
    9. AppArmor turned off.
    10. -
    -

    This is given, for example, on an Ubuntu 22.04 system, which is also used for reproducibility tests.

    -
    note

    To avoid any backwards-compatibility issues, the host software versions should also not be much newer than the Constellation release.

    -

    Run the build

    -

    The following instructions outline qualitatively how to reproduce a build. -Constellation implements these instructions in the Reproducible Builds workflow, which continuously tests for reproducibility. -The workflow is a good place to look up specific version numbers and build steps.

    -
      -
    1. -

      Check out the Constellation repository at the tag corresponding to the release.

      -
      git clone https://github.com/edgelesssys/constellation.git
      cd constellation
      git checkout v2.20.0
      -
    2. -
    3. -

      Install the Bazel release specified in .bazelversion.

      -
    4. -
    5. -

      Install Nix (any recent version should do).

      -
    6. -
    7. -

      Run the build with bazel build $target for one of the following targets of interest:

      -
      //cli:cli_enterprise_darwin_amd64
      //cli:cli_enterprise_darwin_arm64
      //cli:cli_enterprise_linux_amd64
      //cli:cli_enterprise_linux_arm64
      //cli:cli_enterprise_windows_amd64
      -
    8. -
    9. -

      Compare the build result with the downloaded release artifact.

      -
    10. -
    -

    Feedback

    -

    Reproduction failures often indicate a bug in the build system or in the build definitions. -Therefore, we're interested in any reproducibility issues you might encounter. -Start a bug report and describe the details of your build environment. -Make sure to include your result binary or a diffoscope report, if possible.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/workflows/s3proxy/index.html b/pr-preview/pr-4027/workflows/s3proxy/index.html deleted file mode 100644 index 7c18c1d21..000000000 --- a/pr-preview/pr-4027/workflows/s3proxy/index.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - -Install s3proxy | Constellation - - - - - - - -
    Version: 2.24

    Install s3proxy

    -

    Constellation includes a transparent client-side encryption proxy for AWS S3 and compatible stores. -s3proxy encrypts objects before sending them to S3 and automatically decrypts them on retrieval, without requiring changes to your application. -With s3proxy, you can use S3 for storage in a confidential way without having to trust the storage provider.

    -

    Limitations

    -

    Currently, s3proxy has the following limitations:

    -
      -
    • Only PutObject and GetObject requests are encrypted/decrypted by s3proxy. -By default, s3proxy will block requests that may expose unencrypted data to S3 (e.g. UploadPart). -The allow-multipart flag disables request blocking for evaluation purposes.
    • -
    • Using the Range header on GetObject is currently not supported and will result in an error.
    • -
    -

    These limitations will be removed with future iterations of s3proxy. -If you want to use s3proxy but these limitations stop you from doing so, consider opening an issue.

    -

    Deployment

    -

    You can add the s3proxy to your Constellation cluster as follows:

    -
      -
    1. Add the Edgeless Systems chart repository: -
      helm repo add edgeless https://helm.edgeless.systems/stable
      helm repo update
      -
    2. -
    3. Set ACCESS_KEY and ACCESS_SECRET to valid credentials you want s3proxy to use to interact with S3.
    4. -
    5. Deploy s3proxy: -
      helm install s3proxy edgeless/s3proxy --set awsAccessKeyID="$ACCESS_KEY" --set awsSecretAccessKey="$ACCESS_SECRET"
      -
    6. -
    -

    If you want to run a demo application, check out the Filestash with s3proxy example.

    -

    Technical details

    -

    Encryption

    -

    s3proxy relies on Google's Tink Cryptographic Library to implement cryptographic operations securely. -The used cryptographic primitives are NIST SP 800 38f for key wrapping and AES-GCM with 256 bit keys for data encryption.

    -

    s3proxy uses envelope encryption to encrypt objects. -This means s3proxy uses a key encryption key (KEK) issued by the KeyService to encrypt data encryption keys (DEKs). -Each S3 object is encrypted with its own DEK. -The encrypted DEK is then saved as metadata of the encrypted object. -This enables key rotation of the KEK without re-encrypting the data in S3. -The approach also allows access to objects from different locations, as long as each location has access to the KEK.

    -

    Traffic interception

    -

    To use s3proxy, you have to redirect your outbound S3 traffic to s3proxy. -This can either be done by modifying your client application or by changing the deployment of your application.

    -

    The necessary deployment modifications are to add DNS redirection and a trusted TLS certificate to the client's trust store. -DNS redirection can be defined for each pod, allowing you to use s3proxy for one application without changing other applications in the same cluster. -Adding a trusted TLS certificate is necessary as clients communicate with s3proxy via HTTPS. -To have your client application trust s3proxy's TLS certificate, the certificate has to be added to the client's certificate trust store. -The Filestash with s3proxy example shows how to do this.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/workflows/sbom/index.html b/pr-preview/pr-4027/workflows/sbom/index.html deleted file mode 100644 index 1e36b9169..000000000 --- a/pr-preview/pr-4027/workflows/sbom/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -Consume software bill of materials (SBOMs) | Constellation - - - - - - - -
    Version: 2.24

    Consume software bill of materials (SBOMs)

    -
    Loading asciinema cast...
    -
    -

    Constellation builds produce a software bill of materials (SBOM) for each generated artifact. -You can use SBOMs to make informed decisions about dependencies and vulnerabilities in a given application. Enterprises rely on SBOMs to maintain an inventory of used applications, which allows them to take data-driven approaches to managing risks related to vulnerabilities.

    -

    SBOMs for Constellation are generated using Syft, signed using Cosign, and stored with the produced artifact.

    -
    note

    The public key for Edgeless Systems' long-term code-signing key is:

    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT
    JmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==
    -----END PUBLIC KEY-----

    The public key is also available for download at https://edgeless.systems/es.pub and in the Twitter profile @EdgelessSystems.

    Make sure the key is available in a file named cosign.pub to execute the following examples.

    -

    Verify and download SBOMs

    -

    The following sections detail how to work with each type of artifact to verify and extract the SBOM.

    -

    Constellation CLI

    -

    The SBOM for Constellation CLI is made available on the GitHub release page. The SBOM (constellation.spdx.sbom) and corresponding signature (constellation.spdx.sbom.sig) are valid for each Constellation CLI for a given version, regardless of architecture and operating system.

    -
    curl -LO https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom
    curl -LO https://github.com/edgelesssys/constellation/releases/download/v2.2.0/constellation.spdx.sbom.sig
    cosign verify-blob --key cosign.pub --signature constellation.spdx.sbom.sig constellation.spdx.sbom
    -

    Container Images

    -

    SBOMs for container images are attached to the image using Cosign and uploaded to the same registry.

    -

    As a consumer, use cosign to download and verify the SBOM:

    -
    # Verify and download the attestation statement
    cosign verify-attestation ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --type 'https://cyclonedx.org/bom' --key cosign.pub --output-file verification-service.att.json
    # Extract SBOM from attestation statement
    jq -r .payload verification-service.att.json | base64 -d > verification-service.cyclonedx.sbom
    -

    A successful verification should result in similar output:

    -
    $ cosign verify-attestation ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --type 'https://cyclonedx.org/bom' --key cosign.pub --output-file verification-service.sbom

    Verification for ghcr.io/edgelesssys/constellation/verification-service@v2.2.0 --
    The following checks were performed on each of these signatures:
    - The cosign claims were validated
    - The signatures were verified against the specified public key
    $ jq -r .payload verification-service.sbom | base64 -d > verification-service.cyclonedx.sbom
    -
    note

    This example considers only the verification-service. The same approach works for all containers in the Constellation container registry.

    -

    Vulnerability scanning

    -

    You can use a plethora of tools to consume SBOMs. This section provides suggestions for tools that are popular and known to produce reliable results, but any tool that consumes SPDX or CycloneDX files should work.

    -

    Syft is able to convert between the two formats in case you require a specific type.

    -

    Grype

    -

    Grype is a CLI tool that lends itself well for integration into CI/CD systems or local developer machines. It's also able to consume the signed attestation statement directly and does the verification in one go.

    -
    grype att:verification-service.sbom --key cosign.pub --add-cpes-if-none -q
    -

    Dependency Track

    -

    Dependency Track is one of the oldest and most mature solutions when it comes to managing software inventory and vulnerabilities. Once imported, it continuously scans SBOMs for new vulnerabilities. It supports the CycloneDX format and provides direct guidance on how to comply with U.S. Executive Order 14028.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/workflows/scale/index.html b/pr-preview/pr-4027/workflows/scale/index.html deleted file mode 100644 index ad78841af..000000000 --- a/pr-preview/pr-4027/workflows/scale/index.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - -Scale your cluster | Constellation - - - - - - - -
    Version: 2.24

    Scale your cluster

    -

    Constellation provides all features of a Kubernetes cluster including scaling and autoscaling.

    -

    Worker node scaling

    -

    Autoscaling

    -

    Constellation comes with autoscaling disabled by default. To enable autoscaling, find the scaling group of -worker nodes:

    -
    kubectl get scalinggroups -o json | yq '.items | .[] | select(.spec.role == "Worker") | [{"name": .metadata.name, "nodeGoupName": .spec.nodeGroupName}]'
    -

    This will output a list of scaling groups with the corresponding cloud provider name (name) and the cloud provider agnostic name of the node group (nodeGroupName).

    -

    Then, patch the autoscaling field of the scaling group resource with the desired name to true:

    -
    # Replace <name> with the name of the scaling group you want to enable autoscaling for
    worker_group=<name>
    kubectl patch scalinggroups $worker_group --patch '{"spec":{"autoscaling": true}}' --type='merge'
    kubectl get scalinggroup $worker_group -o jsonpath='{.spec}' | yq -P
    -

    The cluster autoscaler now automatically provisions additional worker nodes so that all pods have a place to run. -You can configure the minimum and maximum number of worker nodes in the scaling group by patching the min or -max fields of the scaling group resource:

    -
    kubectl patch scalinggroups $worker_group --patch '{"spec":{"max": 5}}' --type='merge'
    kubectl get scalinggroup $worker_group -o jsonpath='{.spec}' | yq -P
    -

    The cluster autoscaler will now never provision more than 5 worker nodes.

    -

    If you want to see the autoscaling in action, try to add a deployment with a lot of replicas, like the -following Nginx deployment. The number of replicas needed to trigger the autoscaling depends on the size of -and count of your worker nodes. Wait for the rollout of the deployment to finish and compare the number of -worker nodes before and after the deployment:

    -
    kubectl create deployment nginx --image=nginx --replicas 150
    kubectl -n kube-system get nodes
    kubectl rollout status deployment nginx
    kubectl -n kube-system get nodes
    -

    Manual scaling

    -

    Alternatively, you can manually scale your cluster up or down:

    -
      -
    1. Go to Auto Scaling Groups and select the worker ASG to scale up.
    2. -
    3. Click Edit
    4. -
    5. Set the new (increased) Desired capacity and Update.
    6. -
    -

    Control-plane node scaling

    -

    Control-plane nodes can only be scaled manually and only scaled up!

    -

    To increase the number of control-plane nodes, follow these steps:

    -
      -
    1. Go to Auto Scaling Groups and select the control-plane ASG to scale up.
    2. -
    3. Click Edit
    4. -
    5. Set the new (increased) Desired capacity and Update.
    6. -
    -

    If you scale down the number of control-planes nodes, the removed nodes won't be able to exit the etcd cluster correctly. This will endanger the quorum that's required to run a stable Kubernetes control plane.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/workflows/storage/index.html b/pr-preview/pr-4027/workflows/storage/index.html deleted file mode 100644 index b3315415a..000000000 --- a/pr-preview/pr-4027/workflows/storage/index.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - -Use persistent storage | Constellation - - - - - - - -
    Version: 2.24

    Use persistent storage

    -

    Persistent storage in Kubernetes requires cloud-specific configuration. -For abstraction of container storage, Kubernetes offers volumes, -allowing users to mount storage solutions directly into containers. -The Container Storage Interface (CSI) is the standard interface for exposing arbitrary block and file storage systems into containers in Kubernetes. -Cloud service providers (CSPs) offer their own CSI-based solutions for cloud storage.

    -

    Confidential storage

    -

    Most cloud storage solutions support encryption, such as GCE Persistent Disks (PD). -Constellation supports the available CSI-based storage options for Kubernetes engines in AWS, Azure, GCP, and STACKIT. -However, their encryption takes place in the storage backend and is managed by the CSP. -Thus, using the default CSI drivers for these storage types means trusting the CSP with your persistent data.

    -

    To address this, Constellation provides CSI drivers for AWS EBS, Azure Disk, GCE PD, and OpenStack Cinder, offering encryption on the node level. They enable transparent encryption for persistent volumes without needing to trust the cloud backend. Plaintext data never leaves the confidential VM context, offering you confidential storage.

    -

    For more details see encrypted persistent storage.

    -

    CSI drivers

    -

    Constellation supports the following drivers, which offer node-level encryption and optional integrity protection.

    -

    Constellation CSI driver for AWS Elastic Block Store -Mount Elastic Block Store storage volumes into your Constellation cluster. -Follow the instructions on how to install the Constellation CSI driver or check out the repository for more information.

    -

    Note that in case the options above aren't a suitable solution for you, Constellation is compatible with all other CSI-based storage options. For example, you can use AWS EFS, Azure Files, or GCP Filestore with Constellation out of the box. Constellation is just not providing transparent encryption on the node level for these storage types yet.

    -

    Installation

    -

    The Constellation CLI automatically installs Constellation's CSI driver for the selected CSP in your cluster. -If you don't need a CSI driver or wish to deploy your own, you can disable the automatic installation by setting deployCSIDriver to false in your Constellation config file.

    -

    AWS comes with two storage classes by default.

      -
    • encrypted-rwo -
        -
      • Uses SSDs of gp3 type
      • -
      • ext-4 filesystem
      • -
      • Encryption of all data written to disk
      • -
      -
    • -
    • integrity-encrypted-rwo -
        -
      • Uses SSDs of gp3 type
      • -
      • ext-4 filesystem
      • -
      • Encryption of all data written to disk
      • -
      • Integrity protection of data written to disk
      • -
      -
    • -

    For more information on encryption algorithms and key sizes, refer to cryptographic algorithms.

    info

    The default storage class is set to encrypted-rwo for performance reasons. -If you want integrity-protected storage, set the storageClassName parameter of your persistent volume claim to integrity-encrypted-rwo.

    Alternatively, you can create your own storage class with integrity protection enabled by adding csi.storage.k8s.io/fstype: ext4-integrity to the class parameters. -Or use another filesystem by specifying another file system type with the suffix -integrity, e.g., csi.storage.k8s.io/fstype: xfs-integrity.

    Note that volume expansion isn't supported for integrity-protected disks.

    -
      -
    1. -

      Create a persistent volume

      -

      A persistent volume claim is a request for storage with certain properties. -It can refer to a storage class. -The following creates a persistent volume claim, requesting 20 GB of storage via the encrypted-rwo storage class:

      -
      cat <<EOF | kubectl apply -f -
      kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
      name: pvc-example
      namespace: default
      spec:
      accessModes:
      - ReadWriteOnce
      storageClassName: encrypted-rwo
      resources:
      requests:
      storage: 20Gi
      EOF
      -
    2. -
    3. -

      Create a Pod with persistent storage

      -

      You can assign a persistent volume claim to an application in need of persistent storage. -The mounted volume will persist restarts. -The following creates a pod that uses the previously created persistent volume claim:

      -
      cat <<EOF | kubectl apply -f -
      apiVersion: v1
      kind: Pod
      metadata:
      name: web-server
      namespace: default
      spec:
      containers:
      - name: web-server
      image: nginx
      volumeMounts:
      - mountPath: /var/lib/www/html
      name: mypvc
      volumes:
      - name: mypvc
      persistentVolumeClaim:
      claimName: pvc-example
      readOnly: false
      EOF
      -
    4. -
    -

    Change the default storage class

    -

    The default storage class is responsible for all persistent volume claims that don't explicitly request storageClassName. -Constellation creates a storage class with encryption enabled and sets this as the default class. -In case you wish to change it, follow the steps below:

    -
      -
    1. -

      List the storage classes in your cluster:

      -
      kubectl get storageclass
      -

      The output is similar to this:

      -
      NAME                      PROVISIONER                         RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
      encrypted-rwo (default) {your-csp}.csi.confidential.cloud Delete Immediate true 1d
      integrity-encrypted-rwo {your-csp}.csi.confidential.cloud Delete Immediate false 1d
      -

      The default storage class is marked by (default).

      -
    2. -
    3. -

      Mark old default storage class as non default

      -

      If you previously used another storage class as the default, you will have to remove that annotation:

      -
      kubectl patch storageclass encrypted-rwo -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
      -
    4. -
    5. -

      Mark new class as the default

      -
      kubectl patch storageclass integrity-encrypted-rwo -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
      -
    6. -
    7. -

      Verify that your chosen storage class is default:

      -
      kubectl get storageclass
      -

      The output is similar to this:

      -
      NAME                                PROVISIONER                         RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
      encrypted-rwo {your-csp}.csi.confidential.cloud Delete Immediate true 1d
      integrity-encrypted-rwo (default) {your-csp}.csi.confidential.cloud Delete Immediate false 1d
      -
    8. -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/workflows/terminate/index.html b/pr-preview/pr-4027/workflows/terminate/index.html deleted file mode 100644 index 375eb8123..000000000 --- a/pr-preview/pr-4027/workflows/terminate/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - -Terminate your cluster | Constellation - - - - - - - -
    Version: 2.24

    Terminate your cluster

    -
    info

    This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details.

    -
    Loading asciinema cast...
    -
    -

    You can terminate your cluster using the CLI. For this, you need the Terraform state directory named constellation-terraform in the current directory.

    -
    danger

    All ephemeral storage and state of your cluster will be lost. Make sure any data is safely stored in persistent storage. Constellation can recreate your cluster and the associated encryption keys, but won't backup your application data automatically.

    -

    Terminate the cluster by running:

    constellation terminate

    Or without confirmation (e.g., for automation purposes):

    constellation terminate --yes

    This deletes all resources created by Constellation in your cloud environment. -All local files created by the apply command are deleted as well, except for constellation-mastersecret.json and the configuration file.

    caution

    Termination can fail if additional resources have been created that depend on the ones managed by Constellation. In this case, you need to delete these additional -resources manually. Just run the terminate command again afterward to continue the termination process of the cluster.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/workflows/terraform-provider/index.html b/pr-preview/pr-4027/workflows/terraform-provider/index.html deleted file mode 100644 index c9da38bb7..000000000 --- a/pr-preview/pr-4027/workflows/terraform-provider/index.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - -Use the Terraform provider | Constellation - - - - - - - -
    Version: 2.24

    Use the Terraform provider

    -

    The Constellation Terraform provider allows to manage the full lifecycle of a Constellation cluster (namely creation, upgrades, and deletion) via Terraform. -The provider is available through the Terraform registry and is released in lock-step with Constellation releases.

    -

    Prerequisites

    -
      -
    • a Linux / Mac operating system (ARM64/AMD64)
    • -
    • a Terraform installation of version v1.4.4 or above
    • -
    -

    Quick setup

    -

    This example shows how to set up a Constellation cluster with the reference IAM and infrastructure setup. This setup is also used when creating a Constellation cluster through the Constellation CLI. You can either consume the IAM / infrastructure modules through a remote source (recommended) or local files. The latter requires downloading the infrastructure and IAM modules for the corresponding CSP from terraform-modules.zip on the Constellation release page and placing them in the Terraform workspace directory.

    -
      -
    1. Create a directory (workspace) for your Constellation cluster.
    2. -
    -
    mkdir constellation-workspace
    cd constellation-workspace
    -
      -
    1. Use one of the example configurations for using the Constellation Terraform provider or create a main.tf file and fill it with the resources you want to create. The Constellation Terraform provider documentation offers thorough documentation on the resources and their attributes.
    2. -
    3. Initialize and apply the Terraform configuration.
    4. -
    -

    Initialize the providers and apply the configuration.

    terraform init
    terraform apply

    Optionally, you can prefix the terraform apply command with TF_LOG=INFO to collect Terraform logs while applying the configuration. This may provide helpful output in debugging scenarios.

    -
      -
    1. Connect to the cluster.
    2. -
    -
    terraform output -raw kubeconfig > constellation-admin.conf
    export KUBECONFIG=$(realpath constellation-admin.conf)
    -

    Bringing your own infrastructure

    -

    Instead of using the example infrastructure used in the quick setup, you can also provide your own infrastructure. -If you need a starting point for a custom infrastructure setup, you can download the infrastructure / IAM Terraform modules for the respective CSP from the Constellation GitHub releases. You can modify and extend the modules per your requirements, while keeping the basic functionality intact. -The module contains:

    -
      -
    • {csp}: cloud resources the cluster runs on
    • -
    • iam/{csp}: IAM resources used within the cluster
    • -
    -

    When upgrading your cluster, make sure to check the Constellation release notes for potential breaking changes in the reference infrastructure / IAM modules that need to be considered.

    -

    Cluster upgrades

    - -

    The steps for applying the upgrade are as follows:

    -
      -
    1. Update the version constraint of the Constellation Terraform provider in the required_providers block in your Terraform configuration.
    2. -
    3. If you explicitly set any of the version attributes of the provider's resources and data sources (e.g. image_version or constellation_microservice_version), make sure to update them too. Refer to Constellation's version support policy for more information on how each Constellation version and its dependencies are supported.
    4. -
    5. Update the IAM / infrastructure configuration. - -
    6. -
    7. Upgrade the Terraform module and provider dependencies and apply the targeted configuration.
    8. -
    -
      terraform init -upgrade
    terraform apply
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/workflows/troubleshooting/index.html b/pr-preview/pr-4027/workflows/troubleshooting/index.html deleted file mode 100644 index 58e51ccd4..000000000 --- a/pr-preview/pr-4027/workflows/troubleshooting/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - -Troubleshooting | Constellation - - - - - - - -
    Version: 2.24

    Troubleshooting

    -

    This section aids you in finding problems when working with Constellation.

    -

    Common issues

    -

    Issues with creating new clusters

    -

    When you create a new cluster, you should always use the latest release. -If something doesn't work, check out the known issues.

    -

    Azure: Resource Providers can't be registered

    -

    On Azure, you may receive the following error when running apply or terminate with limited IAM permissions:

    -
    Error: Error ensuring Resource Providers are registered.

    Terraform automatically attempts to register the Resource Providers it supports to
    ensure it's able to provision resources.

    If you don't have permission to register Resource Providers you may wish to use the
    "skip_provider_registration" flag in the Provider block to disable this functionality.

    [...]
    -

    To continue, please ensure that the required resource providers have been registered in your subscription by your administrator.

    -

    Afterward, set ARM_SKIP_PROVIDER_REGISTRATION=true as an environment variable and either run apply or terminate again. -For example:

    -
    ARM_SKIP_PROVIDER_REGISTRATION=true constellation apply
    -

    Or alternatively, for terminate:

    -
    ARM_SKIP_PROVIDER_REGISTRATION=true constellation terminate
    -

    Azure: Can't update attestation policy

    -

    On Azure, you may receive the following error when running apply from within an Azure environment, e.g., an Azure VM:

    -
    An error occurred: patching policies: updating attestation policy: unexpected status code: 403 Forbidden
    -

    The problem occurs because the Azure SDK we use internally attempts to authenticate towards the Azure API with the managed identity of your current environment instead of the Azure CLI token.

    -

    We decided not to deviate from this behavior and comply with the ordering of credentials.

    -

    A solution is to add the required permissions to the managed identity of your environment. For example, the managed identity of your Azure VM, instead of the account that you've authenticated with in the Azure CLI.

    -

    If your setup requires a change in the ordering of credentials, please open an issue and explain your desired behavior.

    -

    Nodes fail to join with error untrusted measurement value

    -

    This error indicates that a node's attestation statement contains measurements that don't match the trusted values expected by the JoinService. -This may for example happen if the cloud provider updates the VM's firmware such that it influences the runtime measurements in an unforeseen way. -A failed upgrade due to an erroneous attestation config can also cause this error. -You can change the expected measurements to resolve the failure.

    -
    caution

    Attestation and trusted measurements are crucial for the security of your cluster. -Be extra careful when manually changing these settings. -When in doubt, check if the encountered issue is known or contact support.

    -
    tip

    During an upgrade with modified attestation config, a backup of the current configuration is stored in the join-config config map in the kube-system namespace under the attestationConfig_backup key. To restore the old attestation config after a failed upgrade, replace the value of attestationConfig with the value from attestationConfig_backup:

    kubectl patch configmaps -n kube-system join-config -p "{\"data\":{\"attestationConfig\":\"$(kubectl get configmaps -n kube-system join-config -o "jsonpath={.data.attestationConfig_backup}")\"}}"
    -

    You can use the apply command to change measurements of a running cluster:

    -
      -
    1. Modify the measurements key in your local constellation-conf.yaml to the expected values.
    2. -
    3. Run constellation apply.
    4. -
    -

    Keep in mind that running apply also applies any version changes from your config to the cluster.

    -

    You can run these commands to learn about the versions currently configured in the cluster:

    -
      -
    • Kubernetes API server version: kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.kubernetesClusterVersion
    • -
    • image version: kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.imageVersion
    • -
    • microservices versions: helm list --filter 'constellation-services' -n kube-system
    • -
    -

    Upgrading Kubernetes resources fails

    -

    Constellation manages its Kubernetes resources using Helm. -When applying an upgrade, the charts that are about to be installed, and a values override file overrides.yaml, -are saved to disk in your current workspace under constellation-upgrade/upgrade-<timestamp>/helm-charts/. -If upgrading the charts using the Constellation CLI fails, you can review these charts and try to manually apply the upgrade.

    -
    caution

    Changing and manually applying the charts may destroy cluster resources and can lead to broken Constellation deployments. -Proceed with caution and when in doubt, -check if the encountered issue is known or contact support.

    -

    Diagnosing issues

    -

    Logs

    -

    To get started on diagnosing issues with Constellation, it's often helpful to collect logs from nodes, pods, or other resources in the cluster. Most logs are available through Kubernetes' standard -logging interfaces.

    -

    To debug issues occurring at boot time of the nodes, you can use the serial console interface of the CSP while the machine boots to get a read-only view of the boot logs.

    -

    Apart from that, Constellation also offers further observability integrations.

    -

    Node shell access

    -

    Debugging via a shell on a node is directly supported by Kubernetes.

    -
      -
    1. -

      Figure out which node to connect to:

      -
      kubectl get nodes
      # or to see more information, such as IPs:
      kubectl get nodes -o wide
      -
    2. -
    3. -

      Connect to the node:

      -
      kubectl debug node/constell-worker-xksa0-000000 -it --image=busybox
      -

      You will be presented with a prompt.

      -

      The nodes file system is mounted at /host.

      -
    4. -
    5. -

      Once finished, clean up the debug pod:

      -
      kubectl delete pod node-debugger-constell-worker-xksa0-000000-bjthj
      -
    6. -
    -

    Emergency SSH access

    -

    Emergency SSH access to nodes can be useful to diagnose issues or download important data even if the Kubernetes API isn't reachable anymore.

    -
      -
    1. -

      Enter the constellation-terraform directory in your Constellation workspace and enable emergency SSH access to the cluster:

      -
       cd constellation-terraform
      echo "emergency_ssh = true" >> ./terraform.tfvars
      terraform apply
      -
    2. -
    3. -

      Sign an existing SSH key with your master secret:

      -
      cd ../ # go back to your Constellation workspace
      constellation ssh --key your_public_key.pub
      -

      A certificate is written to constellation_cert.pub.

      -

      The certificate is valid for 24 hours and enables you to access your Constellation nodes using -certificate based authentication.

      -
    4. -
    5. -

      Now you can connect to any Constellation node using your certificate and your private key.

      -
      ssh -o CertificateFile=constellation_cert.pub -o UserKnownHostsFile=./known_hosts -i <your private key> root@<ip of constellation node>
      -

      Normally, you don't have access to the Constellation nodes since they reside in a private network. -To access those nodes anyways, you can use your Constellation load balancer as a proxy jump host. -For this, use something along the following SSH client configuration:

      -
      Host <LB public IP>
      ProxyJump none

      Host *
      IdentityFile <your private key>
      PreferredAuthentications publickey
      CertificateFile=constellation_cert.pub
      UserKnownHostsFile=./known_hosts
      User root
      ProxyJump <LB public IP>
      -

      With this configuration you can connect to a Constellation node using ssh -F <this config> <private node IP>. -You can obtain the private node IP and the public IP of the load balancer using your CSP's web UI. Note that if -you use the load balancers domain name, ssh host certificate verification doesn't work, so using the public IP is recommended.

      -
    6. -
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/workflows/trusted-launch/index.html b/pr-preview/pr-4027/workflows/trusted-launch/index.html deleted file mode 100644 index 25cb6712e..000000000 --- a/pr-preview/pr-4027/workflows/trusted-launch/index.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - -Use Azure trusted launch VMs | Constellation - - - - - - - -
    Version: 2.24

    Use Azure trusted launch VMs

    -

    Constellation also supports trusted launch VMs on Microsoft Azure. Trusted launch VMs don't offer the same level of security as Confidential VMs, but are available in more regions and in larger quantities. The main difference between trusted launch VMs and normal VMs is that the former offer vTPM-based remote attestation. When used with trusted launch VMs, Constellation relies on vTPM-based remote attestation to verify nodes.

    -
    caution

    Trusted launch VMs don't provide runtime encryption and don't keep the cloud service provider (CSP) out of your trusted computing base.

    -

    Constellation supports trusted launch VMs with instance types Standard_D*_v4 and Standard_E*_v4. Run constellation config instance-types for a list of all supported instance types.

    -

    VM images

    -

    Azure currently doesn't support community galleries for trusted launch VMs. Thus, you need to manually import the Constellation node image into your cloud subscription.

    -

    The latest image is available at https://cdn.confidential.cloud/constellation/images/azure/trusted-launch/v2.2.0/constellation.img. Simply adjust the version number to download a newer version.

    -

    After you've downloaded the image, create a resource group constellation-images in your Azure subscription and import the image. -You can use a script to do this:

    -
    wget https://raw.githubusercontent.com/edgelesssys/constellation/main/hack/importAzure.sh
    chmod +x importAzure.sh
    AZURE_IMAGE_VERSION=2.2.0 AZURE_RESOURCE_GROUP_NAME=constellation-images AZURE_IMAGE_FILE=./constellation.img ./importAzure.sh
    -

    The script creates the following resources:

    -
      -
    1. A new image gallery with the default name constellation-import
    2. -
    3. A new image definition with the default name constellation
    4. -
    5. The actual image with the provided version. In this case 2.2.0
    6. -
    -

    Once the import is completed, use the ID of the image version in your constellation-conf.yaml for the image field. Set confidentialVM to false.

    -

    Fetch the image measurements:

    -
    IMAGE_VERSION=2.2.0
    URL=https://public-edgeless-constellation.s3.us-east-2.amazonaws.com//communitygalleries/constellationcvm-b3782fa0-0df7-4f2f-963e-fc7fc42663df/images/constellation/versions/$IMAGE_VERSION/measurements.yaml
    constellation config fetch-measurements -u$URL -s$URL.sig
    -
    info

    The constellation apply command will issue a warning because manually imported images aren't recognized as production grade images:

    Configured image doesn't look like a released production image. Double check image before deploying to production.

    Please ignore this warning.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/workflows/upgrade/index.html b/pr-preview/pr-4027/workflows/upgrade/index.html deleted file mode 100644 index 524f3819b..000000000 --- a/pr-preview/pr-4027/workflows/upgrade/index.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - - -Upgrade your cluster | Constellation - - - - - - - -
    Version: 2.24

    Upgrade your cluster

    -

    Constellation provides an easy way to upgrade all components of your cluster, without disrupting its availability. -Specifically, you can upgrade the Kubernetes version, the nodes' image, and the Constellation microservices. -You configure the desired versions in your local Constellation configuration and trigger upgrades with the apply command. -To learn about available versions you use the upgrade check command. -Which versions are available depends on the CLI version you are using.

    -

    Update the CLI

    -

    Each CLI comes with a set of supported microservice and Kubernetes versions. -Most importantly, a given CLI version can only upgrade a cluster of the previous minor version, but not older ones. -This means that you have to upgrade your CLI and cluster one minor version at a time.

    -

    For example, if you are currently on CLI version v2.6 and the latest version is v2.8, you should

    -
      -
    • upgrade the CLI to v2.7,
    • -
    • upgrade the cluster to v2.7,
    • -
    • and only then continue upgrading the CLI (and the cluster) to v2.8 after.
    • -
    -

    Also note that if your current Kubernetes version isn't supported by the next CLI version, use your current CLI to upgrade to a newer Kubernetes version first.

    -

    To learn which Kubernetes versions are supported by a particular CLI, run constellation config kubernetes-versions.

    -

    Migrate the configuration

    -

    The Constellation configuration file is located in the file constellation-conf.yaml in your workspace. -Refer to the migration reference to check if you need to update fields in your configuration file. -Use constellation config migrate to automatically update an old config file to a new format.

    -

    Check for upgrades

    -

    To learn which versions the current CLI can upgrade to and what's installed in your cluster, run:

    -
    # Show possible upgrades
    constellation upgrade check

    # Show possible upgrades and write them to config file
    constellation upgrade check --update-config
    -

    You can either enter the reported target versions into your config manually or run the above command with the --update-config flag. -When using this flag, the kubernetesVersion, image, microserviceVersion, and attestation fields are overwritten with the smallest available upgrade.

    -

    Apply the upgrade

    -

    Once you updated your config with the desired versions, you can trigger the upgrade with this command:

    -
    constellation apply
    -

    Microservice upgrades will be finished within a few minutes, depending on the cluster size. -If you are interested, you can monitor pods restarting in the kube-system namespace with your tool of choice.

    -

    Image and Kubernetes upgrades take longer. -For each node in your cluster, a new node has to be created and joined. -The process usually takes up to ten minutes per node.

    -

    When applying an upgrade, the Helm charts for the upgrade as well as backup files of Constellation-managed Custom Resource Definitions, Custom Resources, and Terraform state are created. -You can use the Terraform state backup to restore previous resources in case an upgrade misconfigured or erroneously deleted a resource. -You can use the Custom Resource (Definition) backup files to restore Custom Resources and Definitions manually (e.g., via kubectl apply) if the automatic migration of those resources fails. -You can use the Helm charts to manually apply upgrades to the Kubernetes resources, should an upgrade fail.

    -
    note

    For advanced users: the upgrade consists of several phases that can be individually skipped through the --skip-phases flag. -The phases are infrastracture for the cloud resource management through Terraform, helm for the chart management of the microservices, image for OS image upgrades, and k8s for Kubernetes version upgrades.

    -

    Check the status

    -

    Upgrades are asynchronous operations. -After you run apply, it will take a while until the upgrade has completed. -To understand if an upgrade is finished, you can run:

    -
    constellation status
    -

    This command displays the following information:

    -
      -
    • The installed services and their versions
    • -
    • The image and Kubernetes version the cluster is expecting on each node
    • -
    • How many nodes are up to date
    • -
    -

    Here's an example output:

    -
    Target versions:
    Image: v2.6.0
    Kubernetes: v1.25.8
    Service versions:
    Cilium: v1.12.1
    cert-manager: v1.10.0
    constellation-operators: v2.6.0
    constellation-services: v2.6.0
    Cluster status: Some node versions are out of date
    Image: 23/25
    Kubernetes: 25/25
    -

    This output indicates that the cluster is running Kubernetes version 1.25.8, and all nodes have the appropriate binaries installed. -23 out of 25 nodes have already upgraded to the targeted image version of 2.6.0, while two are still in progress.

    -

    Apply further upgrades

    -

    After the upgrade is finished, you can run constellation upgrade check again to see if there are more upgrades available. If so, repeat the process.

    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/workflows/verify-cli/index.html b/pr-preview/pr-4027/workflows/verify-cli/index.html deleted file mode 100644 index cb0f3ecae..000000000 --- a/pr-preview/pr-4027/workflows/verify-cli/index.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - -Verify the CLI | Constellation - - - - - - - -
    Version: 2.24

    Verify the CLI

    -
    info

    This recording presents the essence of this page. It's recommended to read it in full for the motivation and all details.

    -
    Loading asciinema cast...
    -
    -

    Edgeless Systems uses sigstore and SLSA to ensure supply-chain security for the Constellation CLI and node images ("artifacts"). sigstore consists of three components: Cosign, Rekor, and Fulcio. Edgeless Systems uses Cosign to sign artifacts. All signatures are uploaded to the public Rekor transparency log, which resides at https://rekor.sigstore.dev.

    -
    note

    The public key for Edgeless Systems' long-term code-signing key is:

    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT
    JmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==
    -----END PUBLIC KEY-----

    The public key is also available for download at https://edgeless.systems/es.pub and in the Twitter profile @EdgelessSystems.

    -

    The Rekor transparency log is a public append-only ledger that verifies and records signatures and associated metadata. The Rekor transparency log enables everyone to observe the sequence of (software) signatures issued by Edgeless Systems and many other parties. The transparency log allows for the public identification of dubious or malicious signatures.

    -

    You should always ensure that (1) your CLI executable was signed with the private key corresponding to the above public key and that (2) there is a corresponding entry in the Rekor transparency log. Both can be done as described in the following.

    -
    info

    You don't need to verify the Constellation node images. This is done automatically by your CLI and the rest of Constellation.

    -

    Verify the signature

    -
    info

    This guide assumes Linux on an amd64 processor. The exact steps for other platforms differ slightly.

    -

    First, install the Cosign CLI. Next, download and verify the signature that accompanies your CLI executable, for example:

    -
    $ cosign verify-blob --key https://edgeless.systems/es.pub --signature constellation-linux-amd64.sig constellation-linux-amd64

    Verified OK
    -

    The above performs an offline verification of the provided public key, signature, and executable. To also verify that a corresponding entry exists in the public Rekor transparency log, add the variable COSIGN_EXPERIMENTAL=1:

    -
    $ COSIGN_EXPERIMENTAL=1 cosign verify-blob --key https://edgeless.systems/es.pub --signature constellation-linux-amd64.sig constellation-linux-amd64

    tlog entry verified with uuid: afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13 index: 3477047
    Verified OK
    -

    🏁 You now know that your CLI executable was officially released and signed by Edgeless Systems.

    -

    Optional: Manually inspect the transparency log

    -

    To further inspect the public Rekor transparency log, install the Rekor CLI. A search for the CLI executable should give a single UUID. (Note that this UUID contains the UUID from the previous cosign command.)

    -
    $ rekor-cli search --artifact constellation-linux-amd64

    Found matching entries (listed by UUID):
    362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13
    -

    With this UUID you can get the full entry from the transparency log:

    -
    $ rekor-cli get --uuid=362f8ecba72f4326afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13

    LogID: c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d
    Index: 3477047
    IntegratedTime: 2022-09-12T22:28:16Z
    UUID: afaba7f6635b3e058888692841848e5514357315be9528474b23f5dcccb82b13
    Body: {
    "HashedRekordObj": {
    "data": {
    "hash": {
    "algorithm": "sha256",
    "value": "40e137b9b9b8204d672642fd1e181c6d5ccb50cfc5cc7fcbb06a8c2c78f44aff"
    }
    },
    "signature": {
    "content": "MEUCIQCSER3mGj+j5Pr2kOXTlCIHQC3gT30I7qkLr9Awt6eUUQIgcLUKRIlY50UN8JGwVeNgkBZyYD8HMxwC/LFRWoMn180=",
    "publicKey": {
    "content": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFZjhGMWhwbXdFK1lDRlh6akd0YVFjckw2WFpWVApKbUVlNWlTTHZHMVN5UVNBZXc3V2RNS0Y2bzl0OGUyVEZ1Q2t6bE9oaGx3czJPSFdiaUZabkZXQ0Z3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=="
    }
    }
    }
    }
    -

    The field publicKey should contain Edgeless Systems' public key in Base64 encoding.

    -

    You can get an exhaustive list of artifact signatures issued by Edgeless Systems via the following command:

    -
    rekor-cli search --public-key https://edgeless.systems/es.pub --pki-format x509
    -

    Edgeless Systems monitors this list to detect potential unauthorized use of its private key.

    -

    Verify the provenance

    -

    Provenance attests that a software artifact was produced by a specific repository and build system invocation. For more information on provenance visit slsa.dev and learn about the adoption of SLSA for Constellation.

    -

    Just as checking its signature proves that the CLI hasn't been manipulated, checking the provenance proves that the artifact was produced by the expected build process and hasn't been tampered with.

    -

    To verify the provenance, first install the slsa-verifier. Then make sure you have the provenance file (constellation.intoto.jsonl) and Constellation CLI downloaded. Both are available on the GitHub release page.

    -
    info

    The same provenance file is valid for all Constellation CLI executables of a given version independent of the target platform.

    -

    Use the verifier to perform the check:

    -
    $ slsa-verifier verify-artifact constellation-linux-amd64 \
    --provenance-path constellation.intoto.jsonl \
    --source-uri github.com/edgelesssys/constellation

    Verified signature against tlog entry index 7771317 at URL: https://rekor.sigstore.dev/api/v1/log/entries/24296fb24b8ad77af2c04c8b4ae0d5bc5...
    Verified build using builder https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v1.2.2 at commit 18e9924b416323c37b9cdfd6cc728de8a947424a
    PASSED: Verified SLSA provenance
    - - \ No newline at end of file diff --git a/pr-preview/pr-4027/workflows/verify-cluster/index.html b/pr-preview/pr-4027/workflows/verify-cluster/index.html deleted file mode 100644 index d093383e4..000000000 --- a/pr-preview/pr-4027/workflows/verify-cluster/index.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - -Verify your cluster | Constellation - - - - - - - -
    Version: 2.24

    Verify your cluster

    -

    Constellation's attestation feature allows you, or a third party, to verify the integrity and confidentiality of your Constellation cluster.

    -

    Fetch measurements

    -

    To verify the integrity of Constellation you need trusted measurements to verify against. For each node image released by Edgeless Systems, there are signed measurements, which you can download using the CLI:

    -
    constellation config fetch-measurements
    -

    This command performs the following steps:

    -
      -
    1. Download the signed measurements for the configured image. By default, this will use Edgeless Systems' public measurement registry.
    2. -
    3. Verify the signature of the measurements. This will use Edgeless Systems' public key.
    4. -
    5. Write measurements into configuration file.
    6. -
    -

    The configuration file then contains a list of measurements similar to the following:

    -
    # ...
    measurements:
    0:
    expected: "0f35c214608d93c7a6e68ae7359b4a8be5a0e99eea9107ece427c4dea4e439cf"
    warnOnly: false
    4:
    expected: "02c7a67c01ec70ffaf23d73a12f749ab150a8ac6dc529bda2fe1096a98bf42ea"
    warnOnly: false
    5:
    expected: "e6949026b72e5045706cd1318889b3874480f7a3f7c5c590912391a2d15e6975"
    warnOnly: true
    8:
    expected: "0000000000000000000000000000000000000000000000000000000000000000"
    warnOnly: false
    9:
    expected: "f0a6e8601b00e2fdc57195686cd4ef45eb43a556ac1209b8e25d993213d68384"
    warnOnly: false
    11:
    expected: "0000000000000000000000000000000000000000000000000000000000000000"
    warnOnly: false
    12:
    expected: "da99eb6cf7c7fbb692067c87fd5ca0b7117dc293578e4fea41f95d3d3d6af5e2"
    warnOnly: false
    13:
    expected: "0000000000000000000000000000000000000000000000000000000000000000"
    warnOnly: false
    14:
    expected: "d7c4cc7ff7933022f013e03bdee875b91720b5b86cf1753cad830f95e791926f"
    warnOnly: true
    15:
    expected: "0000000000000000000000000000000000000000000000000000000000000000"
    warnOnly: false
    # ...
    -

    Each entry specifies the expected value of the Constellation node, and whether the measurement should be enforced (warnOnly: false), or only a warning should be logged (warnOnly: true). -By default, the subset of the available measurements that can be locally reproduced and verified is enforced.

    -

    During attestation, the validating side (CLI or join service) compares each measurement reported by the issuing side (first node or joining node) individually. -For mismatching measurements that have set warnOnly to true only a warning is emitted. -For mismatching measurements that have set warnOnly to false an error is emitted and attestation fails. -If attestation fails for a new node, it isn't permitted to join the cluster.

    -

    The verify command

    -
    note

    The steps below are purely optional. They're automatically executed by constellation apply when you initialize your cluster. The constellation verify command mostly has an illustrative purpose.

    -

    The verify command obtains and verifies an attestation statement from a running Constellation cluster.

    -
    constellation verify [--cluster-id ...]
    -

    From the attestation statement, the command verifies the following properties:

    -
      -
    • The cluster is using the correct Confidential VM (CVM) type.
    • -
    • Inside the CVMs, the correct node images are running. The node images are identified through the measurements obtained in the previous step.
    • -
    • The unique ID of the cluster matches the one from your constellation-state.yaml file or passed in via --cluster-id.
    • -
    -

    Once the above properties are verified, you know that you are talking to the right Constellation cluster and it's in a good and trustworthy shape.

    -

    Custom arguments

    -

    The verify command also allows you to verify any Constellation deployment that you have network access to. For this you need the following:

    -
      -
    • The IP address of a running Constellation cluster's VerificationService. The VerificationService is exposed via a NodePort service using the external IP address of your cluster. Run kubectl get nodes -o wide and look for EXTERNAL-IP.
    • -
    • The cluster's clusterID. See cluster identity for more details.
    • -
    • A constellation-conf.yaml file with the expected measurements of the cluster in your working directory.
    • -
    -

    For example:

    -
    constellation verify -e 192.0.2.1 --cluster-id Q29uc3RlbGxhdGlvbkRvY3VtZW50YXRpb25TZWNyZXQ=
    - - \ No newline at end of file

    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%0DqbVKh%x8 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 diff --git a/pr-preview/pr-4027/assets/images/example-online-boutique-c89a9a15b1d4c086d3654bf75843295e.jpg b/pr-preview/pr-4027/assets/images/example-online-boutique-c89a9a15b1d4c086d3654bf75843295e.jpg deleted file mode 100644 index 026f0d86593411ba20b8c39e15f6158ef6ce381e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 263458 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